我正在学习UVM教程的基础知识。我读到的每个地方的事务对象总是从uvm_sequence_item
扩展而不是uvm_transaction
,因为uvm_sequence_item
具有其他功能,如事务ID等。如果是这种情况,为什么{{1}甚至在UVM类层次结构中的类?
谁使用uvm_transaction
以外的uvm_transaction
?
这是因为遗产吗?
答案 0 :(得分:5)
这就是UVM Class Reference对此的说法:
" uvm_transaction类是UVM事务的根基类。 uvm_transaction继承了uvm_object的所有方法,增加了一个计时和记录界面。
此类提供时间戳属性,通知事件和事务记录支持。
不建议使用此类作为用户定义事务的基础。其子类型uvm_sequence_item将用作所有用户定义的事务类型的基类。"
答案 1 :(得分:1)
如果您引用uvm类层次结构(链接:[https://www.google.co.in/search?biw=1366&bih=620&tbm=isch&sa=1&btnG=Search&q=uvm+class+hierarchy#imgrc=Laxc9UWNpnGTpM%3A][1]),那么您会发现uvm_transaction父类,而uvm_sequence是子类。
因此,子类可以访问父类的所有属性。 但是父类无法访问子类属性。
uvm_sequence_item有自己的功能,如get_sequencer_id,set_sequencer_id,get_root_sequence。
在层序列的情况下,测序仪内部使用这些方法。
您可以通过start方法,uvm_do系列或config_db调用序列。
这些方法中的每一个都调用start_item(req)和finish_item(req)。
task start_item(uvm_sequence_item item)
task finish_item(uvm_sequence_item item)
如果在第一个参数中观察数据类型,则函数为uvm_sequence_item。
共有八个uvm课程。
(1) uvm_driver.svh
(2) uvm_push_driver.svh
(3) uvm_sequencer.svh
(4) uvm_push_sequencer.svh
(5) uvm_sequencer_library.svh
(6) uvm_sequencer_analysis_fifo.svh
(7) uvm_sequence.svh
(8) uvm_sequencer_param_base.svh
这些类使用uvm_sequence_item参数化而不是使用uvm_transaction参数化。
如果您使用uvm_transaction而不是uvm_sequence_item,那么ti将从uvm_sequencer_param_base.svh发出错误(找不到set_sequence_id,这是uvm_sequence_item的属性,而不是uvm_transaction)。
因此,序列,音序器和驱动程序的通信没有完成。
在大多数情况下,如果您的代码中不要使用uvm_sequencer,那么您可以使用uvm_transaction,它不会发出错误。
但是,如果您的代码包含uvm_sequener 并且您使用 uvm_transaction ,则会发出错误(无法找到成员'set_sequence_id')。
答案 2 :(得分:0)
请注意,从uvm_transaction类继承uvm_sequence_item以及uvm_objects。因此,静态行为和非静态行为(也就是说)类层次结构都是从uvm_transaction开始的。
现在,我可以将任何我想要的功能添加到uvm_sequence_item中,以便uvm_sequence_item的每个继承者都能得到它。我可以在不修改uvm_transction_item的情况下完成此操作。否则,uvm_transaction的任何更改都会导致组件类层次结构中的不需要的功能(静态行为),甚至可能导致意外的副作用。
PS:其他OOP语言和SV之间的区别之一是SV中不允许多重继承。例如,在C ++的情况下,我可以继承新类中的2个类。 SV中不允许这样做。因此,从uvm_sequence_item继承uvm_transaction和uvm_sequence_item属性的唯一方法是继承uvm_sequence_item。这可能是你困惑的根源。