Teach Lecciones con laboratorios remotos

Lección Teach

Lógica digital en la DE1-SoC (2/6): tablas de verdad, SOP/POS, mapas de Karnaugh y multiplexores

El alumnado conecta tablas de verdad, formas booleanas, mapas de Karnaugh y multiplexores, y prueba lógica combinacional minimizada en la DE1-SoC.

  • Altera DE1-SoC
  • 70 min
  • Secundaria (16–18 años)
  • Español
  • Sistemas digitales y FPGA

¿Primera vez que activas Teach? Puedes realizar una sesión de clase sin costo. El alumnado entra con un código de clase.

Mapa de Karnaugh de F(C,B,A) con los mintérminos 1, 3, 4 y 6 marcados como 1. Dos pares adyacentes están rodeados, pero los términos reducidos no aparecen en la imagen. El alumnado debe decidir qué variable cambia dentro de cada grupo y escribir los términos simplificados.
Altera DE1-SoC

Resultados de aprendizaje

  • Derivar las formas suma de productos (SOP) y producto de sumas (POS) 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.

  • Construir y verificar un multiplexor 4 a 1 que enruta una de cuatro entradas hacia una salida.

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.

1

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?

2

Suma de productos y mapa de Karnaugh

14 min

Mintérmino. Un *mintérmino* es un AND (producto) construido con todas las entradas, cada una normal o negada, que vale 1 en una sola 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 (~C & ~B & A): este producto solo vale 1 cuando C=0, B=0 y A=1.

Suma de productos canónica (SOP). Para construir F, une con OR los mintérminos de todas las filas donde F=1. Usa la tabla de verdad anterior para escribir tú los cuatro mintérminos de F. No saltes esta forma completa: la probarás en la placa antes de probar la forma reducida.

Minimización con mapa de Karnaugh. Un *mapa K* reorganiza la tabla de verdad para que las celdas adyacentes difieran en una sola entrada. Cuando dos 1 adyacentes se agrupan, la variable que cambia dentro del grupo no importa para ese par y desaparece, dejando un término más pequeño. El diagrama de abajo marca las cuatro celdas con 1 y muestra dos grupos posibles. Tu trabajo es leer cada grupo: decidir qué entrada se mantiene, cuál cambia y qué término producto queda.

Mapa de Karnaugh de F(C,B,A) con los mintérminos 1, 3, 4 y 6 marcados como 1. Dos pares adyacentes están rodeados, pero los términos reducidos no aparecen en la imagen. El alumnado debe decidir qué variable cambia dentro de cada grupo y escribir los términos simplificados.

Mapa de Karnaugh de F. Cada pareja marcada contiene dos 1 adyacentes. En cada grupo, compara las dos celdas y tacha la variable que cambia; las variables que se mantienen forman el término reducido.

Escribe la SOP canónica completa de F(C,B,A) a partir de las cuatro filas de la tabla donde F=1. Usa ~ para NOT, & para AND y | para OR.

Usando el mapa K, escribe el término producto reducido para cada uno de los dos grupos. En cada grupo, indica qué variable cambia y por tanto desaparece. Después combina los dos términos reducidos en una expresión mínima para F.

Desaparece alguna variable de entrada en tu expresión mínima? Explica qué te dice eso sobre cómo depende F de sus tres entradas. Después busca dos filas de la tabla que difieran solo en esa variable, y da sus números de fila y valores de F para comprobarlo.

3

Construcción: 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 editarás la misma plantilla para probar la expresión mínima que obtuviste con el mapa K.

El módulo de abajo está incompleto a propósito. Sustituye TODO_CANONICAL_SOP_EXPRESSION por tu SOP completa. Después de comprobarla en la placa, sustituye esa misma línea por tu expresión minimizada y sintetiza de nuevo.

