Estaba leyendo esta página http://www.asic-world.com/verilog/verilog_one_day3.html cuando me encontré con lo siguiente:
Normalmente tenemos que restablecer los flip-flops, por lo que cada vez que el reloj hace transición de 0 a 1 (posedge), verificamos si se afirma el reinicio (reinicio síncrono), luego continuamos con la lógica normal. Si miramos de cerca, vemos que en el caso de la lógica combinacional teníamos «=» para la asignación, y para el bloque secuencial teníamos el operador «< =». Bueno, «=» es una asignación de bloqueo y «< =» es una asignación sin bloqueo. «=» ejecuta el código secuencialmente dentro de un inicio / final, mientras que «< =» sin bloqueo se ejecuta en paralelo.
Estaba bastante seguro de que las asignaciones sin bloqueo eran secuenciales, mientras que las asignaciones de bloqueo eran paralelas. Después de todo, puede realizar asignaciones de bloqueo con instrucciones de asignación fuera de los bloques always, y todas se ejecutan en paralelo. ¿Es esto un error o el comportamiento es diferente dentro de un bloque always? Y, si el comportamiento ES diferente dentro de un bloque always, ¿se pueden realizar asignaciones sin bloqueo fuera de un bloque always?
Respuesta
estaba bastante seguro de que las asignaciones sin bloqueo eran secuenciales mientras que las asignaciones de bloqueo eran paralelas.
La asignación de bloqueo se ejecuta «en serie» porque una asignación de bloqueo bloquea la ejecución de la siguiente instrucción hasta que se completa. Por lo tanto, los resultados de la siguiente instrucción pueden depender de que se complete la primera.
La asignación sin bloqueo se ejecuta en paralelo porque describe asignaciones que ocurren todas al mismo tiempo. El resultado de una declaración en la segunda línea no dependerá de los resultados de la declaración en la primera línea. En cambio, la segunda línea se ejecutará como si la primera línea no hubiera sucedido todavía.
Comentarios
Respuesta
Las sentencias de asignación no son «bloqueantes» ni «no bloqueantes», son «continuas». La salida de una instrucción de asignación es siempre igual a la función especificada de sus entradas. Las asignaciones de «bloqueo» y «no bloqueo» solo existen dentro de los bloques always.
Una asignación de bloqueo tiene efecto inmediatamente cuando se procesa. Una asignación sin bloqueo tiene lugar al final del procesamiento del «delta de tiempo» actual.
Los bloques siempre se pueden usar para modelar lógica combinatoria o secuencial (systemverilog tiene always_comb y always_ff para hacer esto explícito). La lógica combinatoria suele ser más eficiente de usar = pero normalmente no importa.
Cuando se modela lógica secuencial (por ejemplo, siempre @ (posedge clk)), normalmente se utilizan asignaciones sin bloqueo. Esto le permite Determine el «estado después del borde del reloj» en términos de «el estado antes del borde del reloj».
A veces es útil usar asignaciones de bloqueo en bloques siempre secuenciales como «variables». Si hace esto, hay dos reglas clave a tener en cuenta.
- No acceda a un reg que se establece con asignaciones de bloqueo dentro de un bloque siempre secuencial desde fuera del bloque siempre en el que está asignado.
- No mezcle asignaciones de bloqueo y no bloqueo en el mismo reg.
Es probable que romper estas reglas resulte en fallas de síntesis y / o diferencias de comportamiento entre la simulación y la síntesis.
Comentarios
- » » No acceda a un registro configurado con asignaciones de bloqueo dentro de un bloque siempre secuencial desde fuera del bloque siempre está asignado en. » » ¿Puede explicarlo?
- Los diferentes bloques secuenciales siempre no tienen un orden. Por lo tanto, leer un » reg » configurado con una asignación de bloqueo en un bloque siempre de otro bloque siempre conducirá a un comportamiento impredecible.
- E incluso si parece funcionar en simulación, una herramienta de síntesis debería mirar eso y decir » nope «. Utilizo registros locales para esas vars intermedias y me aseguro de que siempre se asignen en cada reloj antes de leerse, de modo que no haya ‘ almacenamiento ‘ está implícito.
- IIRC al menos en cuartos, solo se considera una advertencia, no un error.
- No debe usar una asignación sin bloqueo en la lógica combinacional, puede bloquearse la simulación. Para obtener más detalles, consulte esta respuesta: electronics.stackexchange.com/a/506047/238188
Respuesta
El término Tarea de bloqueo confunde a la gente porque la palabra bloqueo parecería sugerir una lógica secuencial en el tiempo. Pero en lógica sintetizada no significa esto , porque todo opera en paralelo .
Quizás un término menos confuso sería asignación inmediata , que aún diferenciaría los resultados intermedios de la lógica combinacional de la entradas a elementos de memoria no transparentes (por ejemplo, registros cronometrados), que pueden tener asignación retrasada .
Desde un punto de vista legalista, todo funciona muy bien. De hecho, puede considerar que =
es una operación de bloqueo (secuencial en el tiempo) incluso dentro de always_comb
secuencias. Sin embargo, la distinción entre secuencial en el tiempo y paralelo no hace ninguna diferencia en este caso porque el always_comb
bloque está definido para repetirse hasta que la secuencia de instrucciones converja en un estado estable – que es exactamente lo que hará el circuito de hardware (si cumple con los requisitos de tiempo).
El subconjunto sintetizable de Verilog (y especialmente SystemVerilog) es extremadamente simple y fácil de usar, una vez que conozca los modismos necesarios. Solo tiene que superar el uso inteligente de la terminología asociada con los llamados elementos conductuales en el idioma.
Comentarios
- En los estilos de codificación conductuales ( en comparación con RTL ), la distinción entre bloqueo y no bloqueo puede ser relevante. En algunos casos, la herramienta de síntesis puede inferir un RTL funcionalmente equivalente a partir de diseños de componentes de comportamiento.
- Por supuesto, el procedural de SystemVerilog, aplicable especialmente a
initial
declaraciones dentro deprogram
bloques, utiliza (secuencial en el tiempo) asignación de bloqueo exclusivamente. Esto es útil para el diseño de testbench , pero generalmente no para la especificación RTL.
assign
ocurren fuera de los bloques always y generalmente se usan para describir combinatorias (no enclavadas ) lógica (aunque siempre bloquea, con algunas excepciones, describe la lógica secuencial). AFAIK, lasassign
siempre ejecutan » en paralelo » siempre que su LHS tenga un cambio de valor .