- 1 1. Introducción
- 2 2. Tipos de datos básicos en Verilog
- 3 3. Conceptos básicos de los arreglos
- 4 4. Uso de arreglos multidimensionales
- 5 5. Modelado de memoria con arreglos
- 6 6. Extensiones de arreglos en SystemVerilog
- 7 7. Mejores prácticas en la manipulación de arreglos
- 8 8. Preguntas frecuentes (FAQ)
- 9 9. Conclusión
1. Introducción
Verilog es un lenguaje de descripción de hardware ampliamente utilizado y resulta esencial en el diseño de circuitos como FPGA o ASIC. Para realizar un diseño eficiente con Verilog, la comprensión de los arreglos es sumamente importante.
El uso de arreglos permite manejar conjuntos de datos de manera concisa e intuitiva, lo que mejora la legibilidad y el mantenimiento del código. En particular, cuando se requiere agrupar múltiples señales o representar estructuras de memoria como la RAM, los arreglos resultan muy efectivos.
En este artículo, nos centraremos en la palabra clave «arreglos en Verilog» y explicaremos desde la definición básica hasta técnicas prácticas de aplicación en proyectos reales. Cubriremos los tipos de arreglos, las extensiones de SystemVerilog, así como errores comunes y preguntas frecuentes, con el objetivo de profundizar la comprensión del lector.
El contenido está pensado para principiantes, e incluye ejemplos de código prácticos, de modo que podrás seguirlo fácilmente hasta el final.
2. Tipos de datos básicos en Verilog
Antes de trabajar con arreglos en Verilog, es necesario comprender los tipos de datos básicos. Verilog proporciona varios tipos principales diseñados para manejar señales lógicas en el diseño de circuitos.
Diferencias entre reg y wire
Los tipos de datos más comunes en Verilog son reg
(registro) y wire
(cable). Se utilizan de manera distinta según el comportamiento de las señales lógicas.
- wire
wire
se utiliza como una línea de conexión entre módulos o circuitos. Siempre debe estar conducido por otra señal, y la asignación se realiza con la sentenciaassign
. Es adecuado para salidas de circuitos combinacionales. Ejemplo:
wire a;
assign a = b & c;
- reg
reg
se utiliza como una variable que almacena temporalmente un valor. Se asigna dentro de bloques de proceso (comoalways
) y representa elementos de memoria como biestables o flip-flops. Ejemplo:
reg q;
always @(posedge clk) begin
q <= d;
end
Tipos de datos para arreglos
En Verilog, los arreglos se definen principalmente con reg
, aunque en algunos casos también es posible usar wire
. No obstante, en las primeras versiones de Verilog existían limitaciones como la falta de soporte para arreglos multidimensionales. Estas restricciones se resolvieron en gran medida con SystemVerilog.
Ejemplo de sintaxis básica para definir un arreglo:
reg [7:0] data_array [0:15]; // Arreglo de 16 elementos de 8 bits
Comprender los fundamentos de los tipos de datos ayuda a evitar confusiones en la declaración y uso de arreglos. Una mala elección entre reg y wire puede provocar errores en la simulación o la síntesis lógica.
3. Conceptos básicos de los arreglos
En Verilog, los arreglos se utilizan cuando se desea manejar varias señales del mismo tipo de manera conjunta. Con ellos, es posible organizar señales y mejorar la legibilidad y reutilización del código.
Declaración de arreglos
En Verilog se soportan principalmente arreglos unidimensionales, con la siguiente sintaxis:
reg [ancho_de_bits] nombre_arreglo [rango_de_indice];
Ejemplo específico:
reg [7:0] data_array [0:15]; // Arreglo de 16 elementos de 8 bits
Aquí, data_array
tiene 16 elementos indexados de 0 a 15, cada uno con un ancho de 8 bits (1 byte).
Acceso a elementos de un arreglo
Cada elemento de un arreglo se accede mediante un índice. Al igual que en C, la indexación comienza en 0.
data_array[0] = 8'hFF; // Asigna 0xFF al primer elemento
data_array[1] = 8'd12; // Asigna 12 decimal al segundo elemento
También es posible inicializar o modificar los elementos dentro de un bloque always
usando bucles.
integer i;
always @(posedge clk) begin
for (i = 0; i < 16; i = i + 1) begin
data_array[i] <= 8'd0;
end
end
Ventajas de los arreglos
- Procesamiento en bloque: combinados con bucles
for
, permiten aplicar la misma operación a múltiples señales de forma simultánea. - Estructuración del circuito: facilitan la organización de registros y señales, manteniendo una arquitectura clara.
- Implementación de modelos de memoria: pueden representar estructuras como RAM o ROM directamente en el código (se explicará más adelante).
Puntos a tener en cuenta
En Verilog no se admite la asignación directa a todo el arreglo (data_array = valor
). Solo es posible operar a nivel de cada elemento. Además, originalmente solo se soportaban arreglos unidimensionales; para usar arreglos multidimensionales se requiere Verilog 2001 o SystemVerilog.
4. Uso de arreglos multidimensionales
El uso de arreglos multidimensionales en Verilog permite manejar estructuras de datos más complejas de manera eficiente y simplificar el diseño del circuito.
No obstante, es importante mencionar que en Verilog IEEE 1364-1995 no se admitían arreglos multidimensionales. Fueron introducidos oficialmente a partir de Verilog 2001. Para operaciones aún más flexibles, se recomienda el uso de SystemVerilog.
Declaración de arreglos multidimensionales
A partir de Verilog 2001 es posible declarar un arreglo con varios índices para una misma variable. Ejemplo:
reg [7:0] matrix [0:3][0:3]; // Matriz de 4x4 elementos de 8 bits
Con esta declaración, matrix
contiene 16 elementos, organizados en un arreglo bidimensional.
Acceso y asignación de elementos
Los arreglos multidimensionales también permiten el acceso mediante índices para asignar valores específicos:
matrix[0][0] = 8'hA5;
matrix[2][3] = 8'd255;
Uso de bucles for anidados
Los arreglos multidimensionales se manipulan de forma flexible con bucles anidados. Ejemplo de inicialización:
integer i, j;
always @(posedge clk) begin
for (i = 0; i < 4; i = i + 1) begin
for (j = 0; j < 4; j = j + 1) begin
matrix[i][j] <= 8'd0;
end
end
end
Aplicaciones de los arreglos multidimensionales
- Diseños que requieren operaciones matriciales o filtros.
- Procesamiento de imágenes o señales digitales (DSP), con manipulación de datos por píxeles.
- Organización de bloques de ROM/RAM o asociación de direcciones con pares de datos.
Limitaciones y consideraciones
- Es necesario verificar la compatibilidad de la herramienta de síntesis, ya que algunas no admiten completamente arreglos multidimensionales.
- Pueden existir restricciones al combinarlos con instanciación de módulos o interfaces.
- Conviene conocer las diferencias con SystemVerilog para evitar problemas de compatibilidad.

