我有一个模块,它有一个端口,其宽度应取决于函数的值: (语法是 Verilog/Systemverilog 混合,因为我使用 yosys 进行综合,仅支持有限数量的 SV)
module MY_MODULE#(
parameter MY_PARAM = 2,
parameter PARAM_TWO = 10
)(
input logic CLK_CI,
...
input logic [my_func(MY_PARAM, PARAM_TWO):0] RND,
...
output logic Finish_SO
);
问题是该函数需要使用 for 循环来计算值,因为我需要对一些计算值进行求和。示例:
function automatic int myfunc(input loop_control, input variables);
int carry;
int variables_next = 0;
for (int i = 0; i < loop_control; i++) begin
carry = variables_next & 1;
variables_next = (variables_next >> 1) + carry;
end
myfunc = carry;
endfunction
从技术上讲,只要输入恒定,函数的输出就恒定。就我而言,我总是使用 localparams 调用该函数,这些参数是常量。然而,由于我使用 for 循环并且进位变量发生变化,因此它被认为是非常量。
验证器错误: 期望表达式为常量,但无法确定 FUNCREF 'myfunc' 的常量
来自 yosys 的错误: 常量表达式中的非常量函数调用。
有没有办法让一个带有for循环的函数作为常量函数?
我可以对参数数组中的值进行硬编码,但我宁愿不这样做。
我想创建一个函数,它使用常量(本地参数)输入来创建可与端口定义一起使用的输出。我尝试过的一种方法是在我的生成 for 循环中获取我需要的值,但是我还没有找到一种方法来在生成 for 循环中添加本地参数。
您可以尝试按如下方式预先计算您的参数
module MY_MODULE#(
parameter MY_PARAM = 2,
parameter PARAM_TWO = 10,
localparam my_func_data = my_func(MY_PARAM, PARAM_TWO)
)(
input logic CLK_CI,
input logic [my_func_data:0] RND,
output logic Finish_SO
);
function automatic int my_func(input loop_control, input variables);
int carry;
int variables_next = 0;
for (int i = 0; i < loop_control; i++) begin
carry = variables_next & 1;
variables_next = (variables_next >> 1) + carry;
end
my_func = carry;
endfunction
endmodule
就我而言,Vivado 在您的构造中发出警告的另一个原因是您的函数名为
myfunc
,但您试图调用 my_func
。在这种情况下引发的第一个错误是“范围必须由常量表达式界定”,第二个错误是“myfunc”未声明”。