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