前言:Test Bench 就是用來(lái)模擬真實(shí)電路的,我們可以通過(guò)看波形圖分析自己的電路是不是寫對(duì)了!也可以通過(guò)模擬需要實(shí)例化的 module 的邏輯來(lái)判斷自己的電路是不是寫對(duì)了务荆!
首先我們寫出我們需要測(cè)試的 module:
// counter.v
module counter (clk, reset, enable, count);
input clk, reset, enable;
output [3:0] count;
reg [3:0] count;
always @ (posedge clk) begin
if (reset == 1'b1) begin
count <= 0;
end else if ( enable == 1'b1) begin
count <= count + 1;
end
end
endmodule
接下來(lái)我們要給這個(gè) counter module 寫 Test Bench
0X00 實(shí)例化
實(shí)例化的方法如下:
module counter_tb;
reg clk, reset, enable;
wire [3:0] count;
counter U0 (
.clk (clk),
.reset (reset),
.enable (enable),
.count (count)
);
endmodule
但是如果只寫這個(gè)的話會(huì)報(bào)錯(cuò):
*** These modules were missing:
counter referenced 1 times.
***
解決方法有兩個(gè)(如果是用 iverilog 的話):
- include
`include "conter.v"
- 或者是在 iverilog 命令中加上 counter.v
iverilog -o counter conter_tb.v counter.v
這兩者不能重復(fù)!
0X01 模擬時(shí)鐘
接下來(lái)我們要模擬始終脈沖:
module counter_tb;
reg clk, reset, enable;
wire [3:0] count;
counter U0 (
.clk (clk),
.reset (reset),
.enable (enable),
.count (count)
);
initial begin
clk = 0;
reset = 0;
enable = 0;
// 通常使用 forever 模擬始終脈沖
forever begin
clk = ~clk;
end
end
endmodule
0X02 添加比較邏輯
module counter_tb;
reg clk, reset, enable;
wire [3:0] count;
counter U0 (
.clk (clk),
.reset (reset),
.enable (enable),
.count (count)
);
// 自定義事件用 -> 觸發(fā)
event terminate_sim;
// 監(jiān)聽自定義事件
initial begin
@ (terminate_sim);
#5 $finish;
end
initial begin
clk = 0;
reset = 0;
enable = 1;
// 通常使用 forever 模擬始終脈沖
forever begin
#10 clk = ~clk;
end
end
reg [3:0] count_compare;
always @ (posedge clk)
if (reset == 1'b1) begin
count_compare <= 0;
end else if ( enable == 1'b1) begin
count_compare <= count_compare + 1;
end
always @ (posedge clk)
if (count_compare != count) begin
$display ("DUT Error at time %d", $time);
$display (" Expected value %d, Got Value %d", count_compare, count);
// 觸發(fā)自定義事件
#5 -> terminate_sim;
end
endmodule
上面這個(gè)例子,是在自己的 module 中一邊調(diào)用 counter 這個(gè) module 一邊自己模擬 counter 的邏輯。從而去比較兩者的是不是相等的道偷,從而避免去看波形圖!
未完待續(xù)...