我有一个父类和很多子类。我想实例化所有子类并将它们转换为父对象数组/队列,这样我就可以使用父数组/队列做一些有用的事情。
代码如下:
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());
答案 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();