使用串联的基于索引的数组右移;错误:前缀中不允许有范围

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

我正在尝试实现一个数组右移器。

它接受一个整数数组,然后将所有内容右移到指定索引位置的右侧,并在索引位置插入指定的整数值。

例如

如果 arr = {1, 2, 3, 4, 5, 6, 7, .... 16}; idx = 4;插入值=0; 然后 new_arr = {1, 2, 3, 0, 4, 5, 6, ... 15}

下面是我的代码:

// Right shifts the arrays from given index, and inserts given value.

`timescale 1ns / 1ps

module indexed_rsh(
                        input wire [511:0] arr,
                        input wire [3:0] idx,
                        input wire [31:0] insert_value,
                        output wire [511:0] new_arr
                    );

logic [0:15][31:0] arr_sig, new_arr_sig;

assign arr_sig = arr;
assign new_arr = new_arr_sig;

genvar i;
generate
    for (i=0; i < 16; i = i + 1)
        begin
            always_comb
                if(idx == i)
                    new_arr_sig [0:15][31:0]  = {arr_sig[0:i-1][31:0], insert_value, arr_sig[i:14][31:0]};
        end
endgenerate

endmodule

在 EDAplayground 上,我在第 21 行收到语法错误,并在第 23 行收到“错误:无效模块项”。

在 Vivado 中,我在第 23 行收到一条错误消息“前缀中不允许范围”。 如果前缀中不允许使用范围,那么索引 2D 数组的好方法是什么?

verilog system-verilog vivado edaplayground
2个回答
0
投票

这是一种在给定的 32 位索引偏移处将 32 位值插入到 512 位值中的方法,同时将其他位右移:

module indexed_rsh (
    input wire [511:0] arr,
    input wire [3:0] idx,
    input wire [31:0] insert_value,
    output reg [511:0] new_arr
);

always_comb begin
    for (int i=0; i<16; i++) begin
        int offset32;
        offset32 = 32*i;
        for (int j=0; j<32; j++) begin
            if (i < idx) begin
                new_arr[j + offset32] = arr[j + offset32];
            end else if (i == idx) begin
                new_arr[j + offset32] = insert_value[j];
            end else begin
                new_arr[j + offset32] = arr[j + offset32 - 32];
            end
       end
    end
end

endmodule

如果你想使用内部二维压缩数组:

module indexed_rsh (
    input wire [511:0] arr,
    input wire [3:0] idx,
    input wire [31:0] insert_value,
    output wire [511:0] new_arr
);

logic [15:0][31:0] arr_sig, new_arr_sig;
assign arr_sig = arr;
assign new_arr = new_arr_sig;

always_comb begin
    for (int i=0; i<16; i++) begin
        if (i < idx) begin
            new_arr_sig[i] = arr_sig[i];
        end else if (i == idx) begin
            new_arr_sig[i] = insert_value;
        end else begin
            new_arr_sig[i] = arr_sig[i-1];
        end
    end
end
endmodule

-1
投票

(回复工具,作为答案发布并附上图片)

嗨,我想在这里更新一下,上面的代码没有综合预期的电路。

也许 Vivado 由于在“if”条件中使用“i”而感到困惑,并试图为此生成硬件。

我尝试使用生成来指定我不想合成 if 条件,但出现语法错误。对于我的理想电路,我需要找出在always->for->if块的嵌套中理想地放置generate的位置。

现在,我最终做了一个分层模块,包含下图所示的逻辑。图中所示的逻辑是针对数组的每个元素进行实例化的。我使用生成 for 循环将信号 ref_const[i] 硬连线到值“i”(0 表示第一个实例化,1 表示第二个实例化,...)。

(我将 Sel=0 指定为错误,因为我的数组始终具有非零值)

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