UVM实战指南(3)

2019-08-30 16:37

第16-18行:在数据对象中构造函数并不是必须的。如果使用构造函数,它的所有的参数都必须有缺省值. (针对uvm_object如此,但是uvm_component并不是这样,其parent参数并没有缺省值,因为不可能在类中知道其父组件)

4.3.1 UVM自动域

使用`uvm_object_utils_begin(TYPE)和`uvm_object_utils_end宏来完成UVM对象的基本操作声明。

? ? ? ?

实现get_type_name()函数,此函数返回内容为这个对象类型名字的字符串 实现create()函数,此函数通过调用指定类型的构造函数来创建一个对象 在工厂中注册此类型,以便在测试向量中的其他地方能够被重载 实现一个静态方法get_type(),此方法在工厂操作中需要被用到

`uvm_field_*宏将自动实现指定域的一些对象方法:print(), copy(), clone(), pack(), unpack(), compare(),以及record()。支持嵌套对象以及用户自定义。宏语法如下: 语法:`uvm_field_*(field_name,flag)

“field_name”必须是类的某个属性的标识符;“flag”用来定制此域的自动化。“flag”是一数字,可以用或“|”或者“+”进行组合。此语法适合:对象、字符串、事件(event)、实数、队列、以及不同类型的数组。

域自动有多种形式,请参考UVM参考手册。

4.3.2 uvm_object定义指南

?

建议从uvm_sequence_item继承对象,此方式能够给对象增加一些额外的域,同时允许对象成为uvm_sequence随机的一部分。

对`uvm_field_*宏使用UVM_DEFAULT作为“flag”参数(而不是UVM_ALL_ON)。目的是为了让UVM架构增加一些缺省下并不打开的自动功能。其他一些标志是用来去掉一些自动化功能的。

?

? ? ? ?

在构造函数中的参数中将类名字设置为缺省值

不要忘记调用super.new(name),作为构造函数的第一个语句 另一个不同的宏包含了类型参数:`uvm_object_param_utils*

`uvm_field_object缺省是深度操作。如果你使用另外一个对象,请使用UVM_REFERENCE标志来禁止深度操作。

实例4-3演示了域自动宏的更多用法,包括类组合和动态数组。此例子中的yapp_packet类包含一个pkt_header域。

实例4–3:uvm_object自动域

1 class packet_header extends uvm_object; // Packet Header class 2 rand bit [ 5:0] length; 3 rand bit [ 1:0] addr;

4 `uvm_object_utils_begin (packet_header) 5 `uvm_field_int (length, UVM _DEFAULT) 6 `uvm _field_int(addr, UVM _DEFAULT) 7 `uvm_object_utils_end 8 endclass : packet_header

9 typedef enum bit { BAD _PARITY, GOOD _PARITY } parity_e; 10 class yapp_packet extends uvm_object; 11 // Physical Data

12 rand packet_header header; // pkt_header class contains: addr, length 13 rand bit [7:0] payload [] ; // dynamic array in the range [1:63] 14 bit [7:0] parity; // calculated in post _randomize() 15 // Control Knob

16 rand parity_e parity_type; // randomized to determine parity type 17 rand int packet_delay;

18 // UVM macros for built-in automation - These declarations enable automation 19 // of the data_item fields and implement create() and get _type _name() 20 `uvm_object_utils_begin (yapp_packet) 21 `uvm _field _object (header, UVM _DEFAULT) 22 `uvm _field _array _int (payload, UVM _DEFAULT) 23 `uvm _field _int (parity, UVM _DEFAULT)

24 `uvm_field_enum(parity_e, parity_type, UVM _DEFAULT)

25 `uvm _field _int(packet _delay, UVM _DEFAULT | UVM_DEC | UVM_NOCOMPARE) 26 `uvm_object_utils_end

27 // Constructor - required syntax for UVM automation and utilities 28 function new (string name = \29 super.new(name);

