首页 > 解决方案 > UVM中的工厂覆盖参数化类

问题描述

我有一个参数化的 seq_item 如下

class seq_item#(int A = 64) extends uvm_sequence_item;
  `uvm_object_param_utils(seq_item#(A))
  rand logic [A-1:0] v;
  constraint v_c {
    v inside {[0:1000]};
  }
endclass : seq_item

class extended_seq_item#(int A = 64) extends seq_item#(A);
  `uvm_object_param_utils(extended_seq_item#(A))
  constraint extended_v_c {
    v inside {[10:50]};
  }
endclass : extended_seq_item

class reg_adapter#(int A = 100) extends uvm_reg_adapter;
  `uvm_object_param_utils(reg_adapter#(A))
  typedef seq_item#(A) seq_item_t;
  function new(string name = "reg_adapter")
    seq_item_t req;
    req = seq_item_t::type_id::create("req");
  endfunction
endclass : reg_adapter

class test extends uvm_test;
  `uvm_component_utils(test)
  reg_adapter#(10) adapter;
  function void build_phase(uvm_phase phase);
    seq_item#(10)::type_id::set_type_override(extended_seq_item#(10)::get_type());
    super.build_phase(phase);
    adapter = reg_adapter::type_id::create("adapter");
  endfunction : build_phase
endclass : test

在我的 UVM TB 中,我需要使用 extended_seq_item 工厂覆盖所有 seq_item 实例。不同的实例会有不同的 A 参数值。我如何工厂覆盖它?

问题是 seq_item 来自共同的抵押品,它对 rand 变量 v 具有通用约束,适用于所有 IP。对于我的 IP,我需要为 extended_seq_item 中给出的 v 添加一个额外的约束。我的 IP 使用 reg_adapter 预计将采用 extended_seq_item 并添加了额外的约束

谢谢和问候, 基兰

标签: system-veriloguvm

解决方案


不幸的是,具有不同参数值的参数化类(专业化是 LRM 的术语)被视为单独的类类型,因此您需要为每个参数值提供覆盖。

seq_item#(10)::type_id::set_type_override(extended_seq_item#(10)::get_type());
seq_item#(20)::type_id::set_type_override(extended_seq_item#(20)::get_type());
seq_item#(30)::type_id::set_type_override(extended_seq_item#(30)::get_type());

如果您可以将此代码放入 A 已经参数化的位置,例如在参数化环境或代理的 build_phase 中,那么它可能不会像上面那样痛苦。


现在我看到更多代码,问题出在这一行中的类范围,应该被捕获为错误

adapter = reg_adapter::type_id::create("adapter");

应该写成

adapter = reg_adapter#(10)::type_id::create("adapter");

推荐阅读