UVM实战卷I学习笔记5——UVM基础(3)fieldautomation机制

UVM实战卷I学习笔记5——UVM基础(3)fieldautomation机制
⽬录
field automation机制相关的宏
最简单的uvm_field系列宏有如下⼏种:
`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_object的类型、事
件及字符串类型。除枚举类型外都是两个参数,对枚举类型来说需要有三个参数。假如有枚举类型tb_bool_e,同时有变量tb_flag,那么在使⽤field automation机制时应该使⽤如下⽅式实现:
typedef enum{TB_TRUE, TB_FALSE} tb_bool_e;
tb_bool_e tb_flag;
`uvm_field_enum(tb_bool_e, tb_flag, UVM_ALL_ON)
与动态数组有关的uvm_field系列宏有:(少了event类型和real类型,enum类型的数组⾥也只有两个参数。)
`define uvm_field_array_enum(ARG,FLAG)
`define uvm_field_array_int(ARG,FLAG)
`define uvm_field_array_object(ARG,FLAG)
`define uvm_field_array_string(ARG,FLAG)
与静态数组相关的uvm_field系列宏有:(4种,且对于enum类型来说只需要两个参数)
`define uvm_field_sarray_int(ARG,FLAG)
`define uvm_field_sarray_enum(ARG,FLAG)
`define uvm_field_sarray_object(ARG,FLAG)张少川
`define uvm_field_sarray_string(ARG,FLAG)
与队列相关的uvm_field系列宏有:(4种,且对于enum类型来说只需要两个参数)
`define uvm_field_queue_enum(ARG,FLAG)
`define uvm_field_queue_int(ARG,FLAG)
`define uvm_field_queue_object(ARG,FLAG)
`define uvm_field_queue_string(ARG,FLAG)
联合数组是SV中定义的⼀种⾮常有⽤的数据类型,在验证平台中经常使⽤。UVM对其提供了良好的⽀持,与联合数组相关的uvm_field宏有:
经济危机论文`define uvm_field_aa_int_string(ARG, FLAG)
`define uvm_field_aa_string_string(ARG, FLAG)
`define uvm_field_aa_object_string(ARG, FLAG)
`define uvm_field_aa_int_int(ARG, FLAG)
`define uvm_field_aa_int_int_unsigned(ARG, FLAG)
`define uvm_field_aa_int_integer(ARG, FLAG)
`define uvm_field_aa_int_integer_unsigned(ARG, FLAG)
`define uvm_field_aa_int_byte(ARG, FLAG)
`define uvm_field_aa_int_byte_unsigned(ARG, FLAG)
`define uvm_field_aa_int_shortint(ARG, FLAG)
张炜 你在高原`define uvm_field_aa_int_shortint_unsigned(ARG, FLAG)
`define uvm_field_aa_int_longint(ARG, FLAG)
`define uvm_field_aa_int_longint_unsigned(ARG, FLAG)
`define uvm_field_aa_string_int(ARG, FLAG)
`define uvm_field_aa_object_int(ARG, FLAG)
联合数组有两⼤识别标志:存储数据的类型和索引的类型。在这⼀系列uvm_field系列宏中出现的第⼀个类型是存储数据类型,第⼆个类型是索引类型,如uvm_field_aa_int_string⽤于声明那些存储的数据是int,⽽其索引是string类型的联合数组。
*field automation机制的常⽤函数
copy函数⽤于实例的复制,其原型为:extern function void copy (uvm_object rhs);
厅官被双开 曾唱养生歌《祝你健康》如果要把A实例复制到B实例中,那么应该使⽤B.copy(A)。在使⽤此函数前,B实例必须已经使⽤new函数分配好了内存空间。
compare函数⽤于⽐较两个实例是否⼀样,其原型为:extern function bit compare (uvm_object rhs, uvm_comparer
comparer=null);
如果要⽐较A与B是否⼀样,可使⽤Apare(B),也可使⽤Bpare(A)。当两者⼀致时返回1;否则为0。
pack_bytes函数⽤于将所有字段打包成byte流,其原型为:extern function int pack_bytes (ref byte unsigned bytestream[ ], input uvm_packer packer=null);
unpack_bytes函数⽤于将⼀个byte流逐⼀恢复到某个类的实例中,其原型为:extern function int unpack_bytes (ref byte unsigned bytestream[ ], input uvm_packer packer=null);
pack函数⽤于将所有字段打包成bit流,其原型为:extern function int pack (ref bit bitstream[ ], input uvm_packer packer=null); unpack函数⽤于将⼀个bit流逐⼀恢复到某个类的实例中,其原型为:extern function int unpack (ref bit bitstream[ ], input
uvm_packer packer=null);
pack_ints函数⽤于将所有字段打包成int(4个byte或dword)流,其原型为:extern function int pack_ints (ref int unsigned intstream[ ], input uvm_packer packer=null);
unpack_ints函数⽤于将⼀个int流逐⼀恢复到某个类的实例中,其原型为:extern function int unpack_ints (ref int unsigned intstream[ ], input uvm_packer packer=null);
print函数⽤于打印所有字段,还有前⾯介绍过的clone函数,其原型为:extern virtual function uvm_object clone ();
除了上述函数之外,field automation机制还提供⾃动得到使⽤config_db::set设置的参数的功能。
field automation机制中标志位的使⽤
实现功能:给DUT施加⼀种CRC错误的异常激励。实现这个功能的⼀种⽅法是在my_transaction中添加⼀个
crc_err的标志位:在post_randomize中计算CRC前先检查⼀下crc_err字段,如果为1则直接使⽤随机值, 否则使⽤真实的CRC。
rand bit[15:0] ether_type;
rand byte pload[];
rand bit[31:0] crc;
rand bit crc_err;
...
function void post_randomize();
if(crc_err)
;//do nothing
else
crc = calc_crc;
endfunction
...
endclass
在sequence中可使⽤如下⽅式产⽣CRC错误的激励:`uvm_do_with(tr, {tr.crc_err == 1;})
对于多出来的这个字段,是不是也应该⽤uvm_field_int宏来注册呢?如果不使⽤宏注册的话,那么当调⽤print函数时显⽰结果中就看不到其值,但如果使⽤了宏,结果就是这个根本就不需要在pack和unpack操作中出现的字段出现了。这会带来极⼤的问题。
UVM考虑到了这⼀点,它采⽤在后⾯的控制域中加⼊UVM_NOPACK的形式来实现:
`uvm_object_utils_begin(my_transaction)
`uvm_field_int(dmac, UVM_ALL_ON)
`uvm_field_int(smac, UVM_ALL_ON)
`uvm_field_int(ether_type, UVM_ALL_ON)
`uvm_field_array_int(pload, UVM_ALL_ON)
`uvm_field_int(crc, UVM_ALL_ON)
`uvm_field_int(crc_err, UVM_ALL_ON | UVM_NOPACK)
`uvm_object_utils_end
使⽤上述语句后,当执⾏pack和unpack操作时,UVM就不会考虑这个字段了。这种写法是⽤或(|)来实现的。UVM的这些标志位本⾝其实是⼀个17bit的数字:
//A=ABSTRACT Y=PHYSICAL
//F=REFERENCE, S=SHALLOW, D=DEEP
//K=PACK, R=RECORD, P=PRINT, M=COMPARE, C=COPY
//---------------------- AYFSD K R P M C
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);
UVM_ALL_ON的值是’b000000101010101,表⽰打开copy、compare、print、record、pack功能。
UVM_ALL_ON|UVM_NOPACK的结果就是‘b000001101010101。这样UVM在执⾏pack操作时,⾸先检查bit9, 发现其为1,直接忽略bit8所代表的UVM_PACK。
*field automation中宏与if的结合
在以太⽹中有⼀种帧是VLAN帧,是在普通以太⽹帧基础上扩展⽽来的,且并不是所有的以太⽹帧都是VLAN帧,如果⼀个帧是VLAN帧,那么其中就会有vlan_id等字段,类似vlan_id等字段是属于帧结构的⼀部分,但这个字段可能有,也可能没有。由于读者已经习惯了使⽤uvm_field系列宏来进⾏pack和unpack操作,那么很直观的想法是使⽤动态数组的形式来实现:
rand bit[31:0] vlan[];
rand bit[15:0] eth_type;
rand byte pload[];
rand bit[31:0] crc;
`uvm_object_utils_begin(my_transaction)
`uvm_field_int(smac, UVM_ALL_ON)
`uvm_field_int(dmac, UVM_ALL_ON)
`uvm_field_array_int(vlan, UVM_ALL_ON)
`uvm_field_int(eth_type, UVM_ALL_ON)
`uvm_field_array_int(pload, UVM_ALL_ON)
`uvm_object_utils_end
endclass
在随机化普通以太⽹帧时,可使⽤如下⽅式:
my_transaction tr;
tr =new();
assert(tr.randomize() with {vlan.size()==0;});百人会
协议中规定vlan的字段固定为4个字节,所以在随机化VLAN帧时,可使⽤如下⽅式:
my_transaction tr;
tr =new();
assert(tr.randomize() with {vlan.size()==1;});
协议中规定vlan的4个字节各有不同的含义,分别代表4个不同的字段。如果使⽤上⾯的⽅式,问题虽然解决了,但这4个字段的含义不太明确。
⼀个可⾏的解决⽅案是:
class my_transaction extends uvm_sequence_item;
rand bit[47:0] dmac;
rand bit[47:0] smac;
rand bit[15:0] vlan_info1;
rand bit[2:0] vlan_info2;
rand bit vlan_info3;
rand bit[11:0] vlan_info4;
rand bit[15:0] ether_type;
rand byte pload[];
rand bit[31:0] crc;
rand bit is_vlan;
`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
endclass
使⽤这种⽅式的VLAN帧,在执⾏print操作时,4个字段的信息将会⾮常明显;在调⽤compare函数时,如果两个transaction不同,将会更加明确地指明是哪个字段不⼀样。

本文发布于:2024-09-21 22:07:14,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/365941.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:字段   类型   数组
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议