关于Testbench的知识(内含例程)

关于Testbench的知识(内含例程) Testbench功能

  • 产生激励Generate stimulus
  • 将激励输入到待测设计DUB-Design Under Verification
  • 产生预期Generate Expectation
  • 获取响应Capture response
  • 检查相应的正确性Check the response for correctness
  • 根据验证目标评估验证进度Measure the progress against the overall verification goals
验证四要素
  1. 灌激励:产生输入信号;
  2. 做预期:产生预期信号;
  3. 集响应:收集输出信号;
  4. 作比较:比较结果;
fulladd_tb实例 之前的文章Verilog描述——一位全加器,四选一选择器,计数器中有关于fulladd_tb的实例,这次,也以它来作为testbench的实例:
RTL code
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

逻辑图
关于Testbench的知识(内含例程)
文章图片

testbench内容
连接含有工程源码,无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例化的写法 //**************************************************************************//fulladdfulladd_u0( .cout(cout),// 端口连接的方法 .sum(sum),// DUT和Testbench连接信号可以同名字 .ain(ain), .bin(bin), .cin(cin) ); endmodule // The end of fulladd_tb.v

Run simulation 在modelsim中新建工程,添加已经写好的fulladd.vfulladd_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

将输出接口的sumcount注释就可以了。
注意
【关于Testbench的知识(内含例程)】每次修改完RTL codeTestbench需要重新编译一遍工程文件;
之后在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窗口就有了波形:
关于Testbench的知识(内含例程)
文章图片

同时在Transcript中也会有对应的打印信息:
关于Testbench的知识(内含例程)
文章图片

完成。

    推荐阅读