Как объявить и использовать массивы байтов 1D и 2D в Verilog?

Как объявить и использовать массивы байтов 1D и 2D в Verilog?

например. как сделать что-то вроде

byte a_2D[3][3];
byte a_1D[3];

// using 1D
for (int i=0; i< 3; i++)
{
    a_1D[i] = (byte)i;
}

// using 2D
for (int i=0; i< 3; i++)
{
    for (int j=0; j< 3; j++)
    {
        a_2D[i][j] = (byte)i*j;
    }
}

person Ursa Major    schedule 10.06.2010    source источник


Ответы (3)


Verilog мыслит битами, поэтому reg [7:0] a[0:3] даст вам массив 4x8 бит (= массив 4x1 байт). Вы получаете первый байт из этого с помощью a[0]. Третий бит второго байта равен a[1][2].

Для двумерного массива байтов сначала проверьте свой симулятор/компилятор. Старые версии (я полагаю, до 01 года) не будут поддерживать это. Затем reg [7:0] a [0:3] [0:3] даст вам двумерный массив байтов. К одному биту можно получить доступ, например, с помощью a[2][0][7].

reg [7:0] a [0:3];
reg [7:0] b [0:3] [0:3];

reg [7:0] c;
reg d;

initial begin

   for (int i=0; i<=3; i++) begin
      a[i] = i[7:0];
   end

   c = a[0];
   d = a[1][2]; 


   // using 2D
   for (int i=0; i<=3; i++)
      for (int j=0; j<=3; j++)
          b[i][j] = i*j;  // watch this if you're building hardware

end
person Marty    schedule 10.06.2010
comment
Являются ли распакованные массивы несинтезируемыми? Почему вы говорите, что b[i][j] может быть проблемой? - person Rajesh Shashi Kumar; 12.06.2019
comment
Этот пример немного сбивает с толку. Я бы предложил указать разные порядковые номера для i и j. Сейчас они оба 0-3. Предположим, у вас есть reg [7:0] b [0:2] [0:3]; трудно сказать размер b[i]. - person Rock; 19.07.2019
comment
@RajeshS Их можно синтезировать, но только с помощью SystemVerilog. - person Kaiser Keister; 14.10.2019

В дополнение к превосходному ответу Марти, спецификация SystemVerilog предлагает тип данных byte. Далее объявляется 4x8-битная переменная (4 байта), каждому байту присваивается значение, а затем отображаются все значения:

module tb;

byte b [4];

initial begin
    foreach (b[i]) b[i] = 1 << i;
    foreach (b[i]) $display("Address = %0d, Data = %b", i, b[i]);
    $finish;
end

endmodule

Это распечатывает:

Address = 0, Data = 00000001
Address = 1, Data = 00000010
Address = 2, Data = 00000100
Address = 3, Data = 00001000

По концепции это похоже на reg [7:0] a [0:3]; Марти. Однако byte — это тип данных с 2 состояниями (0 и 1), а reg — с 4 состояниями (01xz). Использование byte также требует, чтобы ваша цепочка инструментов (симулятор, синтезатор и т. д.) поддерживала этот синтаксис SystemVerilog. Обратите также внимание на более компактный синтаксис цикла foreach (b[i]).

Спецификация SystemVerilog поддерживает широкий спектр типов многомерных массивов. LRM может объяснить их лучше, чем я; см. IEEE Std 1800-2005, глава 5.

person toolic    schedule 10.06.2010

На самом деле это просто, как программирование на C, вам просто нужно передать индексы массива справа при объявлении. Но да, синтаксис будет как [0:3] для 4 элементов.

reg a[0:3]; 

Это создаст 1D массив из одного бита. Точно так же 2D-массив можно создать следующим образом:

reg [0:3][0:2];

Теперь в C предположим, что вы создаете 2D-массив int, тогда он внутри создаст 2D-массив из 32 бит. Но, к сожалению, Verilog — это HDL, поэтому он мыслит битами, а не набором битов (хотя в Verilog есть тип данных int), он может позволить вам создать любое количество битов для хранения внутри элемента массива (что не является случае с C вы не можете хранить 5 бит в каждом элементе 2D-массива в C). Таким образом, чтобы создать 2D-массив, в котором каждый отдельный элемент может содержать 5-битное значение, вы должны написать следующее:

reg [0:4] a [0:3][0:2];
person Karan Shah    schedule 09.12.2014