我想在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
答案 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