Teach Remote lab lessons

Teach lesson

Lógica digital na DE1-SoC com VHDL (2/6): tabelas-verdade, SOP, mapas de Karnaugh e extensões opcionais

Implemente em VHDL uma função booleana como SOP canônica, minimize-a com um mapa de Karnaugh e, se houver tempo, experimente extensões POS, MUX e display de 7 segmentos.

  • Altera DE1-SoC
  • 45 min
  • Graduação, introdutório
  • Português (Brasil)
  • Digital systems & FPGA
Altera DE1-SoC
Altera DE1-SoC

Learning Outcomes

  • Obter uma soma de produtos (SOP) canônica a partir de uma tabela-verdade.

  • Minimizar uma função booleana com um mapa de Karnaugh e interpretar a expressão simplificada.

  • Comparar no hardware real uma forma canônica e sua forma mínima e confirmar que são equivalentes.

  • Reconhecer POS, multiplexador e display de dois dígitos como extensões opcionais.

Student activity preview

Activity Content

Preview only. In a class session, students can fill in responses and submit their work to the teacher.

1

Da tabela-verdade ao circuito

8 min

Na Lição 1, você ligou portas individuais às chaves. Projetos reais começam um nível acima: primeiro se decide o que o circuito deve fazer, normalmente por meio de uma tabela-verdade, e depois se encontra uma rede de portas que produza esse comportamento. Nesta lição, você obterá a mesma função por mais de um caminho e depois a tornará menor.

A função dos dois primeiros exercícios é F(C,B,A), com três entradas. Você ligará SW(0)=A, SW(1)=B, SW(2)=C e mostrará o resultado em LEDR(0). As linhas seguem a ordem de contagem binária C B A, de 000 a 111:

- Linha 0: C B A = 0 0 0F=0
- Linha 1: C B A = 0 0 1F=1
- Linha 2: C B A = 0 1 0F=0
- Linha 3: C B A = 0 1 1F=1
- Linha 4: C B A = 1 0 0F=1
- Linha 5: C B A = 1 0 1F=0
- Linha 6: C B A = 1 1 0F=1
- Linha 7: C B A = 1 1 1F=0

F vale 1 em quatro das oito linhas e 0 nas outras quatro. Identifique-as diretamente na tabela antes de responder. Essa divisão orienta a lição: as linhas com F=1 produzem a soma de produtos, e as linhas com F=0 produzem o produto de somas.

Lembre-se das convenções da placa: uma chave para cima representa 1 lógico, e LEDR é ativo em nível alto. Os circuitos desta lição são puramente combinacionais: a saída depende apenas das posições atuais das chaves, sem clock.

Em quantas das oito linhas F vale 1, e quais são essas linhas?

2

Soma de produtos e mapa de Karnaugh

14 min

Mintermo. Um *mintermo* é um termo AND (produto) construído com todas as entradas, cada uma aparecendo uma vez, direta ou negada, e que vale 1 em exatamente uma linha. Para três entradas, há oito mintermos. A linha 1 é C=0, B=0, A=1, portanto seu mintermo é (not C and not B and A).

Soma canônica de produtos (SOP). Para construir F, aplique OR aos mintermos de todas as linhas em que F=1:

- Linha 1 C=0,B=0,A=1(not C and not B and A)
- Linha 3 C=0,B=1,A=1(not C and B and A)
- Linha 4 C=1,B=0,A=0(C and not B and not A)
- Linha 6 C=1,B=1,A=0(C and B and not A)

A SOP canônica é correta, mas dispendiosa: quatro termos AND de três entradas alimentam um OR de quatro entradas.

Minimização com mapa de Karnaugh. Um *mapa de Karnaugh* reorganiza a tabela-verdade para que células adjacentes difiram em apenas uma entrada. Quando dois 1s adjacentes formam um grupo, a variável que *muda* entre eles não afeta esse grupo e pode ser eliminada.

- Agrupe os mintermos 1 e 3. Compare o que permanece igual e o que muda.
- Agrupe os mintermos 4 e 6. Esse grupo contorna a borda porque as colunas 00 e 10 também são adjacentes na ordem Gray.

Escreva um termo reduzido para cada grupo e combine os dois com or. Depois verifique qual entrada desaparece de ambos os grupos e o que isso diz sobre a dependência de F.

