避免latch verilog FPGA 基礎(chǔ)練習(xí)2
發(fā)現(xiàn)問題,用技術(shù)解決問題。興趣是自己的源動(dòng)力 !
前言
本文由如何避免latch的問題場景,來更詳細(xì)的描述verilog中的組合邏輯電路和時(shí)序邏輯電路等等理論知識。由latch這個(gè)問題入手來闡述更多理論知識,有助于更好的理解和記憶。
一、latch是什么?
Latch其實(shí)就是鎖存器,是一種在異步電路系統(tǒng)中,對輸入信號電平敏感的單元,用來存儲信息。鎖存器在數(shù)據(jù)未鎖存時(shí),輸出端的信號隨輸入信號變化,就像信號通過一個(gè)緩沖器,一旦鎖存信號有效,則數(shù)據(jù)被鎖存,輸入信號不起作用。因此,鎖存器也被稱為透明鎖存器,指的是不鎖存時(shí)輸出對于輸入是透明的。
簡單理解latch的核心就是一句話:一旦鎖存信號有效,則數(shù)據(jù)被鎖存,輸入信號不起作用。
二、latch出現(xiàn)的場景和危害
2.1 場景
Latch的問題是因?yàn)?strong>只有組合邏輯才會產(chǎn)生這種問題,產(chǎn)生Latch是我們在同步電路中盡量避免的,但并不表示Latch沒有用的或者說是錯(cuò)誤的,Latch在異步電路中是非常有用的,只是我們設(shè)計(jì)的是同步電路,要盡量避免。
上面這句話說只有組合邏輯才產(chǎn)生latch,又接著說latch在同步電路中要避免,如果不理解組合邏輯、時(shí)序邏輯、異步電路和同步電路,理解起來會有點(diǎn)繞。2.3、2.4節(jié)會對這句話解惑。
2.2 危害
在同步電路中Latch會產(chǎn)生不好的效果
- 如對毛刺敏感;不能異步復(fù)位,上電后處于不定態(tài);還會讓靜態(tài)時(shí)序分析變得十分復(fù)雜;
理解:從latch本身的特性出發(fā):一旦鎖存信號有效,則數(shù)據(jù)被鎖存,輸入信號不起作用。理解了這句話,就可以明白為什么latch會產(chǎn)生這么多不良效果了
- 在FPGA的資源中,大部分器件沒有鎖存器這個(gè)東西,所以需要用使用寄存器來組成鎖存器所以會占用更多邏輯資源;在ASIC設(shè)計(jì)中,鎖存器也會帶來額外的延時(shí)和DFT,并不利于提高系統(tǒng)的工作頻 率
簡單理解就是:鎖存器可能會有多個(gè)寄存器組成,浪費(fèi)資源。
2.3 組合邏輯和時(shí)序邏輯
這里先給出組合邏輯和時(shí)序邏輯的概念的簡單理解:
- 組合邏輯:數(shù)字電路滿足任意時(shí)刻的輸出僅僅取決于該時(shí)刻的輸入,那么該數(shù)字電路為組合邏輯電路。簡單理解就是輸入進(jìn)來立刻輸出*
注意:這里的數(shù)字電路不是僅僅理解為一個(gè)電路與門,如下圖。可能是一個(gè)復(fù)雜的組合邏輯。
兩種組合邏輯代碼如下:
always @(*)
temp <= A + B;
assign temp <= A + B;
- 時(shí)序邏輯:如果數(shù)字電路任意時(shí)刻的輸出不僅取決于當(dāng)前時(shí)刻的輸入,而且還取決于數(shù)字電路原來的狀態(tài),那么該數(shù)字電路為時(shí)序邏輯電路。簡單理解就是輸出的值要依賴某個(gè)狀態(tài),這個(gè)狀態(tài)就是時(shí)鐘的上升沿或者下降沿*
下面是時(shí)序邏輯代碼示例
always @(posedge clk or posedge reset) begin
if (reset) begin
Q <= 4'b0000;
end else begin
Q <= Q + 1;
end
end
2.4 同步(時(shí)序)邏輯電路 和 異步(時(shí)序)邏輯電路
- 同步時(shí)序電路:狹隘的定義就是數(shù)字電路(簡單或者復(fù)雜的與或門組合)被同一個(gè)時(shí)鐘信號驅(qū)動(dòng)。
注意理解:時(shí)序邏輯電路中肯定有組合邏輯的成分存在,但組合邏輯電路中卻不可能有時(shí)序邏輯的成分存在。
這里可以返回到2.1節(jié)去理解,latch只有在組合邏輯中存在。因?yàn)闀r(shí)序電路中存在組合邏輯(這里不要只從verilog代碼層面去考慮,要從verilog代碼映射的電路圖來考慮,如上圖),所以需要在同步電路中去避免latch的產(chǎn)生。
- 異步時(shí)序電路:簡單理解就是一個(gè)時(shí)序電路(異步也是時(shí)序電路),多個(gè)有差異的時(shí)鐘來決定輸入和輸出。
這里總結(jié)一下第二節(jié)的內(nèi)容:組合邏輯、時(shí)序邏輯、同步時(shí)序和異步時(shí)序,理解的關(guān)鍵就是抓住輸入和輸出這兩個(gè)關(guān)鍵詞。即:輸入和輸出不依賴其他信號就是組合邏輯,依賴時(shí)鐘就是時(shí)序邏輯。時(shí)序邏輯中又分同步和異步,輸入輸出只依賴一個(gè)時(shí)鐘就是同步,依賴多個(gè)時(shí)鐘就是異步。
理解以上概念了,再回頭看latch發(fā)生的場景,就豁然開朗了。
三、如何避免latch
- 情況一:組合邏輯中if語句沒有else
module latch_one
(
input wire in1 , //輸入信號in1
input wire in2 , //輸入信號in2
input wire in3 , //輸入信號in3
output reg [7:0] out //輸出信號out
);
//out:根據(jù)3個(gè)輸入信號選擇輸出對應(yīng)的8bit out信號
always@(*)
if({in1, in2, in3} == 3'b000)
out = 8'b0000_0001;
else if({in1, in2, in3} == 3'b001)
out = 8'b0000_0010;
else if({in1, in2, in3} == 3'b010)
out = 8'b0000_0100;
else if({in1, in2, in3} == 3'b011)
out = 8'b0000_1000;
else if({in1, in2, in3} == 3'b100)
out = 8'b0001_0000;
else if({in1, in2, in3} == 3'b101)
out = 8'b0010_0000;
else if({in1, in2, in3} == 3'b110)
out = 8'b0100_0000;
else if({in1, in2, in3} == 3'b111)
out = 8'b1000_0000;
// else 把最后一個(gè)if的else注釋掉,就會產(chǎn)生latch
// out = 8'b0000_0001;
endmodule
- 情況二:組合邏輯中case的條件不能夠完全列舉且不寫default
module latch_two
(
input wire in1 , //輸入信號in1
input wire in2 , //輸入信號in2
input wire in3 , //輸入信號in2
output reg [7:0] out //輸出信號out
);
//out:根據(jù)3個(gè)輸入信號選擇輸出對應(yīng)的8bit out信號
always@(*)
case({in1, in2, in3})
3'b000 : out = 8'b0000_0001;
3'b001 : out = 8'b0000_0010;
3'b010 : out = 8'b0000_0100;
3'b011 : out = 8'b0000_1000;
3'b100 : out = 8'b0001_0000;
3'b101 : out = 8'b0010_0000;
3'b110 : out = 8'b0100_0000;
//把最后一種情況和default都注釋掉,使case的條件不能夠完全列舉
//3'b111 : out = 8'b1000_0000;
//default: out = 8'b0000_0001;
endcase
endmodule
endmodule
- 情況三:組合邏輯中輸出變量賦值給自己
module latch_three
(
input wire in1 , //輸入信號in1
input wire in2 , //輸入信號in2
input wire in3 , //輸入信號in3
output reg [7:0] out //輸出信號out
);
//out:根據(jù)3個(gè)輸入信號選擇輸出對應(yīng)的8bit out信號
always@(*)
if({in1, in2, in3} == 3'b000)
out = 8'b0000_0001;
else if({in1, in2, in3} == 3'b001)
out = 8'b0000_0010;
elseif({in1, in2, in3} == 3'b010)
out = 8'b0000_0100;
elseif({in1, in2, in3} == 3'b011)
out = 8'b0000_1000;
elseif({in1, in2, in3} == 3'b100)
out = 8'b0001_0000;
elseif({in1, in2, in3} == 3'b101)
out = 8'b0010_0000;
elseif({in1, in2, in3} == 3'b110)
out = 8'b0100_0000;
elseif({in1, in2, in3} == 3'b111)
out = 8'b1000_0000;
else
out = out;//輸出變量賦值給自己
總結(jié)
核心思想:在拋出latch這個(gè)問題的情況下,去理解一些基礎(chǔ)的理論概念,大致理解就行。知道在編寫代碼的時(shí)候,如何去避免latch。
- 歡迎一起交流學(xué)習(xí),如有錯(cuò)誤之處,還請各位指正。
參考資料文章來源:http://www.zghlxwxcb.cn/news/detail-758269.html
[1] FPGA之組合邏輯與時(shí)序邏輯、同步邏輯與異步邏輯的概念文章來源地址http://www.zghlxwxcb.cn/news/detail-758269.html
到了這里,關(guān)于避免latch verilog FPGA 基礎(chǔ)練習(xí)2的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!