具有可配置大小的Systemverilog localparam数组

时间:2016-12-19 12:17:24

标签: 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
};

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

"显而易见"将生成SystemVerilog中的选项,但我读到在生成块中放置一个参数定义会生成一个相对于生成块(source)中的层次范围的新本地参数。

有什么建议吗?

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

但是,我不想拥有" *"在我的代码中因为我​​担心合成工具会生成一个乘数,然后它会尝试简化,因为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

我想也许我找到了解决方案。通过不定义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

1 个答案:

答案 0 :(得分:3)

您可以使用函数的返回值设置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