Verilog/SystemVerilog:“常量”函数被认为是非常量

问题描述 投票:0回答:1

我有一个模块,它有一个端口,其宽度应取决于函数的值: (语法是 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 循环中添加本地参数。

verilog system-verilog hdl yosys verilator
1个回答
0
投票

您可以尝试按如下方式预先计算您的参数

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”未声明”。

© www.soinside.com 2019 - 2024. All rights reserved.