Error: [VRFC 10-2951] 'WIDTH_DIFF' is not a constant

Error: [VRFC 10-2951] 'WIDTH_DIFF' is not a constant

我正在尝试对数据路径进行一些宽度操作,需要在必要时填充一些零。我已经在 verilog 中编写了以下逻辑并尝试进行综合。以下代码是一个最小的工作示例,显示了我面临的问题。 当我 运行 下面的代码时。

module mwe
    #(parameter RWIDTH = 20, // can be 20 or 16
      parameter BWIDTH = 16  // is generally always 16
     )
    (
    input clk,
    input rst,
    input a,
    output reg [RWIDTH -1:0] y
    );

    wire     [8*BWIDTH-1:0]          native_wdata_bus;  // 128 bit bus
     reg     [8*RWIDTH-1:0]          modified_wdata_bus;    // can be 128 bit or 160 bit bus based on RDATA configuration

    wire     [8*RWIDTH-1:0]          native_rdata_bus;  // can be 128 bit or 160 bit bus based on RDATA configuration
     reg     [8*BWIDTH-1:0]          modified_rdata_bus;    // generally is 128 bit bus

    // locally calulating the WIDTH_DIFF
    localparam WIDTH_DIFF = RWIDTH-BWIDTH;

    // function to pad zeros
    function [WIDTH_DIFF -1 : 0] pad_zeros(input WIDTH_DIFF);
        pad_zeros = {WIDTH_DIFF{1'b0}};
    endfunction

    always @* begin : width_change
        integer i;
        for (i=0; i<8; i=i+1) begin
            modified_rdata_bus[BWIDTH*i +: BWIDTH-1] = native_rdata_bus[(RWIDTH*i)+WIDTH_DIFF +: (RWIDTH-1)-WIDTH_DIFF];
            if(RWIDTH != BWIDTH)
                modified_wdata_bus[(RWIDTH*i) +: (RWIDTH-1)] = {native_wdata_bus[(BWIDTH*i) +: (BWIDTH-1)], pad_zeros(WIDTH_DIFF)};
            else
                modified_wdata_bus[RWIDTH*i +: RWIDTH-1] = native_wdata_bus[BWIDTH*i +: BWIDTH-1];
            end
    end

endmodule

我使用 Vivado xvlog 编译代码时得到以下信息。

INFO: [VRFC 10-2263] Analyzing Verilog file "/home/rtl/mwe/mwe.v" into library work
INFO: [VRFC 10-311] analyzing module mwe
ERROR: [VRFC 10-2951] 'WIDTH_DIFF' is not a constant [/home/rtl/mwe/mwe.v:23]
ERROR: [VRFC 10-2865] module 'mwe' ignored due to previous errors [/home/rtl/mwe/mwe.v:1]

我一直在查看其他与我类似的错误 。但它仍然没有完全回答我的问题。为什么 Verilog 编译器解释 WIDTH_DIFF 不是常量?

虽然我有兴趣解决这个问题,但我也在尝试了解 verilog 如何解释上面的代码(任何指针都会有所帮助)。

在函数声明中,您使用了:input WIDTH_DIFF。输入是变量类型,不是常量类型。因此,在函数内部的表达式{WIDTH_DIFF{1'b0}}中,WIDTH_DIFF被解释为一个变量,而不是常量。

您可以删除该函数并直接使用串联内联。变化:

modified_wdata_bus[(RWIDTH*i) +: (RWIDTH-1)] = {native_wdata_bus[(BWIDTH*i) +: (BWIDTH-1)], pad_zeros(WIDTH_DIFF)};

至:

modified_wdata_bus[(RWIDTH*i) +: (RWIDTH-1)] = {native_wdata_bus[(BWIDTH*i) +: (BWIDTH-1)], {WIDTH_DIFF{1'b0}}};