Mapa de Karnaugh de F(C,B,A), com os mintermos 1, 3, 4 e 6 marcados como 1. Dois pares adjacentes estão contornados, sem mostrar os termos reduzidos nem a expressão final.

Mapa de Karnaugh de F. Em cada grupo, identifique as variáveis que mantêm o mesmo valor e elimine a variável que muda.

Agora aplique o mesmo método a uma função diferente. G(C,B,A) vale 1 exatamente nas linhas 0, 2, 5 e 7. Escreva a SOP canônica completa de G, com um mintermo para cada linha. Use os operadores VHDL not, and e or.

Na expressão mínima de F, qual variável desaparece dos dois grupos? Explique o que sua ausência revela. Depois encontre duas linhas que diferem somente nessa variável e informe os números das linhas e os valores de F.

3

Monte: SOP canônica e depois forma mínima

14 min

Agora implemente a função na placa real. Execute primeiro a SOP canônica, confira as oito linhas e depois troque-a pela expressão minimizada para confirmar que as saídas são idênticas.

-- Código inicial do estudante: preencha as linhas TODO antes de sintetizar.
-- Lição 2 - Exercício 1-B: soma de produtos.
-- F(C,B,A): mintermos 1,3,4,6. SW(0)=A, SW(1)=B, SW(2)=C. Saída em 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);

    -- Primeiro passo: complete a SOP canônica com os quatro mintermos.
    LEDR(0) <= TODO_CANONICAL_SOP;

    -- Segundo passo: substitua a linha acima pela expressão mínima do mapa.
    -- LEDR(0) <= TODO_MINIMIZED_EXPRESSION;
    LEDR(9 downto 1) <= (others => '0');
end architecture rtl;
  1. Abra o laboratório VHDL da DE1-SoC. O editor mostra blink.vhd.

  2. Selecione todo o conteúdo de blink.vhd, substitua-o pelo código acima e mantenha o nome da entidade blink.

  3. No primeiro passo, complete TODO_CANONICAL_SOP. Deixe ativa exatamente uma linha que controle LEDR(0).

  4. Clique em Synthesize (Sintetizar). Se um tour guiado cobrir o botão, feche-o ou pule-o. Aguarde de 1 a 3 minutos e corrija qualquer erro até obter sucesso com 0 erros.

  5. Clique em Upload to FPGA (Enviar para a FPGA) e aguarde a câmera ao vivo.

  6. Percorra em SW(2 downto 0) (C B A) as oito combinações 000 a 111 e registre LEDR(0).

  7. No segundo passo, substitua a atribuição canônica pela expressão minimizada. Sintetize, envie novamente e confira algumas linhas, por exemplo 001, 100 e 111.

Defina SW(2 downto 0) = C B A em cada linha e registre LEDR(0) na execução da SOP canônica (1 = aceso, 0 = apagado). Depois confira três linhas com a expressão mínima.

C = SW2 B = SW(1) A = SW(0) SOP canônica em LEDR0 (observado)

Quais três linhas você conferiu com a expressão minimizada? LEDR(0) coincidiu com a SOP canônica nas três? Em uma frase, diga o que isso confirma.

Envie sua evidência. Faça uma captura da câmera com a expressão minimizada executando em uma linha para a qual F=1, por exemplo C B A = 100, e anexe-a abaixo.

> Bônus opcional, sem envio obrigatório. Se o Quartus mostrar o relatório de recursos, compare a contagem de elementos lógicos da SOP canônica com a da forma mínima. Esse relatório não aparece em todas as sessões e não faz parte da evidência obrigatória.

4

Extensão opcional: a mesma função como produto de somas

10 min

Se houver tempo, construa a mesma F pelas linhas com 0. Um maxtermo é um termo OR (soma) com todas as entradas que vale 0 em exatamente uma linha. Para a linha 0, o maxtermo é (A or B or C).

No produto canônico de somas (POS), aplique AND aos maxtermos de todas as linhas em que F=0: 0, 2, 5 e 7. Uma variável aparece negada no maxtermo quando vale 1 na linha correspondente.

-- Código inicial do estudante: preencha a linha TODO antes de sintetizar.
-- Lição 2 - Exercício 1-C: produto de somas (POS).
-- Mesma F(C,B,A). Maxtermos: linhas 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: produto das somas dos maxtermos
    LEDR(9 downto 1) <= (others => '0');
