Verilog-код: инициализация 2D-массива с использованием вложенного цикла for - PullRequest
0 голосов
/ 08 мая 2018

Я недавно пытаюсь сохранить двумерный массив, элементы которого состоят из 8-битных целых чисел (0 ~ 4), сначала вводя его элементы построчно (обрабатывая его как одномерный массив), а затем получая доступ к значениям в 1D массив. моя процедура выглядит следующим образом:

1. Инициализировать массив 2048-бит-1D (8 * 16 * 16) (Row1 в коде) в тестовом стенде в качестве ввода

2. вырезать массив 1D каждые 8 ​​бит и назначить 8-битное число для элементов в массиве 2D

3. использовать другой одномерный массив (Row2 в коде), чтобы наблюдать конечный результат, потому что массив не может быть использован как выходной экземпляр Так что на самом деле я превращаю одномерный массив с 256 8-битными элементами в двумерный массив с 16 * 16 8-битными элементами.

проблема в том, что после запуска симуляции, кажется, что большинство элементов в массиве 2D находится в состоянии высокого 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

1 Ответ

0 голосов
/ 08 мая 2018

Это (8*i*j) не работает. У вас есть два вложенных цикла, поэтому значение i во втором цикле должно увеличиваться с шагом 16. (Размер внутреннего цикла) Попробуйте 8 * (i * 16 + j) -1

Ваш код несколько непоследователен в том, что вы иногда используете 0, а иногда 1 как самый низкий индекс. Я предлагаю вам начать все свои массивы и векторы с 0. [2047: 0] Это соглашение Verilog.


Я преобразовал ваш код, используя соглашения Verilog, которые я использую. Я также удалил все лишние сигналы, такие как часы и сброс. С помощью следующего кода X-es или Z-es отсутствуют ни в Row2, ни в arr.

`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-мерных массивов определенного типа в памяти (который является линейным), например, например. Компиляторы Си делают.

Вы можете использовать 2048: 1, но тогда вам придется гораздо сложнее подумать, как преобразовать индексы в одномерный массив. Вероятно, замените i и j в моей формуле на что-то вроде i-1, j-1.

...