fpga檢測上升沿

檢測上升沿的原理:使用高頻的時鐘對信號進行採樣,因此要實現上升沿檢測,時鐘頻率至少要在信號最高頻率的2倍以上,否則就可能出現漏檢測。具體請參見下面代碼。

module edge_check(clk, rst_n, signal, pos_edge, neg_edge, both_edge);

input clk;
input rst_n;
input signal;
output pos_edge;
output neg_edge;
output both_edge;


reg sig_r0, sig_r1;  // 狀態寄存器
always @ (posedge clk or negedge rst_n)
    if (!rst_n) begin 
        sig_r0 <= 1'b0;
        sig_r1 <= 1'b0;
    end else begin 
        sig_r0 <= signal;
        sig_r1 <= sig_r0;
    end 

assign pos_edge = (~sig_r1) & (sig_r0);
assign neg_edge = sig_r1 & (~sig_r0);   
assign both_edge = sig_r1 ^ sig_r0;  // 雙邊沿檢測,或pos_edge|neg_edge

endmodule 

使用Quartus II綜合佈線之後的RTL視圖如下:

check_regs

從RTL視圖中可以看出,電路是通過一個異步復位的D觸發器實現的。

ModelSim的仿真視圖如下,從中可看出已檢測出上升和下降沿,但存在一個延時,這是因爲使用了時鐘同步的檢測。

modelsim1

或者上面的Verilog代碼還可以換一種寫法,效率上差不了太多;

module edge_check(clk, rst_n, signal, pos_edge, neg_edge, both_edge);

input clk;
input rst_n;
input signal;
output pos_edge;
output neg_edge;
output both_edge;

reg [1:0]sig_fifo;
reg sig_r0, sig_r1;  // 狀態寄存器
always @ (posedge clk or negedge rst_n)
    if (!rst_n) begin 
        sig_fifo <= 2'b0;
    end else begin 
        sig_fifo <= {sig_fifo[0], signal};
    end 

assign pos_edge = (sig_fifo == 2'b01);
assign neg_edge = (sig_fifo == 2'b10);  
assign both_edge = sig_fifo[0] ^ sig_fifo[1];  // 雙邊沿檢測,或pos_edge|neg_edge

endmodule 

生成的RTL視圖爲

check_fifo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章