邊沿檢測(cè)電路(轉(zhuǎn))

所謂邊沿檢測(cè)(又叫沿提取),就是檢測(cè)輸入信號(hào)的上升沿和下降沿。在設(shè)計(jì)數(shù)字系統(tǒng)時(shí),邊沿檢測(cè)是一種很重要的思想,實(shí)際編程時(shí)用的最多的時(shí)序電路應(yīng)該就是邊沿檢測(cè)電路和分頻電路了。

那么,邊沿檢測(cè)電路該如何實(shí)現(xiàn)呢?

我們知道,在always塊的敏感信號(hào)列表中可以直接用posedge和negedge來(lái)提取上升沿和下降沿,但是如果要在always程序塊的內(nèi)部檢測(cè)上升沿或者下降沿呢?還是用poesedge和negedge嗎?顯然是不可以的,因?yàn)檫@樣的語(yǔ)句不可綜合,我在QuartusII中嘗試了,編譯時(shí)提示 ”multiple event control statements not supported for synthesis !“,意思就是不可綜合。實(shí)際上,posedge和negedge只能用在always塊的敏感信號(hào)列表中或者testbench中,所以我們還是通過(guò)其他的辦法來(lái)實(shí)現(xiàn)吧。


要實(shí)現(xiàn)邊沿檢測(cè),最直接的想法是用兩級(jí)寄存器,第二級(jí)寄存器鎖存住某個(gè)時(shí)鐘上升沿到來(lái)時(shí)的輸入電平,第一級(jí)寄存器鎖存住下一個(gè)時(shí)鐘沿到來(lái)時(shí)的輸入電平,如果這兩個(gè)寄存器鎖存住的電平信號(hào)不同,就說(shuō)明檢測(cè)到了邊沿,具體是上升沿還是下降沿可以通過(guò)組合邏輯來(lái)實(shí)現(xiàn)。如下圖所示:

圖1? 用兩級(jí)寄存器實(shí)現(xiàn)邊沿檢測(cè)

上圖使用 block 圖表示的,也可以用verilog編寫出來(lái),代碼如下:??
module edge_cap
(
? ? input clk, rst_n,
? ? input pulse,
? ? output pos_edge,
? ? output neg_edge
);
reg pulse_r1, pulse_r2;
always@ (posedgeclk 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

當(dāng)檢測(cè)到上升沿時(shí), pos_edge信號(hào)輸出一個(gè)時(shí)鐘周期的高電平; 檢測(cè)到下降沿時(shí),neg_edge輸出一個(gè)時(shí)鐘周期的高電平。


乍一看,這個(gè)電路似乎很簡(jiǎn)單地實(shí)現(xiàn)了邊沿檢測(cè)的功能,但是仔細(xì)分析就可以發(fā)現(xiàn)這種方法存在一個(gè)潛在的風(fēng)險(xiǎn):當(dāng)待測(cè)信號(hào)pulse是一個(gè)異步信號(hào)時(shí),輸出可能是亞穩(wěn)態(tài),如果pulse信號(hào)的變化剛好發(fā)生在clk時(shí)鐘的建立時(shí)間和保持時(shí)間之內(nèi),那么第一級(jí)寄存器的輸出 pulse_r1 就會(huì)進(jìn)入亞穩(wěn)態(tài),而pulse_r1的亞穩(wěn)態(tài)會(huì)立即傳遞給pos_edge和neg_edge信號(hào),從而使得整個(gè)電路的輸出進(jìn)入亞穩(wěn)態(tài),進(jìn)而影響下一級(jí)電路的正常工作,甚至導(dǎo)致整個(gè)系統(tǒng)崩潰!

因此,在進(jìn)行異步信號(hào)邊沿提取時(shí),不能直接使用上面的這種電路,而應(yīng)該先將異步信號(hào)同步化,一般采用多加一級(jí)寄存器的方法(打一拍)來(lái)減小亞穩(wěn)態(tài)的發(fā)生概率,如下圖所示:

圖2? 異步信號(hào)邊沿檢測(cè)

也可以用verilog編寫出來(lái),代碼如下:
//異步信號(hào)邊沿檢測(cè)電路,三級(jí)寄存器實(shí)現(xiàn)
module edge_cap
(
? ? input clk, rst_n,
? ? input pulse,
? ? output pos_edge,
? ? output neg_edge
);
reg pulse_r1, pulse_r2, pulse_r3;
always@ (posedgeclk 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
assignpos_edge = (pulse_r2 && ~pulse_r3) ?1:0;
assignneg_edge = (~pulse_r2 && pulse_r3) ?1:0;
endmodule

經(jīng)過(guò)這樣的同步處理后, 可以大大減小電路進(jìn)入亞穩(wěn)態(tài)的概率,如果第一級(jí)寄存器進(jìn)入了亞穩(wěn)態(tài),一般也會(huì)在一個(gè)clk周期內(nèi)穩(wěn)定下來(lái)(可能穩(wěn)定為0也可能穩(wěn)定為1),如下圖所示:

圖中pulse信號(hào)的改變剛好發(fā)生在 clk 的建立時(shí)間和保持時(shí)間之內(nèi),因而第一級(jí)寄存器的輸出pulse_r1可能會(huì)進(jìn)入亞穩(wěn)態(tài),圖中Tco為第一級(jí)寄存器pulse_r1的狀態(tài)建立時(shí)間(即clock to output),一般情況下,亞穩(wěn)態(tài)的決斷時(shí)間(即從進(jìn)入亞穩(wěn)態(tài)到穩(wěn)定下來(lái)的時(shí)間)不會(huì)超過(guò)一個(gè)時(shí)鐘周期,因此在下一個(gè)clk上升沿到來(lái)之前,pulse_r1已經(jīng)穩(wěn)定下來(lái)(可能穩(wěn)定到0也可能穩(wěn)定到1),這樣第二級(jí)寄存器就會(huì)采集到一個(gè)穩(wěn)定的狀態(tài),從而把亞穩(wěn)態(tài)限制在第二級(jí)寄存器之前,保證了整個(gè)電路輸出的穩(wěn)定性。

綜上所述,在異步信號(hào)邊沿檢測(cè)電路中,至少需要采用三級(jí)寄存器來(lái)實(shí)現(xiàn),在對(duì)系統(tǒng)穩(wěn)定性要求較高的數(shù)字系統(tǒng)中,可以采用更多級(jí)的寄存器來(lái)減小亞穩(wěn)態(tài)發(fā)生概率,提高系統(tǒng)穩(wěn)定性。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容