La always
declaración de Verilog , a saber
always @(/* condition */)
/* block of code */
ejecuta el block of code
cuando condition
está satisfecho. ¿Cómo se always
implementa dicho bloque en el hardware?
Primero, tenga en cuenta que no todos los diseños de Verilog son sintetizables. Por lo general, solo se puede usar un subconjunto muy específico de construcciones en un diseño que se realizará en hardware.
Una restricción importante que aparece es que cada reg
variable solo puede asignarse como máximo en una always
declaración. En otras palabras, reg
s tienen afinidad con los always
bloques.
always
Generalmente se pueden usar los siguientes tipos de bloques.
always @(*) begin
// combinational
end
always @(posedge clk) begin
// sequential
end
En el primer caso, *
indica que el bloque debe ejecutarse siempre que cambie cualquier señal utilizada en el bloque o, de manera equivalente, que el bloque debe ejecutarse continuamente. Por lo tanto, los reg
s que tienen afinidad con los always
bloques combinacionales se implementan como señales calculadas a partir de otras señales que utilizan lógica combinacional, es decir, compuertas.
Los registros que tienen afinidad con los always
bloques de este último tipo, por otro lado, son salidas de flip-flops D que están sincronizados en el borde ascendente de clk
(borde descendente si negedge
se usa). Las entradas a los flip-flops, nuevamente, se calculan con lógica combinacional de otras señales.
Considere el siguiente ejemplo, un tanto artificial.
reg out, out_n;
always @(*) begin
out_n = !out;
end
always @(posedge clk) begin
out <= !out;
end
Aquí, out_n
está asociado con el primer always
bloque, out
con el segundo. out_n
se implementará con una sola puerta NOT que conducirá out_n
y se manejará desde out
(tenga en cuenta que es una lógica puramente combinacional). Por otro lado, out
será impulsado por un flip-flop registrado desde clk
. La entrada al flip-flop será calculada nuevamente por una puerta NOT desde out
(que es impulsada por el flip-flop mencionado anteriormente). Los sintetizadores de optimización combinarán las dos compuertas NOT y usarán una compuerta NOT y un flip-flop.
Dependiendo del hardware que tenga disponible, se pueden usar otros tipos de construcciones. Por ejemplo, si los flip-flops tienen reinicios asincrónicos, la siguiente construcción también es sintetizable.
always @(posedge clk or posedge rst) begin
if (rst)
// reset
else
// sequential
end
*
, pensé que indicaba que el bloque debería ejecutarse cada vez que cambia cualquier señal en el bloque (en oposición al diseño ).
Un always
bloque se usa comúnmente para describir un flip-flop, un pestillo o un multiplexor. El código se implementaría con un flip-flop, un pestillo o un multiplexor.
En un FPGA, un flip-flop y un pestillo son generalmente solo dos configuraciones diferentes de un dispositivo de registro de propósito más general. Un multiplexor se construiría a partir de uno o más elementos lógicos de propósito general (LUT).
En general, hay dos formas de diseñar con Verilog:
Visualice la lógica que desea en términos de puertas y registros, luego descubra cómo describirla en Verilog. Las guías de síntesis de los proveedores de FPGA o proveedores de herramientas de síntesis proporcionan una placa de caldera para las estructuras más comunes con las que puede que desee trabajar.
Simplemente escriba Verilog y no se preocupe por el aspecto del hardware subyacente. Sin embargo, incluso si hace esto, todavía tiene que saber qué es y qué no es sintetizable. Entonces, nuevamente, buscará la plantilla que le proporciona su proveedor de herramientas y la adaptará a su aplicación.
EDITAR
La respuesta de Avakar es mucho mejor para su pregunta, pero esto generó una discusión interesante sobre las diferencias entre Xilinx y Altera, por lo que no la eliminaré.
Como se ha dicho, no siempre todos los bloques son sintetizables. También hay algunos bloques que las herramientas de síntesis aceptarán pero que producirán resultados que difieren de lo que producirá un simulador.
Primero fuera de la lista de sensibilidad. La regla habitual es que debe contener solo construcciones de detección de bordes (y generalmente hay una selección limitada de posibles combinaciones) o debe contener (posiblemente mediante el uso de * o systemverilog's always_comb) cada señal utilizada como entrada al bloque. Llamamos al primero un bloque combinatorio y al segundo un bloque secuencial. Por lo general, si solo incluye un subconjunto de entradas en un bloque combinatorio, las herramientas de síntesis simplemente lo ignorarán y actuarán como si se hubiera especificado la lista completa (creando simulaciones / desajustes de síntesis)
Segundo bloqueo vs no bloqueo de asignaciones. En un bloque combinatorio, la diferencia no importa mucho, pero en un bloque secuencial es muy importante.
En un modelo de asignaciones de bloqueo secuencial sin bloqueo, un registro se realiza de forma bastante directa mientras se bloquean las variables del modelo de asignaciones (lo que puede implicar o no registros dependiendo del orden de configuración y lectura). Como regla, un conjunto "reg" que utiliza asignaciones de bloqueo en un bloque secuencial solo debe leerse en el mismo bloque y las asignaciones de bloqueo y no bloqueo no deben mezclarse en el mismo "reg".
La combinación de tareas de bloqueo y no bloqueo para el mismo elemento puede causar fallas de síntesis. Es probable que realizar una evaluación de bloqueo en un bloque y leerlo en otro cause desajustes de simulación / síntesis (y posiblemente incluso desajustes entre diferentes ejecuciones de simulación).
Ahora tenemos las reglas básicas fuera de la forma en que podemos considerar cómo el compilador convierte el código en lógica.
El primer paso es desenrollar todos los bucles. Esto significa que los bucles deben tener un recuento de iteración máximo que se puede determinar en el momento de la síntesis o obtendrá un error de síntesis.
Luego, la herramienta puede analizar el flujo de control del bloque y convertirlo en un flujo de datos. Cada variable se convierte en una o más señales. Cada instrucción if o construcción similar se convierte en uno o más multiplexores que seleccionan qué conjunto de resultados se utilizará realmente.
Es probable que la herramienta intente aplicar algunas optimizaciones.
En cuarto puede ver los resultados de este proceso después de construir su proyecto yendo a "herramientas-> netlist viewers-> rtl viewer".
Después de generar esta representación estructural en términos de elementos lógicos abstractos, la herramienta pasará a asignar esos elementos abstractos a los recursos que el chip realmente tiene.
block of code
sea ...posedge x
o simplementex
posedge
.