¿Cómo se implementan las declaraciones de Verilog "siempre" en el hardware?

8

La alwaysdeclaración de Verilog , a saber

always @(/* condition */)
    /* block of code */

ejecuta el block of codecuando conditionestá satisfecho. ¿Cómo se alwaysimplementa dicho bloque en el hardware?

Randomblue
fuente
Creo que depende en gran medida de lo que block of codesea ​​...
m.Alin
1
Y si la condición es posedge xo simplementex
Justin
@Justin: Asumamos que no hay posedge.
Randomblue

Respuestas:

16

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 regvariable solo puede asignarse como máximo en una alwaysdeclaración. En otras palabras, regs tienen afinidad con los alwaysbloques.

alwaysGeneralmente 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 regs que tienen afinidad con los alwaysbloques 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 alwaysbloques 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 negedgese 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_nestá asociado con el primer alwaysbloque, outcon el segundo. out_nse implementará con una sola puerta NOT que conducirá out_ny se manejará desde out(tenga en cuenta que es una lógica puramente combinacional). Por otro lado, outserá 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
avakar
fuente
Gracias. Con respecto al *, 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 ).
Randomblue
@Randomblue, tienes razón, arreglaré la respuesta. Tenga en cuenta, sin embargo, que los dos son equivalentes en comportamiento.
avakar
Cierto; ¡lo suficientemente justo!
Randomblue
2

Un alwaysbloque 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:

  1. 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.

  2. 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é.

El fotón
fuente
"flip-flop y un pestillo son generalmente solo dos configuraciones diferentes" ¿Lo son? Espero que los pestillos se implementen con LUT (con cuidado si los LUT no están libres de fallas).
avakar
@avakar, sé que en todos los FPGA de Xilinx (o al menos en todos los remotos recientes) los pestillos usan el mismo hardware que un flip-flop, que difieren solo en un bit en el flujo de bits de configuración. No estoy seguro de otras marcas.
Kevin Cathcart
Hmm Algunos diseños antiguos de Altera tenían rutas de retroalimentación que permitirían utilizar LUT para implementar pestillos. Casi parece que la ruta principal podría ser necesaria para implementar pestillos en los diseños más nuevos. Sin embargo, esto no es sorprendente, ya que en el diseño RTL moderno raramente se desean cierres reales (en lugar de chanclas).
Kevin Cathcart
@avakar, estoy más familiarizado con Xilinx, donde el dispositivo de registro se puede configurar como flip-flop o pestillo. Si eso no es posible en Altera o en algún otro proveedor, haría que el consejo general "no diseñe con pestillos" sea aún más fuerte.
El fotón
@KevinCathcart y Photon: Ya veo, no estoy familiarizado con Xilinx, solo con la serie Altera Cyclone, que no tiene circuitos de cierre dedicados.
avakar
0

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.

Peter Green
fuente