System verilog sv中的参数化类队列

System verilog sv中的参数化类队列,system-verilog,uvm,System Verilog,Uvm,在我的测试台中,有两个pcie_代理具有不同的通道。我从pcie VIP扩展了自己的类。比如: class mt_pcie_agent#(int INST=0) extends pcie_agent((INTS==0)?2:(INTST==1)?4:(INST==2)?8:16);//different lanes by instance. ... endcase 现在我想把它们放到我的环境中的队列中 class mt_env extend uvm_env; ... mt_pcie_agent

在我的测试台中,有两个pcie_代理具有不同的通道。我从pcie VIP扩展了自己的类。比如:

class mt_pcie_agent#(int INST=0) extends pcie_agent((INTS==0)?2:(INTST==1)?4:(INST==2)?8:16);//different lanes by instance.
...
endcase
现在我想把它们放到我的环境中的队列中

class mt_env extend uvm_env;
...
mt_pcie_agent rc_agent[$:8];
...
virtual function void build_phase(uvm_phase phase);
  super.build_phase(phase);
  ...
  for(int i=0; i<`NUM_RC; i++) begin //`NUM_RC = 1~8
    case (i)
      0: begin
           rc_agent.push_back(mt_pcie_agent#(0)::type_id::create($sformatf("rc%0d_agent",i), this);
         end
      1: begin
           rc_agent.push_back(mt_pcie_agent#(1)::type_id::create($sformatf("rc%0d_agent",i), this);
         end
      ...
   endcase
   ...
endfunction
...
endclass
class mt_env扩展uvm_env;
...
mt_pcie_代理rc_代理[$:8];
...
虚拟功能无效构建阶段(uvm阶段);
超级建造阶段(阶段);
...

对于(int i=0;i大多数模拟器都会因为类型不匹配而抛出错误。正如您所认识到的那样,
mt#u pcie#代理(1)
不是同一类型,或者被认为是
mt#u pcie#代理(0)
的扩展类。可能有一个模拟器只会抛出警告并让您逃脱,但这不是一个好的实践

您可以将
mt_pcie_代理rc_代理[$:8];
更改为
uvm_代理rc_代理[$:8];
(或
pcie_代理的一些中间非参数或公共参数值父类
)。父句柄可以指向子对象,但它可以访问的范围是有限的。例如,您将无法在env的连接阶段将sequencer直接连接到代理/驱动程序,因为
uvm\U代理
句柄不知道该对象是否有要连接的对象

您可以通过config_db绕过此问题,在config_db中,您
::设置将在env的构建阶段连接到rc_代理的sequencer,然后
::在rc_代理连接阶段获取它

或者,有时只需将rc_代理风格添加到环境中,只需创建所需的内容就更容易了。只需键入更多内容。如果您特别需要代理队列,也可以保留它(指向同一对象的两个指针)。示例:

mt_pcie_agent#(0) rc0_agent;
mt_pcie_agent#(1) rc1_agent;
...
mt_pcie_agent#(7) rc7_agent;
uvm_agent rc_agent[$]; // for what ever reference
...
virtual function void build_phase(uvm_phase phase);
  super.build_phase(phase);
  ...
  for(int i=0; i<`NUM_RC; i++) begin //`NUM_RC = 1~8
    case (i)
      0: begin
           rc0_agent = mt_pcie_agent#(0)::type_id::create($sformatf("rc%0d_agent",i), this);
           rc_agent.push_back(rc0_agent);
         end
      1: begin
           rc1_agent = mt_pcie_agent#(1)::type_id::create($sformatf("rc%0d_agent",i), this);
           rc_agent.push_back(rc1_agent);
         end
      ...
   endcase
   ...
endfunction
mt#u pcie#u代理#(0)rc0#u代理;
mt#U pcie#U代理#(1)rc1#U代理;
...
mt#U代理#(7)rc7#U代理;
uvm_agent rc_agent[$];//参考什么
...
虚拟功能无效构建阶段(uvm阶段);
超级建造阶段(阶段);
...

对于(int i=0;i请格式化您的代码示例,并尝试自己编译。。感谢Greg的帮助。实际上,我想利用VIP供应商的代码,从序列到函数覆盖率,其中包含参数“LANES”。所有这些类都很难找到自己的父类,而不包含“LANES”。这就是我不想使用父类队列的原因。如果我提到的方法可以,我可以节省很多时间,并使代码易于维护。