// Leccion 2 - Ejercicio 1-B: plantilla de suma de productos (SOP)
// F(C,B,A): usa las filas de la tabla de verdad donde F=1. SW[0]=A, SW[1]=B, SW[2]=C.
// Completa primero la SOP canonica. Despues sustituyela por tu expresion minimizada con el mapa K.
module leds_mirror(SW, LEDR);
    input  [9:0] SW;
    output [9:0] LEDR;

    wire A = SW[0];
    wire B = SW[1];
    wire C = SW[2];

    // Paso 1: SOP canonica. Escribe un termino producto por cada fila F=1.
    assign LEDR[0] = TODO_CANONICAL_SOP_EXPRESSION;

    // Paso 2: despues de verificar la forma canonica, sustituye la linea anterior por
    // tu expresion minimizada con el mapa K y sintetiza de nuevo.

    assign LEDR[9:1] = 9'b0;
endmodule
  1. Abre el laboratorio Verilog DE1-SoC. El editor muestra el archivo leds_mirror.v.

  2. Selecciona todo el contenido de leds_mirror.v y reemplázalo por la plantilla anterior. Mantén el módulo llamado leds_mirror.

  3. Sustituye TODO_CANONICAL_SOP_EXPRESSION por tu expresión SOP canónica. Debe quedar una sola línea assign LEDR[0] = ...;.

  4. Haz clic en Synthesize. Si un tour tapa el botón, ciérralo u omítelo. Espera a que termine (normalmente 1-3 minutos). Si aparece un error, revisa punto y coma o paréntesis, corrige y sintetiza de nuevo. Continúa solo cuando el estado final indique 0 errores.

  5. Haz clic en Upload to FPGA y espera la sesión de la placa y la cámara.

  6. Recorre SW[2:0] (C B A) por las ocho combinaciones 000, 001, 010, 011, 100, 101, 110, 111, leyendo LEDR[0] en la cámara. Registra cada resultado en la tabla.

  7. En la segunda prueba, edita la misma línea assign LEDR[0] para usar tu expresión minimizada con el mapa K. Sintetiza y carga de nuevo; comprueba al menos tres filas, incluida una con F=0 y otra con F=1, y confirma que la versión minimizada coincide con la canónica.

Coloca SW[2:0] = C B A en cada fila y registra el valor de LEDR[0] que lees en la cámara (1 = encendido, 0 = apagado). Usa tu propia tabla de verdad para comprobar si la SOP canónica y tu expresión minimizada coinciden.

C = SW2 B = SW1 A = SW0 F = LEDR0 (observado)

Tu SOP canónica y tu expresión minimizada 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 tu expresión minimizada en cualquier fila donde tu tabla prediga F=1. En el texto, indica qué fila C B A elegiste.

> Bonus opcional (no requiere entrega). Quartus informa cuántos elementos lógicos usa un diseño. Si tu sesión muestra ese informe, sintetiza tu SOP canónica y tu expresión minimizada y compara sus elementos lógicos. Trátalo como exploración; el informe de recursos no siempre aparece igual en todas las sesiones.

4

La misma función como producto de sumas

14 min

La SOP construye 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 OR (suma) con todas las entradas, normales o negadas, que vale 0 en una sola fila. Es el espejo de un mintérmino. Para la fila 0 (C=0, B=0, A=0), el maxtérmino es (A | B | C): este OR solo vale 0 cuando A, B y C son todos 0, y vale 1 en las demás filas.

Producto de sumas canónico. Une con AND el maxtérmino 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, así que el AND de todos ellos vale 0 exactamente en las filas F=0. Lee esas filas en la tabla de verdad y escribe tú los cuatro maxtérminos.

// Leccion 2 - Ejercicio 1-C: plantilla de producto de sumas (POS)
// Misma F(C,B,A). Usa las filas de la tabla donde F=0 para escribir los maxterminos.
module leds_mirror(SW, LEDR);
    input  [9:0] SW;
    output [9:0] LEDR;

    wire A = SW[0];
    wire B = SW[1];
    wire C = SW[2];

    // POS canonica: un termino suma por cada fila F=0, todos unidos con AND.
    assign LEDR[0] = TODO_CANONICAL_POS_EXPRESSION;

    assign LEDR[9:1] = 9'b0;