30 header = packet_header::type_id::create(\31 endfunction : new 32 endclass : yapp_packet

第1行:header_packet由uvm_object继承而来

第21行:如果这是一个参考类,那么我们需要使用UVM_REFERENCE标志来避免深度操作。payload是一个动态数组,使用一个特殊的宏可以打印数组的所有成员。 第24行:枚举类型语法有一个额外参数:

`uvm_field_enum(,,)

第30行:不用“header=new(“header”)”,我们使用工厂模式。用`uvm_object_utils实现的create()方法允许在另外项目和测试环境中扩充交易(transaction)。请参考第62页的“UVM工厂”了解更多信息。

4.3.3 UVM对象自动用法实例

下面的例子演示了UVM库内建的自动特性。假定实例4-2中的apb_transfer已经定义。 实例4–4:UVM对象的自动特性的用法

1 module automation_example;

2 // Import the UVM library and include the UVM macros 3 import uvm_pkg::*; 4 `include “uvm_macros.svh” 5 // Include the APB transfer class 6 `include “apb_transfer.sv”

7 apb_transfer my_xfer, tx1, tx2, tx3; 8 initial begin

9 my_xfer = apb_transfer::type _id::create(\10 if (!my_xfer.randomize())

11 `uvm_fatal(“RANDFAIL”,”can not randomize my_xfer”) 12 tx1 = my_xfer; // tx1 and my_xfer share the same memory 13 // Create a new apb_transfer 14 tx2 = apb_transfer::type _id::create(\15 tx2.copy(tx1); // Copies fields from tx1 to tx2

16 $cast(tx3, tx1.clone()); // Creates a new apb_transfer and copy all 17 // specified fields from tx1 to tx3 18 if(!tx3.compare(tx2))

19 `uvm_error(“CompareFailed”, “The comparison failed”) 20 my_xfer.print(); // Prints my_xfer in a table format

21 my_xfer.print(uvm_default_tree_printer); // Prints in “tree” format 22 end

23 endmodule: automation_example

为了使用UVM库,必须导入UVM包,并且包含文件\此例子创建、随机化、复制、克隆、并且打印apb_transfer. 使用宏自动实现一个列表以及树形格式化的打印方法print()。

缺省的表格格式如下:

Name my_xfer addr data direction transmit_delay

Type apb_transfer integral integral

apb_direction_enum integral

Size - 32 32 1 32

Value @560 'hb2cbb864 'heba598d7 APB _WRITE 'h6

缺省的树形格式如下: my_xfer: (apb_transfer@560) {

addr: 'hb2cbb864 data: 'heba598d7 direction: APB _WRITE transmit_delay: 'h6 }

下面的输出显示了第40页实例4-3中随机的yapp_packet。此封包包括一个头对象,一个具有动态数组类型的payload。下面表格中数值很容易格式化并打印如下表格:

Name my_packet header length addr payload [0]

Type yapp_packet pkt_header integral integral da(integral) integral

integral integral ...

Size - - 6 2 48 8 8 8 ... 8 8 8

Value @570 @596 'h30 'h2 - 'h7b 'he7 'h8c ... 'hf 3 'h78 'he1

? ?

...

? ?

[47]

integral integral integral

parity parity_type packet_delay

integral parity_e integral

8 1 32

'h74

GOOD _PARITY

'd8

自动域宏将实现一个字符串打印方法:sprint(),此方法将返回一个可以用来格式化显示的字符串。打印格式是可以配置的,详细请参考UVM参考手册。

注意:表格打印使用的是最复杂的格式化功能,因此运行代价最高。如果你的仿真器要打印大批量的交易(transaction), 最好使用树形格式。

4.3.4 使用UVM自动域

使用UVM 自动域是可选的。尽管用户可以自己实现这部分功能,我们还是建议使用自动宏来实现。使用宏有以下优点:

? ?

高效率:如果自己实现,会需要很多时间来实现这些子例程以及丰富的可选项 可扩展性:在嵌套的对象中增加一个域需要了解UVM的原始实现方式,这常常需要很强的技巧。而用自动宏只需要一行语句即可

实现的一致性对复用很重要——例如,如果每个开发者都是用自行开发的print()方法,那么使用多个包的整合人员将不得不分析各不一样的日志文件,包括域头,值,基,以及结构,这些都属于开发者的各自喜好。

?

? ?

可维护性——维护少数行数的代码简化了UVM开发者的工作

代码正确性——对于大量的数据对象,很难确保所有的例程都是正确的,BUG会出现在不恰当的时间

请注意,这些宏是属于库的内部实现,已经很成熟,不需要用户来调试。对缺省的对象函数print()进行调试就好像对verilog仿真器中的$display函数进行调试。总之,我们见过一些用户最初比较担心宏的使用,后来一旦他们尝试使用宏,就变得十分喜欢它,成为宏的爱好者,并感叹道:“他们真好用!”

UVM实战指南——第2部分

2010-12-24 20:54:22| 分类: SystemVerilog | 标签:uvm |字号 订阅

英文来源:http://www.low-powerdesign.com/article_Cadence-UVM_083010.html 译者序:UVM的核心组件,以及UVM仿真阶段的控制是整个验证环境的基本零部件,必须掌握。UVM的参数config机制对验证增加了许多灵活性和复用性,在参数配置和SystemVerilog Interface信号传递上起到了关键作用。


UVM实战指南(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:《苹果树上的外婆》整本书读书规划

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: