Abstract
邊沿檢測電路(edge detection circuit)是個常用的基本電路。
Introduction
所謂邊沿檢測就是對前一個clock狀態和目前clock狀態的比較,如果是由0變為1,能夠檢測到上升沿,則稱為上升沿檢測電路(posedge edge detection circuit),若是由1變為0,能夠檢測到下降沿,則被稱為下降沿檢測電路(negedge edge dttection circuit),能夠同時檢測上升沿與下降沿的電路稱為雙沿檢測電路(double edge detection)。
上升沿檢測電路
Method 1: 使用兩個reg
r_data_in0與r_data_in1為DFF,分別hold住上一個與目前clock的i_data_in,當i_data_in由1變為0時,則
r_data_in0 1 1 1 0 0 0
r_data_in1 1 1 1 0 0 0 //對r_data_in0取反相與
o_rising_edge得到一個時鍾周期的高電平。
Posedge detection.v / verilog
1 module posedge_detection ( 2 input clk, 3 input rst_n, 4 input i_data_in, 5 output o_rising_edge 6 ); 7 8 reg r_data_in0; 9 reg r_data_in1; 10 11 assign o_rising_edge = ~r_data_in0 & r_data_in1; 12 13 always@(posedge clk, negedge rst_n) begin 14 if (!rst_n) begin 15 r_data_in0 <= 0; 16 r_data_in1 <= 0; 17 end 18 else begin 19 r_data_in0 <= r_data_in1; 20 r_data_in1 <= i_data_in; 21 end 22 end 23 24 endmodule
這種寫法經過綜合后RTL為一個兩位的DFF與一個AND。
Methord 2: 使用一個reg
posedge_detection2.v / verilog
module posedge_detection2( input clk, input rst_n, input i_data_in, output reg o_rising_edge ); reg r_data_in0; always@(posedge clk or negedge rst_n) begin if(!rst_n) r_data_in0 <= 0; else begin r_data_in0 <= i_data_in; if({r_data_in0,i_data_in} == 2'b01) o_rising_edge <= 1; else o_rising_edge <= 0; end end endmodule
這種寫法綜合成RTL之后只有一個D-FF和一個Equal,右邊的o_rising_edge 的D-FF主要是因為always過程塊內的reg。
Vwf仿真圖形如下
下降沿檢測與上升沿相似,不在敘述
雙沿檢測電路(double edge detection)
r_data_in0與r_data_in1位reg,分別hold住上一個clock和目前的clock得i_data_in,就是i_data_in由1變0,或者由0變1,也就是r_data_in1為1,r_data_in0為0,或者是r_data_in1為0,r_data_in0為1,因此用異或(xor)連接兩個寄存器。
Method1 : 使用兩個reg
Double_edge_detection.v/ verilog
module doubleedge_detection ( input clk, input rst_n, input i_data_in, output o_double_edge ); reg r_data_in0; reg r_data_in1; assign o_double_edge = r_data_in0 ^ r_data_in1; always@(posedge clk, negedge rst_n) begin if (!rst_n) begin r_data_in0 <= 0; r_data_in1 <= 0; end else begin r_data_in0 <= r_data_in1; r_data_in1 <= i_data_in; end end endmodule
Method2 :使用一個reg
Double_edge_detection2.v/verilog
module doubleedge_detection2 ( input clk, input rst_n, input i_data_in, output reg o_double_edge ); reg r_data_in0; always@(posedge clk, negedge rst_n) begin if (!rst_n) r_data_in0 <= 0; else begin r_data_in0 <= i_data_in; if ({r_data_in0, i_data_in} == 2'b10) o_double_edge <= 1; else if ({r_data_in0, i_data_in} == 2'b01) o_double_edge <= 1; else o_double_edge <= 0; // another method // o_double_edge <= r_data_in0 ^ i_data_in; end end endmodule
Conclusion
什么時候使用這種電路呢?當input是非同步信號時,為了要讓input與同步的FSM一起處理,必須先經過邊沿檢測,使之與clock同步,然后才能跟FSM一起運作。