大小可配置的Systemverilog localparam数组

1 arrays parameters system-verilog

我想在SystemVerilog中创建和定义localparam数组。数组的大小应该是可配置的,并且每个localparam数组单元的值都基于其位置来计算。本质上这段代码:

localparam [7:0] [ADDR_BITS-1:0] ADDR_OFFSET = '{
  7*PAGE_SIZE,
  6*PAGE_SIZE,
  5*PAGE_SIZE,
  4*PAGE_SIZE,
  3*PAGE_SIZE,
  2*PAGE_SIZE,
  1*PAGE_SIZE,
  0
};
Run Code Online (Sandbox Code Playgroud)

但是其中第一个'7'被替换为参数,并且参数初始化扩展到一般情况。所以我需要一种从0循环到(N-1)并设置ADDR_OFFSET(loop)= loop * PAGE_SIZE的方法。

SystemVerilog中的“ obvious”选项将被生成,但是我读到将参数定义放置在generate块内会生成一个相对于generate块(source)中的分层作用域的新局部参数。

有什么建议么?

供背景参考:我需要根据基地址和数字来计算实际地址。计算很简单:real_address = base_address + number * PAGE_SIZE

但是,我不想在代码中使用“ *”,因为恐怕synt工具会生成一个乘数,然后它会尝试简化,因为PAGE_SIZE是一个恒定值。我猜想,与生成localparam数组时尝试进行所有计算相比,这可能导致更多的逻辑,因为这肯定不会给逻辑带来任何乘数。

因此,使用上述localparam定义,我将执行所需的地址计算,如下所示:

  function [ADDR_BITS-1:0] addr_calc;
    input [ADDR_BITS-1:0] base_addr;
    input [NBITS-1:0]  num;

    addr_calc = base_addr + ADDR_OFFSET[num];
  endfunction
Run Code Online (Sandbox Code Playgroud)

我想也许我找到了解决方案。我不是通过不定义localparam数组而是在循环内执行地址计算来实现上述目的吗?由于systemverilog将循环变量视为“常数”(在生成逻辑时),似乎可以完成相同的工作?这样(在我上面编写的函数中):

for (int loop1 = 0; loop1 < MAXNUM ; loop1++) begin
  if (num == loop1) begin
    addr_offset = CSP_PAGE_SIZE*loop1;
  end
  addr_calc = base_addr + addr_offset;
end
Run Code Online (Sandbox Code Playgroud)

dav*_*_59 5

您可以使用函数的返回值设置localparam。

   localparam bit [7:0] [ADDR_BITS-1:0] ADDR_OFFSET = ADDR_CALC();
   function bit [7:0] [ADDR_BITS-1:0] ADDR_CALC();
      for(int ii=0;ii<$size(ADDR_CALC,1); ii++)
    ADDR_CALC[ii] = ii * PAGE_SIZE;
   endfunction 
Run Code Online (Sandbox Code Playgroud)