Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> Verilog

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;
Nota: ¡Delays explícitos no son sintetizables en puertas lógicas!

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?

  1. Primer if chequea valor de reset activo en bajo rstn
    1. Si rstn es 0, salida q reseteada a 0
    2. Si rstn es 1, reset no aplicado, comportamiento por defecto
  2. Si paso anterior falso:
    1. Chequea d y si es 1, invierte q
    2. Si d es 0, mantiene q
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?

  1. Primer if chequea rstn. En flanco negativo, valor es 0.
    1. Si rstn es 0, reset aplicado, salida reseteada a 0
    2. Caso rstn = 1 no considerado porque evento actual es flanco negativo de rstn

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.

Entender bloques always en Verilog: Sintaxis y listas de sensibilidad

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.

Entender bloques always en Verilog: Sintaxis y listas de sensibilidad

Haz clic aquí para presentación con ejemplo de simulación !

Verilog

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