關於VerilogHDL生成的鎖存器

2021-08-20 04:43:37 字數 3344 閱讀 4980

總是會遇到有寫文件中提到,不要生成鎖存器。問題是

一: 什麼叫鎖存器

二 : 為什麼不要生成鎖存器

三 : 如何避免生成鎖存器

好,現在就這三個問題,一一做出解答

一  什麼叫鎖存器

鎖存器(latch)是一種對

脈衝電平敏感的

儲存單元

電路,它們可以在特定輸入脈衝電平作用下改變狀態。鎖存,就是把

訊號暫存以維持某種電平狀態。鎖存器的最主要作用是快取,其次完成高速的控制其與慢速的外設的不同步問題,再其次是解決驅動的問題,最後是解決乙個 i/o 口既能輸出也能輸入的問題。

我的理解就是乙個鎖進訊號並儲存一段時間的電路,簡稱鎖存器。

二  為什麼不要生成鎖存器

一種說法 : 把該訊號的變化暫存起來,待敏感電平列表中的某乙個訊號變化時再起作用,純組合邏輯電路不可能作到這一點,

綜合器會發出警告。綜合工具會將latch優化掉,造成前、後**結果不一致。

第二種說法: 鎖存器為電平觸發,無效電平鎖存,有效電平輸入即反應到輸出,由於延時不同容易產生毛刺。組合邏輯中資料不需要鎖存,需要避免產生鎖存器。fpga資源中木有鎖存器,需要觸發器加邏輯門構成,消耗邏輯資源較多,但有時為了需要滿足一些規範協議,會用到鎖存器,總之fpga用的很少。 而asic設計中,由於鎖存器構成較簡單,傳輸速度快,用鎖存器可以有效提高整合度,所以用的比較多!

三   如何避免生成鎖存器

乙份資料說  在case () 後面加上    //synthesis full_case。**中//synthesis full_case 是綜合命令,告知綜合工具case中已是全部列舉可能的情況,這樣綜合後無鎖存器。又有人說他在以下**中加入 //synthesis full_case 沒有效果

module

datadistributor(datain,sel,enable,a,b,c,d);

input

datain;

input[1:0

] sel;

input

enable;

output

a;output

c;output

d;output

b;reg

a,b,c,d;

always @(datain or enable or

sel)

begin

if(enable==1

'b1)

begin

case

(sel)

2'b00:a<=datain;2'

b01:b<=datain;2'

b10:c<=datain;2'

b11:d<=datain;

default:a<=datain;

endcase

endelse

begin

a<=1

'bz;

b<=1

'bz;

c<=1

'bz;

d<=1

'bz;

endend

endmodule

這個帖子的結論就是 //synthesis full_case 去除的是沒有描述到的case情況所產生的鎖存器。所以上述**中產生的鎖存器是無法通過這條簡單的語句來消除的,好又有大神提及到

在 always 塊的 if..else 語句中如果所列的條件不完整,綜合時則會產生鎖存器。

example:

always @(action) 

if(action)  out1 <= 1'b1;

沒有考慮到 !action 的情況,預設out1保持不變,這就產生了鎖存器。

優化方法:1.列出 !action 的情況,2.對out1賦初始值

1.always @(action) 

if(action)  out1 <= 1'b1;

else    out1 <= 1'b0; |

2.always @(action)  begin

out <= 1'b0;

if(action)  out1 <= 1'b1;

end滿滿以為這個我就可以大功告成,總算知道怎麼樣避免產生鎖存器了。於是檢查了一下我的**,發現鎖存器好多啊,比如這個

1

//pulse_count and bit_count

2reg [2:0] pulse_count = 3

'd0;

3reg [3:0] bit_count = 4

'd0;

4always @ (posedge i2c_clk) begin

5if (curr_state == `idle) begin

6 pulse_count <= 3

'd0;

7 bit_count <= 4

'd0;

8end

else

begin

9if (pulse_count == 3

'd4) pulse_count <= 3

'd0;

10else

if ((curr_state != `wait) ||scl )

11 pulse_count <= pulse_count + 3

'd1;

12if (((curr_state == `tx) || (curr_state == `rx)) && (pulse_count == 3

'd4)) begin

13if (bit_count == 4

'd8) bit_count <= 4

'd0;

14else bit_count <= bit_count + 4

'd1;

15end

16end

17end

第12行產生的真值表並不全面那麼事產生了鎖存器嗎?這個是李亞民老師的**

上面那位大神博文我只看了一半,後來才發現下面這麼寫:

但是,在描述時序邏輯的時候,也通常利用 if 語句的隱式條件對帶時鐘使能的 d 觸發器建模

example:

always@(posedge clk, negedge rst_n)  begin

if(!rst_n)  sum <= 0;

else if(en)  sum <= a+b;

表示在時鐘正沿來臨時,如果 en 為 1 ,則將 a+b 的值賦給 sum, 言下之意是如果 en 為 0, 那麼 sum 保持原值不變。這裡綜合工具會把**綜合成乙個帶時鐘使能的 d 觸發器。

結論 : 組合邏輯,有無效狀態就會產生鎖存器 

Verilog HDL的任務和函式

任務和函式只能實現組合邏輯,而對時序邏輯無能為力。一 任務 任務就是一段封裝在 task endtask 之間的程式。任務可以彼此呼叫,而且任務內還可以呼叫函式。1 任務定義 形式如下 task task id 任務名 declaration 埠定義 procedural statement 任務的...

VHDL和 verilogHDL的區別

硬體描述語言hdl hardware describe language hdl概述 隨著eda技術的發展,使用硬體語言設計pld fpga成為一種趨勢。目前最主要的硬體描述語言是vhdl和verilog hdl。vhdl發展的顯紓 鋟 細瘢 鳹erilog hdl是在c語言的基礎上發展起來的一種硬...

Verilog HDL 命名的規則研究

verilog命名規範參考資料 這些名稱我們稱之為識別符號,識別符號的命名規則不再強調,與c語言類似,字母 數字 下劃線 和美元符號 開頭只能是字母或者下劃線。模組例項的名稱 通常情況下,可能會多次使用模組的例項,命名的時候通常類似於 ff0,ff1,ff2,ff3,ff4 各種資料型別的名稱 沒什...