我在 SystemVerilog 中有一个类,它代表我系统中的抽象数据事务。它看起来像这样:
class #(param BIT_DEPTH) MyData;
logic [BIT_DEPTH-1:0] thedata [];
metadata_type_t some_info_about_thedata;
//...
endclass
数组中的每个数据元素都是一个整数,表示科学设备对物理现象的测量(不幸的是我不能比这更具体)。这些整数的长度有许多有效的选择 - 它们可以是任何长度(小于 32b 的任何长度)。在一组物理测量中,长度将是统一的。名义上测量的位深度是固定的,但会根据系统配置而变化。
我想将一堆在模拟时未知的
BIT_DEPTH
my_data 放入队列中。
我尝试从基类继承......
class MyBaseData;
int bit_depth;
endclass
class #(param BIT_DEPTH) MyData extends MyBaseData;
logic [BIT_DEPTH-1:0] thedata [];
metadata_type_t some_info_about_thedata;
function new(metadata_type_t md);
this.bit_depth = BIT_DEPTH;
this.some_info_about_thedata = md;
this.thedata = new[some_info_about_thedata.thedatasize];
endfunction
endclass
但显然这不起作用:我无法在运行时创建具有未知参数值的对象:
MyBaseData mbd = queue.pop_back();
MyData#(mbd.bit_depth) mydata; // obviously not allowed
$cast(mydata, mbd);
我真正想要的是拥有一个打包逻辑数据类型,其宽度仅在运行时才知道。
有什么解决办法吗?我认为明显的解决方案是说“将它们存储在 int 中,在某处记录位深度,然后完成它”,但这对我来说感觉非常不优雅。看起来语言应该有一个机制来实现这一点;如果有的话,我想知道。
要完全清楚:此代码用于测试平台。我绝不期望它是可合成的。
SystemVerilog 是静态类型的。类型为压缩数组的变量的宽度必须在运行时之前已知,以便可以生成引用这些变量的表达式的代码。
人们处理此问题的最常见方法是使用固定大小的压缩数组,并具有所需的最大大小。记录您需要的实际大小,并根据需要使用它来屏蔽高位。
另一种选择是使用二维解包动态数组(如果位或某些多个位)
bit mydata[][]; // dynamic array of a dynamic array of bits
bit [7:0] mydata[][]; // dynamic array of a dynamic array of bytes
另一种选择是创建一个非参数化的抽象基类,并用参数化的类扩展它。
interface class base_data;
pure virtual function void initialize(int size);
pure virtual function int sum();
pure virtual function bit sum_compare(base_data rhs);
endclass
class mydata#(int WIDTH) implements base_data;
typedef bit [WIDTH-1:0] data_t;
data_t data[];;
virtual function void initialize(int size);
data = new[size];
void'(std::randomize(data));
endfunction
virtual function int sum;
return data.sum with (int'(item));
endfunction
virtual function bit sum_compare(base_data rhs);
mydata#(WIDTH) R;
if($cast(R,rhs))
return data.sum < R.sum;
else
$error("widths do not match");
endfunction
endclass
module top;
base_data array[4];
mydata#(4) C0 = new;
mydata#(4) C1 = new;
mydata#(8) C2 = new;
mydata#(8) C3 = new;
initial
begin
array[0] = C0;
array[1] = C1;
array[2] = C2;
array[3] = C3;
foreach(array[i]) begin
array[i].initialize(i+5);
$display("sum array[%0d] %d",i,array[i].sum);
end
end
endmodule
如果不知道为什么您认为需要将这些数据元素存储在不同大小的数组中,而不是 32 位整数,或者您需要对这些元素执行什么操作,则很难提出最佳解决方案(XY 问题)。