简单全加器验证—Testbench

一、全加器DUT Code

module adder32(                         //Verilog——2001语法
        input  wire [31:0]  a_in,
        input  wire [31:0]  b_in,
        input  wire [0:0]   c_in,        //carry in,进位位
        output  reg [31:0]  sum_out,
        output  reg [0:0]   c_out        //carry out
        );

        assign {c_out,sum_out} = a_in + b_in + c_in;

endmodule

二、Testbench Code

自动化验证testbench结果可以减少人工检查的时间和可能犯的失误,尤其对于比较大的设计。目前普遍使用两种自动化testbench验证方法:

  • 波形比较:将testbench输出波形与预期波形作比较。不过目前由于该方法很少使用。
  • 自动比对testbench设计:与前种方法不同,该方法实时检查预期结果和实际结果,效率较高,可缩短调试时间。

Testbench仿真一般包含以下几个过程:

  1. 从脚本中获取随机种子和激励数量;
  2. 通过随机种子产生激励;
  3. 将激励发送至DUT;
  4. 将激励发送至Golden model;
  5. 获取DUT输出;
  6. 将DUT输出和Golden model进行一一比较

上述32位加法器的Testbench代码如下:

module adder32_tb_rand();                 //testbench不需要列出端口列表
       reg [31:0]  a_in;
       reg [31:0]  b_in;
       reg [0:0]   c_in;                  //carry in,进位位
       wire[31:0]  sum_out;
       wire[0:0]   c_out;                 //carry out

       int             seed;              //随机种子,用以产生随机激励
       int             stimulus_num;      //发送激励的数量,即要发送多少激励
       reg    [32:0]   data_in[3]={33'h0,33'h0,33'h0};//定义3个激励,并初始化为0,位宽33bit,最高位后边赋0处理

       reg             sti_gen;          //该信号为一个flag,相当于clk

       reg    [32:0]   gld_sum[$];       //该队列用于存储所有的golden model,用于check
       reg    [32:0]   dut_sum[$];       //该队列用于存储所有的DUT输出,用于和Golden model比对
 
       reg    [32:0]    gld_sum_rslt;    //**临时变量,存储单一golden model(一一比对)**
       reg    [32:0]    dut_sum_rslt;    //**临时变量,存储单一DUT输出,和golden model进行一一比对**
        
       event            sti_end;        //控制激励,使激励完全发送完毕再进行比对
        
       int              err_cnt;        //标志信号,记录比对的错误数量

//1.Get random seed and stimulus numbers from external scripts
       initial begin
          if(!$value$plusargs("seed=%0d",seed))begin       //获取由脚本传递进来的随机种子
            seed = 100;
          end
          else begin
            $display("@%0t: seed = %0d",$time,seed);
          end
           
          if(!$value$plusargs("stimulus_num=%0d",stimulus_num))begin   //获取由脚本传递进来的激励数量
            stimulus_num = 50;
          end
          else begin
            $display("@%0t: stimulus_num = %0d",$time,stimulus_num);
          end

//2.Generate stimulus with random seed
       initial begin
          sti_gen = 1'b0;                          //flag初始化
            repeat(stimulus_num)begin
              sti_gen = 1'b0;
              #10;                                 //每隔10个时间单位产生一组激励
              data_in[0][31:0] = $random(seed);    //产生的激励为32bit,(a_in)
              data_in[1][31:0] = $random(seed);    //产生的激励为32bit, (b_in)
              data_in[2] = 1'b0;                   //相当于第33bit进位位,直接置0
              #10//该延迟为了保证激励稳定后才被收集
              sti_gen = 1'b1;                     //flag, 通知采集模块可以采集激励结果,并将其存放到队列中了
              #10;
            end
            ->sti_end;                            //保证激励发送完毕后,再触发事件,进行数据比对
       end

//3.Send stimulus to DUT
     always @(*) begin
       a_in = data_in[0];                          //将激励发送进入DUT中
       b_in = data_in[1];
       c_in = data_in[2];
       //$display("@%0t: a_in=%0h, b_in=%0h, data_in[0]=%0h,data_in[1]=%0h",a_in,b_in,data_in[0],data_in[1]);
       //在此处可添加打印信息,以检查输入激励是否有错误
     end

//4.Send stimulus to Golden model
     initial begin
       repeat(stimulus_num)begin
         @(posedge sti_gen)
         gld_sum.push_back(data_in.sum);         //SV语法,gld_sum队列的内置函数push_back()
       end                                       // 即,将data_in求和后,push_back函数将和放入队列gld_sum中                                 
     end

//5.Capture DUT output
     initial begin
       repeat(stimulus_num)begin
       @(posedge sti_gen)
        dut_sum.push_back({c_out,sum_out});      //SV语法,dut_sum队列的内置函数push_back()
       end                                       // 即,DUT输出后,push_back函数将输出结果放入队列dut_sum中
     end
          
//6.Check result
     initial begin
     
       gld_sum_rslt = 'h0;                       //临时变量,初始化,用于采集单一的golden model
       dut_sum_rslt = 'h0;                       //临时变量,初始化,用于采集单一的DUT输出
       err_cnt = 'h0;                            //比对错误统计,初始化
        
       @sti_end;                                 //等待所有的激励全部发送完毕后,才触发事件,进行比对 
       
       repeat(stimulus_num)begin
         gld_sum_rslt = gld_sum.pop_front();     //队列的pop_front()函数会弹出一个golden model存入临时变量
         dut_sum_rslt = dut_sum.pop_front();     //队列的pop_front()函数会弹出一个DUT输出存入临时变量
          
         if( gld_sum_rslt != dut_sum_rslt ) begin
           $display("@%0t:EEROR::gld_sum!=dut_sum,gld_sum=%0h,dut_sum=%0h",$time,gld_sum_rslt,dut_sum_rslt);
           //打印错误的golden model与DUT输出的比对结果
           err_cnt++//统计错误比对的数量
         end
         
      end

       if(err_cnt == 'h0)begin                       //如果比对无误,则检测通过
         $display("***********************************");
         $display("***********************************");
         $display("************TEST   PASS************");
         $display("***********************************");
         $display("***********************************");
       end

       finish();                                      //结束仿真

endmodule

三、Makefile脚本编译

文件名:Makefile.rand

all: compile simulate

seed = $(shell date +%s);                      //随机种子格式
stimulus_num = 100;                            //仿真时可在外部改变激励个数
                                               //上述两个变量可通过脚本传入Testbench中
compile:
  vcs -sverilog adder32.v adder32_tb_rand.v -debug_all -l comp.log

simulate:
  ./simv -l sim_$(seed).log +plusargs_save +seed=$(seed) +stimulus_num=$(stimulus_num)

编译命令:make -f Makefile.rand

对于Makefile中各个参数的解释:

  • vcs: 编译工具vcs;
  • -sverilog:Testbench中用到sv语法;
  • adder32:当前目录下的DUT文件;
  • adder32_tb_rand.v:当前目录下的Testbench文件;
  • debug_all:习惯性加上;
  • -l comp.log:将编译结果记录在comp.log文件中
  • ./simv:vcs编译完毕会自动产生simv目录;
  • -l sim_$(seed).log:记录仿真结果记录在该文件中;
  • +plusargs_save:将种子seed和激励stimulus_num等变量植入testbench中;
  • +seed=$(seed):植入变量seed,前一个seed为tb中的seed,后一个seed为脚本中的变量seed;
  • +stimulus_num=$(stimulus_num):植入变量stimulus_num,同seed;
发布了21 篇原创文章 · 获赞 10 · 访问量 1832

猜你喜欢

转载自blog.csdn.net/weixin_46022434/article/details/105075703
今日推荐