在 SystemVerilog 中参数化数组元素的宽度

问题描述 投票:0回答:1

是否可以在SystemVerilog中参数化数组元素的宽度?

目前,我正在做以下事情:

localparam N = 5;
localparam int widths[0:N - 1] = '{32, 16, 8, 4, 2};
localparam max_width = widths[0];

bit [max_width - 1:0] data [0:N - 1];

然后在代码中,我仅根据

data
中指定的相应元素的宽度来访问
widths
,期望合成过程会消除不必要的部分:

smth_3 <= data[3][widths[3] - 1:0];
data[1][widths[1] - 1:0] <= smth_1;

有没有一种方法可以通过类似数组的访问来实现这一点,以获得更好的代码可读性和建模便利性?

PS。我已经看到(here)一种使用生成块的方法,但是,它不合适,因为在 Vivado 中我无法使用这样的迭代索引访问数据。

module playgroynd();

localparam N = 5;
localparam int widths [0:N - 1] = '{32, 16, 8, 4, 2};

for (genvar i = 0; i < N; i++) begin : stage
    bit [widths[i] - 1:0] data;
end

initial begin
    for (int i = 0; i < N; i++) begin
        $display("stage data = %0d, width %0d", stage[i].data, $size(stage[i].data)); // Cannot be simulated
    end
    
    // $display("stage data = %0d, width %0d", stage[0].data, $size(stage[0].data)); // Can be simulated
end

endmodule
arrays multidimensional-array system-verilog hdl
1个回答
0
投票

正确。 verilog 中所有基于参数的表达式(生成块)均在编译的细化阶段解析。它们在运行时之前完全展开。

内部过程块(always、initial、final)的所有循环和表达式在运行时进行评估。

因此,在编译时解析的索引表达式在运行时无效。

访问此类数据的唯一方法是仅在编译时。在您的情况下,您可以将初始块移动到生成块内,如您的修改示例所示:

module playgroynd();

localparam N = 5;
localparam int widths [0:N - 1] = '{32, 16, 8, 4, 2};

for (genvar i = 0; i < N; i++) begin : stage
    bit [widths[i] - 1:0] data;
end
for (genvar i = 0; i < N; i++) begin : init
    initial begin
       $display("stage data = %0d, width %0d", stage[i].data, $size(stage[i].data)); // Cannot be simulated
  end      
end

endmodule
© www.soinside.com 2019 - 2024. All rights reserved.