【问题标题】:Verilog code: initializing an 2D array using nested for loopVerilog 代码:使用嵌套 for 循环初始化二维数组
【发布时间】:2018-05-07 21:26:38
【问题描述】:

我最近尝试存储一个二维数组,其元素由 8 位整数(0~4)组成,首先逐行输入其元素(将其视为一维数组),然后访问一维数组。 我的程序如下:

1.在测试台中初始化一个2048-bits-1D(8*16*16)数组(代码中的Row1)作为输入

2.每8位切割一维数组,并将8位数字分配给二维数组中的元素

3.使用另一个一维数组(代码中的Row2)观察最终结果,因为数组不能作为实例输出 所以实际上我正在将一个包含 256 个 8 位元素的一维数组转换为一个包含 16*16 个 8 位元素的二维数组。

问题是在运行模拟之后, 二维数组中的大部分元素似乎都处于高 z 状态, 而它们中的最后一个已正确分配了新值。 谁能解释发生了什么以及我该如何解决?

为了清楚起见,我把我的verilog代码放在下面:

`timescale 1ns / 1ps
module convPE(
    input clk,
    input reset,
    input [2048:1] Row1,
    output [2048:1] Row2
    );
    wire [7:0] arr[17:0][17:0];

    generate
    genvar i,j;
    for(i=16;i>=1;i=i-1)
    begin:gen1
        for(j=16;j>=1;j=j-1)
        begin:gen2
            assign arr[i][j]=Row1[(8*i*j) -: 8];
            assign Row2[(8*i*j) -: 8]=arr[i][j];

        end
    end
    end generate
endmodule

这里是测试台:

`timescale 1ns / 1ps
module testbench;

    // Inputs
    reg [2048:1] Row1;
    reg Clk;
    reg Reset;

    wire [2048:1] Row2;
    convPE uut (
        .clk(Clk),
        .reset(Reset),
        .Row1(Row1),
        .Row2(Row2)
    );

    initial begin
        // Initialize Inputs
        Row1=2048'd0;

        Row1[1784:1777]=8'd1;//1
        Row1[1584:1577]=8'd1;
        Row1[944:937]=8'd1;
        Row1[376:369]=8'd1;
        //2
        Row1[1720:1713]=8'd2;
        Row1[1600:1593]=8'd2;
        Row1[1488:1481]=8'd2;
        Row1[1480:1473]=8'd2;
        Row1[1368:1361]=8'd2;
        Row1[1344:1337]=8'd2;
        Row1[1336:1329]=8'd2;
        Row1[1120:1113]=8'd2;
        Row1[1112:1105]=8'd2;
        Row1[1080:1073]=8'd2;
        Row1[1072:1065]=8'd2;
        Row1[1056:1049]=8'd2;
        Row1[984:977]=8'd2;
        Row1[936:929]=8'd2;
        Row1[856:849]=8'd2;
        Row1[808:801]=8'd2;
        Row1[728:721]=8'd2;
        Row1[680:673]=8'd2;
        Row1[608:601]=8'd2;
        Row1[592:585]=8'd2;
        Row1[584:577]=8'd2;
        Row1[576:569]=8'd2;
        Row1[568:561]=8'd2;
        Row1[560:553]=8'd2;
        Row1[544:537]=8'd2;
        Row1[472:465]=8'd2;
        Row1[424:417]=8'd2;
        Row1[416:409]=8'd2;
        //3
        Row1[1712:1705]=8'd3;
        Row1[1592:1585]=8'd3;
        Row1[1472:1465]=8'd3;
        Row1[1360:1353]=8'd3;
        Row1[1352:1345]=8'd3;
        Row1[1240:1233]=8'd3;
        Row1[1208:1201]=8'd3;
        Row1[1200:1193]=8'd3;
        Row1[1064:1057]=8'd3;
        Row1[992:985]=8'd3;
        Row1[928:921]=8'd3;
        Row1[864:857]=8'd3;
        Row1[736:729]=8'd3;
        Row1[600:593]=8'd3;
        Row1[464:457]=8'd3;
        Row1[456:449]=8'd3;
        Row1[448:441]=8'd3;
        Row1[440:433]=8'd3;
        Row1[432:425]=8'd3;

    //4
        Row1[800:793]=8'd4;
        Row1[672:665]=8'd4;
        Row1[552:545]=8'd4;


        #100
        Reset=1'b1;
        #100
        Reset=1'b0;
        Clk=1'b1;

        // Add stimulus here

    end
   always
    #50 Clk=~Clk;
endmodule

【问题讨论】:

    标签: for-loop multidimensional-array verilog


    【解决方案1】:

    这个(8*i*j) 不起作用。您有两个嵌套循环,因此第二个循环中的 i 必须以 16 步递增。(内部循环的大小)尝试 8*(i*16+j)-1

    您的代码有些不一致,因为您有时使用 0 有时使用 1 作为最低索引。我建议你让所有的数组和向量都从 0 开始。[2047:0] 这是 Verilog 约定。


    我已使用我使用的 Verilog 约定转换了您的代码。我还删除了所有多余的信号,如时钟和复位。使用以下代码,Row2arr 中都没有 X-es 或 Z-es。

    `timescale 1ns / 1ps
    module convPE(
        input [2047:0] Row1,
        output [2047:0] Row2
        );
        wire [7:0] arr[15:0][15:0];
    
        generate
        genvar i,j;
        for(i=0; i<16; i=i+1)
        begin:gen1
            for(j=0; j<16; j=j+1)
            begin:gen2
                assign arr[i][j]=Row1[(8*(i*16+j)) +: 8];
                assign Row2[(8*(i*16+j)) +: 8] =arr[i][j];
            end
        end
        endgenerate
    endmodule
    
    `timescale 1ns / 1ps
    module testbench;
        // Inputs
        reg [2047:0] Row1;
        wire [2047:0] Row2;
    
        convPE uut (
            .Row1(Row1),
            .Row2(Row2)
        );
    
        initial begin
            #100; // I want to see X-es first
            // Initialize Inputs
            Row1=2048'd0;
            #100;
            $stop;        
        end
    endmodule
    

    我使用我的方法的原因是因为它是将某种类型的 N 维数组映射到内存(线性)的标准方法,例如C 编译器可以。

    您可以使用 2048:1,但是您必须更加努力地思考如何将索引转换为一维数组。可能将公式中的 i 和 j 替换为 i-1,j-1 之类的内容。

    【讨论】:

    • 好吧,使用 8*(i*16+j)-1 可能会导致数组索引超出范围。而使用[2048:1]作为指标的原因是为了后面计算的方便。 0 和 17 索引用于零填充,因为它们不会导致胎儿错误,我想我会保留这个表达式。顺便说一句,仍然感谢您的建议:)
    猜你喜欢
    • 2013-01-28
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多