關於鎖存器和觸發器的一點記錄
一,鎖存器與暫存器的區別:
鎖存器與觸發器最大的區別在於,鎖存器是電平觸發,而觸發器是邊沿觸發。鎖存器在不鎖存資料時,輸出隨輸入變化;但一旦資料鎖存時,輸入對輸出不產生任何影響。
首先應該明確鎖存器和觸發器也是由與非門之類的東西構成。尤其是鎖存器,雖說數位電路定義含有鎖存器或觸發器的電路叫時序電路,但鎖存器有很多組合電路的特性。
組合電路就是一個真值表,一個函式,一組輸入對應一組輸出,當前什麼輸入就根據函式得到什麼輸出,實時跟蹤變化,這樣也就容易有冒險、競爭之類的問題產生毛刺。
二.鎖存器的危害:
對毛刺敏感,不能非同步復位,所以上電以後處於不確定的狀態;
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
變為了選擇器。