無(wú)論同步還是異步復位,在對觸發(fā)器時(shí)序進(jìn)行分析的時(shí)候,都要考慮復位端與時(shí)鐘的相位關(guān)系。
對于同步復位,復位信號可以理解為一個(gè)普通的數據信號,它只有在時(shí)鐘的跳變沿才會(huì )其作用,一般只要復位信號持續時(shí)間大于一個(gè)時(shí)鐘周期,就可以保證正確復位。
對于異步復位,復位可以在任何時(shí)候發(fā)生,表面上看跟時(shí)鐘沒(méi)有關(guān)系,但真實(shí)情況是異步復位也需考慮時(shí)鐘跳變沿,因為時(shí)鐘沿變化和異步復位都可以引起Q端數據變化,如果異步復位信號跟時(shí)鐘在一定時(shí)間間隔內發(fā)生變化,Q值將無(wú)法確定,即亞穩態(tài)現象。這個(gè)時(shí)候既是異步復位信號持續時(shí)間再長(cháng)都沒(méi)有辦法,因為不定態(tài)已經(jīng)傳遞下去。
一下資料來(lái)自網(wǎng)絡(luò )-冰凌霄注
1.
一、特點(diǎn):
同步復位:顧名思義,同步復位就是指復位信號只有在時(shí)鐘上升沿到來(lái)時(shí),才能有效。否則,無(wú)法完成對系統的復位工作。用Verilog描述如下:
always @ (posedge clk) begin
if (!Rst_n)
...
end
異步復位:它是指無(wú)論時(shí)鐘沿是否到來(lái),只要復位信號有效,就對系統進(jìn)行復位。用Verilog描述如下:
always @ (posedge clk or negedge Rst_n) begin
if (!Rst_n)
...
end
二、各自的優(yōu)缺點(diǎn):
1、總的來(lái)說(shuō),同步復位的優(yōu)點(diǎn)大概有3條:
a、有利于仿真器的仿真。
b、可以使所設計的系統成為100%的同步時(shí)序電路,這便大大有利于時(shí)序分析,而且綜合出來(lái)的fmax一般較高。
c、因為他只有在時(shí)鐘有效電平到來(lái)時(shí)才有效,所以可以濾除高于時(shí)鐘頻率的毛刺。他的缺點(diǎn)也有不少,主要有以下幾條:
a、復位信號的有效時(shí)長(cháng)必須大于時(shí)鐘周期,才能真正被系統識別并完成復位任務(wù)。同時(shí)還要考慮,諸如:clk skew,組合邏輯路徑延時(shí),復位延時(shí)等因素。
b、由于大多數的邏輯器件的目標庫內的DFF都只有異步復位端口,所以,倘若采用同步復位的話(huà),綜合器就會(huì )在寄存器的數據輸入端口插入組合邏輯,這樣就會(huì )耗費較多的邏輯資源。
2、對于異步復位來(lái)說(shuō),他的優(yōu)點(diǎn)也有三條,都是相對應的
a、大多數目標器件庫的dff都有異步復位端口,因此采用異步復位可以節省資源。
b、設計相對簡(jiǎn)單。
c、異步復位信號識別方便,而且可以很方便的使用FPGA的全局復位端口GSR。
缺點(diǎn):
a、在復位信號釋放(release)的時(shí)候容易出現問(wèn)題。具體就是說(shuō):倘若復位釋放時(shí)恰恰在時(shí)鐘有效沿附近,就很容易使寄存器輸出出現亞穩態(tài),從而導致亞穩態(tài)。
b、復位信號容易受到毛刺的影響。
三、總結:
所以說(shuō),一般都推薦使用異步復位,同步釋放的方式,而且復位信號低電平有效。這樣就可以?xún)扇涿懒恕?/p>
2:推薦的復位方式
所謂推薦的復位方式就是上文中所說(shuō)的:“異步復位,同步釋放”。這就結合了雙方面的優(yōu)點(diǎn),很好的克服了異步復位的缺點(diǎn)(因為異步復位的問(wèn)題主要出現在復位信號釋放的時(shí)候,具體原因可見(jiàn)上文)。
其實(shí)做起來(lái)也并不難,我推薦一種我經(jīng)常使用的方式吧:那就是在異步復位鍵后加上一個(gè)所謂的“reset synchronizer”,這樣就可以使異步復位信號同步化,然后,再用經(jīng)過(guò)處理的復位信號去作用系統,就可以保證比較穩定了。reset sychronizer的Verilog代碼如下:
module Reset_Synchronizer
(output reg rst_n,
input clk, asyncrst_n);
reg rff1;
always @ (posedge clk , negedge asyncrst_n) begin
if (!asyncrst_n) {rst_n,rff1} <= 2'b0;
else {rst_n,rff1} <= {rff1,1'b1};
end
endmodule
大家可以看到,這就是一個(gè)dff,異步復位信號直接接在它的異步復位端口上(低電平有效),然后數據輸入端rff1一直為高電平‘1’。倘若異步復位信號有效的話(huà),觸發(fā)器就會(huì )復位,輸出為低,從而復位后繼系統。但是,又由于這屬于時(shí)鐘沿觸發(fā),當復位信號釋放時(shí),觸發(fā)器的輸出要延遲一個(gè)時(shí)鐘周期才能恢復成‘1’,因此使得復位信號的釋放與時(shí)鐘沿同步化。 此外,還有一種方法更為直接,就是直接在異步復位信號后加一個(gè)D觸發(fā)器,然后用D觸發(fā)器的輸出作為后級系統的復位信號,也能達到相同的效果。這里就不多說(shuō)了。
3:多時(shí)鐘系統中復位的處理方法)
這是一個(gè)很實(shí)際的問(wèn)題,因為在較大型的系統中,一個(gè)時(shí)鐘驅動(dòng)信號顯然不能滿(mǎn)足要求,一定會(huì )根據系統的要求用多個(gè)同源時(shí)鐘(當然也可以是非同源了)去驅動(dòng)系統的不同部分。那么在這樣的多時(shí)鐘系統中,復位鍵怎么設置?它的穩定與否直接關(guān)系到了整個(gè)系統的穩定性,因此要格外注意(在我看來(lái),復位信號在同步時(shí)序系統中的地位和時(shí)鐘信號一樣重要)。下面就說(shuō)一下具體的處理方法,當然所遵循的原則就仍應該是上文的“異步復位,同步釋放”:
1.non-coordinated reset removal:顧名思義,就是同一個(gè)系統中的多個(gè)同源時(shí)鐘域的復位信號,由彼此獨立的“reset synchronizer”驅動(dòng)。當異步復位信號有效時(shí),各時(shí)鐘域同時(shí)復位,但是復位釋放的時(shí)間由各自的驅動(dòng)時(shí)鐘決定,也是就說(shuō):時(shí)鐘快的先釋放,時(shí)鐘慢的后釋放,但是各復位信號之間沒(méi)有先后關(guān)系。
2.sequence coordinated reset removal:這是相對于上述方式來(lái)說(shuō)的,也就是說(shuō)各時(shí)鐘域的復位信號彼此相關(guān),各個(gè)部分系統雖然也同時(shí)復位,但是卻分級釋放。而分級的順序可由各個(gè)“reset synchronizer”的級聯(lián)方式?jīng)Q定?梢韵葟臀磺凹,再復位后級,也可以反過(guò)來(lái)。反正方式很靈活,需要根據實(shí)際需要而定。由于圖片上傳問(wèn)題,我只能用程序表示了,大家湊或看吧,哈哈
例子:三級復位系統,系統中的時(shí)鐘分別為1M,2M,11M:
第一級Reset_Sychronizer程序:
module Reset_Synchronizer
(output reg rst_n,
input clk, asyncrst_n);
reg rff1;
always @ (posedge clk , negedge asyncrst_n)
begin
if (!asyncrst_n) {rst_n,rff1} <= 2'b0;
else {rst_n,rff1} <= {rff1,1'b1};
end
endmodule
第2,3級的Reset_Sychronizer程序:
module Reset_Synchronizer2
(output reg rst_n,
input clk, asyncrst_n,d);
reg rff1;
always @ (posedge clk , negedge asyncrst_n) begin
if (!asyncrst_n) {rst_n,rff1} <= 2'b0;
else {rst_n,rff1} <= {rff1,d};
end
endmodule
頂層模塊的源程序:
include "Reset_Synchronizer.v"
include "Reset_Synchronizer2.v"
module AsynRstTree_Trans
( input Clk1M,Clk2M,Clk11M,SysRst_n,
output SysRst1M_n,SysRst2M_n,SysRst11M_n
);
Reset_Synchronizer Rst1M(.clk(Clk1M),. asyncrst_n(SysRst_n),.rst_n(SysRst1M_n));
Reset_Synchronizer2Rst2M(.clk(Clk2M),.d(SysRst1M_n),. asyncrst_n(SysRst_n),.rst_n(SysRst2M_n));
Reset_Synchronizer2Rst11M(.clk(Clk11M),.d(SysRst2M_n),. asyncrst_n(SysRst_n),.rst_n(SysRst11M_n));
endmodule |