Este es el código:
always @(*)
case(NormalCtrl[7:6])
2'd0: TrigA = 0;
2'd1: TrigA = TrigAA;
2'd2: TrigA = TrigBA;
default: TrigA = TrigA;
endcase
Un latch sensible al nivel se infiere cuando la RTL combinatoria no asigna un valor determinista a todas las combinaciones posibles, o la misma lógica combinacional se asigna a sí misma (es decir, default: TrigA = TrigA;
). Nota: para el resto de esta respuesta cuando digo pestillo, me refiero a un pestillo de sensibilidad de nivel. Si digo flop, me refiero a un flip-flop sensible al borde.
El mux TrigA_i se está utilizando para seleccionar la entrada D del pestillo.
El mux TrigA_i_0 se usa para determinar si el cierre debe ser transparente ( NormalCtrl[7:6]!=2'b11
) o cerrado ( NormalCtrl[7:6]==2'b11
). Funcionalmente, este mux es equivalente a una puerta NAND de 2 entradas.
Hay dos razones posibles por las que el sintetizador decide utilizar un mux como puerta de retención en lugar de una puerta nand:
¿Por qué no usar un mux cuya salida se retroalimenta a sí misma? Puede preguntar. Los muxes no están destinados a ser utilizados como almacenamiento de valor. La síntesis tendría dificultades para garantizar los tiempos de configuración / retención para evitar la metaestabilidad. Además, también existe el riesgo de una falla en los datos ya que los bits seleccionados cambian de 2'b00 a 2'b11 (intermedio 2'b01 o 2'b10). Los sintetizadores utilizan pestillos reales para reducir estos riesgos (conocer los requisitos de configuración / retención, entradas no complejas).
En general, los cierres deben evitarse en la mayoría de los diseños RTL. Los cierres son asíncronos y, por lo tanto, la sincronización es fundamental para que se realice correctamente. Hay un puñado de condiciones donde el uso de cierres es necesario. En estos escenarios, lo mejor es mantener el pestillo lo más simple posible y el pin de habilitación de la puerta debe ser accionado por un flop directo (sin lógica intermedia) para evitar fallas.