日常記錄(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的形式進行傳送。
Le vent se lève! . . . il faut tenter de vivre!
Le vent se lève! . . . il faut tenter de vivre!