5. Modelado de memoria con arreglos
En Verilog es posible modelar estructuras de memoria de manera sencilla utilizando arreglos. De esta forma, se pueden simular y diseñar circuitos de almacenamiento como RAM o ROM.
En particular, los modelos de memoria basados en arreglos unidimensionales se emplean con frecuencia en el diseño de CPUs y sistemas de comunicación.
Sintaxis básica de un modelo de memoria
Ejemplo de una RAM de 32 bits × 1024 direcciones (0–1023):
reg [31:0] memory [0:1023]; // Memoria de 32 bits × 1024 palabras
Con esta declaración, el arreglo memory
puede almacenar 1024 palabras de 32 bits, accesibles mediante índices (direcciones).
Lectura y escritura en memoria
Las operaciones de lectura y escritura en memoria se describen de la siguiente forma:
// Escritura
always @(posedge clk) begin
if (we) begin
memory[addr] <= data_in;
end
end
// Lectura
assign data_out = memory[addr];
Puntos clave:
- La escritura ocurre de forma sincronizada al flanco positivo de
clk
, condicionada porwe
(write enable). - La lectura suele implementarse como una operación combinacional mediante
assign
.
Inicialización de memoria
Para bancos de pruebas o para definir el estado inicial, es posible inicializar el arreglo con un bloque initial
:
integer i;
initial begin
for (i = 0; i < 1024; i = i + 1) begin
memory[i] = 32'd0;
end
end
También es posible cargar valores desde archivos externos usando $readmemh
o $readmemb
:
initial begin
$readmemh("rom_init.hex", memory); // Inicializa en formato hexadecimal
end
Aplicaciones prácticas
- Registros de CPU o microcontroladores
- Simulación del comportamiento de BRAM dentro de FPGAs
- Verificación del funcionamiento de memorias caché
- Lectura de datos almacenados en ROM
Consideraciones
- El tamaño del arreglo influye directamente en el tiempo de simulación y recursos de síntesis.
- El momento de lectura (sincrónica o asincrónica) debe definirse según las especificaciones del diseño y las herramientas utilizadas.
- Para síntesis, es recomendable seguir las guías de inferencia de memoria de cada proveedor.
6. Extensiones de arreglos en SystemVerilog
Hasta Verilog 2001, la funcionalidad de arreglos era limitada, lo que complicaba los diseños. Con la llegada de SystemVerilog, se ampliaron considerablemente las posibilidades, permitiendo una codificación más flexible y potente.
En esta sección exploraremos tres tipos principales de arreglos disponibles en SystemVerilog: arreglos dinámicos, arreglos asociativos y colas (queues).
Arreglos dinámicos
Características
- Pueden cambiar de tamaño en tiempo de ejecución.
- Son útiles cuando el tamaño del arreglo es desconocido o variable.
Declaración y uso
int dyn_array[]; // Declaración de arreglo dinámico
dyn_array = new[10]; // Inicialización con 10 elementos
dyn_array[0] = 100;
Casos de uso
- Almacenamiento temporal de datos en bancos de pruebas
- Gestión de buffers de tamaño variable
Arreglos asociativos
Características
- El índice puede ser un valor arbitrario (entero, cadena, etc.).
- Funcionan como tablas hash.
Declaración y uso
int assoc_array[string]; // Arreglo asociativo con claves tipo string
assoc_array["id_001"] = 42;
Casos de uso
- Gestión de parámetros configurables
- Almacenamiento de valores indexados por ID o nombre
Colas (Queues)
Características
- Tienen comportamiento de tipo FIFO (First-In-First-Out).
- Permiten añadir y eliminar elementos fácilmente, ideales para secuencias dinámicas.
Declaración y uso
int queue_array[$]; // Declaración de cola
queue_array.push_back(10); // Agregar al final
queue_array.push_front(5); // Agregar al inicio
int val = queue_array.pop_front(); // Extraer desde el inicio
Casos de uso
- Almacenamiento temporal en buffers FIFO
- Gestión de eventos o transacciones
Comparación y uso recomendado
Tipo de arreglo | Redimensionamiento | Tipo de índice | Uso recomendado |
---|---|---|---|
Dinámico | Permitido | Entero | Cuando el tamaño no está definido de antemano |
Asociativo | Permitido | Arbitrario (int, string, etc.) | Cuando se requiere búsqueda estilo hash |
Cola | Permitido | Automático (inicio/fin) | Cuando se agregan o eliminan elementos frecuentemente |
Consideraciones
- Estas estructuras son propias de SystemVerilog y no están disponibles en Verilog estándar.
- Su síntesis depende de las herramientas, pero suelen usarse principalmente en bancos de pruebas.
- En proyectos destinados a FPGA o ASIC, es fundamental confirmar si son compatibles antes de utilizarlos.
7. Mejores prácticas en la manipulación de arreglos
Al trabajar con arreglos en Verilog o SystemVerilog, es fundamental mantener un código eficiente y legible. Esta sección presenta una serie de buenas prácticas para garantizar un diseño de hardware claro y seguro.
Aclarar la intención con nombres y comentarios
Los arreglos pueden dificultar la interpretación de lo que representa cada elemento. Por ello, conviene seguir estas recomendaciones:
- Usar nombres descriptivos:
reg [7:0] sensor_data [0:7];
- Agregar comentarios claros sobre su uso y unidades:
// Arreglo que almacena 8 datos de sensores de 8 bits
reg [7:0] sensor_data [0:7];
Cuidar las condiciones de los bucles
Al usar bucles for
con arreglos, se debe verificar la validez de los límites para evitar accesos fuera de rango.
- Un límite mal definido puede causar accesos inválidos o advertencias en simulación.
- La elección entre
<
y<=
debe hacerse con cuidado.
Ejemplo:
integer i;
always @(posedge clk) begin
for (i = 0; i < 8; i = i + 1) begin
sensor_data[i] <= 8'd0;
end
end
Inicializar explícitamente
Un arreglo sin inicialización puede introducir valores indefinidos en la simulación. Esto puede afectar especialmente a memorias o bancos de registros.
initial begin
for (i = 0; i < 256; i = i + 1)
mem[i] = 32'd0;
end
En SystemVerilog, la inicialización puede simplificarse con foreach
o constructores.
Diseñar módulos reutilizables
Los arreglos permiten escalabilidad en el diseño. Para aumentar la reutilización, se recomienda:
- Usar parámetros que definan el tamaño del arreglo:
parameter DEPTH = 16;
reg [7:0] buffer [0:DEPTH-1];
De esta manera, el módulo se adapta a distintas configuraciones sin modificar el código base.
Considerar la síntesis
Es importante tener en cuenta la compatibilidad con las herramientas de síntesis:
- Los arreglos unidimensionales con
reg
son ampliamente soportados. - Los arreglos dinámicos, asociativos o colas de SystemVerilog son no sintetizables y se usan principalmente en simulación.
Para hardware real, se debe priorizar el uso de estructuras compatibles con los compiladores de FPGA o ASIC.
Equilibrar arreglos y modularidad
Aunque los arreglos reducen líneas de código, en diseños grandes puede ser preferible dividir el sistema en módulos independientes.
- Para operaciones repetitivas simples: usar arreglos y bucles.
- Para funciones distintas o sistemas grandes: crear módulos separados y jerárquicos.
8. Preguntas frecuentes (FAQ)
Durante el uso de arreglos en Verilog y SystemVerilog, existen dudas comunes entre principiantes e intermedios. A continuación, respondemos a tres de las más habituales:
Q1. ¿Por qué aparece un error al usar arreglos multidimensionales en Verilog?
A1.
Porque en Verilog 1995 y versiones anteriores a Verilog 2001, no se admitían arreglos multidimensionales o estaban muy limitados.
Por ejemplo, este código es válido solo desde Verilog 2001:
reg [7:0] matrix [0:3][0:3]; // Soportado desde Verilog 2001
Solución:
- Confirmar que la herramienta soporte Verilog 2001 o posterior.
- Si no, representar la matriz con un arreglo unidimensional:
reg [7:0] matrix_1d [0:15]; // Acceso usando (i*4 + j)
Q2. ¿Un RAM escrito con arreglos en Verilog funciona en hardware real?
A2.
Sí. Muchos sintetizadores soportan RAM descrita con arreglos:
reg [31:0] mem [0:255]; // RAM de 32 bits × 256 palabras
Advertencias:
- Debe ajustarse a las plantillas de inferencia de cada herramienta.
- El tipo de lectura/escritura (sincrónica o asincrónica) influye en cómo se sintetiza.
Q3. ¿Pueden sintetizarse arreglos dinámicos, asociativos o colas en SystemVerilog?
A3.
No. Estos arreglos son exclusivos para simulación. No se traducen directamente a hardware.
Se usan en:
- Bancos de pruebas
- Entornos de verificación
- Modelos de transacciones
Para hardware real, es necesario convertirlos a reg
o a arreglos de tamaño fijo.
9. Conclusión
En este artículo hemos explorado el tema de los arreglos en Verilog, desde los conceptos básicos hasta aplicaciones avanzadas. El uso correcto de arreglos contribuye directamente a la eficiencia, legibilidad y mantenibilidad del diseño de hardware.
Puntos clave del artículo
- Comprender los tipos de datos básicos de Verilog (reg y wire) es esencial para evitar errores en el uso de arreglos.
- Los arreglos unidimensionales son fundamentales para agrupar datos o modelar memorias simples.
- Los arreglos multidimensionales fueron introducidos en Verilog 2001 y permiten representar estructuras como matrices.
- SystemVerilog amplió estas capacidades con arreglos dinámicos, asociativos y colas, útiles en entornos de verificación.
- Aplicar las mejores prácticas (inicialización, comentarios claros, modularidad y consideración de la síntesis) mejora la calidad del diseño.
Consejos prácticos
Si bien los arreglos son herramientas poderosas, no siempre deben aplicarse indiscriminadamente. En proyectos destinados a hardware real, es crucial respetar las limitaciones de síntesis y las guías de estilo. Para simulación y verificación, SystemVerilog ofrece estructuras más avanzadas que optimizan la productividad.
El buen diseñador sabe elegir la herramienta adecuada: arreglos simples para hardware sintetizable y estructuras avanzadas para entornos de prueba.
Siguientes temas recomendados
Si ya comprendes los fundamentos de los arreglos, puedes avanzar hacia los siguientes tópicos:
- Uso de la sentencia
generate
para crear arreglos de instancias de manera dinámica. - Combinación de
interface
con arreglos para el diseño de buses. - Implementación de estructuras como FIFO, buffers circulares y memorias ROM optimizadas.
Dominar los arreglos es un paso fundamental en el camino de todo diseñador de Verilog. Con práctica y experiencia, podrás abordar proyectos de mayor complejidad y escalar tus habilidades hacia un diseño digital más profesional.