uvm_primer ch11基于uvm的test

147 阅读1分钟

uvm_primer ch11基于uvm的test

从本章正式进入uvm的世界

使用factory创建case

使用下边的命令,我们可以只编译一次跑多个case;
vsim top_optimized -coverage +UVM_TESTNAME=add_test
vsim top_optimized -coverage +UVM_TESTNAME=random_test
使用UVM_TESTNAME去调用 run_test() 去使用factory,构造不同的类的对象;

传递interface,run_test()

  • set是一个static的方法;
  • run_test()读取+UVM_TESTNAME的参数,并构造这个case的对象;
module top;
   import uvm_pkg::*;
`include "uvm_macros.svh"

   import   tinyalu_pkg::*;
`include "tinyalu_macros.svh"

   tinyalu_bfm       bfm();
   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));

initial begin
  uvm_config_db #(virtual tinyalu_bfm)::set(null, "*", "bfm", bfm);
  run_test();
end

endmodule : top

random_test()

  • `uvm_component_utils使用这个宏,将class注册到factory,这样就不用更改factory的代码,从而可以构造这个random_test的对象;
  • 使用get()函数,得到set的interface;如果get失败,则返回0;
  • 对于objection的理解:run_phase()在退出前,会核实各个对象是否还有raise_objection;如果有就等待;知道最后一个对象drop_objection;
class random_test extends uvm_test;
   `uvm_component_utils(random_test);

 virtual tinyalu_bfm bfm;
   
   function new (string name, uvm_component parent);
      super.new(name,parent);
      if(!uvm_config_db #(virtual tinyalu_bfm)::get(null, "*","bfm", bfm))
        $fatal("Failed to get BFM");
   endfunction : new


   task run_phase(uvm_phase phase);
      random_tester    random_tester_h;
      coverage  coverage_h;
      scoreboard scoreboard_h;

      phase.raise_objection(this);

      random_tester_h    = new(bfm);
      coverage_h  = new(bfm);
      scoreboard_h = new(bfm);
      
      fork
         coverage_h.execute();
         scoreboard_h.execute();
      join_none

      random_tester_h.execute();
      phase.drop_objection(this);
   endtask : run_phase

endclass