Generate stimulus
DUB-Design Under Verification
Generate Expectation
Capture response
Check the response for correctness
Measure the progress against the overall verification goals
之前的文章Verilog描述——一位全加器,四选一选择器,计数器中有关于fulladd_tb的实例,这次,也以它来作为testbench
的实例:
module fulladd(
input ain, bin, cin,
output sum, count
);
wire sum;
wire count;
assign sum = ain ^ bin ^ cin;
assign count = (ain & bin) | (bin & cin) | (ain & cin);
endmodule
连接含有工程源码,无C币下载;
talk is cheap, show u the code.
//**************************************************************************//
// example of fulladd testbench
//**************************************************************************//
`timescale 1ns/1ps // 单位时间的定义,时间单位 / 精度
module fulladd_tb;
reg ain, bin, cin; // 信号类型定义
wire cout, sum;
reg clk;
//**************************************************************************//
// Clock Generation
//**************************************************************************//
always begin
#1 clk = ~clk; // 时钟信号产生的常用写法
end
//**************************************************************************//
// 灌激励,产生输入信号
//**************************************************************************//
initial begin // initial的用法,只执行一次
clk = 0; // 灌激励,产生输入信号
ain = 0;
bin = 1;
cin = 1;
#10; // 延迟一段时间,注意这个后面要有分号
ain = 1;
bin = 1;
cin = 0;
#10;
ain = 1;
bin = 1;
cin = 1;
#10;
$finish; // 仿真结束
end
//**************************************************************************//
// 收集响应
//**************************************************************************//
initial begin // 收集响应
@(posedge clk);
#5;
if ( sum!=0 ) begin // Verilog系统函数,打印信息,用于debug
$display("sum calc ERROR!, sum=%b", sum); // 格式化打印信息
end else begin
$display("sum calculate correct!");
end
if ( cout!=1 ) begin
$display("cout calc ERROR!, cout=%b", cout);
end else begin
$display("cout calculate correct!");
end
#10;
if ( sum!=0 ) begin
$display("sum calc ERROR!, sum=%b", sum);
end else begin
$display("sum calculate correct!");
end
if ( cout!=1 ) begin
$display("cout calc ERROR!, cout=%b", cout);
end else begin
$display("cout calculate correct!");
end
#10;
if ( sum!=1 ) begin
$display("sum calc ERROR!, sum=%b", sum);
end else begin
$display("sum calculate correct!");
end
if ( cout!=1 ) begin
$display("cout calc ERROR!, cout=%b", cout);
end else begin
$display("cout calculate correct!");
end
end
//**************************************************************************//
// Instance例化的写法
//**************************************************************************//
fulladd fulladd_u0(
.cout (cout) , // 端口连接的方法
.sum (sum) , // DUT和Testbench连接信号可以同名字
.ain (ain) ,
.bin (bin) ,
.cin (cin)
);
endmodule // The end of fulladd_tb.v
在modelsim
中新建工程,添加已经写好的fulladd.v 和fulladd_tb.v 文件:
编译有两处错误:
# 2 compiles, 1 failed with 2 errors.
# Compile of fulladd.v failed with 2 errors.
找了一下,是因为输出端口重新定义了,在Modelsim中无法支持:
module fulladd(
input ain, bin, cin,
output sum, count
);
// wire sum;
// wire count;
assign sum = ain ^ bin ^ cin;
assign count = (ain & bin) | (bin & cin) | (ain & cin);
endmodule
将输出接口的sum
和count
注释就可以了。
每次修改完RTL code
或Testbench
需要重新编译一遍工程文件;
之后在libray--work--fulladd_tb
,右键,--simulate
;
在sim
窗口选中fulladd_tb
,在Objects
窗口将所有信号添加wave
(右键信号,add to --wave
,快捷键ctrl a
全选,ctrl w
添加到wave
);
在wave
窗口就有对应信号了;
因为这时候仿真已经结束了,所以,我们需要将wave
窗口的设定保存成do
文件,后续有需要可以直接do
这个do
文件;
在Transcript中,输入:
run 100ns
回车之后在wave窗口就有了波形:
同时在Transcript
中也会有对应的打印信息:
完成。