验证笔记 015:打印UVM环境结构,print_topology?No...

文摘   科技   2024-03-12 12:07   上海  

UVM中有一个常用的方法:print_topology, 用来打印整个验证环境的组件结构。在uvm_test或者uvm_env的end_of_elaboration_phase调用该函数,会得到一个如下格式的uvm结构信息:

demo示意:

package print_pkg; `include "uvm_macros.svh" import uvm_pkg::*;
class print_env extends uvm_env; `uvm_component_utils(print_env)
function new(string name = "print_env", uvm_component parent=null); super.new(name,parent); endfunction: new
virtual function void build_phase(uvm_phase phase); `uvm_info("build_phase", "Entered...", UVM_LOW) super.build_phase(phase); `uvm_info("build_phase", "Exiting...", UVM_LOW) endfunction: build_phase
function void end_of_elaboration_phase(uvm_phase phase); `uvm_info("end_of_elaboration_phase", "Entered...", UVM_LOW) //uvm_top.print_topology(); `uvm_info("end_of_elaboration_phase", "Exiting...", UVM_LOW) endfunction: end_of_elaboration_phase endclass
class print_test extends uvm_test; `uvm_component_utils(print_test)
print_env o_env;
function new(string name = "print_test", uvm_component parent=null); super.new(name,parent); endfunction: new
  virtual function void build_phase(uvm_phase phase); `uvm_info("build_phase", "Entered...", UVM_LOW) super.build_phase(phase); o_env = print_env::type_id::create("o_env",this); `uvm_info("build_phase", "Exiting...", UVM_LOW) endfunction: build_phase function void end_of_elaboration_phase(uvm_phase phase); `uvm_info("end_of_elaboration_phase", "Entered...", UVM_LOW) uvm_top.print_topology(); `uvm_info("end_of_elaboration_phase", "Exiting...", UVM_LOW) endfunction: end_of_elaboration_phase endclassendpackage
program tb; `include "uvm_macros.svh" import uvm_pkg::*; import print_pkg::*; initial run_test("print_test");endprogram

可以得到下面的UVM树结构:

-------------------------------------
Name          Type        Size  Value
-------------------------------------
uvm_test_top  print_test  -     @336 
  o_env       print_env   -     @351 
-------------------------------------

上例子中print_test的end_of_elaboration_phase调用了uvm_top.print_topology方法,print_env中没有调用。实际中,如果在多个uvm_component组件的end_of_elaboration_phase调用该方法,则会在仿真log中多次打印uvm结构,产生较多冗余信息。

上例中,如果print_env的end_of_elaboration_phase也调用了print_topology方法,则会得到重复的打印信息:

UVM_INFO @ 0: reporter [RNTST] Running test print_test...
UVM_INFO uvm_print_topology.sv(38) @ 0: uvm_test_top [build_phase] Entered...
UVM_INFO uvm_print_topology.sv(44) @ 0: uvm_test_top [build_phase] Exiting...
UVM_INFO uvm_print_topology.sv(13) @ 0: uvm_test_top.o_env [build_phase] Entered...
UVM_INFO uvm_print_topology.sv(18) @ 0: uvm_test_top.o_env [build_phase] Exiting...
UVM_INFO uvm_print_topology.sv(22) @ 0: uvm_test_top.o_env [end_of_elaboration_phase] Entered...
UVM_INFO /eda/synopsys/vcs/U-2023.03-SP2-2/etc/uvm-1.2/base/uvm_root.svh(589) @ 0: reporter [UVMTOP] UVM testbench topology:
-------------------------------------
Name          Type        Size  Value
-------------------------------------
uvm_test_top  print_test  -     @336 
  o_env       print_env   -     @351 
-------------------------------------

UVM_INFO uvm_print_topology.sv(24) @ 0: uvm_test_top.o_env [end_of_elaboration_phase] Exiting...
UVM_INFO uvm_print_topology.sv(47) @ 0: uvm_test_top [end_of_elaboration_phase] Entered...
UVM_INFO /eda/synopsys/vcs/U-2023.03-SP2-2/etc/uvm-1.2/base/uvm_root.svh(589) @ 0: reporter [UVMTOP] UVM testbench topology:
-------------------------------------
Name          Type        Size  Value
-------------------------------------
uvm_test_top  print_test  -     @336 
  o_env       print_env   -     @351 
-------------------------------------

UVM_INFO uvm_print_topology.sv(49) @ 0: uvm_test_top [end_of_elaboration_phase] Exiting...
UVM_INFO /eda/synopsys/vcs/U-2023.03-SP2-2/etc/uvm-1.2/base/uvm_report_server.svh(904) @ 0: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---

这种冲突常在block级的UVM环境向SOC集成时出现,因为每个子系统都会有自己的block环境,在各自的block环境中都会调用print_topology方法,这样在SOC集成时,就出现了在end_of_elaboration_phase阶段,多次打印UVM结构信息。

而为了避免这种打印重复,而又能方便地集成环境,可以使用uvm_top的enable_print_top变量来控制。在uvm_root类中,enable_print_top变量用来表示,是否在end_of_elaboration_phase阶段打印UVM结构信息

class uvm_root extends uvm_component;
...
  // Variable: enable_print_topology
  //
  // If setthen the entire testbench topology is printed just after completion
  // of the end_of_elaboration phase.

  bit  enable_print_topology = 0;
  
...

  // phase_started
  // -------------
  // At end of elab phase we need to do tlm binding resolution.
  function void phase_started(uvm_phase phase);
    if (phase == end_of_elaboration_ph) begin
      do_resolve_bindings(); 
      if (enable_print_topology) print_topology();
      begin
          uvm_report_server srvr;
          srvr = uvm_report_server::get_server();
          if(srvr.get_severity_count(UVM_ERROR) > 0) begin
            uvm_report_fatal("BUILDERR""stopping due to build errors", UVM_NONE);
          end
      end      
    end
  endfunction
...


因此可以在block env的build_phase阶段,将enable_print_top置为1,无需在end_of_elaboration_phase阶段手动调用print_topology方法。将上面的例子做如下改写即可:

package print_pkg;
 `include "uvm_macros.svh"
 import uvm_pkg::*;
 class print_env extends uvm_env;
  `uvm_component_utils(print_env)
  function new(string name = "print_env", uvm_component parent=null);
      super.new(name,parent);
  endfunction: new
     virtual function void build_phase(uvm_phase phase);
      `uvm_info("build_phase""Entered...", UVM_LOW)
      super.build_phase(phase);
            uvm_top.enable_print_topology=1;
      `uvm_info("build_phase""Exiting...", UVM_LOW)
  endfunction: build_phase
 endclass
 
 class print_test extends uvm_test;
  `uvm_component_utils(print_test)
  print_env o_env;
  function new(string name = "print_test", uvm_component parent=null);
      super.new(name,parent);
  endfunction: new
     virtual function void build_phase(uvm_phase phase);
      `uvm_info("build_phase""Entered...", UVM_LOW)
      super.build_phase(phase);
            uvm_top.enable_print_topology=1;
   o_env = print_env::type_id::create("o_env",this);
      `uvm_info("build_phase""Exiting...", UVM_LOW)
  endfunction: build_phase
 endclass
endpackage

program tb;
 `include "uvm_macros.svh"
 import uvm_pkg::*;
 import print_pkg::*;
 initial run_test("print_test");
endprogram

可以得到如下的打印结果:

UVM_INFO @ 0: reporter [RNTST] Running test print_test...
UVM_INFO uvm_print_topology.sv(38) @ 0: uvm_test_top [build_phase] Entered...
UVM_INFO uvm_print_topology.sv(44) @ 0: uvm_test_top [build_phase] Exiting...
UVM_INFO uvm_print_topology.sv(13) @ 0: uvm_test_top.o_env [build_phase] Entered...
UVM_INFO uvm_print_topology.sv(18) @ 0: uvm_test_top.o_env [build_phase] Exiting...
UVM_INFO /eda/synopsys/vcs/U-2023.03-SP2-2/etc/uvm-1.2/base/uvm_root.svh(589) @ 0: reporter [UVMTOP] UVM testbench topology:
-------------------------------------
Name          Type        Size  Value
-------------------------------------
uvm_test_top  print_test  -     @336 
  o_env       print_env   -     @351 
-------------------------------------

UVM_INFO uvm_print_topology.sv(22) @ 0: uvm_test_top.o_env [end_of_elaboration_phase] Entered...
UVM_INFO uvm_print_topology.sv(24) @ 0: uvm_test_top.o_env [end_of_elaboration_phase] Exiting...
UVM_INFO uvm_print_topology.sv(47) @ 0: uvm_test_top [end_of_elaboration_phase] Entered...
UVM_INFO uvm_print_topology.sv(49) @ 0: uvm_test_top [end_of_elaboration_phase] Exiting...
UVM_INFO /eda/synopsys/vcs/U-2023.03-SP2-2/etc/uvm-1.2/base/uvm_report_server.svh(904) @ 0: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---


往期验证笔记:

验证笔记 001:后门操作失败的定位思路

验证笔记 002:一次git操作引起的事故

验证笔记 003:当仿真中出现不定态....

验证笔记 004:使用wait_modified的避雷指南

验证笔记 005:UVM REG多reg_map的实践记录

验证笔记 006:关于uvm_hdl_read,你用对了吗?

验证笔记 007:编写动态的验证环境

验证笔记 008:Foreach对Associative Array的constraint约束

验证笔记 009:Systemverilog的流操作和part-select

验证笔记 010:换种方式管理plusargs传入的控制参数

验证笔记 011:大位宽计数器

验证笔记 012:std::randomize,没那么简单

验证笔记 013:force信号快速查找和定位

验证笔记 014:plusargs仿真option,如何添加到compile选项?

这里是验证芯发现,原创不易,欢迎赞赏、点赞、在看和分享。

感谢关注和支持。


验证芯发现
验证工程师的公众号,记录芯片验证的方方面面。