日常记录(69)回顾/100
作者:互联网
uvm的功能覆盖率收集
类定义
创建了一个类,继承于uvm_subscriber#(trans_name)
https://gitee.com/bai-mengwei/sy_uvm_tb/blob/main/inout_coverage.sv#L4
另外需要定义和实例化trans后,后面write的时候需要赋值。
实现write函数
用于外部调用,名字必须为t。(继承关系)
function void write(packet t);
pkt_cg.sa = t.sa;
pkt_cg.da = t.da;
inout_addr.sample();
endfunction: write
提取和报告
function void extract_phase(uvm_phase phase);
cov = inout_addr.get_coverage();
endfunction: extract_phase
function void report_phase(uvm_phase phase);
`uvm_info("COVERAGE_INFO", $sformatf("coverage value is %f", cov), UVM_LOW);
endfunction: report_phase
参数化类注册到factory
正常使用的注册方法,参数化类使用:uvm_component_param_utils宏
module taa ();
import uvm_pkg::*;
class TestA #(int WIDTH=32) extends uvm_component;
// data or class properties
`uvm_component_param_utils(TestA)
/* `uvm_component_utils(TestA) */
rand bit [WIDTH:0] a;
function new(string name="11", uvm_component parent);
super.new(name, parent);
endfunction: new
endclass : TestA
initial begin
/* TestA#(16) a = new("11"); */
TestA a;
a = TestA#(32)::type_id::create("11", uvm_top);
a.a = 1;
$display("factory ok");
uvm_top.print();
$finish;
end
endmodule
输出结果:
factory ok
-------------------------------------
Name Type Size Value
-------------------------------------
<unnamed> uvm_root - @171
11 uvm_component - @335
-------------------------------------
$finish called from file "taa.sv", line 21.
$finish at simulation time 0
如果不使用,而是和其它一样使用的uvm_component_utils,则:输出类型是本身定义的类型。
factory ok
--------------------------------
Name Type Size Value
--------------------------------
<unnamed> uvm_root - @171
11 TestA - @335
--------------------------------
$finish called from file "taa.sv", line 21.
$finish at simulation time 0
SV的构造函数继承
没有定义构造函数
自动继承上一层:
module tbb ();
class Base;
int a;
function new();
$display("show a ");
endfunction : new
endclass : Base
class B extends Base;
int b;
endclass : B
initial begin
B b = new();
end
endmodule
输出:
show a
SV中的clone方法等
clone方法是等价于new和copy的,需要$cast强制转换(不一定转换成功,如果不对)。
A本身是继承了uvm_object的,如果不注册到工厂中,直接可以使用new,带入string,但是继承到工厂中,则需要重新实现一下new构造函数。
这样才能使用。
module tcc ();
import uvm_pkg::*;
class A extends uvm_object;
// data or class properties
int a;
`uvm_object_utils_begin(A)
`uvm_field_int(a, UVM_ALL_ON)
`uvm_object_utils_end
// initialization
function new(string name="A");
super.new("A");
endfunction : new
endclass : A
class C extends A;
// data or class properties
`uvm_object_utils(C)
function new(string name="C");
endfunction : new
endclass : C
initial begin
A a = new("aa");
A b;
C c = new("cc");
/* c = a; */
a = c;
a.a = 1;
/* b = a.clone(); */
$cast(b, a.clone());
$display("value in b %d ", b.a);
$display("value in c %d ", c.a);
end
endmodule
输出结果:
value in b 1
value in c 1
子父类、名称函数
uvm_root是顶层类,uvm全局实例化一个uvm_top的实例化类。
- get_type_name 通用函数,打印出实例化的类名
- get_parent,uvm_top没有parent,为null,下面定义的tb是有parent的。
- m_parent变量,在component中的内部直接可用变量,为父类实例。
- 此外还有get_child、get_children、get_first_child、等函数。
module tdd ();
import uvm_pkg::*;
class test_base extends uvm_test;
`uvm_component_utils(test_base)
// data or class properties
// initialization
function new(string name="test_base", uvm_component parent);
super.new(name, parent);
endfunction : new
endclass : test_base
initial begin
test_base tb = new("tb", uvm_top);
uvm_top.print();
$display("uvm_root name: ", uvm_root::get());
$display("--------------------------------");
$display("uvm_top name: ", uvm_top.get_type_name());
$display("--------------------------------");
$display("uvm_top parent : ", uvm_top.get_parent());
$display("--------------------------------");
$display("test_case parent : ", tb.get_parent());
$display("--------------------------------");
$display("test_case parent name: ", tb.get_parent().get_type_name());
$display("--------------------------------");
$display("test_case parent name: ", tb.m_parent.get_type_name());
;
end
endmodule
输出结果:
---------------------------------
Name Type Size Value
---------------------------------
<unnamed> uvm_root - @171
tb test_base - @335
---------------------------------
uvm_root name: '{use_uvm_seeding:'h1, m_leaf_name:"", m_inst_id:171, m_inst_count:344, __m_uvm_status_container:{ ref to class uvm_status_container}, uvm_global_copy_map:'{}, m_rh:{ ref to class uvm_report_handler}, enable_stop_interrupt:0, m_config_deprecated_warned:'h0, m_config_set:'h1, print_config_matches:'h0, print_enabled:'h1, tr_database:null, m_domain:{ ref to class uvm_domain}, m_phase_imps:'{}, m_current_phase:null, m_phase_process:null, m_build_done:'h0, m_phasing_active:0, m_parent:null, m_children:'{"tb":{ ref to class uvm_component}} , m_children_by_handle:'{ref to class test_base:{ ref to class uvm_component}} , m_main_stream:null, m_streams:'{}, m_tr_h:'{}, m_name:"", type_name:"uvm_component", event_pool:null, recording_detail:'h0, m_verbosity_settings:'{}, m_time_settings:'{}, m_uvm_applied_cl_action:'{}, m_uvm_applied_cl_sev:'{}, clp:{ ref to class uvm_cmdline_processor}, finish_on_completion:'h1, top_levels:'{{ ref to class uvm_component}} , enable_print_topology:'h0, phase_timeout:9200, m_inst:{ ref to class uvm_root}, m_phase_all_done:'h0, trace_args:'{}, clp_inst:{ ref to class uvm_cmdline_processor}, disable_apply_cfg_settings:'h0, m_relnotes_done:'h1}
--------------------------------
uvm_top name: uvm_root
--------------------------------
uvm_top parent : null
--------------------------------
test_case parent : '{use_uvm_seeding:'h1, m_leaf_name:"", m_inst_id:171, m_inst_count:344, __m_uvm_status_container:{ ref to class uvm_status_container}, uvm_global_copy_map:'{}, m_rh:{ ref to class uvm_report_handler}, enable_stop_interrupt:0, m_config_deprecated_warned:'h0, m_config_set:'h1, print_config_matches:'h0, print_enabled:'h1, tr_database:null, m_domain:{ ref to class uvm_domain}, m_phase_imps:'{}, m_current_phase:null, m_phase_process:null, m_build_done:'h0, m_phasing_active:0, m_parent:null, m_children:'{"tb":{ ref to class uvm_component}} , m_children_by_handle:'{ref to class test_base:{ ref to class uvm_component}} , m_main_stream:null, m_streams:'{}, m_tr_h:'{}, m_name:"", type_name:"uvm_component", event_pool:null, recording_detail:'h0, m_verbosity_settings:'{}, m_time_settings:'{}, m_uvm_applied_cl_action:'{}, m_uvm_applied_cl_sev:'{}, clp:{ ref to class uvm_cmdline_processor}, finish_on_completion:'h1, top_levels:'{{ ref to class uvm_component}} , enable_print_topology:'h0, phase_timeout:9200, m_inst:{ ref to class uvm_root}, m_phase_all_done:'h0, trace_args:'{}, clp_inst:{ ref to class uvm_cmdline_processor}, disable_apply_cfg_settings:'h0, m_relnotes_done:'h1}
--------------------------------
test_case parent name: uvm_root
--------------------------------
test_case parent name: uvm_root
automation中嵌入if
if语句不可能在class中的function或者task之外的,但是在automation中间是可以的。
module tee ();
import uvm_pkg::*;
class packet extends uvm_sequence_item;
rand bit a;
rand int b;
`uvm_object_utils_begin(packet)
`uvm_field_int(a, UVM_ALL_ON)
if (a) begin
`uvm_field_int(b, UVM_ALL_ON)
end
`uvm_object_utils_end
// data or class properties
// initialization
function new(string name="packet");
super.new(name);
endfunction : new
endclass : packet
initial begin
packet pt;
pt = new("pt");
pt.randomize() with{a==1;};
pt.print();
pt.randomize() with{a==0;};
pt.print();
end
endmodule
正常输出:
--------------------------------
Name Type Size Value
--------------------------------
pt packet - @335
a integral 1 'h1
b integral 32 'he91ad7b9
--------------------------------
---------------------------
Name Type Size Value
---------------------------
pt packet - @335
a integral 1 'h0
---------------------------
打印信息、行为控制
重载严重性
set_report_severity_override
设置最大ERROR退出
set_report_max_quit_count
设置自定义的严重性的行为
set_report_severity_action
设置严重性文件
set_report_severity_file
$stop和自动ERROR停止的有效性
使用run等ucli命令,实现继续运行
https://blog.csdn.net/kevindas/article/details/78991759
module tff ();
import uvm_pkg::*;
class info_test extends uvm_component;
UVM_FILE error_log;
`uvm_component_utils(info_test)
// data or class properties
function void info_print();
`uvm_info("UVM_INFO1", "UVM_INFO1", UVM_LOW);
`uvm_info("UVM_INFO1", "UVM_INFO1", UVM_LOW);
`uvm_info("UVM_INFO1", "UVM_INFO1", UVM_LOW);
`uvm_info("UVM_INFO1", "UVM_INFO1", UVM_LOW);
`uvm_warning("UVM_WARNING", "UVM_WARNING");
`uvm_warning("UVM_WARNING", "UVM_WARNING");
`uvm_warning("UVM_WARNING", "UVM_WARNING");
`uvm_warning("UVM_WARNING", "UVM_WARNING");
endfunction: info_print
// initialization
function new(string name="info_test", uvm_component parent);
super.new(name, parent);
endfunction : new
function void set_severity();
error_log = $fopen("error.log", "w");
set_report_severity_override(UVM_INFO, UVM_WARNING);
set_report_severity_override(UVM_WARNING, UVM_ERROR);
// don't have effect
/* set_report_severity_id_override(UVM_INFO, "info_test", UVM_WARNING); */
set_report_max_quit_count(3);
set_report_severity_action(UVM_ERROR, UVM_STOP | UVM_DISPLAY | UVM_COUNT | UVM_LOG);
set_report_severity_file(UVM_ERROR, error_log);
$stop;
$error("fake: now the max quit count is %d", 3);// get_report_max_quit_count());
endfunction: set_severity
function void final_phase(uvm_phase phase);
// can't reach, there is no run_test call
super.final_phase(phase);
$display("final");
$fclose(error_log);
endfunction: final_phase
endclass : info_test
initial begin
info_test it;
it = info_test::type_id::create("info_test", uvm_top);
it.set_severity();
it.info_print();
end
endmodule
输出结果:
$stop不影响结果UVM的ERROR计数
$stop at time 0 Scope: tff.\info_test::set_severity File: tff.sv Line: 32
ucli% run
Error: "tff.sv", 33: tff: at time 0
fake: now the max quit count is 3
UVM_WARNING tff.sv(8) @ 0: info_test [UVM_INFO1] UVM_INFO1
UVM_WARNING tff.sv(9) @ 0: info_test [UVM_INFO1] UVM_INFO1
UVM_WARNING tff.sv(10) @ 0: info_test [UVM_INFO1] UVM_INFO1
UVM_WARNING tff.sv(11) @ 0: info_test [UVM_INFO1] UVM_INFO1
UVM_ERROR tff.sv(12) @ 0: info_test [UVM_WARNING] UVM_WARNING
ucli% run
UVM_ERROR tff.sv(13) @ 0: info_test [UVM_WARNING] UVM_WARNING
ucli% run
UVM_ERROR tff.sv(14) @ 0: info_test [UVM_WARNING] UVM_WARNING
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_report_server.svh(894) @ 0: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
Quit count reached!
Quit count : 3 of 3
** Report counts by severity
UVM_INFO : 1
UVM_WARNING : 4
UVM_ERROR : 3
UVM_FATAL : 0
** Report counts by id
[UVM/RELNOTES] 1
[UVM_INFO1] 4
[UVM_WARNING] 3
$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh", line 135.
$finish at simulation time 0
层次结构与检查赋值
打印层次结构
下面二者大同小异,
- uvm_top.print();
- uvm_top.print_topology();
- factory是只有在uvm-1.1 才可以使用的。显示进入工工厂的类名了。
module tgg ();
import uvm_pkg::*;
class my_env extends uvm_env;
`uvm_component_utils(my_env)
// data or class properties
int a;
// initialization
function new(string name="my_env", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(int)::get(this, "", "int_value", a);
`uvm_info("VALUE_A", $sformatf("value a is %d", a), UVM_LOW)
endfunction: build_phase
endclass : my_env
class base_test extends uvm_test;
my_env env;
`uvm_component_utils(base_test)
// data or class properties
function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = my_env::type_id::create("env_path", this);
/* uvm_config_db#(int)::set(this, "env_path", "int_value", 1); */
uvm_config_db#(bit [3:0])::set(this, "env_path", "int_value", 1);
endfunction: build_phase
// initialization
function new(string name="base_test", uvm_component parent);
super.new(name, parent);
endfunction : new
function void start_of_simulation_phase(uvm_phase phase);
super.start_of_simulation_phase(phase);
uvm_top.print();
uvm_top.print_topology();
check_config_usage();
// only used in uvm1.1
/* factory.print(); */
endfunction: start_of_simulation_phase
endclass : base_test
initial begin
run_test("base_test");
end
endmodule
检查赋值是否正常
check_config_usage。
以下是异常的,因为uvm_config_db没有给定正确的类型名。
输出结果:
UVM_INFO @ 0: reporter [RNTST] Running test base_test...
UVM_INFO tgg.sv(17) @ 0: uvm_test_top.env_path [VALUE_A] value a is 0
--------------------------------------
Name Type Size Value
--------------------------------------
<unnamed> uvm_root - @172
uvm_test_top base_test - @336
env_path my_env - @349
--------------------------------------
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh(589) @ 0: reporter [UVMTOP] UVM testbench topology:
------------------------------------
Name Type Size Value
------------------------------------
uvm_test_top base_test - @336
env_path my_env - @349
------------------------------------
UVM_INFO @ 0: uvm_test_top [CFGNRD] ::: The following resources have at least one write and no reads :::
int_value [/^uvm_test_top\.env_path$/] : (bit[3:0]) 1
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_resource.svh(564) @ 0: reporter [UVM/RESOURCE/ACCESSOR] uvm_test_top reads: 0 @ 0 writes: 1 @ 0
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_report_server.svh(894) @ 0: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
** Report counts by severity
UVM_INFO : 6
UVM_WARNING : 0
UVM_ERROR : 0
UVM_FATAL : 0
** Report counts by id
[CFGNRD] 1
[RNTST] 1
[UVM/RELNOTES] 1
[UVM/RESOURCE/ACCESSOR] 1
[UVMTOP] 1
[VALUE_A] 1
$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh", line 527.
$finish at simulation time 0
UVM-1.2不再使用default_sequence机制
UVM—1.1进行drv和seq通信时:
module tgg ();
import uvm_pkg::*;
class my_trans extends uvm_sequence_item;
`uvm_object_utils(my_trans)
rand int a;
function new(string name="my_trans");
super.new(name);
endfunction : new
endclass : my_trans
class my_drv extends uvm_driver#(my_trans);
`uvm_component_utils(my_drv)
function new(string name="drv", uvm_component parent);
super.new(name, parent);
endfunction : new
task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
`uvm_info("MY_DRV", $sformatf("get an item %d", req.a), UVM_LOW)
seq_item_port.get_next_item(req);
`uvm_info("MY_DRV", $sformatf("get an item %d", req.a), UVM_LOW)
seq_item_port.item_done();
end
endtask: run_phase
endclass : my_drv
class my_seq extends uvm_sequence#(my_trans);
`uvm_object_utils(my_seq)
function new(string name="my_seq");
super.new(name);
endfunction: new
task body();
/* starting_phase.raise_objection(this); */
if (starting_phase!=null) begin
starting_phase.raise_objection(this);
end
/* repeat (10) begin */
/* `uvm_do_with(req, {a>0; a < 10;}) */
/* `uvm_info("SEQ_SEND", "send seq", UVM_LOW) */
/* end */
req = new("my_trans");
for (int i = 0; i < 10; i++) begin
start_item(req);
req.randomize() with {a>5; a< 10;};
finish_item(req);
end
if (starting_phase!=null) begin
starting_phase.drop_objection(this);
end
endtask
endclass : my_seq
class my_test extends uvm_test;
`uvm_component_utils(my_test);
typedef uvm_sequencer#(my_trans) my_seqr;
my_drv drv;
my_seqr seqr;
function new(string name="tes", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
seqr = my_seqr::type_id::create("seqr", this);
drv = my_drv::type_id::create("drv", this);
uvm_config_db#(uvm_object_wrapper)::set(this, "seqr.main_phase", "default_sequence", my_seq::type_id::get());
endfunction: build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
drv.seq_item_port.connect(seqr.seq_item_export);
endfunction: connect_phase
endclass : my_test
initial begin
run_test("my_test");
end
endmodule
uvm_config_db#(uvm_object_wrapper)::set(this, "seqr.main_phase", "default_sequence", my_seq::type_id::get());
输出正常。
点击查看代码
UVM_INFO @ 0: reporter [RNTST] Running test my_test...
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 7
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 7
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 9
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 9
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 7
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 7
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 6
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 6
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 6
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 6
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 9
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 9
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 8
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 8
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 7
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 7
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 6
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 6
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 9
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 9
--- UVM Report Summary ---
** Report counts by severity
UVM_INFO : 21
UVM_WARNING : 0
UVM_ERROR : 10
UVM_FATAL : 0
** Report counts by id
[MY_DRV] 20
[RNTST] 1
[uvm_test_top.seqr] 10
$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.1/base/uvm_root.svh", line 439.
$finish at simulation time 0
但是使用uvm-1.2则异常:
点击查看代码
UVM_INFO @ 0: reporter [RNTST] Running test my_test...
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 7
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 7
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item 9
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item 9
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_report_server.svh(894) @ 0: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
** Report counts by severity
UVM_INFO : 6
UVM_WARNING : 0
UVM_ERROR : 2
UVM_FATAL : 0
** Report counts by id
[MY_DRV] 4
[RNTST] 1
[UVM/RELNOTES] 1
[uvm_test_top.seqr] 2
$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh", line 527.
$finish at simulation time 0
UVM—1.1进行drv和seq通信时:
取消使用starting_phase机制,而是在其它地方,手动实例化seq,然后指定seqr,发送。
实例:
module tgg ();
import uvm_pkg::*;
class my_trans extends uvm_sequence_item;
`uvm_object_utils(my_trans)
rand int a;
function new(string name="my_trans");
super.new(name);
endfunction : new
endclass : my_trans
class my_drv extends uvm_driver#(my_trans);
`uvm_component_utils(my_drv)
static int i=0;
function new(string name="drv", uvm_component parent);
super.new(name, parent);
endfunction : new
task run_phase(uvm_phase phase);
/* forever begin */
/* seq_item_port.get_next_item(req); */
/* `uvm_info("MY_DRV", $sformatf("i: %0d, get an item %d", i, req.a), UVM_LOW) */
/* seq_item_port.get_next_item(req); */
/* `uvm_info("MY_DRV", $sformatf("i: %0d, get an item %d", i, req.a), UVM_LOW) */
/* seq_item_port.item_done(); */
/* i = i + 1; */
/* end */
forever begin
seq_item_port.try_next_item(req);
if(req!=null) begin
`uvm_info("MY_DRV", $sformatf("i: %0d, get an item %d", i, req.a), UVM_LOW)
i++;
seq_item_port.item_done();
end else begin
;
end
end
endtask: run_phase
endclass : my_drv
class my_seq extends uvm_sequence#(my_trans);
`uvm_object_utils(my_seq)
function new(string name="my_seq");
super.new(name);
endfunction: new
task body();
repeat (5) begin
`uvm_do_with(req, {a>0; a < 10;})
`uvm_info("SEQ_SEND", "send seq", UVM_LOW)
end
req = new("my_trans");
for (int i = 0; i < 5; i++) begin
start_item(req);
req.randomize() with {a>5; a< 10;};
finish_item(req);
end
endtask
endclass : my_seq
class my_test extends uvm_test;
`uvm_component_utils(my_test);
typedef uvm_sequencer#(my_trans) my_seqr;
my_drv drv;
my_seqr seqr;
my_seq seq;
function new(string name="tes", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
seqr = my_seqr::type_id::create("seqr", this);
drv = my_drv::type_id::create("drv", this);
/* uvm_config_db#(uvm_object_wrapper)::set(this, "seqr.main_phase", "default_sequence", seq.get_type()); */
endfunction: build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
drv.seq_item_port.connect(seqr.seq_item_export);
endfunction: connect_phase
task run_phase(uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
seq = new("seq");
seq.start(seqr);
phase.drop_objection(this);
endtask: run_phase
endclass : my_test
initial begin
run_test("my_test");
end
endmodule
输出结果:
UVM_INFO @ 0: reporter [RNTST] Running test my_test...
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 0, get an item 9
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 1, get an item 2
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 2, get an item 1
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 3, get an item 6
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 4, get an item 4
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 5, get an item 7
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 6, get an item 7
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 7, get an item 8
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 8, get an item 9
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 9, get an item 7
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_objection.svh(1276) @ 0: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_report_server.svh(894) @ 0: reporter [UVM/REPORT/SERVER]
--- UVM Report Summary ---
** Report counts by severity
UVM_INFO : 18
UVM_WARNING : 0
UVM_ERROR : 0
UVM_FATAL : 0
** Report counts by id
[MY_DRV] 10
[RNTST] 1
[SEQ_SEND] 5
[TEST_DONE] 1
[UVM/RELNOTES] 1
$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh", line 527.
$finish at simulation time 0
seqr\seq\drv通信机制
- drv是get方式向seqr要数据的。seq要发的话,要seqr同意,seqr是看drv要不要的。
- drv在get到数据后,如果认定这个数据没有收到,那重新get,seqr是备份了seq的数据的,可以再次给drv。
- drv在get到数据后,收到了,发送item_done,seqr知道drv得到数据了,就删掉了备份。
- seq发送的时候,使用宏uvm_do[_with],可以使用:实例化、start_item、然后randomize、然后finish_item的形式进行发送。
标签:回顾,top,item,phase,uvm,test,69,100,UVM 来源: https://www.cnblogs.com/bai2022/p/15966283.html