時序邏輯 UDP 與組合邏輯 UDP 在定義形式和行為功能上均有不同,主要區(qū)別如下:
... : <current_state> : <next_state> ;
表示時序邏輯的 UDP 主要分為 2 種:電平觸發(fā) UDP 與 邊沿觸發(fā) UDP。
電平觸發(fā) UDP 的輸出是根據(jù)輸入電平狀態(tài)的改變而改變。
帶有清零端的 D 鎖存器的功能描述為:
其真值表為(q 表示當前狀態(tài),q+ 表示下一個狀態(tài)):
其實編寫 UDP 的過程,可以理解為換一種格式編寫真值表的過程。
帶有清零端的 D 鎖存器的 UDP 可以描述如下:
primitive d_latch(q, clear, en, d);
output q ;
reg q ;
input d, en, clear ;
initial
q = 0 ;
table
//clear en d :q :q+ ;
1 ? ? :? :0 ; //clear
0 0 ? :? :- ; //"-" means stable
0 1 0 :? :0 ; //q = d
0 1 1 :? :1 ;
endtable
endprimitive
當然,也可以在羅列端口信號時就聲明其類型,并且賦初值。
primitive d_latch2(
output reg q = 0,
input clear, en, d);
......
endprimitive
邊沿觸發(fā) UDP 的輸出是根據(jù)輸入跳邊沿和(或)輸入電平狀態(tài)的改變而改變。
直接給出帶有異步復位端(RST)且在時鐘下降沿采集信號的 D 觸發(fā)器的"真值表":
可見此"真值表"中還加入了上下沿的概念,是為了方便編寫 UDP 代碼。
此 D 觸發(fā)器的時序邏輯 UDP 描述如下:
primitive D_TRI(
output reg Q = 0,
input RST, CP, D);
table
//RST CP D :Q :Q+ ;
//(1) 清零
1 ? ? :? :0 ; //RST=1 時清零
(??) ? ? :? :- ; //忽略 RST 邊沿變化
//(2) 時鐘下降沿采集
0 (10) 0 :? :0 ; //時鐘下降沿采集信號
0 (10) 1 :? :1 ;
//possible negedge
0 (1x) ? :? :- ; //可能是時鐘下降沿時保持
0 (x0) ? :? :- ;
//(3) 時鐘上升沿保持
0 (0?) ? :? :- ; //時鐘上升沿時保持
//possible posedge
0 (x1) ? :? :- ; //可能是時鐘上升沿時保持
//(4) 非時鐘沿變化時,即便數(shù)據(jù)有跳變,輸出仍然保持
0 ? (??) :? :- ;
endtable
endprimitive // D_TRI
對此觸發(fā)器進行簡單的仿真,testbench 描述如下。
`timescale 1ns/1ps
module test ;
reg D, CP = 0 ;
reg RST ;
wire Q ;
always #5 CP = ~CP ;
//data driver
initial begin
D = 0 ;
#12 D = 1 ;
#10 D = 0 ;
#14 D = 1 ;
#3 D = 0 ;
#18 D = 0 ;
end
//reset driver
initial begin
RST = 0 ;
#3 RST = 1 ;
#2 RST = 0 ;
#22 RST = 1 ;
#1 RST = 0 ;
end
D_TRI u_d_trigger(Q, RST, CP, D);
initial begin
forever begin
#100;
//$display("---gyc---%d", $time);
if ($time >= 1000) begin
$finish ;
end
end
end
endmodule // test
仿真結果如下。
由圖可知,在 cap1 時刻,Q 端被復位清零;在 cap2 時刻,即時鐘下降沿時,輸出端采集到 D 端輸入 1;在 cap3 時刻,Q 端又被清零。符合設計。
需要注意的是:
狀態(tài)表每行多個輸入部分,最多只能有一個跳邊沿,例如下面狀態(tài)表的表述是錯誤的。
table
......
(10) (10) 1 :? :1 ;
endtable
電平觸發(fā)的狀態(tài)表輸入項,其優(yōu)先級高于邊沿觸發(fā)的狀態(tài)表輸入項。若兩者在同一時刻出現(xiàn),則輸出端的狀態(tài)由電平觸發(fā)的狀態(tài)表決定。
例如上述 D 觸發(fā)器中,RST 可以看做是電平觸發(fā),CP 可以看做是邊沿觸發(fā)。當 RST 上升沿與 CP 端下降沿同時刻來臨時,輸出端會變?yōu)?nbsp;0 ,如下圖 cap 時刻。當然,實際的時序應該避免時鐘和復位邊沿同時到來。
邊沿觸發(fā) UDP 中,必須為每一個輸入信號都指定邊沿變化時輸出信號的變化情況,否則在該信號的跳變沿處可能會造成輸出端為 X 。
例如缺少 RST 邊沿變化的說明:
//(??) ? ? :? :- ; //忽略 RST 邊沿變化
則在 RST 下降沿輸出會變?yōu)?nbsp;x。
再例如缺少時鐘穩(wěn)定、D 端數(shù)據(jù)變化時的說明:
//(4) 非時鐘沿變化時,即便數(shù)據(jù)有跳變,輸出仍然保持
//0 ? (??) :? :- ;
則 D 端數(shù)據(jù)變化的邊沿處也會使輸出為 x。
UDP 狀態(tài)表的電平和跳變沿縮寫符號及說明如下表所示。
縮寫符 | 含義 | 說明 |
---|---|---|
? | 0, 1, x | 只能用于輸入 |
b | 1, 1 | 只能用于輸入 |
- | 保持原值不變 | 只能用于輸出 |
(ab) | 信號由 a 變 b | 用作輸入端邊沿的指示 |
r | (01) | 信號的上升沿 |
f | (10) | 信號的下降沿 |
p | (01), (0x) 或 (x1) | 可能是信號的上升沿 |
n | (10), (1x) 或 (x0) | 可能是信號的下降沿 |
* | (??) | 信號任意邊沿的變化 |
針對數(shù)字設計時是選擇使用 module 還是 primitive,要從設計需求、復雜度等方面進行綜合考慮。下面給出一些指導性的建議。
點擊這里下載源碼
更多建議: