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
endclass
endpackage
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 set, then 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 ---
往期验证笔记:
验证笔记 006:关于uvm_hdl_read,你用对了吗?
验证笔记 008:Foreach对Associative Array的constraint约束
验证笔记 009:Systemverilog的流操作和part-select
验证笔记 010:换种方式管理plusargs传入的控制参数
验证笔记 014:plusargs仿真option,如何添加到compile选项?
这里是验证芯发现,原创不易,欢迎赞赏、点赞、在看和分享。
感谢关注和支持。