Entender bloques always en Verilog: Sintaxis y listas de sensibilidad
Un bloque always es uno de los bloques procedimentales en Verilog. Las sentencias dentro se ejecutan secuencialmente.
Sintaxis
always @ (evento) [sentencia]
always @ (evento) begin [múltiples sentencias] end
El bloque always se ejecuta en algún evento particular. El evento se define por una lista de sensibilidad.
¿Qué es la lista de sensibilidad?
Una lista de sensibilidad es la expresión que define cuándo debe ejecutarse el bloque always y se especifica tras el operador @ entre paréntesis ( ). Puede contener una o un grupo de señales cuyo cambio de valor ejecutará el bloque.
// Ejecuta always cuando cambie valor de "a" o "b"
always @ (a or b) begin
[sentencias]
end
¿Para qué se usa el bloque always?
Un bloque always puede realizar elementos combinacionales o secuenciales. Un elemento secuencial como flip-flop se activa con clock y reset. Un bloque combinacional se activa cuando cambia una de sus entradas. Estos bloques hardware trabajan concurrentemente. Para modelar esto, un always se hace proceso continuo que se dispara y actúa cuando una señal en la lista de sensibilidad se activa.
En el ejemplo siguiente, todas las sentencias dentro del always se ejecutan en cada flanco positivo de clk.
// Ejecuta always en flanco positivo de señal "clk"
always @ (posedge clk) begin
[sentencias]
end
¿Qué pasa si no hay lista de sensibilidad?
El bloque always se repite continuamente durante la simulación. La lista de sensibilidad aporta sentido de timing: cuando cualquier señal en la lista cambia, el always se dispara. Si no hay sentencias de control de tiempo dentro, ¡la simulación se cuelga por bucle infinito de delay cero!
Ejemplo
El ejemplo siguiente invierte valor de clk. La sentencia se ejecuta cada 0 unidades de tiempo. ¡Ejecuta para siempre por ausencia de delay!
// always inicia en tiempo 0
// ¿Cuándo se repite? No hay control de tiempo, se queda
// y repite en 0 unidades. ¡Bucle infinito y simulación cuelga!
always clk = ~clk;
Incluso si lista de sensibilidad vacía, debe haber otro delay. Tiempo de simulación avanza con sentencia de delay dentro de always:
always #10 clk = ~clk;
Por tanto, código real de diseño Verilog siempre requiere lista de sensibilidad.
Ejemplo de Diseño de Elemento Secuencial
El código define módulo tff que acepta entrada de datos, clock y reset activo en bajo. La salida se invierte cuando d es 1 en flanco positivo de clock. El always se dispara en flanco positivo de clk o flanco negativo de rstn.
¿Qué pasa en flanco positivo de clock?
- Primer
ifchequea valor de reset activo en bajorstn- Si
rstnes 0, salidaqreseteada a 0 - Si
rstnes 1, reset no aplicado, comportamiento por defecto
- Si
- Si paso anterior falso:
- Chequea
dy si es 1, invierteq - Si
des 0, mantieneq
- Chequea
module tff (input d, clk, rstn, output reg q);
always @ (posedge clk or negedge rstn) begin
if (!rstn) q <= 0;
else if (d) q <= ~q;
else q <= q;
end
endmodule
¿Qué pasa en flanco negativo de reset?
- Primer
ifchequearstn. En flanco negativo, valor es 0.- Si
rstnes 0, reset aplicado, salida reseteada a 0 - Caso
rstn= 1 no considerado porque evento actual es flanco negativo derstn
- Si
Ejemplo de Diseño de Elemento Combinacional
Un always también sirve para diseñar bloques combinacionales. El siguiente circuito digital combina tres puertas lógicas dando salida en o.

El código siguiente es un module con cuatro entradas y una salida o. El always se dispara cuando cualquier señal en lista de sensibilidad cambia. Señal de salida declarada reg en lista de puertos porque se usa en bloque procedimental. Todas las señales en bloque procedimental deben ser reg.
module combo (
input a, input b, input c, input d,
output reg o
);
always @ (a or b or c or d) begin
o <= ~((a & b) | (c^d));
end
endmodule
La señal o se vuelve 1 cuando expresión RHS verdadera, 0 cuando falsa.

Verilog
- Dominar Verilog: Tutorial completo para diseño de circuitos digitales
- Dominar la concatenación en Verilog: Guía práctica
- Verilog Esencial: Resumen conciso
- Comprender las asignaciones en Verilog: tipos, sintaxis y mejores prácticas
- Bloqueante vs. No bloqueante en Verilog: Diferencias clave explicadas
- Dominar las funciones en Verilog para diseño RTL eficiente
- Comprender las Tasks en Verilog: Funciones vs Tasks, sintaxis y uso
- Generador de reloj en Verilog: Guía de diseño e implementación
- Dominar las funciones matemáticas en Verilog para diseño de hardware eficiente
- Dominar $timeformat en Verilog: Control de precisión y visualización
- Comprender e imprimir timescales de Verilog en cualquier alcance