endmodule
  1. En el laboratorio Verilog DE1-SoC, selecciona todo leds_mirror.v y reemplázalo por la plantilla POS anterior. Mantén el módulo llamado leds_mirror.

  2. Sustituye TODO_CANONICAL_POS_EXPRESSION por la POS canónica de F.

  3. Haz clic en Synthesize y espera. Corrige cualquier error de sintaxis y sintetiza de nuevo.

  4. Haz clic en Upload to FPGA y espera la cámara.

  5. Recorre SW[2:0] (C B A) por las ocho combinaciones 000 ... 111, leyendo LEDR[0] cada vez. Comprueba que la POS produce las mismas filas observadas que tu tabla de la SOP.

  6. Si una fila no coincide, revisa ambas posibilidades: el maxtérmino POS de esa fila y las posiciones físicas SW[2]=C, SW[1]=B, SW[0]=A.

Para esta F, cómo se compara el tamaño de la POS canónica con la SOP canónica?

5

Un multiplexor 4 a 1

12 min

Un multiplexor (MUX) es un selector: 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. El módulo usa una instrucción case dentro de always @(*). La rama default no está de adorno: en un bloque combinacional always, si alguna combinación de entrada dejara Y sin asignar, el sintetizador inferiría un latch para "recordar" el valor anterior. Eso convertiría tu lógica combinacional pura en memoria accidental. Asignar Y en todas las ramas, aquí mediante default, garantiza que Y siempre tenga un valor definido y que no se cree ningún latch.

// Leccion 2 - Ejercicio 1-D: plantilla de multiplexor 4 a 1
// Entradas de datos: SW[3]=D3, SW[2]=D2, SW[1]=D1, SW[0]=D0
// Lineas de seleccion: SW[5]=S1, SW[4]=S0. Salida: LEDR[0]=Y.
module leds_mirror(SW, LEDR);
    input  [9:0] SW;
    output [9:0] LEDR;

    wire D0 = SW[0], D1 = SW[1], D2 = SW[2], D3 = SW[3];
    wire S0 = SW[4], S1 = SW[5];

    reg Y;
    always @(*) begin
        case ({S1, S0})
            2'b00:   Y = TODO_SELECTED_INPUT_00;
            2'b01:   Y = TODO_SELECTED_INPUT_01;
            2'b10:   Y = TODO_SELECTED_INPUT_10;
            2'b11:   Y = TODO_SELECTED_INPUT_11;
            default: Y = 1'b0;   // el default evita inferir un latch
        endcase
    end

    assign LEDR[0]   = Y;
    assign LEDR[9:1] = 9'b0;
endmodule
  1. En el laboratorio Verilog de la DE1-SoC, selecciona todo el contenido de leds_mirror.v y reemplázalo por el módulo del multiplexor. Mantén el nombre leds_mirror.

  2. Pulsa Sintetizar y espera a que termine. Corrige cualquier error y vuelve a sintetizar.

  3. Pulsa Enviar a la FPGA y espera a la cámara.

  4. Coloca los cuatro interruptores de datos en el patrón SW[3:0] = 1010: D3=1 (SW[3] arriba), D2=0 (SW[2] abajo), D1=1 (SW[1] arriba), D0=0 (SW[0] abajo).

  5. Ahora recorre las líneas de selección S1:S0 = 00, 01, 10, 11 usando SW[5] (S1) y SW[4] (S0). Para cada valor, lee LEDR[0] (Y) y anótalo en la tabla. Con datos 1010, la salida debe seguir la línea seleccionada: 0, 1, 0, 1.

  6. Como comprobación rápida, elige un valor de selección, cambia el interruptor de datos correspondiente y confirma que Y sigue solo a esa línea mientras las otras no afectan.

Mantén los datos en SW[3:0] = 1010 (D3 D2 D1 D0 = 1 0 1 0). Para cada valor de selección, coloca SW[5]=S1 y SW[4]=S0, anota qué entrada se selecciona y registra el LEDR[0] observado (Y). Con este patrón, Y esperada es 0, 1, 0, 1.

S1 = SW5 S0 = SW4 Entrada seleccionada (D0..D3) Y = LEDR0 (observado)

Sube tu evidencia. Captura una imagen de la cámara del multiplexor con datos SW[3:0] = 1010 y selección S1:S0 = 01 (SW[4] arriba, SW[5] abajo). Eso selecciona D1 = 1, así que LEDR[0] debe estar encendido. Adjunta la captura abajo.

Imagina que borras la línea default: Y = 1'b0;, de modo que alguna combinación dejara Y sin asignar. Qué pieza de hardware no deseada inferiría el sintetizador, y por qué eso contradice el multiplexor puramente combinacional que querías construir?

6

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 7'b1000000: seis 0 para los segmentos encendidos y un 1 para el g apagado.

Distribución de un display de siete segmentos. Las barras se etiquetan a arriba, b arriba derecha, c abajo derecha, d abajo, e abajo izquierda, f arriba izquierda y g en el centro. Los bits van en orden g f e d c b a y son activos en bajo, así que un segmento se enciende con 0; el dígito 0 enciende a hasta f y apaga g.

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 7'b1000000.

El diseño siguiente lee SW[3: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 output [6:0] HEX1 a la lista de puertos del módulo. El leds_mirror inicial solo expone HEX0. El módulo de abajo ya declara HEX0 y HEX1, así que es el ejemplo concreto de ese puerto adicional.

// Leccion 2 - Ejercicio 1-E (opcional): plantilla de decodificador decimal de dos digitos
// Completa los patrones activos en bajo y las ecuaciones de decenas/unidades.
module leds_mirror(SW, HEX0, HEX1);
    input  [9:0] SW;        // SW[3:0] = value 0..15
    output [6:0] HEX0;      // digito de unidades
    output [6:0] HEX1;      // digito de decenas (0 or 1)

    wire [4:0] v = {1'b0, SW[3:0]};

    function [6:0] seg;
        input [3:0] d;
        case (d)
            4'd0: seg = 7'b1000000;
            4'd1: seg = TODO_SEGMENT_PATTERN_1;
            4'd2: seg = TODO_SEGMENT_PATTERN_2;
            4'd3: seg = TODO_SEGMENT_PATTERN_3;
            4'd4: seg = TODO_SEGMENT_PATTERN_4;
            4'd5: seg = TODO_SEGMENT_PATTERN_5;
            4'd6: seg = TODO_SEGMENT_PATTERN_6;
            4'd7: seg = TODO_SEGMENT_PATTERN_7;
            4'd8: seg = TODO_SEGMENT_PATTERN_8;
            4'd9: seg = TODO_SEGMENT_PATTERN_9;
            default: seg = 7'b1111111;
        endcase
    endfunction

    wire [3:0] tens = TODO_TENS_DIGIT;
    wire [3:0] ones = TODO_ONES_DIGIT;

    assign HEX0 = seg(ones);
    assign HEX1 = seg(tens);
endmodule
  1. Opcional. En el laboratorio Verilog de la DE1-SoC, reemplaza todo el contenido de leds_mirror.v por el módulo decodificador. Mantén el nombre leds_mirror. Confirma que la lista de puertos dice module leds_mirror(SW, HEX0, HEX1);: el output [6:0] HEX1 añadido permite controlar el display de decenas.

  2. Pulsa Sintetizar, corrige cualquier error y vuelve a sintetizar.

  3. Pulsa Enviar a la FPGA y espera a la cámara.

  4. Coloca SW[3:0] en algunos valores y lee ambos displays: 0000 debe mostrar 0 en HEX0 y 0 en HEX1; 1001 (decimal 9) muestra 9 y 0; 1111 (decimal 15) muestra 5 en HEX0 y 1 en HEX1.

Qué cambio en la lista de puertos del módulo fue necesario para que este diseño pudiera encender HEX1, y por qué era necesario?

7

Qué has construido

4 min

En un párrafo breve, resume lo que hiciste con F(C,B,A): cómo la SOP canónica y la POS salieron de la tabla de verdad, cómo el mapa de Karnaugh redujo F a tu expresión mínima y qué te dijo cualquier variable que desapareciera. Menciona que confirmaste en la placa que las formas canónica y mínima daban salidas idénticas.

Para el multiplexor con datos SW[3:0] = 1010, qué secuencia de valores de Y observaste cuando S1:S0 fue 00, 01, 10, 11, y por qué esa secuencia corresponde al dato seleccionado cada vez?

Convierte esta vista previa en una sesión de clase real

Activa LabsLand Teach para usar esta lección con tus estudiantes. La primera vez que actives Teach, podrás realizar una sesión de clase sin costo.