混合設計描述方式
在模塊中,結構的和行為的結構可以自由混合。也就是說,模塊描述中可以包含實例化的門、模塊實例化語句、連續賦值語句以及always語句和initial語句的混合。它們之間可以相互包含。來自always語句和initial語句(切記只有寄存器類型數據可以在這兩種語句中賦值)的值能夠驅動門或開關,而來自于門或連續賦值語句(只能驅動線網)的值能夠反過來用于觸發always語句和initial語句。
下面是混合設計方式的1位全加器實例。
module FA_Mix (A, B, Cin, Sum, Cout);
input A,B, Cin;
output Sum, Cout;
reg Cout;
reg T1, T2, T3;
wire S1;
xor X1(S1, A, B); // 門實例語句。
always
@ ( A or B or Cin ) begin // always 語句。
T1 = A & Cin;
T2 = B & Cin;
T3 = A & B;
Cout = (T1| T2) | T3;
end
assign Sum = S1 ^ Cin; // 連續賦值語句。
endmodule
只要A或B上有事件發生,門實例語句即被執行。只要A、B或Cin上有事件發生,就執行always 語句,并且只要S1或Cin上有事件發生,就執行連續賦值語句。
設計模擬
Verilog HDL不僅提供描述設計的能力,而且提供對激勵、控制、存儲響應和設計驗證的建模能力。激勵和控制可用初始化語句產生。驗證運行過程中的響應可以作為“變化時保存”或作為選通的數據存儲。最后,設計驗證可以通過在初始化語句中寫入相應的語句自動與期望的響應值比較完成。
下面是測試模塊Top的例子。該例子測試2.3節中講到的FA_Seq模塊。
‘timescale 1ns/1ns
module Top; // 一個模塊可以有一個空的端口列表。
reg PA, PB, PCi;
wire PCo, PSum;
// 正在測試的實例化模塊:
FA_Seq F1(PA, PB, PCi, PSum, PCo); // 定位。
initial
begin: ONLY_ONCE
reg [3:0] Pal;
//需要4位, Pal才能取值8。
for (Pal = 0; Pal < 8; Pal = Pal + 1)
begin
{PA, PB, PCi} = Pal;
#5 $display (“PA, PB, PCi = %b%b%b”, PA, PB, PCi,
“ : : : PCo, PSum=%b%b”, PCo, PSum);
end
end
endmodule
在測試模塊描述中使用位置關聯方式將模塊實例語句中的信號與模塊中的端口相連接。也就是說,PA連接到模塊FA_Seq的端口A,PB連接到模塊FA_Seq的端口B,依此類推。注意初始化語句中使用了一個for循環語句,在PA、PB和PCi上產生波形。for 循環中的第一條賦值語句用于表示合并的目標。自右向左,右端各相應的位賦給左端的參數。初始化語句還包含有一個預先定義好的系統任務。系統任務$display將輸入以特定的格式打印輸出。
系統任務$display調用中的時延控制規定$display任務在5個時間單位后執行。這5個時間單位基本上代表了邏輯處理時間。即是輸入向量的加載至觀察到模塊在測試條件下輸出之間的延遲時間。
這一模型中還有另外一個細微差別。Pal在初始化語句內被局部定義。為完成這一功能,初始化語句中的順序過程(begin-end)必須標記。在這種情況下, ONLY_ONCE是順序過程標記。如果在順序過程內沒有局部聲明的變量,就不需要該標記。下面是測試模塊產生的輸出。
PA, PB, PCi = 000 ::: PCo, PSum = 00
PA, PB, PCi = 001 ::: PCo, PSum = 01
PA, PB, PCi = 010 ::: PCo, PSum = 01
PA, PB, PCi = 011 ::: PCo, PSum = 10
PA, PB, PCi = 100 ::: PCo, PSum = 01
PA, PB, PCi = 101 ::: PCo, PSum = 10
PA, PB, PCi = 110 ::: PCo, PSum = 10
PA, PB, PCi = 111 ::: PCo, PSum = 11
驗證與非門交叉連接構成的RS_FF模塊的測試模塊如下例所示。
`timescale 10ns/1ns
module RS_FF (Q, Qbar, R, S);
output Q, Qbar;
input R, S;
nand #1 (Q, R, Qbar);
nand #1 (Qbar, S, Q,);
//在門實例語句中,實例名稱是可選的。
endmodule
module Test;
reg TS, TR;
wire TQ, TQb;
//測試模塊的實例語句:
RS_FF NSTA (.Q(TQ), .S(TS), .R(TR), .Qbar(TQb));
//采用端口名相關聯的連接方式。
// 加載激勵:
initial
begin:
TR = 0;
TS = 0;
#5 TS = 1;
#5 TS = 0;
TR = 1;
#5 TS = 1;
TR = 0;
#5 TS = 0;
#5 TR = 1;
end
//輸出顯示:
initial
$monitor ("At time %t ," , $time,
"TR = %b, TS=%b, TQ=%b, TQb= %b", TR, TS, TQ, TQb);
endmodule
RS_FF模塊描述了設計的結構。在門實例語句中使用門時延;例如,第一個實例語句中的門時延為1個時間單位。該門時延意味著如果R或Qbar假定在T時刻變化,Q將在T+1時刻獲得計算結果值。
模塊Test是一個測試模塊。測試模塊中的RS_FF用實例語句說明其端口用端口名關聯方式連接。在這一模塊中有兩條初始化語句。第一個初始化語句只簡單地產生TS和TR上的波形。這一初始化語句包含帶有語句間時延的程序塊過程賦值語句。
第二條初始化語句調用系統任務$monitor。這一系統任務調用的功能是只要參數表中指定的變量值發生變化就打印指定的字符串。下面是測試模塊產生的輸出。請注意`timescale指令在時延上的影響。
At time 0, TR=0, TS=0, TQ=x, TQb= x
At time 10, TR=0, TS=0, TQ=1, TQb= 1
At time 50, TR=0, TS=1, TQ=1, TQb= 1
At time 60, TR=0, TS=1, TQ=1, TQb= 0
At time 100, TR=1, TS=0, TQ=1, TQb= 0
At time 110, TR=1, TS=0, TQ=1, TQb= 1
At time 120, TR=1, TS=0, TQ=0, TQb= 1
At time 150, TR=0, TS=1, TQ=0, TQb= 1
At time 160, TR=0, TS=1, TQ=1, TQb= 1
At time 170, TR=0, TS=1, TQ=1, TQb= 0
At time 200, TR=0, TS=0, TQ=1, TQb= 0
At time 210, TR=0, TS=0, TQ=1, TQb= 1
At time 250, TR=1, TS=0, TQ=1, TQb= 1
At time 260, TR=1, TS=0, TQ=0, TQb= 1
?
評論