Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Verilog

Массивы и памяти в Verilog: мастерство многомерных структур данных

Объявление массива сети или переменной может быть скалярным или векторным. Любое число измерений создаётся указанием адресного диапазона после имени идентификатора — это многомерный массив. Массивы разрешены для типов reg, wire, integer, real.

reg y1 [11:0];           // скалярный reg-массив глубины 12, каждый 1 бит
wire [0:7] y2 [3:0]      // 8-битный векторный net глубины 4
reg [7:0] y3 [0:1][0:3]; // 2D массив rows=2, cols=4, каждый 8 бит

Для доступа к конкретному элементу массива нужно указать индекс для каждого измерения (может быть выражением других переменных). Массив можно сформировать для любого поддерживаемого типа данных.

Память из n 1-битных reg не эквивалентна n-битовому векторному reg.

Присваивание

y1 = 0;           // Недопустимо: нельзя присвоить все элементы сразу
y2[0] = 8'ha2;    // присвоить 0xa2 индексу 0
y2[2] = 8'h1c;    // присвоить 0x1c индексу 2
y3[1][2] = 8'hdd; // присвоить 0xdd rows=1 cols=2
y3[0][0] = 8'haa; // присвоить 0xaa rows=0 cols=0

Пример

Код ниже показывает моделирование, присваивание и доступ к разным массивам. mem1 — 8-битный вектор, mem2 — 8-битный массив глубины 4 ([0:3]), mem3 — 16-битный векторный 2D массив 4×2. Переменным присваиваются значения и выводятся.

module des ();
reg [7:0] mem1;
reg [7:0] mem2 [0:3];
reg [15:0] mem3 [0:3][0:1];
initial begin
    int i;
    mem1 = 8'ha9;
    $display ("mem1 = 0x%0h", mem1);
    mem2[0] = 8'haa; mem2[1] = 8'hbb; mem2[2] = 8'hcc; mem2[3] = 8'hdd;
    for(i = 0; i < 4; i = i+1) $display("mem2[%0d] = 0x%0h", i, mem2[i]);
    for(int i = 0; i < 4; i += 1)
        for(int j = 0; j < 2; j += 1) begin
            mem3[i][j] = i + j;
            $display("mem3[%0d][%0d] = 0x%0h", i, j, mem3[i][j]);
        end
end
endmodule

Simulation Log

ncsim> run
mem1 = 0xa9
mem2[0] = 0xaa
mem2[1] = 0xbb
mem2[2] = 0xcc
mem2[3] = 0xdd
mem3[0][0] = 0x0
mem3[0][1] = 0x1
mem3[1][0] = 0x1
mem3[1][1] = 0x2
mem3[2][0] = 0x2
mem3[2][1] = 0x3
mem3[3][0] = 0x3
mem3[3][1] = 0x4
ncsim: *W,RNQUIE: Simulation is complete.

Памяти (Memories)

Памяти — цифровые элементы хранения данных и информации в цифровых схемах. RAM и ROM — классические примеры. Элементы хранения моделируются одномерными массивами типа reg и называются памятью. Каждый элемент может представлять слово и адресуется единственным индексом массива.

Вектор регистра (Register Vector)

Verilog-векторы объявляются диапазоном размера слева от имени переменной и реализуются в триггеры соответствующей разрядности. В коде ниже модуль des принимает такт, сброс и управляющие сигналы для чтения/записи.

Содержит 16-битный элемент хранения register, обновляемый при записи и возвращающий текущее значение при чтении. Запись происходит, когда sel и wr высоки на одном фронте такта. Чтение — когда sel высок, wr низок.

module des (
    input clk, input rstn, input wr, input sel, input [15:0] wdata, output [15:0] rdata
);
reg [15:0] register;
always @ (posedge clk) begin
    if (!rstn) register <= 0;
    else begin
        if (sel & wr) register <= wdata;
        else register <= register;
    end
end
assign rdata = (sel & ~wr) ? register : 0;
endmodule

Схема показывает: 16-битный триггер обновляется когда логика записи активна, текущее значение возвращается когда логика чтения активна.

Массив (Array)

Здесь register — массив из 4 локаций по 16 бит. Модуль принимает дополнительный вход addr для доступа к конкретному индексу.

module des (
    input clk, input rstn, input [1:0] addr, input wr, input sel, input [15:0] wdata, output [15:0] rdata
);
reg [15:0] register [0:3];
integer i;
always @ (posedge clk) begin
    if (!rstn) begin
        for (i = 0; i < 4; i = i+1) register[i] <= 0;
    end else begin
        if (sel & wr) register[addr] <= wdata;
        else register[addr] <= register[addr];
    end
end
assign rdata = (sel & ~wr) ? register[addr] : 0;
endmodule

На схеме видно: каждый индекс массива — 16-битный триггер, входной адрес используется для доступа к конкретному набору триггеров.

Verilog

  1. Массивы в C#: объявление, инициализация и операции
  2. Понимание взаимосвязи между массивами и указателями в C
  3. Техники копирования массивов в Java: подробное руководство
  4. Массивы в C++: объявление, инициализация и работа с указателями
  5. Динамическое выделение массивов в C++: практическое руководство с примерами кода
  6. Учебник по массивам в Java: объявление, создание и инициализация с примерами кода
  7. Освоение Verilog: полное руководство по проектированию цифровых схем
  8. Освоение конкатенации в Verilog: практическое руководство
  9. Межназначенные и внутриназначенные задержки в Verilog: понимание и применение
  10. MATLAB: Мастерство работы с многомерными и специальными массивами