El presupuesto de un circuito
Sintetizar un circuito es convertir su descripción en una lista de puertas y biestables reales. Esa lista se llama netlist. Contar sus celdas dice cuánto espacio y cuánta energía pedirá el circuito.
Es como el presupuesto de una obra: cada puerta cuesta un poco. Hoy contarás las puertas de varios diseños y verás por qué un descuido puede dejar un latch.
Al final de esta lección
Nota
Puedo decir por qué un diseño necesita menos puertas y por qué un latch es un error.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Síntesis | convertir la descripción en puertas y biestables | |
| Netlist | la lista de celdas y sus conexiones que sale de la síntesis | |
| Celda | una puerta o un biestable de la netlist | $_AND_ |
| yosys | la herramienta de síntesis del laboratorio | |
| Biestable | una celda que guarda un bit y cambia solo con el reloj | $_DFF_P_ |
| Latch | una celda que guarda un bit sin reloj, casi siempre por error | $_DLATCH_P_ |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
yosys convierte la descripción en celdas
La orden hdl gates ARCHIVO.v MÓDULO sintetiza un módulo con yosys y cuenta las celdas de la netlist. Cada tipo de celda tiene un nombre.
$_AND_ y $_XOR_ son puertas. $_SDFF_PP0_ es un biestable con reset síncrono. El contador del laboratorio guarda cuatro bits, así que lleva cuatro de estos biestables.
Entra en la carpeta del laboratorio
cd ~/hdlSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Cuenta las celdas del semisumador
hdl gates half_adder.v half_adderSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Cuenta las celdas del contador
hdl gates counter.v counterSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejemplo: las celdas del contador
| Celda | Cuántas | Qué es |
|---|---|---|
| $_SDFF_PP0_ | 4 | Biestables, uno por bit de q |
| $_XOR_ | 3 | Puertas de la suma |
| $_AND_ | 2 | Puertas de la suma |
| $_NOT_ | 1 | Una puerta inversora |
| Total | 10 | Seis puertas y cuatro biestables |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una misma función puede costar menos puertas
Dos descripciones distintas pueden calcular lo mismo y salir con distinto número de celdas. La función a & b | a & c se puede sacar factor común: a & (b | c).
Los siguientes Runs escriben las dos versiones en /tmp con printf y cuentan sus celdas. El orden en que escribes una función cambia lo que pide el circuito.
Escribe la versión sin factor común
printf 'module m1(input a, input b, input c, output y);\n assign y = (a & b) | (a & c);\nendmodule\n' > /tmp/m1.vSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Cuenta sus celdas
hdl gates /tmp/m1.v m1Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la versión con factor común
printf 'module m2(input a, input b, input c, output y);\n assign y = a & (b | c);\nendmodule\n' > /tmp/m2.vSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Cuenta sus celdas
hdl gates /tmp/m2.v m2Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un latch nace de una salida sin valor
Un bloque always de lógica debe dar valor a cada salida en todos los casos. Si un if no tiene else, cuando la condición falla el circuito tiene que recordar el valor anterior.
Para recordar usa un latch: guarda un bit sin reloj y sigue a su entrada mientras en vale 1. Es casi siempre un error, y el laboratorio rechaza un diseño que lo tenga.
Escribe un módulo con un if sin else
printf 'module latch(input en, input d, output reg q);\n always @(en or d) if (en) q = d;\nendmodule\n' > /tmp/latch.vSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Cuenta su celda
hdl gates /tmp/latch.v latchSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el mismo módulo con un else
printf 'module nolatch(input en, input d, output reg q);\n always @(en or d) if (en) q = d; else q = 0;\nendmodule\n' > /tmp/nolatch.vSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Cuenta su celda
hdl gates /tmp/nolatch.v nolatchSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un error frecuente
Advertencia
Mucha gente cree que un if sin else es inofensivo, como en Python. En un circuito, la salida siempre vale algo. Si no dices qué, el circuito guarda el valor anterior y sale un latch. La solución es dar un valor en todos los casos.
Para ir más lejos
Escribe en /tmp un contador de ocho bits, copiando counter.v con otro ancho, y cuenta sus celdas. Antes de lanzar la orden, apunta cuántas esperas.
Compara con el contador de cuatro bits. Piensa qué parte del total crece al mismo ritmo que los bits y qué parte crece más deprisa.