記錄...
一些關於Verilog撰寫方面的筆記...
1. TestBench的module宣告不用宣告input port和output ports
ex:
電路設計檔的module宣告:
test.v
----------
module test (in1, in2, out); <= 有宣告所需的input和output ports
其TestBench檔的module宣告:
test_tb.v
----------
module test_tb; <= 不需要宣告test.v中所需的input和output ports
2. TestBench通常input ports會改宣告成reg型態 / output ports會改宣告成wire型態
ex:
電路設計檔的input / output ports宣告:
test.v
----------
module test (i0, i1, i2, out);
input i0, i1, i2;
output out;
reg out;
其TestBench檔的input / output ports宣告:
test_tb.v
----------
module test_tb;
reg i0, i1, i2; <= input ports改宣告成reg型態
wire out; <= output ports改宣告成wire型態
3. 這是發生在撰寫4 Bits Up-Down Counter時發生的邏輯錯誤:
4 Bits Up-Down Counter電路設計檔:
Four_Bits_Up_Down_Counter.v
----------
// 4 Bits Up-Down Counter with reset and control signal
module Four_Bits_Up_Down_Counter (control, reset, clk, out);
input control, reset, clk;
output [3:0] out;
reg [3:0] out;
always @(posedge clk)
begin
if (~reset) // When reset = 0: zero the value of out
begin
out <= 4'b0;
end
else if (control) // If control = 1: Up-count the number
begin
// Only Up-count while the number not reach 4'b1111
if (out != 4'b1111)
begin
out <= out + 1;
end
end
else // Else if control = 0: Down-count the number
begin
// Only Down-count while the number not reach 4'b0000
if (out != 4'b0000)
begin
out <= out - 1;
end
end
end
endmodule
其TestBench檔:
Four_Bits_Up_Down_Counter_tb.v
----------
// 4 Bits Up-Down Counter with reset and control signal Test Bench
module Four_Bits_Up_Down_Counter_tb;
reg control, reset, clk;
wire [3:0] out;
Four_Bits_Up_Down_Counter tb (.control(control), .reset(reset), .clk(clk), .out(out));
initial
begin
control = 1'b1;
reset = 1'b0;
clk = 1'b0;
#10 reset = 1'b1;
#500 $finish;
end
always
begin
#10 clk = !clk;
end
endmodule
其模擬出來的out都會是Unknown的訊號:
其原因在於...
當clk由負緣拉為正緣時:
always @(posedge clk)
程式才會進入下面的if / else判斷式
但由於在clk由負緣拉為正緣前:
always
begin
#10 clk = !clk;
end
reset就已經由0改設成為1了:
#5 reset = 1'b1;
也因此導致out沒有初始值 = Unknow
如此之後不論判斷式再怎麼加 / 減
其值均會為Unknown,導致錯誤的結果
解決方法:
將進入判斷式的條件多加:always @(posedge clk or negedge reset)
將reset也加入進入判斷式的條件中...
如此當reset由正緣拉為負緣時
就會一併將out初始為0000了
原本一直以為是自己Verilog有寫錯...
在問過學長後才發現原來有這麼一個隱藏的問題!!
果然有經驗的一看到就可以很快的發現問題出在哪...