uvm_primer ch10 面向对象的testbench

package

当import 一个package之后,可以访问package中所有的定义数据等;

package tinyalu_pkg;
      typedef enum bit[2:0] {
    
    no_op  = 3'b000,
                             add_op = 3'b001, 
                             and_op = 3'b010,
                             xor_op = 3'b011,
                             mul_op = 3'b100,
                             rst_op = 3'b111} operation_t;


`include "coverage.svh"
`include "tester.svh"
`include "scoreboard.svh"
`include "testbench.svh"
endpackage : tinyalu_pkg
   

top中定义dut/interface/testbench,并连接

使用interface连接testbench和dut;

module top;
  import   tinyalu_pkg::*;
`include "tinyalu_macros.svh"
   
   tinyalu DUT (.A(bfm.A), .B(bfm.B), .op(bfm.op), 
                .clk(bfm.clk), .reset_n(bfm.reset_n), 
                .start(bfm.start), .done(bfm.done), .result(bfm.result));

   tinyalu_bfm     bfm();

   testbench    testbench_h;
   

   initial begin
      testbench_h = new(bfm);
      testbench_h.execute();
   end
   
endmodule : top

testbench

testbench中实例化激励/coverage/scb等模块
重点关注virtual tinyalu_bfm bfm;
virtual tinyalu_bfm bfm是一个对象 该对象在面向对象中等价于模块的端口列表;
virtual 告诉编译器bfm这个变量将来会赋值一个tinyalu_bfm类型的句柄;但是在编译的时候bfm中还没有句柄;

-还有问题关于virtual 存疑

class testbench;

   virtual tinyalu_bfm bfm;

   tester    tester_h;
   coverage  coverage_h;
   scoreboard scoreboard_h;
   
   function new (virtual tinyalu_bfm b);
       bfm = b;
   endfunction : new

   task execute();
      tester_h    = new(bfm);
      coverage_h   = new(bfm);
      scoreboard_h = new(bfm);

      fork
         tester_h.execute();
         coverage_h.execute();
         scoreboard_h.execute();
      join_none
   endtask : execute
endclass : testbench

激励tester

class tester;

   virtual tinyalu_bfm bfm;

   function new (virtual tinyalu_bfm b);
       bfm = b;
   endfunction : new


   protected function operation_t get_op();
      bit [2:0] op_choice;
      op_choice = $random;
      case (op_choice)
        3'b000 : return no_op;
        3'b001 : return add_op;
        3'b010 : return and_op;
        3'b011 : return xor_op;
        3'b100 : return mul_op;
        3'b101 : return no_op;
        3'b110 : return rst_op;
        3'b111 : return rst_op;
      endcase // case (op_choice)
   endfunction : get_op

   protected function byte get_data();
      bit [1:0] zero_ones;
      zero_ones = $random;
      if (zero_ones == 2'b00)
        return 8'h00;
      else if (zero_ones == 2'b11)
        return 8'hFF;
      else
        return $random;
   endfunction : get_data
   
   task execute();
      byte         unsigned        iA;
      byte         unsigned        iB;
      shortint     unsigned        result;
      operation_t                  op_set;
      bfm.reset_alu();
      op_set = rst_op;
      iA = get_data();
      iB = get_data();
      bfm.send_op(iA, iB, op_set, result);
      op_set = mul_op;
      bfm.send_op(iA, iB, op_set, result);
      bfm.send_op(iA, iB, op_set, result);
      op_set = rst_op;
      bfm.send_op(iA, iB, op_set, result);
      repeat (10) begin : random_loop
         op_set = get_op();
         iA = get_data();
         iB = get_data();
         bfm.send_op(iA, iB, op_set, result );
         $display("%2h %6s %2h = %4h",iA, op_set.name(), iB, result);
      end : random_loop
      $stop;
   endtask : execute
   
endclass : tester

猜你喜欢

转载自blog.csdn.net/weixin_39060517/article/details/113046291
今日推荐