Matrices y memorias Verilog
Una matriz la declaración de una red o variable puede ser escalar o vectorial. Se puede crear cualquier cantidad de dimensiones especificando un rango de direcciones después del nombre del identificador y se denomina matriz multidimensional. Las matrices están permitidas en Verilog para reg
, wire
, integer
y real
tipos de datos.
reg y1 [11:0]; // y is an scalar reg array of depth=12, each 1-bit wide
wire [0:7] y2 [3:0] // y is an 8-bit vector net with a depth of 4
reg [7:0] y3 [0:1][0:3]; // y is a 2D array rows=2,cols=4 each 8-bit wide
Se debe especificar un índice para cada dimensión para acceder a un elemento particular de una matriz y puede ser una expresión de otras variables. Se puede formar una matriz para cualquiera de los diferentes tipos de datos admitidos en Verilog.
Tenga en cuenta que una memoria de n registro de 1 bit no es lo mismo que un registro de vector de n bits.
Tarea
y1 = 0; // Illegal - All elements can't be assigned in a single go
y2[0] = 8'ha2; // Assign 0xa2 to index=0
y2[2] = 8'h1c; // Assign 0x1c to index=2
y3[1][2] = 8'hdd; // Assign 0xdd to rows=1 cols=2
y3[0][0] = 8'haa; // Assign 0xaa to rows=0 cols=0
Ejemplo
El código que se muestra a continuación simplemente muestra cómo se pueden modelar, asignar y acceder a diferentes arreglos. mem1 es un vector de 8 bits, mem2 es una matriz de 8 bits con una profundidad de 4 (especificada por el rango [0:3]) y mem3 es una matriz 2D de vector de 16 bits con 4 filas y 2 columnas. A estas variables se les asignan diferentes valores y se imprimen.
module des ();
reg [7:0] mem1; // reg vector 8-bit wide
reg [7:0] mem2 [0:3]; // 8-bit wide vector array with depth=4
reg [15:0] mem3 [0:3][0:1]; // 16-bit wide vector 2D array with rows=4,cols=2
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) begin
$display("mem2[%0d] = 0x%0h", i, mem2[i]);
end
for(int i = 0; i < 4; i += 1) begin
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
end
endmodule
Registro de simulación 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.
Recuerdos
Las memorias son elementos de almacenamiento digital que ayudan a almacenar datos e información en circuitos digitales. Las RAM y las ROM son buenos ejemplos de tales elementos de memoria. Los elementos de almacenamiento se pueden modelar utilizando matrices unidimensionales de tipo reg
y se llama memoria . Cada elemento en la memoria puede representar una palabra y se referencia mediante un índice de matriz único.
Vector de registro
Los vectores de Verilog se declaran utilizando un rango de tamaño en el lado izquierdo del nombre de la variable y estos se convierten en flops que coinciden con el tamaño de la variable. En el código que se muestra a continuación, el módulo de diseño acepta reloj, reinicio y algunas señales de control para leer y escribir en el bloque.
Contiene un elemento de almacenamiento de 16 bits llamado registro que simplemente se actualiza durante las escrituras y devuelve el valor actual durante las lecturas. El registro se escribe cuando sel y wr están altos en el mismo borde del reloj. Devuelve los datos actuales cuando sel es alto y wr es bajo.
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
El esquema de hardware muestra que un flop de 16 bits se actualiza cuando la lógica de control para escritura está activa y el valor actual se devuelve cuando la lógica de control está configurada para lectura.
Matriz
En este ejemplo, el registro es una matriz que tiene cuatro ubicaciones, cada una con un ancho de 16 bits. El módulo de diseño acepta una señal de entrada adicional que se llama addr para acceder a un índice particular en la matriz.
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) begin
register[i] <= 0;
end
end else begin
if (sel & wr)
register[addr] <= wdata;
else
register[addr] <= register[addr];
end
end
assign rdata = (sel & ~wr) ? register[addr] : 0;
endmodule
Se puede ver en el esquema de hardware que cada índice de la matriz es un flop de 16 bits y la dirección de entrada se usa para acceder a un conjunto particular de flop.
Verilog
- Matrices de C#
- Relación entre matrices y punteros
- Matrices de copia de Java
- Matrices en C++ | Declarar | Inicializar | Ejemplos de puntero a matriz
- C++ Asignación dinámica de arreglos con ejemplo
- Tutorial de Java Arrays:declarar, crear, inicializar [ejemplo]
- Tutorial de Verilog
- Concatenación Verilog
- Retraso de asignación inter e intra de Verilog
- MATLAB - Matrices
- La guía definitiva para arreglos de cuadrícula de bolas