日常记录(41)UVM打印冗余度设置\config_db\执行顺序
field的automation部分
取消trans的部分字段被打包的效果。并提供if语句。
`uvm_object_utils_begin(my_transaction) `uvm_field_int(dmac, UVM_ALL_ON) `uvm_field_int(smac, UVM_ALL_ON) if(is_vlan)begin `uvm_field_int(vlan_info1, UVM_ALL_ON) `uvm_field_int(vlan_info2, UVM_ALL_ON) `uvm_field_int(vlan_info3, UVM_ALL_ON) `uvm_field_int(vlan_info4, UVM_ALL_ON) end `uvm_field_int(ether_type, UVM_ALL_ON) `uvm_field_array_int(pload, UVM_ALL_ON) `uvm_field_int(crc, UVM_ALL_ON | UVM_NOPACK) `uvm_field_int(is_vlan, UVM_ALL_ON | UVM_NOPACK) `uvm_object_utils_end
在调用过程中,可使用seq的uvm_do_with宏进行约束定义,
或在seq中手动实现tr的实例化,实例化使用randomize时候提供with约束。
打印冗余度设置
设置了当前的component冗余度,base_test.sv中(top的下层)定义了env、drv等,在其中引用其对应对象,设置冗余度打印。
LOW=100,NONE=0,HIGH=300,设置为HIGH后,显示小于等于HIGH的内容。DEBUG=500.
env.i_agt.drv.set_report_verbosity_level(UVM_HIGH); env.i_agt.drv.set_report_id_verbosity("my_driver", UVM_HIGH); env.i_agt.set_report_verbosity_level_hier(UVM_HIGH); env.i_agt.set_report_id_verbosity_hier("my_monitor", UVM_HIGH);
显示冗余度信息。
只可打印出数字,%s失效
$display("LEVEL %0d", env.i_agt.drv.get_report_verbosity_level());
打印严重性的 重载
将WARNING重载为ERROR,只针对特定component起效。如果是要对sequence起效,则对seqr进行操作。
env.i_agt.drv.set_report_severity_override(UVM_WARNING, UVM_ERROR); env.i_agt.drv.set_report_severity_id_override(UVM_WARNING, "my_driver", UVM_ERROR);
+uvm_set_severity=comp,id,cur severity,new severity
超出多个ERROR打印则终止
设置为5个。(set_max-quit_count? get_max_quit_count为什么不能用?P51-52)
set_report_max_quit_count(5);
将其它也纳入计数
drv中设置了UVM_COUNT,
hier进行子模块的递归设置
id指定设置的模块。其中的my_drv和my_driver的id在uvm_info和uvm_error中指出。
set_report_max_quit_count(5); env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY| UVM_COUNT); env.i_agt.drv.set_report_id_action("my_drv", UVM_DISPLAY| UVM_COUNT); env.i_agt.set_report_severity_action_hier(UVM_WARNING, UVM_DISPLAY| UVM_COUNT); env.i_agt.set_report_id_action_hier("my_drv", UVM_DISPLAY| UVM_COUNT); env.i_agt.drv.set_report_severity_id_action(UVM_WARNING, "my_driver", UVM_DISPLAY| UVM_COUNT); env.i_agt.set_report_severity_id_action_hier(UVM_WARNING, "my_driver", UVM_DISPLAY| UVM_COUNT);
设定严重性暂停进入交互
drv中设定了UVM_STOP
env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY| UVM_STOP); env.i_agt.set_report_severity_action_hier(UVM_WARNING, UVM_DISPLAY| UVM_STOP); env.i_agt.drv.set_report_id_action("my_drv", UVM_DISPLAY| UVM_STOP); env.i_agt.set_report_id_action_hier("my_drv", UVM_DISPLAY| UVM_STOP); env.i_agt.drv.set_report_severity_id_action(UVM_WARNING, "my_driver", UVM_DISPLAY| UVM_STOP); env.i_agt.set_report_severity_id_action_hier(UVM_WARNING, "my_driver", UVM_DISPLAY| UVM_STOP);
INFO写入文件
UVM_LOG选项,另外是声明、创建、关闭文件
UVM_FILE driver_log; UVM_FILE drv_log; virtual function void connect_phase(uvm_phase phase); driver_log = $fopen("driver.log", "w"); drv_log = $fopen("drv.log", "w"); env.i_agt.drv.set_report_severity_id_file(UVM_WARNING, "my_driver", driver_log); env.i_agt.drv.set_report_severity_id_file(UVM_INFO, "my_drv", drv_log); env.i_agt.drv.set_report_id_action("my_driver", UVM_DISPLAY| UVM_LOG); env.i_agt.drv.set_report_id_action("my_drv", UVM_DISPLAY| UVM_LOG); env.i_agt.set_report_severity_id_file_hier(UVM_WARNING, "my_driver", driver_log); env.i_agt.set_report_severity_id_file_hier(UVM_INFO, "my_drv", drv_log); env.i_agt.set_report_id_action_hier("my_driver", UVM_DISPLAY| UVM_LOG); env.i_agt.set_report_id_action_hier("my_drv", UVM_DISPLAY| UVM_LOG); endfunction virtual function void final_phase(uvm_phase phase); $fclose(driver_log); $fclose(drv_log); endfunction
其中的ID是在drv中的如下:info和warning指出
task my_driver::main_phase(uvm_phase phase); vif.data <= 8'b0; vif.valid <= 1'b0; while(!vif.rst_n) @(posedge vif.clk); while(1) begin seq_item_port.get_next_item(req); `uvm_info("my_drv", "this information is uvm_info", UVM_MEDIUM) `uvm_warning("my_driver", "this information is warning") drive_one_pkt(req); seq_item_port.item_done(); end endtask
控制打印行为的不显示
COUNT计数、EXIT退出、NO_ACTION不显示
env.i_agt.drv.set_report_severity_action(UVM_INFO, UVM_NO_ACTION); env.scb.set_report_severity_action(UVM_INFO, UVM_NO_ACTION);
config_db
automation的省略get语句
如果定义了automation注册,
int pre_num; `uvm_component_utils_begin(my_driver) `uvm_field_int(pre_num, UVM_ALL_ON) `uvm_component_utils_end
则可以使用super.build_phase,获取来自test_top下的my_case的build_phase的数据设置。
uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 7);
设置完毕后可以使用如下方式,在new以后,获取到数字3,但是在super.build以后,自动get(uvm_config_db#(int)::get...), 获取到数字7.
virtual function void build_phase(uvm_phase phase); `uvm_info("my_driver", $sformatf("before super.build_phase, the pre_num is %0d", pre_num), UVM_LOW) super.build_phase(phase); `uvm_info("my_driver", $sformatf("after super.build_phase, the pre_num is %0d", pre_num), UVM_LOW) if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif)) `uvm_fatal("my_driver", "virtual interface must be set for vif!!!") endfunction
get语句生效顺序
更上层的component优先级更高,在进行如下get的时候,作为最终值。如果在drv等下层设置,则无效。
uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 999);
如果第一个参数不是this(寄件人),则不好。
当同一个优先级时,以最终更改的语句作为最终值。如果drv使用uvm_root::get()作为寄件人,(真实顶层,位于my_case上层)
,相同优先级却在更下层的执行模块中,则更优先。
通配符
设置了其下所有通配模块的vif为对应的inf,ouf等,
uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt*", "vif", input_if); uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.o_agt*", "vif", output_if); `uvm_info("top_tb", "use wildchar in top_tb's config_db::set!", UVM_LOW)
检查变量的get情况
当有些变量没有get时,可能是set有问题。
get和set一般在build_phase进行,该相位结束后,进入connect_phase,这里检查一下至今为止仍未获取过的变量。
check_config_usage()
virtual function void connect_phase(uvm_phase phase); super.connect_phase(phase); check_config_usage(); endfunction
检查component的可见信息
其中1为当前及以下的component,0位当前。
print_config(1);
虚类
https://blog.csdn.net/immeatea_aun/article/details/89216857
virtual class
虚类一般用来定义类的格式,、类的成员、类的参数等,虚类不能被实例化,只能被扩展(重载)后实例化,用于在项目中定义一些标准的类。
虚类中的方法通常使用关键字 " pure virtual " 纯虚方法。同时OOP规定,只要class中存在一个没有被实现的pure function,就不允许例化这个class。
执行顺序
build_phase
https://blog.csdn.net/wonder_coole/article/details/90082376
- build_phase是按自上而下的原则执行的,但只有直接上下级关系的节点能保证先后顺序。
- 对于在UVM树中具有叔侄关系的节点的创建顺序,并不能保证谁先谁后。
- build_phase是按照深度优先的原则遍历的。
build_phase开始后,先对下属节点进行new,然后结束build_phase。结束后,对下属节点进行build_phase.
connect_phase的执行
connect_phase的执行顺序是从下往上执行的,先执行driver和monitor的connect_phase,再执行agent的connnect_phase。
Le vent se lève! . . . il faut tenter de vivre!
Le vent se lève! . . . il faut tenter de vivre!