end architecture rtl;
  1. Substitua todo o conteúdo de blink.vhd pela entidade POS acima e mantenha o nome blink.

  2. Clique em Synthesize, corrija qualquer erro e sintetize novamente.

  3. Clique em Upload to FPGA e aguarde a câmera.

  4. Percorra SW(2 downto 0) de 000 a 111. Confirme a sequência 0, 1, 0, 1, 1, 0, 1, 0.

  5. Se uma linha divergir, confira as posições SW(2)=C, SW(1)=B, SW(0)=A.

Para esta função F, como o tamanho da POS canônica se compara ao da SOP canônica?

5

Extensão opcional: multiplexador 4 para 1

10 min

Um multiplexador (MUX) encaminha uma entre várias entradas de dados para uma saída, conforme as linhas de seleção.

- Dados: SW(3)=D3, SW(2)=D2, SW(1)=D1, SW(0)=D0
- Seleção: SW(5)=S1, SW(4)=S0
- Saída: LEDR(0)=Y

S1 & S0 escolhe 00 → D0, 01 → D1, 10 → D2, 11 → D3. A atribuição selecionada termina em when others. Esse ramo garante que Y receba um valor em todos os casos; caso contrário, o sintetizador poderia inferir um latch, acrescentando memória indesejada ao circuito combinacional.

-- Lição 2 - Exercício 1-D: multiplexador 4 para 1.
-- Dados em SW(3 downto 0), seleção S1=SW(5), S0=SW(4), saída em 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 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;
  1. Substitua blink.vhd pela entidade do multiplexador e mantenha o nome blink.

  2. Clique em Synthesize, aguarde e corrija qualquer erro.

  3. Clique em Upload to FPGA e aguarde a câmera.

  4. Defina SW(3 downto 0)=1010, isto é, D3=1, D2=0, D1=1, D0=0.

  5. Antes de olhar para a câmera, preveja a saída. Depois percorra S1:S0 = 00, 01, 10, 11 com SW(5) e SW(4) e registre LEDR(0).

  6. Escolha uma seleção, altere a chave de dados correspondente e confirme que Y acompanha apenas essa entrada.

Mantenha SW(3 downto 0)=1010. Para cada seleção, preveja a entrada escolhida e Y antes de observar a câmera; depois registre LEDR(0).

S1 = SW5 S0 = SW4 Entrada selecionada (D0..D3) Y previsto antes da câmera Y = LEDR0 (observado)

Se algum valor de seleção deixasse Y sem atribuição, que componente indesejado o sintetizador poderia inferir, e por que isso contrariaria o multiplexador puramente combinacional pretendido?

6

Bônus: decodificador decimal de dois dígitos e 7 segmentos

4 min

Este exercício é opcional. Na DE1-SoC, os displays HEX são ativos em nível baixo, com ordem {g,f,e,d,c,b,a}. Um segmento acende com 0; assim, o dígito zero usa "1000000".

Display de sete segmentos com barras a a g. A ordem dos bits é g f e d c b a e os segmentos são ativos em nível baixo; o dígito zero acende a até f e apaga g.

Nomes dos segmentos e ordem ativa em nível baixo {g,f,e,d,c,b,a}. 0 acende um segmento e 1 o apaga; o dígito zero usa "1000000".

O projeto lê SW(3 downto 0) como um valor de 0 a 15, mostra as unidades em HEX0 e as dezenas em HEX1. Para controlar HEX1, é necessário declará-lo na lista de portas da entidade.

-- Lição 2 - Exercício 1-E (opcional): decodificador decimal de dois dígitos.
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;
  1. Substitua blink.vhd pela entidade acima e confirme que a porta HEX1 : out std_logic_vector(6 downto 0) está declarada.

  2. Clique em Synthesize, corrija qualquer erro e sintetize novamente.

  3. Clique em Upload to FPGA e aguarde a câmera.

  4. Teste 0000 (0 e 0), 1001 (9 e 0) e 1111 (5 em HEX0 e 1 em HEX1).

Que mudança na lista de portas da entidade foi necessária para acender HEX1, e por quê?

7

O que você construiu

4 min

Em um parágrafo, resuma como a SOP canônica veio da tabela, como o mapa reduziu F à sua expressão mínima e o que a ausência de B revelou. Mencione a confirmação no hardware. Se tentou uma extensão opcional, acrescente uma frase.

Na extensão MUX, com SW(3 downto 0)=1010, qual sequência de Y você observou para S1:S0 = 00, 01, 10, 11? Como ela se comparou à sua previsão?