如何在SystemVerilog中模仿静态构造函数?

时间:2016-05-20 12:58:53

标签: macros system-verilog

我有一个父类和很多子类。我想实例化所有子类并将它们转换为父对象数组/队列,这样我就可以使用父数组/队列做一些有用的事情。

代码如下:

class parent;
endclass

class child1 extends parent;
endclass

class child2 extends parent;
endclass

program top;

    child1  c1;
    child2  c2;
    parent p, p_arr[$];

    initial
    begin
      c1 = new;
      assert ($cast(p,c1)) else $fatal;
      p_arr.push_back(p);
      c2 = new;
      assert ($cast(p,c2)) else $fatal;
      p_arr.push_back(p);

      // Doing useful things with p_arr
      // .......
    end
endprogram

我想知道是否有办法让这更加整洁。 所以我将我的代码更改为:

    begin
      assert ($cast(p,child1::new())) else $fatal;   <---- QuestaSim compiler complained about "child1::new"
      p_arr.push_back(p);

      assert ($cast(p,child2.new())) else $fatal; <---- QuestaSim compiler complained about "child2.new"
      p_arr.push_back(p);
    end    

但编译器抱怨直接使用静态构造函数“child1 :: new()”或“child1.new()”。 SystemVerilog是否支持这样的功能? (如果是模拟器无能为力,你能说明模拟器支持它吗?)如果没有,是否有整洁的方法呢?例如使用宏?

宏的问题是我必须使用两个宏来完成它。 一个宏首先在函数/程序的顶部声明实例:

child1  c1; 

然后另一个宏初始化实例并将其放入函数/程序体中的数组:

c1 = new;
assert ($cast(p,c1)) else $fatal;
p_arr.push_back(p);

有没有办法使用一个宏来代替两个宏?

--------------------- EDIT ------------------------ < / p>

感谢@Tudor和@ dave_59的答案,该示例适用于p = child1 :: new()。我意识到我的父类是参数化类。语法也适用于他们。

 p = child1_class #(.WIDTH(WIDTH))::new();   
 p_arr.push_back(p);
 p = child2_class #(.WIDTH(WIDTH))::new();
 p_arr.push_back(p);

不幸的是,对于新的构造函数,我必须明确指定new分配给哪个对象。并且以下语法不起作用。

p_arr.push_back(child1::new());

2 个答案:

答案 0 :(得分:2)

LRM中针对作用域构造函数调用描述的语法是:

child1::new();

如果你很幸运,你的模拟器会支持它。

您的代码中不需要的是$cast(...)语句。由于您正在进行向下转换(从子类到父类),以下内容也是合法的:

p = child1::new();

如果你更幸运,你甚至可以将它缩短为:

p_arr.push_back(child1::new());

但同样,这取决于您的模拟器支持的内容。

答案 1 :(得分:2)

SystemVerilog BNF要求new()出现在作业的RHS上。但是在从扩展类到基类变量进行赋值时,不需要使用$ cast。所以你可以这样做:

module top;
    parent p, p_arr[$];
    initial
      begin
     p = child1::new();
     p_arr.push_back(p);
     p = child2::new();
     p_arr.push_back(p);

     // Doing useful things with p_arr
     // .......
    end
endmodule

您也可以执行

之类的操作
     p_arr = '{3{null}};
     p_arr[0] = child1::new();
     p_arr[1] = child2::new();
     p_arr[2] = child1::new();