所謂邊沿檢測(又叫沿提?。?,就是檢測輸入信號的上升沿和下降沿。在設計數(shù)字系統(tǒng)時,邊沿檢測是一種很重要的思想,實際編程時用的最多的時序電路應該就是邊沿檢測電路和分頻電路了。
那么,邊沿檢測電路該如何實現(xiàn)呢?
我們知道,在always塊的敏感信號列表中可以直接用posedge和negedge來提取上升沿和下降沿,但是如果要在always程序塊的內(nèi)部檢測上升沿或者下降沿呢?還是用poesedge和negedge嗎?顯然是不可以的,因為這樣的語句不可綜合,我在QuartusII中嘗試了,編譯時提示 ”multiple event control statements not supported for synthesis !“,意思就是不可綜合。實際上,posedge和negedge只能用在always塊的敏感信號列表中或者testbench中,所以我們還是通過其他的辦法來實現(xiàn)吧。
要實現(xiàn)邊沿檢測,最直接的想法是用兩級寄存器,第二級寄存器鎖存住某個時鐘上升沿到來時的輸入電平,第一級寄存器鎖存住下一個時鐘沿到來時的輸入電平,如果這兩個寄存器鎖存住的電平信號不同,就說明檢測到了邊沿,具體是上升沿還是下降沿可以通過組合邏輯來實現(xiàn)。如下圖所示:
圖1? 用兩級寄存器實現(xiàn)邊沿檢測
上圖使用 block 圖表示的,也可以用verilog編寫出來,代碼如下:
//邊沿檢測電路 //2014/12/10 module edge_cap ( input clk, rst_n, input pulse, output pos_edge, output neg_edge ); reg pulse_r1, pulse_r2; always @ (posedge clk or negedge rst_n) if(!rst_n) begin pulse_r1 <= 1'b0; pulse_r2 <= 1'b0; end else begin pulse_r1 <= pulse; pulse_r2 <= pulse_r1; end assign pos_edge = (pulse_r1 && ~pulse_r2) ?1:0; assign neg_edge = (~pulse_r1 && pulse_r2) ?1:0; endmodule
當檢測到上升沿時, pos_edge信號輸出一個時鐘周期的高電平; 檢測到下降沿時,neg_edge輸出一個時鐘周期的高電平。
乍一看,這個電路似乎很簡單地實現(xiàn)了邊沿檢測的功能,但是仔細分析就可以發(fā)現(xiàn)這種方法存在一個潛在的風險:當待測信號pulse是一個異步信號時,輸出可能是亞穩(wěn)態(tài),如果pulse信號的變化剛好發(fā)生在clk時鐘的建立時間和保持時間之內(nèi),那么第一級寄存器的輸出 pulse_r1 就會進入亞穩(wěn)態(tài),而pulse_r1的亞穩(wěn)態(tài)會立即傳遞給pos_edge和neg_edge信號,從而使得整個電路的輸出進入亞穩(wěn)態(tài),進而影響下一級電路的正常工作,甚至導致整個系統(tǒng)崩潰!
因此,在進行異步信號邊沿提取時,不能直接使用上面的這種電路,而應該先將異步信號同步化,一般采用多加一級寄存器的方法來減小亞穩(wěn)態(tài)的發(fā)生概率,如下圖所示:
圖2? 異步信號邊沿檢測
也可以用verilog編寫出來,代碼如下:
//異步信號邊沿檢測電路,三級寄存器實現(xiàn) //2014/12/08 module edge_cap ( input clk, rst_n, input pulse, output pos_edge, output neg_edge ); reg pulse_r1, pulse_r2, pulse_r3; always @ (posedge clk or negedge rst_n) if(!rst_n) begin pulse_r1 <= 1'b0; pulse_r2 <= 1'b0; pulse_r3 <= 1'b0; end else begin pulse_r1 <= pulse; pulse_r2 <= pulse_r1; pulse_r3 <= pulse_r2; end assign pos_edge = (pulse_r2 && ~pulse_r3) ?1:0; assign neg_edge = (~pulse_r2 && pulse_r3) ?1:0; endmodule
經(jīng)過這樣的同步處理后, 可以大大減小電路進入亞穩(wěn)態(tài)的概率,如果第一級寄存器進入了亞穩(wěn)態(tài),一般也會在一個clk周期內(nèi)穩(wěn)定下來(可能穩(wěn)定為0也可能穩(wěn)定為1),如下圖所示:
圖中pulse信號的改變剛好發(fā)生在 clk 的建立時間和保持時間之內(nèi),因而第一級寄存器的輸出pulse_r1可能會進入亞穩(wěn)態(tài),圖中Tco為第一級寄存器pulse_r1的狀態(tài)建立時間(即clock to output),一般情況下,亞穩(wěn)態(tài)的決斷時間(即從進入亞穩(wěn)態(tài)到穩(wěn)定下來的時間)不會超過一個時鐘周期,因此在下一個clk上升沿到來之前,pulse_r1已經(jīng)穩(wěn)定下來(可能穩(wěn)定到0也可能穩(wěn)定到1),這樣第二級寄存器就會采集到一個穩(wěn)定的狀態(tài),從而把亞穩(wěn)態(tài)限制在第二級寄存器之前,保證了整個電路輸出的穩(wěn)定性。
綜上所述,在異步信號邊沿檢測電路中,至少需要采用三級寄存器來實現(xiàn),在對系統(tǒng)穩(wěn)定性要求較高的數(shù)字系統(tǒng)中,可以采用更多級的寄存器來減小亞穩(wěn)態(tài)發(fā)生概率,提高系統(tǒng)穩(wěn)定性。
評論
查看更多