object&&component
object是爹
component有如下特点
- 通过在new的时候指定parent参数来形成一种树形的组织结构
- 有phase的自动执行特点。
- 相比object,没有clone()。但是有copy
-
uvm_component_utils: 它用于把一个直接或间接派生自uvm_component的类注册到factory中。
-
uvm_component_param_utils: 它用于把一个直接或间接派生自uvm_component的参数化的类注册到factory中
config
从uvm_object派生。
config的主要功能就是规范验证平台的行为方式。 如规定driver在读取总线时地址信号要持续几个时钟, 片选信号从什么时候开始有效等。
config其实指的是把所有的参数放在一个object中, 然后通过config_db的方式设置给所有需要这些参数的component。
dirver-component
//driver的成员变量
uvm_seq_item_pull_port #(REQ, RSP) seq_item_port;
uvm_seq_item_pull_port #(REQ, RSP) seq_item_prod_if; // alias
uvm_analysis_port #(RSP) rsp_port;
REQ req;
RSP rsp;
为什么要指定parent?
component A中声明一个component B b,这样的话在外界根本不知道A里面有什么,如果例化b的时候指定parent 为this,就是A,那么就可以通过A内部的m_children数组获取A中的儿子们,有助于编译器管理
UVM树
此处uvm_top作为默认树根,当任何类在new的时候指定parent为null时,默认挂载到top子节点
根据树的特性,我们可以使用get_parent()、get_child(“name”)查找
或者get_child(ref array[$])拿全部孩子
get_first_child(“name”)\get_next_child(“name”)\get_num_children()
field automation
`define uvm_field_int(ARG,FLAG)
`define uvm_field_real(ARG,FLAG)
`define uvm_field_enum(T,ARG,FLAG)
`define uvm_field_object(ARG,FLAG)
`define uvm_field_event(ARG,FLAG)
`define uvm_field_string(ARG,FLAG)
格式如上,作用是方便对上述变量使用uvm内定义的函数,如下
- 把某个A实例复制到B实例中, 那么应该使用B.copy( A)
- pack_bytes函数用于将所有的字段打包成byte流
- unpack_bytes函数用于将一个byte流逐一恢复到某个类的实例中
- clone()
如果说我们要注册一个变量,不想pack,因为是我们辅助定义的。FLAG就用
`uvm_field_int(crc_err, UVM_ALL_ON | UVM_NOPACK)
parameter UVM_ALL_ON = 'b000000101010101;
parameter UVM_COPY = (1<<0);
parameter UVM_NOCOPY = (1<<1);
parameter UVM_COMPARE = (1<<2);
parameter UVM_NOCOMPARE = (1<<3);
parameter UVM_PRINT = (1<<4);
parameter UVM_NOPRINT = (1<<5);
parameter UVM_RECORD = (1<<6);
parameter UVM_NORECORD = (1<<7);
parameter UVM_PACK = (1<<8);
parameter UVM_NOPACK = (1<<9);
在自动化块内,可以使用if(rand x),随机化时候随机x。
打印
get_report_verbosity_level获得component的冗余度
typedef enum
{
UVM_NONE = 0,
UVM_LOW = 100,
UVM_MEDIUM = 200,
UVM_HIGH = 300,
UVM_FULL = 400,
UVM_DEBUG = 500
} uvm_verbosity;
set_report_verbosity_level只对某个特定的component起作用。
还可以在仿真时使用,设置全局
重载危险等级
`uvm_warning("my_driver", "this information is warning, but prints as UVM_ERROR")
env.i_agt.drv.set_report_severity_override(UVM_WARNING, UVM_ERROR);
//把warning变成Error
error到达阈值停止sim
set_report_max_quit_count(8);//from build phase
依旧是可以在sim命令输入
no表示不可被重载
其他用法
set_report_max_quit_count(5);
env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY|UVM_COUNT);
//加入worn ing计数
env.i_agt.drv.set_report_severity_action(UVM_ERROR, UVM_DISPLAY);
//移除error
env.i_agt.drv.set_report_id_action("my_drv", UVM_DISPLAY| UVM_COUNT);
//把ID为my_drv的所有信息加入到计数中, 无论是UVM_INFO, 还是UVM_WARNING或者是UVM_ERROR、
UVM_FATAL
env.i_agt.set_report_severity_id_action_hier(UVM_WARNING, "my_driver", UVM_DISPLAY| UVM_COUNT);
<sim command> +uvm_set_action=<comp>,<id>,<severity>,<action>
<sim command> +uvm_set_action="uvm_test_top.env.i_agt.drv,my_driver,UVM_NG,UVM_DISPLAY|UVM_COUNT"
断点调试
virtual function void connect_phase(uvm_phase phase);
env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY| UVM_STOP);
endfunction
和计数停止sim格式一样,用STOP替换
打印信息导入文件
待补充。。。
控制打印信息
/*
UVM_NO_ACTION是不做任何操作;
UVM_DISPLAY是输出到标准输出上;
UVM_LOG是输出到日志文件中,它能工作的前提是设置好了日志文件;
UVM_COUNT是作为计数目标;
UVM_EXIT是直接退出仿真;
UVM_CALL_HOOK是调用一个回调函数;
UVM_STOP是停止仿真, 进入命令行交互模式。
*/
typedef enum
{
UVM_NO_ACTION = 'b000000,
UVM_DISPLAY = 'b000001,
UVM_LOG = 'b000010,
UVM_COUNT = 'b000100,
UVM_EXIT = 'b001000,
UVM_CALL_HOOK = 'b010000,
UVM_STOP = 'b100000
} uvm_action_type;
config_db
独立于环境,如$display("%s", get_full_name());
就是db给出的路径
db最主要的功能就是get、set。
set后省略get调用
只要使用uvm_field_int注册,并且在build_phase中调用super.build_phase(),就可以省略在build_phase中的如下get语句
uvm_config_db#(int)::get(this, "", "pre_num", pre_num);
调用super.build_phase()会自动执行get语句
set多次,get一次
UVM规定层次越高,那么它的优先级越高
层级相同看时间
class case100 extends base_test;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(int)::set(this, "env.i_agt.drv", pre_num_max, 100);
endfunction
endclass
//在base中vm_config_db#(int)::set(this, "env.i_agt.drv", pre_num_max, 90);
//如此由于时间先后,设置的还是100
非同一棵树的实行顺序
在UVM树中,build_phase是自上而下执行。
scb与i_agt处于同一级别中,顺序未知。
获取set情况
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
check_config_usage();
endfunction
print_config(1);//1表示递归的查询,若为0,则只显示当前component的信息