1. 程式人生 > >關於鎖存器和觸發器的一點記錄

關於鎖存器和觸發器的一點記錄

一,鎖存器與暫存器的區別:

鎖存器與觸發器最大的區別在於,鎖存器是電平觸發,而觸發器是邊沿觸發。鎖存器在不鎖存資料時,輸出隨輸入變化;但一旦資料鎖存時,輸入對輸出不產生任何影響。

首先應該明確鎖存器和觸發器也是由與非門之類的東西構成。尤其是鎖存器,雖說數位電路定義含有鎖存器或觸發器的電路叫時序電路,但鎖存器有很多組合電路的特性。

組合電路就是一個真值表,一個函式,一組輸入對應一組輸出,當前什麼輸入就根據函式得到什麼輸出,實時跟蹤變化,這樣也就容易有冒險、競爭之類的問題產生毛刺。

二.鎖存器的危害:

對毛刺敏感,不能非同步復位,所以上電以後處於不確定的狀態;

Latch會使靜態時序分析變得非常複雜;

在PLD晶片中,基本的單元是由查詢表和觸發器組成的,若生成鎖存器反而需要更多的資源。

三.產生的原因

上面說了那沒多隻是覺得網上的沒把鎖存器說明白。下面的才是重點。

1,case

2,if——-else if

3,[email protected](敏感訊號表)

四. 解決

1.case——————加default:

關於defalut的情況:
一是可以 default:data=1‘bx;這個x表示未知,在綜合時可以避免產生鎖存器。在模擬時是紅線表示。

二是 default:data=0;這樣產生一個預設的情況。

2.if———————–一定要有else語句。

3.always———如是說道:在賦值表示式右邊參與賦值的訊號都必須在[email protected](敏感電平列表)中列出。

如果在賦值表示式右端引用了敏感電平列表中沒有列出的訊號,那麼在綜合時,將會為該沒有列出的訊號隱含地產生一個透明鎖存器。
4.賦初值。

分為如下幾種情況:
1.產生latch,warning

[email protected](a or en)
   begin
//      b = 1'b0;
      casex(en)
         3'bxx1: b = a[0];
         3'bx1x: b = a[1];
         3
'b1xx: b = a[2]; // default: b = 1'b0; endcase end

RTL圖如下:


這裡寫圖片描述

2.由於阻塞語句,使用default或者再case前直接賦值;
不產生latch ,綜合是沒有warning

[email protected](a or en)
   begin
//      b = 1'b0;
      casex(en)
         3'bxx1: b = a[0];
         3'bx1x: b = a[1];
         3'b1xx: b = a[2];
         default:  b = 1'b0;
      endcase
   end
[email protected](a or en)
   begin
      b = 1'b0;
      casex(en)
         3'bxx1: b = a[0];
         3'bx1x: b = a[1];
         3'b1xx: b = a[2];
//         default:  b = 1'b0;
      endcase
   end

RTL如下:
這裡寫圖片描述

五.關於時序邏輯if_else不完整
時序電路,生成觸發器,觸發器是有使能端的,使能端無效時資料不變,這是觸發器的特性。

[email protected](posedge I_clk)
   begin
      if(en)
         c <= a;
//      else
//         c <= c;
   end
endmodu


這裡寫圖片描述

常見的錯誤及糾正:

[email protected](a or en)
   begin
      if(en)
         c = a;
   end
endmodule

產生latch:
這裡寫圖片描述

改為:

[email protected](a or en)
   begin
      if(en)
         c = a;
      else
         c = 0;
   end
endmodule

這裡寫圖片描述
變為了選擇器。