一、鎖存器的產(chǎn)生
??鎖存器的產(chǎn)生主要有以下兩種情況:(1)組合邏輯中使用保持狀態(tài);(2)組合邏輯中的if-else語句或case語句未列出所有可能性;
1.1 組合邏輯中使用保持狀態(tài)
assign data_out = valid ? data_in : data_out; //變量保持當(dāng)前值
always @(*) begin
if(valid)
data_out = data_in;
else
data_out = data_out; //變量保持當(dāng)前值
end
1.2 組合邏輯中的if-else語句或case語句未列出所有可能性
??對于組合邏輯中,如果使用if-else語句,未補(bǔ)全else語句,則默認(rèn)在其他條件下,數(shù)據(jù)均保持為原來的狀態(tài),那么也會產(chǎn)生鎖存器。
//if-else語句缺少else
always @(*) begin
if(valid)
data_out = data_in;
end
??而如果在組合邏輯中使用case語句,未列出case中條件所有的可能性,則相當(dāng)于對于未列出的那些情況,數(shù)據(jù)均保持為原來的狀態(tài),也會產(chǎn)生鎖存器。
//case語句未列出所有可能性
always @(*) begin
case(sel)
2'b00: data_out = 2'b00;
2'b01: data_out = data_in;
endcase
end
1.3 小結(jié)
??那么,總而言之,言而總之。對于鎖存器,其產(chǎn)生的原因可以總結(jié)為一點(diǎn):想要通過組合邏輯保持?jǐn)?shù)據(jù)不變。對于組合邏輯的實(shí)現(xiàn),我們可以認(rèn)為它是用很多門電路搭建而成的,那么,門電路與寄存器不同,其不具有保持當(dāng)前狀態(tài)的功能。也就是說,構(gòu)成當(dāng)前組合邏輯的電路中任何一個信號發(fā)生改變,都會導(dǎo)致輸出結(jié)果發(fā)生改變。如果要通過組合邏輯實(shí)現(xiàn)保持?jǐn)?shù)據(jù)的不變,那就只能產(chǎn)生鎖存器了(可以參考《數(shù)字電子技術(shù)基礎(chǔ)》第五版的SR觸發(fā)器)。
二、鎖存器的避免
??我們知道了鎖存器的產(chǎn)生原因,就可以對癥下藥,在編寫Verilog代碼時(shí)注意編碼風(fēng)格,即可避免鎖存器的產(chǎn)生。
(1)在組合邏輯中使用if-else語句時(shí)補(bǔ)全else語句
always @(*) begin
if(sel)
data_out = data_in;
else
data_out = 2'b00;
end
(2)在組合邏輯中使用case語句時(shí),設(shè)置默認(rèn)狀態(tài)default,并默認(rèn)狀態(tài)下的數(shù)據(jù)進(jìn)行賦值
always @(*) begin
case(sel)
xxx: data_out <= 2'b01;
xxx: data_out <= data_in;
default: data_out = 2'b00;
endcase
end
(3)在組合邏輯中,不可一個變量賦值給變量自身
//錯誤示例
always @(*) begin
if(sel)
data_out = data_in;
else
data_out = data_out; //變量賦值給變量自身
end
//正確示例
always @(*) begin
if(sel)
data_out = data_in;
else
data_out = 2'b00; //需要賦值一個準(zhǔn)確的數(shù)值或者其他變量
end
三、鎖存器的消除
??在FPGA設(shè)計(jì)過程中,有可能出現(xiàn)一些情況,必須使用組合邏輯,保證其實(shí)時(shí)性,且需要保持?jǐn)?shù)據(jù)不變,保證其他運(yùn)算的正確性。那么又該如何處理?
3.1 情況一
??假如我們要實(shí)現(xiàn)如下面時(shí)序圖所示功能,輸出data_out在有效信號valid的上升沿處鎖存輸入data_in的值,那么要如何實(shí)現(xiàn)?
??最開始考慮的是采用時(shí)序邏輯進(jìn)行實(shí)現(xiàn),代碼如下。
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
data_out <= 'd0;
else if(valid)
data_out <= data_in;
else
data_out <= data_out;
end
??那么,采用時(shí)序邏輯實(shí)現(xiàn),會導(dǎo)致延遲一怕,無法在有效信號valid的上升沿鎖存數(shù)據(jù),如下圖所示。
??于是考慮使用組合邏輯進(jìn)行實(shí)現(xiàn),代碼如下。
assign data_out = valid ? data_in : data_out;
??但是組合邏輯要實(shí)現(xiàn)保持狀態(tài),必然會產(chǎn)生鎖存器。綜合后會再M(fèi)essages界面會警告出現(xiàn)鎖存器,同時(shí)在Schematic中也可以看到出現(xiàn)了鎖存器,如下圖所示。而在我們的設(shè)計(jì)中,我們是不希望出現(xiàn)鎖存器的,因?yàn)槠洳焕跁r(shí)序分析。
??那么,也可以采用組合邏輯+時(shí)序邏輯的方式實(shí)現(xiàn),通過多使用一部分寄存器資源,來實(shí)現(xiàn)在valid上升沿處進(jìn)行數(shù)據(jù)采樣,且不產(chǎn)生鎖存器,代碼如下。重新綜合后,可見鎖存器消失,同時(shí)可以對齊進(jìn)行仿真,時(shí)序符合前面的要求。文章來源:http://www.zghlxwxcb.cn/news/detail-436597.html
reg [3:0] r_data_in;
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
r_data_in <= 'd0;
else
r_data_in <= data_in;
assign data_out = valid ? data_in ? r_data_in;
文章來源地址http://www.zghlxwxcb.cn/news/detail-436597.html
到了這里,關(guān)于FPGA設(shè)計(jì)中鎖存器產(chǎn)生、避免與消除的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!