Lección Teach
Lógica digital en la DE1-SoC con VHDL (2/6): tablas de verdad, SOP, mapas de Karnaugh y extensiones opcionales
El alumnado implementa una función booleana en VHDL como SOP canónica, la minimiza con un mapa de Karnaugh y prueba extensiones POS/MUX opcionales si hay tiempo.
¿Primera vez en LabsLand? Crea tu cuenta de docente
Resultados de aprendizaje
Derivar una suma de productos (SOP) canónica desde una tabla de verdad.
Minimizar una función booleana con un mapa de Karnaugh y leer la expresión simplificada.
Comparar una forma canónica con su forma mínima en hardware real y confirmar que coinciden.
Reconocer POS, multiplexores y display de dos dígitos como extensiones opcionales si hay tiempo.
Vista previa de la actividad del estudiante
Contenido de la actividad
Solo vista previa. En una sesión de clase, los estudiantes pueden completar respuestas y entregar su trabajo al docente.
De una tabla de verdad a un circuito
8 min
En la Lección 1 conectaste puertas individuales a interruptores. Los diseños reales empiezan un nivel más arriba: decides qué debe hacer un circuito, normalmente mediante una tabla de verdad, y después buscas una red de puertas que produzca ese comportamiento. En esta lección trabajarás una función desde varias formas y luego la harás más pequeña.
La función de los dos primeros ejercicios es F(C,B,A), una función de tres entradas. Conectarás SW(0)=A, SW(1)=B, SW(2)=C, y mostrarás el resultado en LEDR(0). Esta es su tabla de verdad. Las filas están en orden de conteo binario C B A, desde 000 hasta 111:
Tabla de verdad de F(C,B,A), en orden binario:
- Fila 0: C B A = 0 0 0 -> F=0
- Fila 1: C B A = 0 0 1 -> F=1
- Fila 2: C B A = 0 1 0 -> F=0
- Fila 3: C B A = 0 1 1 -> F=1
- Fila 4: C B A = 1 0 0 -> F=1
- Fila 5: C B A = 1 0 1 -> F=0
- Fila 6: C B A = 1 1 0 -> F=1
- Fila 7: C B A = 1 1 1 -> F=0
F vale 1 en cuatro de las ocho filas y 0 en las otras cuatro. Léelo en la tabla antes de responder. Esa separación organiza toda la lección: las filas donde F=1 dan la suma de productos, y las filas donde F=0 dan el producto de sumas. Mantén esta tabla a la vista: todo lo que sigue vuelve a ella.
Recuerda las convenciones de la placa que usaste en la Lección 1: un interruptor arriba es lógica 1, y LEDR es activo en alto, así que el LED se enciende cuando la salida vale 1. Estos ejercicios son puramente combinacionales: la salida depende solo de la posición actual de los interruptores, por lo que no hace falta declarar reloj.
En cuántas de las ocho filas vale 1 la función F, y cuáles son esas filas?
Suma de productos y mapa de Karnaugh
14 min
Mintérmino. Un *mintérmino* es un único término AND (producto) construido con todas las entradas. Cada entrada aparece una vez, normal o negada, y el término vale 1 en exactamente una fila de la tabla de verdad. Para tres entradas hay ocho mintérminos, uno por fila. La fila 1 es C=0, B=0, A=1, así que su mintérmino es (not C and not B and A): este producto vale 1 solo cuando C=0, B=0 y A=1, y vale 0 en todas las demás filas.
Suma de productos canónica (SOP). Para construir F, haces OR de los mintérminos de todas las filas donde F=1. Como cada mintérmino vale 1 solo en su propia fila, el OR vale 1 exactamente en las filas de F=1 y 0 en el resto: eso es justo F. Las cuatro filas con F=1 (1, 3, 4, 6) dan:
- Fila 1 C=0,B=0,A=1 -> (not C and not B and A)
- Fila 3 C=0,B=1,A=1 -> (not C and B and A)
- Fila 4 C=1,B=0,A=0 -> (C and not B and not A)
- Fila 6 C=1,B=1,A=0 -> (C and B and not A)
Por tanto, la SOP canónica es F = (not C and not B and A) or (not C and B and A) or (C and not B and not A) or (C and B and not A). Es correcta, pero poco eficiente: cuatro términos AND de tres entradas alimentando un OR de cuatro entradas.
Minimizar con un mapa de Karnaugh. Un *mapa de Karnaugh* es la tabla de verdad redibujada para que las celdas adyacentes cambien en una sola entrada. Cuando dos 1 adyacentes quedan juntos, la variable que cambia entre ellos no importa para ese par y se puede eliminar.
Agrupa los cuatro mintérminos donde F=1 en dos pares:
- Grupo de los mintérminos 1 y 3. La fila 1 es C=0, B=0, A=1; la fila 3 es C=0, B=1, A=1. Anota qué variables se mantienen iguales y cuál cambia. La variable que cambia se elimina.
- Grupo de los mintérminos 4 y 6. La fila 4 es C=1, B=0, A=0; la fila 6 es C=1, B=1, A=0. Haz la misma comparación. El grupo envuelve el borde del mapa porque las columnas 00 y 10 también son adyacentes en código Gray.
Escribe un término reducido para cada grupo y combínalos con or. Si reconoces una puerta conocida, puedes escribir la forma equivalente; si no, conserva la suma de dos productos. Comprueba además qué entrada desaparece de ambos grupos y qué significa eso para la dependencia de F.
Mapa de Karnaugh de F. Usa los grupos como ayuda: para cada grupo, mira qué variables conservan el mismo valor y elimina la variable que cambia.
Aplica el mismo método de mintérminos a una función *distinta*. Una función G(C,B,A) vale 1 exactamente en las filas 0, 2, 5, 7 (y 0 en las filas 1, 3, 4, 6). Escribe la suma de productos canónica completa de G: el OR de un mintérmino por cada fila donde G=1. Usa los operadores VHDL not, and y or.
En tu expresión mínima de F, qué variable desaparece de los dos grupos? Explica qué te dice su ausencia sobre la dependencia de F respecto a sus tres entradas. Después busca por tu cuenta dos filas de la tabla que difieran solo en esa variable y escribe sus números de fila y valores de F para comprobarlo.
Constrúyelo: SOP canónica y forma mínima
14 min
Ahora lleva la función a la placa real. Ejecutarás primero la SOP canónica, verificarás las ocho filas y después cambiarás a la forma mínima your minimized expression para confirmar que produce exactamente las mismas salidas.
La entidad inicial de abajo deja la expresión de LEDR(0) como TODOs. En la primera prueba, completa la línea activa de SOP canónica a partir de los cuatro mintérminos. En la segunda prueba, sustitúyela por la expresión mínima del mapa de Karnaugh, vuelve a sintetizar y compara.
-- Plantilla de estudiante: completa las lineas TODO antes de sintetizar.
-- Lección 2 - Ejercicio 1-B: suma de productos.
-- F(C,B,A): mintérminos 1,3,4,6. SW(0)=A, SW(1)=B, SW(2)=C. Salida en LEDR(0).
library ieee;
use ieee.std_logic_1164.all;
entity blink is
port (
SW : in std_logic_vector(9 downto 0);
LEDR : out std_logic_vector(9 downto 0)
);
end entity blink;
architecture rtl of blink is
signal A, B, C : std_logic;
begin
A <= SW(0);
B <= SW(1);
C <= SW(2);
-- Primera prueba: completa la SOP canonica con los cuatro minterminos.
LEDR(0) <= TODO_CANONICAL_SOP;
-- Segunda prueba: sustituye la linea anterior por la expresion minima del mapa.
-- LEDR(0) <= TODO_MINIMIZED_EXPRESSION;
LEDR(9 downto 1) <= (others => '0');
end architecture rtl;Abre el laboratorio VHDL de la DE1-SoC. El editor muestra el archivo
blink.vhd.Selecciona todo el contenido de
blink.vhdy reemplázalo por la plantilla SOP de arriba. Completa la asignación TODO de la prueba correspondiente y mantén la entidad con el nombreblink.En la primera prueba, completa la línea activa
TODO_CANONICAL_SOPusando los cuatro mintérminos. Debe quedar una sola línea que controleLEDR(0).Pulsa Sintetizar. Si una guía tapa el botón, ciérrala o sáltala primero. Espera a que termine (aprox. 1-3 minutos). Si informa de un error, revisa punto y coma o paréntesis, corrige y vuelve a sintetizar. Continúa solo cuando el estado final diga que terminó con 0 errores.
Pulsa Enviar a la FPGA y espera a que aparezcan la placa y la cámara en directo.
Recorre
SW(2 downto 0)(C B A) por las ocho combinaciones000, 001, 010, 011, 100, 101, 110, 111, leyendoLEDR(0)en la cámara cada vez. Registra cada resultado en la tabla. (Cambia tambiénSW(1)=Ben el conteo aunque esperes que no importe.)En la segunda prueba, edita el archivo otra vez: sustituye la asignación canónica por la expresión mínima que obtuviste del mapa de Karnaugh. Sintetiza y carga de nuevo; después revisa algunas filas, por ejemplo
001,100,111, y confirma queLEDR(0)coincide con la versión canónica.
Coloca SW(2 downto 0) = C B A en cada fila y registra el valor de LEDR(0) que lees en la cámara (1 = encendido, 0 = apagado). La columna esperada es la función de la tabla de verdad; tu observación debe coincidir tanto para la SOP canónica como para la versión mínima A^C.
| C = SW2 | B = SW(1) | A = SW(0) | SOP canónica LEDR0 (observado) |
|---|---|---|---|
La SOP canónica de cuatro términos y la forma mínima your minimized expression produjeron el mismo LEDR(0) en las filas que comprobaste? En una frase, di qué confirma eso sobre las dos expresiones.
Sube tu evidencia. Captura una imagen de la cámara con la forma mínima your minimized expression ejecutándose en una fila donde F = 1 (por ejemplo C B A = 100: SW(2) arriba, SW(1) y SW(0) abajo, así que LEDR(0) está encendido) y adjúntala abajo.
> Bonus opcional (no requiere entrega). Quartus informa cuántos elementos lógicos usa un diseño. Si tu sesión muestra ese informe, sintetiza la SOP canónica de cuatro términos y el your minimized expression de una sola operación y compara el número de elementos lógicos: la forma mínima debería usar menos. Trátalo como exploración; el informe de recursos no siempre se muestra igual en todas las sesiones, así que no forma parte de la evidencia obligatoria.
Extensión opcional: la misma función como producto de sumas
10 min
Extensión opcional si hay tiempo: la SOP construyó F desde sus filas con 1. El producto de sumas (POS) construye la misma F desde sus filas con 0.
Maxtérmino. Un *maxtérmino* es un único término OR (suma) que usa todas las entradas, normales o negadas, y vale 0 en exactamente una fila. Es la imagen simétrica del mintérmino. Para la fila 0 (C=0, B=0, A=0), el maxtérmino es (A or B or C): este OR vale 0 solo cuando A, B y C son todos 0, y vale 1 en cualquier otra fila.
Producto de sumas canónico. Haz AND de los maxtérminos de cada fila donde F=0. Cada maxtérmino fuerza la salida a 0 en su propia fila y la deja a 1 en las demás; por tanto, el AND de todos ellos vale 0 exactamente en las filas de F=0, otra vez la misma función F. Las cuatro filas donde F=0 son 0, 2, 5, 7:
- Fila 0 C=0,B=0,A=0 -> (A or B or C)
- Fila 2 C=0,B=1,A=0 -> (A or not B or C)
- Fila 5 C=1,B=0,A=1 -> (not A or B or not C)
- Fila 7 C=1,B=1,A=1 -> (not A or not B or not C)
En cada maxtérmino, una variable aparece *negada* cuando vale 1 en esa fila F=0, para que el término se haga 0 allí. La entidad de abajo implementa esta POS canónica directamente. Describe exactamente la misma función, así que sus ocho salidas deben coincidir con lo que ya registraste: las filas 0..7 dan 0, 1, 0, 1, 1, 0, 1, 0.
-- Plantilla de estudiante: completa las lineas TODO antes de sintetizar.
-- Lección 2 - Ejercicio 1-C: producto de sumas (POS).
-- Misma F(C,B,A). Maxtérminos (filas F=0): 0, 2, 5, 7. SW(0)=A, SW(1)=B, SW(2)=C.
library ieee;
use ieee.std_logic_1164.all;
entity blink is
port (
SW : in std_logic_vector(9 downto 0);
LEDR : out std_logic_vector(9 downto 0)
);
end entity blink;
architecture rtl of blink is
signal A, B, C : std_logic;
begin
A <= SW(0);
B <= SW(1);
C <= SW(2);
LEDR(0) <= TODO_POS_EXPRESSION; -- TODO: producto de sumas maxtermino
LEDR(9 downto 1) <= (others => '0');
end architecture rtl;En el laboratorio VHDL de la DE1-SoC, selecciona todo el contenido de
blink.vhdy reemplázalo por la entidad POS de arriba. Mantén el nombreblink.Pulsa Sintetizar y espera a que termine. Corrige cualquier error de sintaxis y vuelve a sintetizar.
Pulsa Enviar a la FPGA y espera a la cámara en directo.
Recorre
SW(2 downto 0)(C B A) por las ocho combinaciones000 ... 111, leyendoLEDR(0)cada vez. Confirma que la secuencia de salidas es0, 1, 0, 1, 1, 0, 1, 0, igual que en la SOP.Si alguna fila no coincide con
0, 1, 0, 1, 1, 0, 1, 0, lo más probable es que haya un desliz al colocar interruptores. Revisa cuál interruptor esC, cuálBy cuálA, y vuelve a leer esa fila.
Para esta F concreta, cómo se compara la POS canónica con la SOP canónica en tamaño?
Extensión opcional: un multiplexor 4 a 1
10 min
Extensión opcional si tu docente quiere un ejemplo de selector: un multiplexor (MUX) enruta una de varias entradas de datos hacia una sola salida, elegida por unas líneas de selección. Un MUX 4 a 1 tiene cuatro entradas de datos y necesita dos líneas de selección, porque dos bits eligen entre 2^2 = 4 entradas. Se comporta como un conmutador giratorio: el valor de selección decide qué línea de datos queda conectada a la salida.
La asignación de pines de este ejercicio, escrita de forma explícita para evitar ambigüedad en el orden de bits, es:
- Entradas de datos: SW(3)=D3, SW(2)=D2, SW(1)=D1, SW(0)=D0
- Líneas de selección: SW(5)=S1, SW(4)=S0
- Salida: LEDR(0) = Y
El valor de selección S1 & S0 elige la línea de datos: 00 -> D0, 01 -> D1, 10 -> D2, 11 -> D3. La entidad usa with sel select y termina con when others. Esa rama final no está de adorno: en VHDL combinacional, toda salida debe recibir un valor para toda entrada posible. Si algún camino dejara Y sin asignar, el sintetizador podría inferir un latch para recordar el valor anterior.
-- Plantilla de estudiante: completa las lineas TODO antes de sintetizar.
-- Lección 2 - Ejercicio 1-D: multiplexor 4 a 1 con asignación seleccionada.
-- Datos: SW(3)=D3, SW(2)=D2, SW(1)=D1, SW(0)=D0. Selección: SW(5)=S1, SW(4)=S0.
library ieee;
use ieee.std_logic_1164.all;
entity blink is
port (
SW : in std_logic_vector(9 downto 0);
LEDR : out std_logic_vector(9 downto 0)
);
end entity blink;
architecture rtl of blink is
signal D0, D1, D2, D3 : std_logic;
signal S0, S1, Y : std_logic;
signal sel : std_logic_vector(1 downto 0);
begin
D0 <= SW(0); D1 <= SW(1); D2 <= SW(2); D3 <= SW(3);
S0 <= SW(4); S1 <= SW(5);
sel <= S1 & S0;
with sel select
Y <= TODO_FOR_00 when "00",
TODO_FOR_01 when "01",
TODO_FOR_10 when "10",
TODO_FOR_11 when "11",
'0' when others;
LEDR(0) <= Y;
LEDR(9 downto 1) <= (others => '0');
end architecture rtl;En el laboratorio VHDL de la DE1-SoC, selecciona todo el contenido de
blink.vhdy reemplázalo por la entidad del multiplexor. Mantén el nombreblink.Pulsa Sintetizar y espera a que termine. Corrige cualquier error y vuelve a sintetizar.
Pulsa Enviar a la FPGA y espera a la cámara.
Coloca los cuatro interruptores de datos en el patrón
SW(3 downto 0) = 1010:D3=1(SW(3)arriba),D2=0(SW(2)abajo),D1=1(SW(1)arriba),D0=0(SW(0)abajo).Antes de mirar la cámara, predice qué entrada de datos elegirá cada valor de selección. Después recorre
S1:S0 = 00, 01, 10, 11usandoSW(5)(S1) ySW(4)(S0). Para cada valor, leeLEDR(0)(Y) y registra predicción y observación en la tabla.Como comprobación rápida, elige un valor de selección, cambia el interruptor de datos correspondiente y confirma que
Ysigue solo a esa línea mientras las otras no afectan.
Mantén los datos en SW(3 downto 0) = 1010 (D3 D2 D1 D0 = 1 0 1 0). Para cada valor de selección, coloca SW(5)=S1 y SW(4)=S0, predice qué entrada se selecciona y cuánto valdrá Y, y después registra LEDR(0) observado.
| S1 = SW5 | S0 = SW4 | Entrada seleccionada (D0..D3) | Y predicho antes de la cámara | Y = LEDR0 (observado) |
|---|---|---|---|---|
Sube tu evidencia. Captura una imagen de cámara de tu prueba del multiplexor. En la tabla anterior, marca la fila que corresponde a la captura para que tu docente compare la Y predicha y observada.
Imagina que eliminas la rama when others => '0' o dejas algún valor de selección sin valor para Y. Qué pieza de hardware no deseada podría inferir el sintetizador, y por qué contradice el multiplexor puramente combinacional que querías construir?
Bonus: decodificador decimal de dos dígitos en 7 segmentos
4 min
Este ejercicio es opcional. Si tienes tiempo, es un salto interesante desde un solo LED hasta una salida formateada en los displays de siete segmentos.
Un display de siete segmentos tiene siete barras, etiquetadas a a g, que se encienden en combinaciones para dibujar un dígito. En la DE1-SoC cada display HEX es activo en bajo y el orden de bits es {g, f, e, d, c, b, a}: un segmento se enciende cuando su bit vale 0. Por tanto, el patrón del dígito 0 (segmentos a,b,c,d,e,f encendidos y g apagado) es "1000000": seis 0 para los segmentos encendidos y un 1 para el g apagado.
Nombres de los segmentos y orden de bits activo en bajo {g,f,e,d,c,b,a} en los displays HEX de la DE1-SoC. Un bit 0 enciende su segmento; un 1 lo apaga. El dígito 0 enciende todos los segmentos salvo g, con codificación "1000000".
El diseño siguiente lee SW(3 downto 0) como un valor 0..15, muestra la cifra de unidades en HEX0 y la cifra de decenas (0 o 1) en HEX1. Observa algo que el proyecto inicial no te da automáticamente: para controlar HEX1 debes añadir HEX1 : out std_logic_vector(6 downto 0) a la lista de puertos de la entidad. El blink inicial solo expone HEX0. La entidad de abajo ya declara HEX0 y HEX1, así que es el ejemplo concreto de ese puerto adicional.
-- Plantilla de estudiante: completa las lineas TODO antes de sintetizar.
-- Leccion 2 - Ejercicio 1-E (opcional): decodificador decimal de dos digitos.
-- SW(3 downto 0) selecciona 0..15. HEX0 muestra unidades; HEX1 muestra decenas.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity blink is
port (
SW : in std_logic_vector(9 downto 0);
HEX0 : out std_logic_vector(6 downto 0);
HEX1 : out std_logic_vector(6 downto 0)
);
end entity blink;
architecture rtl of blink is
signal v : unsigned(4 downto 0);
signal tens : unsigned(3 downto 0);
signal ones : unsigned(3 downto 0);
function seg(d : unsigned(3 downto 0)) return std_logic_vector is
begin
case d is
when "0000" => return "1000000"; -- 0
when "0001" => return TODO_SEG_1;
when "0010" => return TODO_SEG_2;
when "0011" => return TODO_SEG_3;
when others => return "1111111";
end case;
end function;
begin
v <= resize(unsigned(SW(3 downto 0)), 5);
tens <= TODO_TENS;
ones <= TODO_ONES;
HEX0 <= seg(ones);
HEX1 <= seg(tens);
end architecture rtl;Opcional. En el laboratorio VHDL de la DE1-SoC, reemplaza todo el contenido de
blink.vhdpor la entidad decodificador. Mantén el nombreblink. Confirma que la lista de puertos de la entidad incluyeHEX1 : out std_logic_vector(6 downto 0);: ese puerto añadido permite controlar el display de decenas.Pulsa Sintetizar, corrige cualquier error y vuelve a sintetizar.
Pulsa Enviar a la FPGA y espera a la cámara.
Coloca
SW(3 downto 0)en algunos valores y lee ambos displays:0000debe mostrar0enHEX0y0enHEX1;1001(decimal 9) muestra9y0;1111(decimal 15) muestra5enHEX0y1enHEX1.
¿Qué cambio en la lista de puertos de la entidad fue necesario para que este diseño pudiera encender HEX1, y por qué era necesario?
Qué construiste
4 min
En un párrafo breve, resume lo que hiciste con F(C,B,A): cómo la SOP canónica salió de la tabla de verdad, cómo el mapa de Karnaugh redujo F a your minimized expression, y qué te dijo la desaparición de B. Menciona que confirmaste en la placa que las formas canónica y mínima daban salidas idénticas. Si probaste la POS, el MUX o el display de 7 segmentos opcionales, añade una frase extra.
(Extensión opcional MUX) Para el multiplexor con datos SW(3 downto 0) = 1010, qué secuencia de valores de Y observaste cuando S1:S0 fue 00, 01, 10, 11, y cómo se comparó con tu predicción?