Lenguajes descriptores de hardware
En Verilog, cambiar un «<=» por un «=» convierte un registro de desplazamiento en tres copias del mismo flip-flop. Un HDL no se ejecuta: describe un circuito donde todo pasa al mismo tiempo.
01Describir hardware, no programarlo
Un lenguaje descriptor de hardware (HDL) se parece a un lenguaje de programación y no es uno. Un programa en C es una lista de instrucciones que un procesador ejecuta de a una, en orden. Una descripción en VHDL o Verilog es la descripción de un circuito: cada sentencia es un pedazo de hardware que existe y funciona al mismo tiempo que todos los demás. No hay un «ahora se ejecuta esta línea»; hay compuertas y flip-flops que reaccionan todos a la vez a sus entradas.
Ese cambio de mentalidad es la dificultad principal de esta unidad, y casi todos los errores de quien aprende HDL vienen de escribir como si fuera C: esperar que las cosas pasen en orden, usar variables como en un programa, o escribir un bucle esperando que se repita en el tiempo cuando en realidad se va a desplegar en hardware copiado.
02VHDL y Verilog
Dos lenguajes dominan el diseño digital desde los años ochenta, y cualquier herramienta de FPGA acepta los dos:
| VHDL | Verilog / SystemVerilog | |
|---|---|---|
| Origen | Departamento de Defensa de EE. UU., 1983; norma IEEE 1076 | Industria privada, 1984; norma IEEE 1364, hoy IEEE 1800 |
| Estilo | Fuertemente tipado y verboso, derivado de Ada | Compacto, sintaxis parecida a C |
| Dónde se usa más | Europa, aeroespacial, defensa, muchas universidades | Industria de semiconductores de EE. UU. y Asia, verificación |
El mismo contador de cuatro bits con reset sincrónico, en los dos:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity contador is
port (clk, rst : in std_logic;
q : out unsigned(3 downto 0));
end;
architecture rtl of contador is
signal c : unsigned(3 downto 0);
begin
process (clk) begin
if rising_edge(clk) then
if rst = '1' then c <= (others => '0');
else c <= c + 1;
end if;
end if;
end process;
q <= c;
end;VHDL
module contador (
input clk, rst,
output reg [3:0] q
);
always @(posedge clk)
if (rst) q <= 4'd0;
else q <= q + 4'd1;
endmoduleVerilog
Las dos describen exactamente el mismo circuito: cuatro flip-flops D, un sumador de cuatro bits que suma uno y un multiplexor que elige entre la suma y cero según el reset. Ninguna de las dos «cuenta» en el sentido de un programa: describen la conexión que, flanco a flanco, hace contar al hardware.
03Bloqueante y no bloqueante
En Verilog hay dos maneras de asignar dentro de un bloque con reloj, y confundirlas produce circuitos distintos de los que se querían:
| Asignación | Semántica | Uso correcto |
|---|---|---|
No bloqueante b <= a; | Todos los lados derechos se leen antes del flanco y todos los izquierdos se actualizan juntos después: como flip-flops reales | Lógica secuencial, con reloj |
Bloqueante b = a; | Se ejecuta en orden: la línea siguiente ya ve el valor nuevo, como en C | Lógica combinacional |
Elegís el ejemplo y el tipo de asignación, y avanzás de a un flanco de reloj. La tabla muestra el valor de cada registro después de cada flanco, y la nota de abajo explica qué circuito sintetizaría la herramienta.
04Simulación y síntesis
Un mismo archivo HDL tiene dos destinos. El simulador lo ejecuta para ver cómo se comporta en el tiempo; el sintetizador lo traduce a compuertas y flip-flops reales. No todo lo que simula se puede sintetizar:
| Construcción | En simulación | En síntesis |
|---|---|---|
Retardos como #10 o after 10 ns | Se respetan | Se ignoran: el retardo lo pone el silicio |
| Leer y escribir archivos | Útil en los bancos de prueba | No existe |
if sin else en lógica combinacional | Mantiene el valor anterior | Genera un latch no deseado |
Bucle for de 8 vueltas | Se repite ocho veces | Se despliega: ocho copias del hardware en paralelo |
Por eso todo diseño se verifica con un banco de prueba (testbench): un módulo que no se sintetiza, que genera los estímulos, observa las salidas y compara con lo esperado. En la industria, escribir la verificación lleva más trabajo que escribir el diseño.
05Diferencias con un lenguaje procedural
| C, Python | VHDL, Verilog | |
|---|---|---|
| Ejecución | Secuencial, una instrucción por vez | Concurrente: todo funciona al mismo tiempo |
| El tiempo | Implícito, lo marca el procesador | Explícito: flancos de reloj y retardos |
| Lo que produce | Instrucciones para un procesador que ya existe | El circuito mismo |
| Un bucle | Repite en el tiempo | Replica en el espacio |
| Memoria dinámica, recursión | Naturales | Imposibles: el hardware no crece mientras funciona |
| Error típico | Una excepción en tiempo de ejecución | Un circuito que simula bien y en la placa hace otra cosa |
06Dónde aparece en la electrónica
| Caso | El papel del HDL |
|---|---|
| Diseño con FPGA | Todo el diseño se escribe en HDL y la herramienta lo sintetiza para el dispositivo |
| Circuitos integrados a medida (ASIC) | El mismo HDL, sintetizado sobre una biblioteca de celdas de una fábrica |
| Verificación de un procesador | SystemVerilog con bancos de prueba aleatorizados y aserciones |
| Síntesis de alto nivel (HLS) | Se escribe en C o C++ y una herramienta genera el HDL: útil para filtros y procesamiento de señales |
07En el laboratorio
Simular el contador de la sección 2 con un simulador libre (GHDL o Icarus Verilog) y un banco de prueba que aplique reset y veinte flancos. Ver en GTKWave que vuelve a cero después de 15.
Escribir un multiplexor combinacional con un if sin else, sintetizarlo y
buscar en el informe la advertencia de latch inferido. Corregirlo y comparar.
Sintetizar las dos versiones del registro de desplazamiento del laboratorio y comparar en el visor de esquemáticos cuántos flip-flops genera cada una.
08Errores frecuentes
- Pensar las sentencias como pasos en el tiempo. Son partes de un circuito que funcionan a la vez.
- Usar asignación bloqueante en un bloque con reloj. Colapsa registros y rompe desplazamientos e intercambios.
- Dejar un
ifsinelseen lógica combinacional. Genera un latch. - Esperar que
#10produzca un retardo en la FPGA. El sintetizador lo ignora. - No escribir banco de prueba. Lo que no se simuló, falla en la placa.
09Autoevaluación
¿Qué diferencia fundamental hay entre un programa en C y una descripción en VHDL?
El programa se ejecuta en orden sobre un procesador; la descripción define un circuito cuyas partes funcionan todas al mismo tiempo.
¿Qué hace b <= a; c <= b; en un bloque con reloj?
Un registro de desplazamiento: en cada flanco, c toma el valor
anterior de b y b el de a.
¿Y con asignaciones bloqueantes?
c ve el valor nuevo de b, que ya es a: los
dos registros toman a en el mismo flanco y el desplazamiento desaparece.
¿Qué genera un if sin else en lógica
combinacional?
Un latch, porque la salida tiene que recordar su valor cuando la condición no se cumple.
¿Qué es un banco de prueba?
Un módulo que no se sintetiza, que aplica estímulos al diseño y verifica sus salidas en simulación.
10Para ampliar
- Pong P. Chu. FPGA Prototyping by VHDL Examples. 2.ª ed., Wiley, 2017. VHDL aprendido construyendo circuitos reales sobre una placa, con la síntesis siempre a la vista.
- Samir Palnitkar. Verilog HDL: A Guide to Digital Design and Synthesis. 2.ª ed., Prentice Hall, 2003. El texto clásico de Verilog, con el capítulo de asignaciones bloqueantes y no bloqueantes.
- Clifford E. Cummings. Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!. SNUG San José, 2000. El artículo que fijó las reglas de estilo que hoy usa toda la industria.