$display 語法 (課本 p2-10 - p2-12)
$display("Hello world")
可以在螢幕上顯示 Hello world 字串,在半加器的測試檔中作以下修改:
initial begin
$display("Half Adder test begin!!"); // 加入此行
$dumpvars;
$dumpfile("testha.dmp");
#0 a=0;
b=0;
$display($time, "=>a=%b,b=%b,sumX=%b,coutX=%b",a,b,sumX,coutX); // 加入此行
然後執行模擬,我們可以得到以下螢幕輸出:
Half Adder test begin!!
0=>a=0,b=0,sumX=x,coutX=x
從以上輸出我們可以得到當 a=0, b=0 的時候,sumX 跟 coutX 的值為 x (未知)。為什麼會有這個輸出結果 ?
原因:所有的電路都有延遲,當訊號在第 0 秒輸入時,不可能輸出就跟著改變。因此,
我們可以再修改程式碼如下:
#0 a=0;
b=0;
$display($time, "=>a=%b,b=%b,sumX=%b,coutX=%b",a,b,sumX,coutX);
#1
$display($time, "=>a=%b,b=%b,sumX=%b,coutX=%b",a,b,sumX,coutX);
其輸出為:
Half Adder test begin!!
0=>a=0,b=0,sumX=x,coutX=x
1=>a=0,b=0,sumX=0,coutX=0
我們可以觀察上面的第二行,發現在第 1 個時間單位時,sumX=0, coutX=0。這表示經過一個時間單位的延遲之後,電路已完成運算並在輸出端看到結果。
現在有個問題,萬一我們每個訊號的改變都希望能從螢幕上看到數值,該如何作 ?
1. 每一個訊號改變都加上 $display ==> 累死人,我們最好不要作這種蠢事
2. 使用 $monitor ==> 比較聰明的作法
因此我們可以將測試檔改成:
initial begin
$display("Half Adder test begin!!"); // 加入此行
$monitor($time, "=>a=%b,b=%b,sumX=%b,coutX=%b",a,b,sumX,coutX); // 加入此行
$dumpvars;
$dumpfile("testha.dmp");
#0 a=0;
b=0;
其輸出為:
Half Adder test begin!!
0=>a=0,b=0,sumX=0,coutX=0
10=>a=0,b=1,sumX=1,coutX=0
20=>a=1,b=0,sumX=1,coutX=0
30=>a=1,b=1,sumX=0,coutX=1
我們可以看到只要加一行 $monitor 之後,系統即會根據輸出/入的變化而自動列印其數值,不必每一行都加 $display。
RTL level 的程式寫法
連接運算子 (p 5-19)
請將 half adder 以 rtl 方式撰寫出來
//RTL Level code | // Gate Level code
//ha_rtl.v | // ha_gate.v
module half_adder(x, y, Sum, Cout); | module half_adder(x, y, Sum, Cout);
|
input x, y; | input x, y;
output Sum, Cout; | output Sum, Cout;
reg Sum, Cout; |
| // Circuit Description
// Circuit Description |
| xor xor0(Sum, x, y);
always @ (x or y) | and and0(Cout, x, y);
{Cout,Sum} = x+y; |
| endmodule
endmodule |
上面左邊的程式碼是告訴我們以 RTL 方式撰寫出來的 code,現在我們希望能將寫完的程式進行模擬,請執行:
cver ha_rtl.v test_ha.v
此時我們可以看到
1. $monitor 輸出與之前 ha_gate.v 相同
2. testha.dmp 亦相同
使用 continuous assignment 來撰寫 half adder:
module half_adder(x, y, Sum, Cout);
input x, y;
output Sum, Cout;
// Circuit Description
assign {Cout, Sum} = x + y;
endmodule
上面的例子是使用 assign 語法 (又稱為 continuous assignment,課本 p5-2) 來進行 half adder 的設計。
小結:在這三個半加器的例子中,我們使用了同一個 test fixture 來針對我們所寫的三個不同語法之半加器進行測試,而且測試後之結果均一模一樣。