run_test() 验证平台的入口

Run,just run!    ——阿甘正传
 
一个简单的例子:
 1 module tb_top;
 2     dut u_dut ();
 3 
 4     initial begin
 5         run_test();
 6     end
 7 
 8     config_db #()::set();
 9     
10 endmoudle

UVM验证平台从仿真器执行时,开始执行initial中的run_test(); 这时首先去uvm_global.svh中查找run_test();

// Title: Globals

//------------------------------------------------------------------------------
//
// Group: Simulation Control
//
//------------------------------------------------------------------------------

// Task: run_test
//
// Convenience function for uvm_top.run_test(). See <uvm_root> for more
// information.

task run_test (string test_name="");
  uvm_root top;
  uvm_coreservice_t cs;
  cs = uvm_coreservice_t::get();
  top = cs.get_root();
  top.run_test(test_name);
endtask
全局的run_test() 又调用uvm_root.svh的run_test()
  1 //----------------------------------------------------------------------------
  2   // Group: Simulation Control
  3   //----------------------------------------------------------------------------
  4 
  5 
  6   // Task: run_test
  7   //
  8   // Phases all components through all registered phases. If the optional
  9   // test_name argument is provided, or if a command-line plusarg,
 10   // +UVM_TESTNAME=TEST_NAME, is found, then the specified component is created
 11   // just prior to phasing. The test may contain new verification components or
 12   // the entire testbench, in which case the test and testbench can be chosen from
 13   // the command line without forcing recompilation. If the global (package)
 14   // variable, finish_on_completion, is set, then $finish is called after
 15   // phasing completes.
 16 
 17   extern virtual task run_test (string test_name="");
 18 
 19 
 20 // run_test
 21 // --------
 22 
 23 task uvm_root::run_test(string test_name="");
 24 
 25   uvm_report_server l_rs;
 26   uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
 27   uvm_factory factory=cs.get_factory();
 28   bit testname_plusarg;
 29   int test_name_count;
 30   string test_names[$];
 31   string msg;
 32   uvm_component uvm_test_top;
 33 
 34   process phase_runner_proc; // store thread forked below for final cleanup
 35 
 36   testname_plusarg = 0;
 37 
 38   // Set up the process that decouples the thread that drops objections from
 39   // the process that processes drop/all_dropped objections. Thus, if the
 40   // original calling thread (the "dropper") gets killed, it does not affect
 41   // drain-time and propagation of the drop up the hierarchy.
 42   // Needs to be done in run_test since it needs to be in an
 43   // initial block to fork a process.
 44   uvm_objection::m_init_objections();
 45 
 46 `ifndef UVM_NO_DPI
 47 
 48   // Retrieve the test names provided on the command line.  Command line
 49   // overrides the argument.
 50   test_name_count = clp.get_arg_values("+UVM_TESTNAME=", test_names);
 51 
 52   // If at least one, use first in queue.
 53   if (test_name_count > 0) begin
 54     test_name = test_names[0];
 55     testname_plusarg = 1;
 56   end
 57 
 58   // If multiple, provided the warning giving the number, which one will be
 59   // used and the complete list.
 60   if (test_name_count > 1) begin
 61     string test_list;
 62     string sep;
 63     for (int i = 0; i < test_names.size(); i++) begin
 64       if (i != 0)
 65         sep = ", ";
 66       test_list = {test_list, sep, test_names[i]};
 67     end
 68     uvm_report_warning("MULTTST", 
 69       $sformatf("Multiple (%0d) +UVM_TESTNAME arguments provided on the command line.  '%s' will be used.  Provided list: %s.", test_name_count, test_name, test_list), UVM_NONE);
 70   end
 71 
 72 `else
 73 
 74      // plusarg overrides argument
 75   if ($value$plusargs("UVM_TESTNAME=%s", test_name)) begin
 76     `uvm_info("NO_DPI_TSTNAME", "UVM_NO_DPI defined--getting UVM_TESTNAME directly, without DPI", UVM_NONE)
 77     testname_plusarg = 1;
 78   end
 79 
 80 `endif
 81 
 82   // if test now defined, create it using common factory
 83   if (test_name != "") begin
 84       uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
 85       uvm_factory factory=cs.get_factory();
 86       
 87     if(m_children.exists("uvm_test_top")) begin
 88       uvm_report_fatal("TTINST",
 89           "An uvm_test_top already exists via a previous call to run_test", UVM_NONE);
 90       #0; // forces shutdown because $finish is forked
 91     end
 92     $cast(uvm_test_top, factory.create_component_by_name(test_name,
 93           "", "uvm_test_top", null));
 94 
 95     if (uvm_test_top == null) begin
 96       msg = testname_plusarg ? {"command line +UVM_TESTNAME=",test_name} : 
 97                                {"call to run_test(",test_name,")"};
 98       uvm_report_fatal("INVTST",
 99           {"Requested test from ",msg, " not found." }, UVM_NONE);
100     end
101   end
102 
103   if (m_children.num() == 0) begin
104     uvm_report_fatal("NOCOMP",
105           {"No components instantiated. You must either instantiate",
106            " at least one component before calling run_test or use",
107            " run_test to do so. To run a test using run_test,",
108            " use +UVM_TESTNAME or supply the test name in",
109            " the argument to run_test(). Exiting simulation."}, UVM_NONE);
110     return;
111   end
112 
113   begin
114       if(test_name=="") 
115           uvm_report_info("RNTST", "Running test ...", UVM_LOW); 
116       else if (test_name == uvm_test_top.get_type_name())
117           uvm_report_info("RNTST", {"Running test ",test_name,"..."}, UVM_LOW); 
118       else
119           uvm_report_info("RNTST", {"Running test ",uvm_test_top.get_type_name()," (via factory override for test \"",test_name,"\")..."}, UVM_LOW);
120   end
121   
122   // phase runner, isolated from calling process
123   fork begin
124     // spawn the phase runner task
125     phase_runner_proc = process::self();
126     uvm_phase::m_run_phases();
127   end
128   join_none
129   #0; // let the phase runner start
130   
131   wait (m_phase_all_done == 1);
132   
133   // clean up after ourselves
134   phase_runner_proc.kill();
135 
136   l_rs = uvm_report_server::get_server();
137   l_rs.report_summarize();
138 
139   if (finish_on_completion)
140     $finish;
141 
142 endtask
View Code

在该run_test 实现中根据有没有DPI调用phase.这样在运行仿真命令时通过simcmd +UVM_TESTNAME=my_case 来执行该case,这样整个系统就被调用了起来。这样做有什么好处?它根据传入的字符串或者从运行参数+UVM_TESTNAME="test_name"读取字符串来生成uvm_test对象, 并运行这个对象的全部phase函数来执行一次测试用例的运行,很方便实现regression。

 
参考文献:

 

 

posted on 2017-11-19 14:30  dpc525  阅读(5355)  评论(0编辑  收藏  举报

导航