我需要uvm_sequence_item
根据配置对信号宽度进行参数化。
在 uvm_sequence_item 中声明配置对象是个好主意吗?
或者是否可以uvm_sequence_item
像下面这样参数化?:
class my_sequence#(int width) extends uvm_sequence_item;
我需要uvm_sequence_item
根据配置对信号宽度进行参数化。
在 uvm_sequence_item 中声明配置对象是个好主意吗?
或者是否可以uvm_sequence_item
像下面这样参数化?:
class my_sequence#(int width) extends uvm_sequence_item;
这个想法是,如果你有一个带有特定参数的特定基类,那么为该参数定义不同值的子类类型不兼容:
// base class
class my_base_class #(int PARAM = 1);
endclass
PARAM 值为 2 和 3 的子类类型不兼容。
在您的情况下,您可以执行以下操作:
// common base class, no subclass
class my_base_item extends uvm_sequence_item;
// ...
endclass
// parameterized class
class my_param_item #(int PARAM = 1) extends my_base_item;
// ...
endclass
在您的序列中,您将项目定义为 my_base_item:
class my_sequence extends uvm_sequence;
my_base_item item;
task body();
item = my_base_item::type_id::create("item");
endtask
endclass
根据您的配置,您在某处设置类型覆盖:
my_base_item::type_id::set_type_override(my_param_item #(32))::get_type(), 1);
我没有对此进行测试,但它应该可以工作,因为 'my_param_item 的所有参数化仍然是 my_base_item 类型。
在驱动程序中,您必须根据您的参数值进行一些转换:
task drive();
// ...
case (param) begin
16:
begin
my_param_item #(16) m_item;
$cast(m_item, item); // item is the base item you got from the sequencer
do_drive_16(m_item);
end
32:
// ...
end
endtask
您必须像这样进行强制转换,因为您不能基于动态值声明参数化。参数必须在编译时知道。
最好的方法是使用工厂覆盖机制而不是 config_db 机制来选择你想要的参数化序列/_item。
请参阅下面的链接。它已经在那里提到了。
https://verificationacademy.com/cookbook/usingfactoryoverrides