鎖存器:組合電路與時序電路的橋梁
在網(wǎng)上看到一個帖子說了這樣一個說辭,我覺得很不錯,分享給大家:鎖存器不就是組合邏輯電路與時序邏輯電路的橋梁么?
其實仔細想想也是,之前功利性的學習根本沒有仔細考慮為什么拿到數(shù)電基礎(chǔ)的書后,目錄設(shè)計總是按照組合邏輯、鎖存器、時序邏輯去安排章節(jié)。
現(xiàn)在思考后我覺得很有道理(聽我開始瞎掰)最初數(shù)字電路的組合邏輯解決了很多問題,但是卻沒有很好的解決如何將這個狀態(tài)做存儲,有些設(shè)計情況下不得不將一些信號的狀態(tài)存儲,所以就使用邏輯門構(gòu)建了鎖存器的概念,設(shè)計的靈活性得到進一步提升,但是同時又存在了另外一個問題,鎖存器就像一個閥門,但是由于這個閥門打開后內(nèi)部是隨時可以變化的,這也給如何檢驗設(shè)計的正確性帶來了難度,所以急需一個器件或者設(shè)計去解決這個問題,進而有了時序邏輯電路中觸發(fā)器的概念,觸發(fā)器也就隨著 “需求和發(fā)展” 出現(xiàn)。
因此,組合邏輯、鎖存器、時序邏輯,這樣安排更像說明了數(shù)字電路的發(fā)展和迭代的歷史,雖然鎖存器的一般內(nèi)容比較少,但不可否認,鎖存器就是組合邏輯電路與時序邏輯電路的橋梁。
鎖存器概念
鎖存器( latch)是電平觸發(fā)的存儲單元,數(shù)據(jù)存儲的狀態(tài)取決于輸入時鐘(或者使能)信號的電平值,僅當鎖存器處于使能狀態(tài)時,輸出才會隨著數(shù)據(jù)輸入發(fā)生變化。
鎖存器不同于觸發(fā)器,鎖存器在不鎖存數(shù)據(jù)時,輸出端的信號隨輸入信號變化,就像信號通過一個緩存器一樣;一旦鎖存信號起鎖存作用,則數(shù)據(jù)被鎖住,輸入信號不起作用。因此鎖存器也稱為透明鎖存器, 指的是不鎖存時輸出對輸入是透明的。
鎖存器的分類包括 RS 鎖存器、門控 RS 鎖存器和 D 鎖存器, 此處介紹下 D 鎖存器。
D 鎖存器就是能夠?qū)⑤斎氲膯温窋?shù)據(jù) D 存入到鎖存器中的電路,D鎖存器的電路圖如下圖所示。
從 D 鎖存器的電路圖中可以看出,該電路主要是由兩個部分組成,第一個部分是由 G1、 G2兩個與非門組成的 RS 鎖存器,第二個部分是由 G3、 G4 兩個與非門組成的控制電路。C 為控制信號,用來控制 G3 和 G4 的激勵輸入。
下面來分析下 D 鎖存器的工作原理:
當控制信號 C=0 時,根據(jù)與非門的邏輯定律,無論 D輸入什么信號, RD 和 SD 信號都會輸出為1。RD 和 SD 都同時等于 1 的話,鎖存器的輸出端 Q 將維持原狀態(tài)不變。
當控制端 C=1 時,如果此時 D=0,SD 就等于1, RD 就等于 0,根據(jù) RS 鎖存器的邏輯規(guī)律,電路的結(jié)果就為 0 狀態(tài);如果 D =1,那么 RD 就等于 1,SD 也就等于 0,鎖存器的結(jié)果就為 1 狀態(tài),也就是說,此時鎖存器的狀態(tài)是由激勵輸入端 D 來確定的,D 等于什么,鎖存器的狀態(tài)就是什么。
根據(jù)上面的描述,可以推出 D 鎖存器的特性表, Qn 是指觸發(fā)器當前邏輯狀態(tài)也即觸發(fā)前的狀態(tài), Qn+1 是指觸發(fā)后的狀態(tài)。
通過這個表格,可以看出,當 C 為 1 時, D 的狀態(tài)和 Qn+1 的狀態(tài)完全一樣,當 D=0 時, Qn+1=0,當 D=1 時, Qn+1=1。進一步畫出 D 鎖存器的波形圖。
從 D 鎖存器的波形圖可以看出, D 是鎖存器的輸入信號, C 是鎖存器的控制信號,Q 是鎖存器的輸出信號。當控制信號 C 為高電平時,輸出信號 Q 將跟隨輸入信號 D 的變化而變化。
為什么要避免鎖存器?(Latch的危害)
前面雖然提到鎖存器是組合邏輯電路與時序電路的橋梁,但是其靈活性很難保證在設(shè)計中進行精準分析。在實際使用中,Latch 多用于門控時鐘(clock gating)的控制,在絕大多數(shù)設(shè)計中我們要避免產(chǎn)生鎖存器。它會讓設(shè)計的時序出問題,并且它的隱蔽性很強, 新人很難查出問題。
- 毛刺敏感 :鎖存器最大的危害在于不能過濾毛刺和影響工具進行時序分析。這對于下一級電路是極其危險的。這也就是為什么寄存器不用電平觸發(fā)而選擇使用邊沿觸發(fā)的原因。所以,只要能用觸發(fā)器的地方,就不用鎖存器。
- 不能異步復位: 由于其能夠儲存上次狀態(tài)的原因,上電后Latch處于不定態(tài)。
- 占用更多資源: 對于絕大多數(shù)當前主流的FPGA架構(gòu)資源中,基本是不包含Latch,這也就意味著需要更多的資源去實現(xiàn)搭建Latch。在早些版本的某些FPGA內(nèi)部包含了Latch。
- 使時序分析變得復雜: 鎖存器沒有時鐘信號,只有數(shù)據(jù)輸入和使能以及輸出 q 端,沒有時鐘信號也就說明沒有辦法對這種器件進行時序分析, 這個在時序電路里面是非常危險的行為,因為可能引起時序不滿足導致電路功能實現(xiàn)有問題。
- 額外的延時: 在ASIC設(shè)計中,鎖存器也會帶來額外的延時和DFT,并不利于提高系統(tǒng)的工作頻率。
結(jié)構(gòu)完整就能避免Latch?
關(guān)于如何避免,可能大多數(shù)的人首先想到的是組合邏輯電路中,在if-else結(jié)構(gòu)中缺少else或case結(jié)構(gòu)中缺少default所導致,所以中要求if-else結(jié)構(gòu)和case結(jié)構(gòu)要寫完整。但結(jié)構(gòu)完整就真能完全避免Latch的產(chǎn)生嗎?
module demo(
input wire [1:0] en,
output reg[3:0] latchtest
);
always @(*) begin
if (en ==1) begin
latchtest = 'd6;
end
else if (en ==2) begin
latchtest = 'd3;
end
else begin
latchtest = latchtest;
end
end
endmodule
圖上示例這種情況,雖然邏輯完整但也會生成latch,其原因是針對該邏輯信號進行了保持,構(gòu)成了邏輯環(huán)路。
latch測試
同樣下圖中的設(shè)計也會產(chǎn)生鎖存器,原因是雖然邏輯完備但是沒有針對單一信號進行完備邏輯的處理,在部分邏輯信號進行了保持,所以邏輯仍生成了latch。
//demo1
reg latchtest1,latchtest2;
always @(*)begin
if(enable)
latchtest1 = in;
else
latchtest2 = in;
end
下面的設(shè)計是我認為比較隱晦的latch。乍一看,分支完備,case語句也有default,但在EDA工具進行分析后仍出現(xiàn)latch
module demo(
input wire [1:0] en,
output reg[3:0] latchtest
);
always @(*) begin
case (en)
0:latchtest[0] = 'd1;
1:latchtest[1] = 'd1;
2:latchtest[2] = 'd1;
3:latchtest[3] = 'd1;
default:latchtest = 'd1;
endcase
end
分析其根本原因仍然是,針對相關(guān)的分支條件該信號的部分bit位進行了保持。
隱晦的latch設(shè)計
此外,三目運算符在組合邏輯設(shè)計時進行邏輯保持,同樣會引入latch。
鎖存器產(chǎn)生的根本原因
生成latch的例子很多,從例子來看不論是單個信號或者是一個信號某些位,只要在組合邏輯設(shè)計時他存在邏輯保持都有可能生成latch,但說鎖存器產(chǎn)生的根本原因,即為代碼設(shè)計時的邏輯:需要在組合邏輯中避免保持的操作。當組合邏輯需要保持時,就會綜合出鎖存器。
避免Latch的解決方法
整理常見出現(xiàn)組合邏輯保持的情況,也即能得到避免生成latch的相關(guān)方法。
- if else分支結(jié)構(gòu)不完整
- 組合邏輯中case結(jié)構(gòu)不完整
- 組合邏輯設(shè)計時使用三目運算符存在邏輯保持
- 使用原信號進行賦值或者使用原信號進行條件判斷
- 敏感信號列表不完整
所以避免latch的方法就是,要對以上或者其他未列舉的組合邏輯中存在邏輯保持的情況進行改寫和規(guī)避,即可避免頭疼的latch生成。簡單來說就是:優(yōu)化代碼邏輯,避免組合邏輯的邏輯保持。 當遇到邏輯保持的情況時,要對存在邏輯保持的分支進行補全,或者使用賦初值的方法進行覆蓋邏輯保持時的情況。
// 補全條件分支結(jié)構(gòu)
always @(*) begin
if (en)
dout = in ;
else
dout = 'd0 ;
end
//賦初值
always @(*) begin
dout = 'd0 ;
if (en)
dout = data ; //如果en有效,改寫q的值,否則q會保持為0
end
必要的邏輯保持怎么處理?
可能對于有些情況無法完全避免掉組合邏輯設(shè)計的邏輯保持,對于這種情況,可以在這個組合邏輯路徑中插入一級寄存器,寄存器的輸出替代原來邏輯保持的部分,示例如下:
wire [DATA_WIDTH-1:0] accsum_in = (ab_sum_valid)?sum_in:dout;
always @(posedge clk or negedge rst_n) begin
if(rst_n == 'd0)begin
dout <= 'd0;
end
else if(adder1_outvld == 1)begin
dout <= sum_in ;
end
end
-
FPGA設(shè)計
+關(guān)注
關(guān)注
9文章
428瀏覽量
26489 -
EDA工具
+關(guān)注
關(guān)注
4文章
265瀏覽量
31715 -
鎖存器
+關(guān)注
關(guān)注
8文章
905瀏覽量
41448 -
觸發(fā)器
+關(guān)注
關(guān)注
14文章
1996瀏覽量
61056 -
DFT
+關(guān)注
關(guān)注
2文章
224瀏覽量
22681
發(fā)布評論請先 登錄
相關(guān)推薦
評論