Массивы и памяти в 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
- Массивы в C#: объявление, инициализация и операции
- Понимание взаимосвязи между массивами и указателями в C
- Техники копирования массивов в Java: подробное руководство
- Массивы в C++: объявление, инициализация и работа с указателями
- Динамическое выделение массивов в C++: практическое руководство с примерами кода
- Учебник по массивам в Java: объявление, создание и инициализация с примерами кода
- Освоение Verilog: полное руководство по проектированию цифровых схем
- Освоение конкатенации в Verilog: практическое руководство
- Межназначенные и внутриназначенные задержки в Verilog: понимание и применение
- MATLAB: Мастерство работы с многомерными и специальными массивами