Teach Remote lab lessons

Teach lesson

Lógica digital na DE1-SoC com VHDL (5/6): máquinas de estados finitos

Construa e modifique uma FSM de Moore para um semáforo na DE1-SoC, com uma extensão opcional de detector Mealy.

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

Learning Outcomes

  • Explicar uma máquina de estados finitos em termos de estados, transições e saídas.

  • Explicar por que o controlador de semáforo é uma máquina de Moore e reconhecer um detector de Mealy como extensão opcional.

  • Ler e modificar uma FSM VHDL com dois ou três blocos: registrador de estado, lógica de próximo estado e lógica de saída.

  • Construir e modificar um controlador de semáforo na DE1-SoC real.

  • Explicar por que o reset assíncrono ativo em nível baixo importa quando uma FSM com clock lento precisa voltar a um estado conhecido.

Student activity preview

Activity Content

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

1

O que é uma máquina de estados finitos

10 min

Você já construiu circuitos que têm memória: um flip-flop guarda um bit, um registrador guarda vários e um contador guarda a contagem atual. Uma máquina de estados finitos (FSM) organiza essa memória em *situações significativas*. A cada instante, a máquina está em exatamente um elemento de um conjunto pequeno e fixo de estados. Em um semáforo, esses estados podem ser GREEN, YELLOW e RED. O número de estados é finito, daí o nome, e a máquina sempre está em exatamente um deles.

Uma FSM é definida por três elementos:

- Estados — o conjunto finito de situações em que a máquina pode estar. Um deles é o estado de reset, no qual a máquina começa.
- Transições — as regras para passar de um estado a outro. Em cada borda de clock, a máquina observa o estado atual e as entradas e decide qual será o próximo estado. A transição GREEN -> YELLOW significa: “se estiver em GREEN e a condição for satisfeita, vá para YELLOW na próxima borda”.
- Saídas — os valores que a máquina aplica às saídas, aqui os LEDs, em cada situação.

Toda a máquina avança com o clock: em cada borda, ela pode passar a outro estado com base no estado atual e nas entradas atuais, depois mantém esse estado até a borda seguinte. Entre as bordas, ela apenas espera. É o mesmo comportamento de amostragem e retenção que você viu nos flip-flops, agora usado para percorrer uma sequência de estados.

Moore e Mealy. As FSMs têm dois tipos, que diferem apenas na origem das saídas:

- Em uma máquina de Moore, as saídas dependem apenas do estado atual. Se você conhece o estado, conhece as saídas; as entradas não aparecem na equação de saída. O semáforo é Moore: quando o estado é RED, o LED vermelho está aceso, independentemente das entradas.
- Em uma máquina de Mealy, as saídas dependem do estado atual e das entradas atuais em conjunto. O mesmo estado pode produzir saídas diferentes conforme a entrada naquele instante. O detector de sequência afirma “detectado” em certo estado *somente quando o bit de entrada também tem o valor correto*.

As saídas de Moore permanecem estáveis enquanto a máquina fica em um estado. As saídas de Mealy podem mudar assim que uma entrada muda, mesmo sem sair do estado. Isso as torna rápidas, mas também possivelmente breves e sujeitas a glitches, o que será importante na câmera.

A estrutura padrão de uma FSM em VHDL. Quase todas as FSMs deste curso são escritas como dois ou três blocos que trabalham juntos:

1. Um registrador de estado — um processo VHDL acionado por clock (if rising_edge(clock) then ...) que guarda o estado atual e, em cada borda, copia o próximo estado. É o único bloco com memória.
2. Um processo de próximo estado — um processo combinacional VHDL que calcula o próximo estado a partir do estado atual e das entradas. Ele deve atribuir valores padrão seguros antes do case ou cobrir explicitamente todos os ramos, para que todo caminho atribua as saídas e next_state.
3. Lógica de saída — atribuições concorrentes de sinais ou atribuições em processo combinacional que determinam as saídas a partir do estado (Moore) ou do estado e das entradas (Mealy).

Os dois projetos desta lição seguem essa estrutura: um processo de estado acionado por clock, um processo combinacional de próximo estado com valores padrão e a lógica de saída.

Uma máquina de venda automática lembra quanto dinheiro foi inserido e libera um produto quando o total alcança o preço. Ao modelá-la como FSM, o que melhor representa o estado?

Um circuito acende um LED sempre que está no estado BUSY e a entrada go vale 1. Essa saída é Moore ou Mealy? Explique em uma frase.

2

Uma observação necessária: reset assíncrono nestas FSMs

7 min

Antes de construir qualquer coisa, observe uma mudança deliberada em relação às lições anteriores.

Na Lição 3, o flip-flop e o registrador usavam reset síncrono: o reset era testado dentro do processo acionado por clock, como if KEY(0) = '0' then Q <= '0'; dentro de if rising_edge(CLOCK_50) then. A Lição 4 já usou reset assíncrono ativo em nível baixo em circuitos de clock lento; esta lição mantém esse estilo no estado da FSM para que o reset não espere o clock lento.

As FSMs desta lição usam reset assíncrono ativo em nível baixo. Observe a lista de sensibilidade do registrador de estado:

process(slow_clk, KEY)
begin
    if KEY(0) = '0' then state <= TODO_RESET_STATE;
    elsif rising_edge(slow_clk) then state <= TODO_NEXT_STATE;
    end if;
end process;

Colocar KEY na lista de sensibilidade do processo e testar if KEY(0) = '0' then antes do ramo da borda de clock faz o processo de estado responder no instante em que KEY(0) vai a nível baixo, quando você pressiona o botão, e não somente em uma borda de slow_clk. Assim, pressionar KEY(0) força a máquina ao estado conhecido imediatamente, sem esperar o clock lento.

Expresse claramente a diferença:

- Reset síncrono (Lições 2–3): entra em vigor somente em uma borda de clock. É limpo e previsível, mas, se o clock for lento, é preciso esperar a borda.
- Reset assíncrono (Lições 5–6): entra em vigor imediatamente, no instante em que o sinal de reset é ativado, independentemente do clock.

Por que mudar? Estas FSMs são acionadas por um slow_clk dividido, com bordas separadas por segundos. Com reset síncrono, você poderia pressionar KEY(0) e não ver nada acontecer por mais de um segundo, até a próxima borda lenta. Se a máquina estivesse presa, esse seria justamente o momento em que você mais precisaria de uma saída imediata. O reset assíncrono oferece na placa real esse retorno confiável e instantâneo ao início. KEY é ativo em nível baixo: KEY(0) vai a zero quando o botão é pressionado e KEY(0) = '0' permanece verdadeiro enquanto ele é mantido pressionado.

Você pressiona KEY(0) quando ainda falta cerca de um segundo para a próxima borda de slow_clk. Com o reset assíncrono usado nestas FSMs, quando a máquina passa ao estado de reset? Quando um reset síncrono faria essa passagem?

O registrador de estado é escrito como process(slow_clk, KEY), com if KEY(0) = '0' then ... elsif rising_edge(slow_clk) then .... O que o ramo de reset assíncrono (if KEY(0) = '0' then ...) acrescenta? Como o reset se comportaria se você o removesse, deixando apenas um processo acionado por rising_edge(slow_clk)?

3

Exercício 3-A: o semáforo (uma FSM de Moore)

10 min

Sua primeira FSM é um controlador de semáforo. Ele tem três estados e os percorre em um ciclo fixo, mantendo cada luz por um número definido de pulsos:

GREEN -> YELLOW -> RED -> GREEN -> ...

As conexões são LEDR(0) = verde, LEDR(1) = amarelo, LEDR(2) = vermelho e KEY(0) = reset ativo em nível baixo, que devolve a máquina a GREEN. A máquina é acionada por um slow_clk dividido: cada borda de subida é um pulso da máquina de estados. Com este divisor, considere cerca de 0,67 s por pulso visível; a primeira borda de subida após o reset pode chegar antes.

Esta é uma máquina de Moore. A lógica de saída ao final é

LEDR(0) <= TODO_GREEN_LED;
LEDR(1) <= TODO_YELLOW_LED;
LEDR(2) <= TODO_RED_LED;

Cada LED é função somente do estado; nenhuma entrada aparece. Conhecer o estado determina exatamente qual luz está acesa. Essa é a propriedade que define uma máquina de Moore.

Dois registradores separados realizam dois trabalhos diferentes. Leia o registrador de estado com atenção, pois o projeto contém *duas* memórias fáceis de confundir:

- state, um sinal do tipo state_t, guarda qual luz está acesa: GREEN, YELLOW ou RED. Esse é o estado da FSM.
- timer, um sinal unsigned(2 downto 0), é um contador de permanência separado, que conta regressivamente quantos pulsos restam na luz atual. Enquanto timer é maior que zero, ele apenas diminui (timer <= timer - 1) e o estado não muda. Somente quando timer chega a 0 a máquina avança para next_state e recarrega timer para a nova luz.

Portanto, o registrador de estado guarda *qual* luz está acesa e o temporizador conta *por quanto tempo* ela permanece acesa. São registradores diferentes, com finalidades diferentes; o temporizador mantém cada luz ativa em vez de deixá-la passar em um único pulso.

Tempos reais de permanência segundo o código. Ao entrar em cada estado, a máquina recarrega timer; contar do valor carregado até 0, inclusive, fornece o número de pulsos:

- GREEN carrega timer = 3 e conta 3, 2, 1, 0 -> 4 pulsos (cerca de 2,7 s).
- YELLOW carrega timer = 1 e conta 1, 0 -> 2 pulsos (cerca de 1,3 s).
- RED carrega timer = 3 -> 4 pulsos (cerca de 2,7 s).

Um ciclo completo tem, portanto, 4 + 2 + 4 = 10 pulsos, aproximadamente 10 × 0,67 s = 6,7 s do início ao fim.

Máquina de estados finitos de Moore para um semáforo, com três círculos rotulados VERDE, AMARELO e VERMELHO ligados em ciclo. GREEN dura 4 pulsos, YELLOW dura 2 e RED dura 4; cada estado acende um único LED, mostrando que a saída depende somente do estado. Uma seta KEY(0)=reinício aponta para VERDE.

O semáforo como máquina de Moore de três estados: GREEN -> YELLOW -> RED -> GREEN. O temporizador mantém cada estado por um número fixo de pulsos: GREEN 4, YELLOW 2 e RED 4; um pulso visível dura cerca de 0,67 s. Cada estado acende exatamente um LED, portanto as saídas dependem somente do estado. KEY(0) reinicia a máquina em GREEN.

Esta é a entidade completa. O divisor produz slow_clk; o processo de estado com reset assíncrono avança a luz quando o temporizador termina; um processo combinacional calcula a próxima luz; e as três atribuições concorrentes aos LEDs formam a lógica de saída de Moore.

-- Código inicial: complete as linhas TODO antes de sintetizar.
-- Lição 5 - Exercício 3-A: controlador de semáforo (FSM de Moore).
-- KEY(0)=reset. LEDR(0)=verde, LEDR(1)=amarelo, LEDR(2)=vermelho.
-- Permanências: GREEN = 4 pulsos, YELLOW = 2 pulsos, RED = 4 pulsos.
-- Um pulso visível é uma borda de subida de slow_clk, cerca de 0,67 s com este divisor.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity blink is
    port (
        CLOCK_50 : in  std_logic;
        KEY      : in  std_logic_vector(3 downto 0);
        LEDR     : out std_logic_vector(9 downto 0)
    );
end entity blink;

architecture rtl of blink is
    type state_t is (GREEN, YELLOW, RED);
    signal state, next_state : state_t := GREEN;
    signal timer : unsigned(2 downto 0) := "011";
    constant DIV : unsigned(24 downto 0) := to_unsigned(16666666, 25);
    signal div_count : unsigned(24 downto 0) := (others => '0');
    signal slow_clk : std_logic := '0';
begin
    process(CLOCK_50)
    begin
        if rising_edge(CLOCK_50) then
            if KEY(0) = '0' then
                div_count <= (others => '0'); slow_clk <= '0';
            elsif div_count = DIV then
                div_count <= (others => '0'); slow_clk <= not slow_clk;
            else
                div_count <= div_count + 1;
            end if;
        end if;
    end process;

    process(state)
    begin
        case state is
            when GREEN  => next_state <= TODO_AFTER_GREEN;
            when YELLOW => next_state <= TODO_AFTER_YELLOW;
            when RED    => next_state <= TODO_AFTER_RED;
        end case;
    end process;

    process(slow_clk, KEY)
    begin
        if KEY(0) = '0' then
            state <= GREEN; timer <= "011";
        elsif rising_edge(slow_clk) then
            if timer = 0 then
                state <= next_state;
                case next_state is
                    when GREEN  => timer <= TODO_GREEN_RELOAD; -- 4 pulsos
                    when YELLOW => timer <= TODO_YELLOW_RELOAD; -- 2 pulsos
                    when RED    => timer <= TODO_RED_RELOAD; -- 4 pulsos
                end case;
            else
                timer <= timer - 1;
            end if;
        end if;
    end process;

    LEDR(0) <= TODO_GREEN_OUTPUT;
    LEDR(1) <= TODO_YELLOW_OUTPUT;
    LEDR(2) <= TODO_RED_OUTPUT;
    LEDR(9 downto 3) <= (others => '0');
end architecture rtl;

As saídas do semáforo são atribuições concorrentes, como LEDR(0) <= '1' when state = GREEN else '0';. Para tornar uma dessas saídas Mealy em vez de Moore, que tipo de termo ausente agora seria necessário acrescentar à expressão?

4

Exercício 3-A na placa: observe e modifique

12 min

Agora construa o semáforo na DE1-SoC real, meça cada fase e depois modifique-o.

  1. Abra o laboratório VHDL da DE1-SoC. O editor mostra o arquivo blink.vhd.

  2. Selecione todo o conteúdo de blink.vhd e substitua-o pelo código inicial do semáforo acima. Complete todas as linhas TODO, mantenha a entidade blink e preserve CLOCK_50 : in std_logic.

  3. Clique em Synthesize. Se o tour guiado cobrir o botão, feche-o ou pule-o. Aguarde a conclusão, cerca de 1–3 minutos. Os erros mais comuns são a ausência de CLOCK_50 na lista de portas ou de um ponto e vírgula; corrija e sintetize novamente. Prossiga somente quando o estado final indicar compilação bem-sucedida com 0 erros.

  4. Clique em Upload to FPGA e aguarde a placa ao vivo e a câmera.

  5. Observe o ciclo. Acompanhe LEDR(0) (verde), LEDR(1) (amarelo) e LEDR(2) (vermelho). Conte por quantos segundos, ou pulsos de cerca de 0,67 s, cada luz permanece acesa e registre. Compare com o código: GREEN deve durar 4 pulsos, YELLOW 2 e RED 4.

  6. Pressione reset. Enquanto a luz estiver em YELLOW ou RED, pressione e solte KEY(0). A máquina deve voltar imediatamente a GREEN. Esse é o reset assíncrono em ação.

Observe o ciclo do semáforo e meça cada fase na câmera. Registre a duração observada, em segundos ou pulsos de cerca de 0,67 s, e compare com os pulsos esperados no código: GREEN 4, YELLOW 2 e RED 4.

Fase (LED aceso) Pulsos esperados (código) Duração observada (s ou pulsos)

Envie sua evidência. Aguarde a fase YELLOW e faça uma captura da câmera quando LEDR(1) (amarelo) estiver aceso e LEDR(0) (verde) e LEDR(2) (vermelho) estiverem apagados. Anexe-a abaixo.

Agora faça uma alteração obrigatória de temporização no projeto.

(Modifique) Altere os tempos de permanência. Edite os valores de recarga de timer para que o ciclo seja GREEN = 6 pulsos, YELLOW = 4 pulsos, RED = 6 pulsos. O temporizador conta do valor carregado até 0, inclusive; portanto, N pulsos exigem carregar N - 1: use "101" (5) para GREEN, "011" (3) para YELLOW e "101" (5) para RED, tanto no case do registrador de estado quanto na linha de reset, se o valor inicial mudar. Sintetize, envie à FPGA, confirme os novos tempos na câmera e calcule a nova duração total do ciclo em pulsos.

Extensão opcional: acrescente um estado vermelho piscante. Adicione um quarto estado, FLASH_RED, depois de RED somente se o professor pedir. Para não acionar LEDR(2) em dois lugares, substitua a atribuição atual do LED vermelho por um único acionador combinado, como LEDR(2) <= '1' when state = RED else timer(0) when state = FLASH_RED else '0';. Depois, acrescente FLASH_RED ao tipo VHDL state_t e ao case de próximo estado, dê a ele uma permanência no case do temporizador, sintetize, envie e confirme que o LED vermelho pisca antes de voltar ao verde.

Para fazer YELLOW durar o dobro, qual valor de registrador você alteraria (state ou timer), em que ponto exato do código e qual registrador deixaria completamente inalterado?

Depois de alterar os valores de recarga, execute o semáforo novamente. Registre o número modificado de pulsos observado em cada estado para comprovar a alteração no código, não apenas descrevê-la.

Estado Pulsos modificados observados Valor de recarga usado no código

Com os tempos modificados (GREEN = 6, YELLOW = 4 e RED = 6 pulsos), qual é a duração total de um ciclo completo em pulsos? Mostre a soma.

Usando o código e sua observação, justifique em duas ou três frases que esta é uma máquina de Moore. Identifique a lógica de saída e explique por que os LEDs são função somente do estado, e não de uma entrada.

5

Extensão opcional: detector da sequência 1011 (FSM de Mealy)

11 min

Sua segunda FSM observa um fluxo de bits que chegam, um por pulso de clock, em SW(0) e acende um LED quando acaba de encontrar o padrão 1011. Esta é uma máquina de Mealy: ela afirma “detectado” em certo estado *somente quando o bit de entrada também é o correto*, portanto a saída depende do estado e da entrada em conjunto.

As conexões são SW(0) = bit serial de entrada, KEY(0) = reset ativo em nível baixo, LEDR(0) = detecção e LEDR(5 downto 1) = estado atual em codificação one-hot, um LED por estado, para acompanhar a máquina. A borda de subida do slow_clk dividido, isto é, um pulso, ocorre aproximadamente a cada 1,33 s com este divisor.

Os estados. O detector lembra quanto de 1011 já foi reconhecido:

- S0 — nada reconhecido ainda; é o estado de reset.
- S1 — o último bit foi 1; reconheceu 1.
- S2 — reconheceu 10.
- S3 — reconheceu 101.
- S4 — reconheceu o 1011 completo. A partir daqui, a máquina ainda pode iniciar um novo reconhecimento, permitindo detecções sobrepostas: o 1 final de um 1011 pode ser o 1 inicial do seguinte.

Em cada pulso, o bloco de próximo estado observa o estado atual e o bit em SW(0). A saída detect é ativada dentro de S3 somente quando o bit recebido é 1, pois 101 seguido por 1 completa 1011. Essa é a saída de Mealy, determinada pelo estado e pela entrada.

Por que retemos a saída — leia com atenção. O sinal de Mealy bruto detect fica alto por apenas um pulso. Em clock rápido, seria invisível; mesmo neste clock lento, um lampejo de cerca de 1,33 s pode passar despercebido na câmera remota. Por isso, o projeto não liga detect diretamente ao LED. Em vez disso, ele retém a detecção: um registrador separado, detected_latch, recebe 1 quando detect dispara e permanece em 1 até você pressionar reset. LEDR(0) mostra esse latch. Depois de detectar 1011, o LED acende e fica aceso até KEY(0). Assim, um evento breve se torna uma indicação estável e fotografável.

Máquina de estados finitos de Mealy que detecta a sequência 1011, com cinco estados S0 a S4. As setas mostram transições conforme o bit de entrada. Em S3, a entrada 1 completa 1011 e ativa detect; a entrada 0 volta a S2 para preservar o sufixo 10 e permitir sobreposição. De S4, 1 volta a S1 e 0 a S0. O pulso de detecção fica retido em LEDR(0) até o reset.

O detector de 1011 como máquina de Mealy com cinco estados. S0 a S4 indicam quanto de 1011 já foi reconhecido. A saída detect, marcada na transição de S3, depende do estado S3 e da entrada 1 em conjunto, portanto é Mealy. A regra de sobreposição mantém a máquina pronta para outro reconhecimento; por exemplo, S3 com 0 volta a S2, não a S0. O pulso detect de um ciclo fica retido em LEDR(0) até o reset.

Esta é a entidade completa. Observe os dois processos: um processo combinacional calcula next_state e o sinal Mealy detect; um process(slow_clk, KEY) acionado por clock guarda o estado e o latch, com reset assíncrono.

-- Código inicial: complete as linhas TODO antes de sintetizar.
-- Lição 5 - Exercício 3-B: detector da sequência 1011 (FSM de Mealy) com detecção retida.
-- SW(0)=bit serial de entrada. KEY(0)=reset. LEDR(0)=latch de detecção.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity blink is
    port (
        CLOCK_50 : in  std_logic;
        KEY      : in  std_logic_vector(3 downto 0);
        SW       : in  std_logic_vector(9 downto 0);
        LEDR     : out std_logic_vector(9 downto 0)
    );
end entity blink;

architecture rtl of blink is
    type state_t is (S0, S1, S2, S3, S4);
    signal state, next_state : state_t := S0;
    signal detect, detected_latch : std_logic := '0';
    constant DIV : unsigned(26 downto 0) := to_unsigned(33333333, 27);
    signal div_count : unsigned(26 downto 0) := (others => '0');
    signal slow_clk : std_logic := '0';
begin
    process(CLOCK_50)
    begin
        if rising_edge(CLOCK_50) then
            if KEY(0) = '0' then
                div_count <= (others => '0'); slow_clk <= '0';
            elsif div_count = DIV then
                div_count <= (others => '0'); slow_clk <= not slow_clk;
            else
                div_count <= div_count + 1;
            end if;
        end if;
    end process;

    process(state, SW)
    begin
        next_state <= S0;
        detect <= '0';
        case state is
            when S0 => TODO_TRANSITION_FROM_S0;
            when S1 => TODO_TRANSITION_FROM_S1;
            when S2 => TODO_TRANSITION_FROM_S2;
            when S3 => TODO_TRANSITION_FROM_S3_AND_DETECT;
            when S4 => TODO_TRANSITION_FROM_S4;
        end case;
    end process;

    process(slow_clk, KEY)
    begin
        if KEY(0) = '0' then
            state <= S0; detected_latch <= '0';
        elsif rising_edge(slow_clk) then
            state <= next_state;
            if TODO_DETECT_CONDITION then detected_latch <= '1'; end if;
        end if;
    end process;

    LEDR(0) <= detected_latch;
    LEDR(5 downto 1) <= "00001" when state = S0 else
                         "00010" when state = S1 else
                         "00100" when state = S2 else
                         "01000" when state = S3 else
                         "10000";
    LEDR(9 downto 6) <= (others => '0');
end architecture rtl;

Seria possível prever exatamente quando detect dispara observando apenas os LEDs de estado LEDR(5 downto 1), *sem* saber o valor de SW(0)? Use sua resposta para explicar por que essa saída é Mealy, não Moore.

6

Extensão opcional na placa: insira bits e recupere

12 min

Agora construa o detector e insira bits manualmente. Para inserir um bit: ajuste SW(0) ao valor desejado, espere um pulso completo do clock lento, cerca de 1,33 s, para a máquina amostrá-lo na próxima borda de subida, depois mude SW(0) para o bit seguinte e espere outra vez. Observe LEDR(5 downto 1) para acompanhar o estado.

  1. Em blink.vhd, substitua todo o conteúdo pelo código inicial do detector 1011 acima. Complete todas as transições e condições TODO, mantenha a entidade blink e preserve CLOCK_50 : in std_logic.

  2. Clique em Synthesize, aguarde o sucesso e depois clique em Upload to FPGA.

  3. Comece com reset. Pressione e solte KEY(0). LEDR(0) (detectado) deve estar apagado, e os LEDs de estado LEDR(5 downto 1) devem mostrar S0 (00001).

  4. Insira 1, 0, 1, 1. Coloque SW(0) = 1 e espere cerca de 1,33 s; coloque SW(0) = 0 e espere; depois 1 e espere; finalmente 1 e espere. Após o último 1, LEDR(0) deve ficar retido em ligado. Registre os LEDs de estado depois de cada bit.

  5. Reinicie e insira 1, 0, 1, 0, 1, 1, com um bit errado no meio. A máquina não deve disparar falsamente, deve se recuperar e ainda detectar o 1011 final, retendo LEDR(0) ligado. Isso mostra que a FSM se recupera de um bit errado em vez de ficar presa.

  6. Use reset sempre que quiser iniciar um novo fluxo; somente o reset apaga o LEDR(0) retido.

Insira o fluxo 1,0,1,1, um bit por pulso do clock lento, cerca de 1,33 s cada. Após cada bit, leia o estado em LEDR(5 downto 1), com codificação one-hot 00001=S0, 00010=S1, 00100=S2, 01000=S3 e 10000=S4, e indique se LEDR(0), detectado, ficou retido em ligado. A detecção deve ser retida após o último 1.

Bit inserido (SW(0)) LEDR(5 downto 1) observado (one-hot) LEDR(0) detectado? (aceso/apagado)

Envie sua evidência. Depois de inserir 1, 0, 1, 1, LEDR(0) (detectado) fica retido aceso até o reset, um estado estável que pode ser fotografado. Faça uma captura da câmera mostrando LEDR(0) aceso e anexe-a abaixo.

Extensão opcional se houver tempo: modifique o detector para reconhecer 101 em vez de 1011. Primeiro desenhe o novo diagrama de estados: são necessários estados para “nada reconhecido”, “reconheceu 1” e “reconheceu 10”; a saída de detecção deve disparar quando, no estado “reconheceu 10”, o bit seguinte for 1. Se implementar, mantenha o latch e a exibição one-hot, sintetize, envie e confirme que inserir 1, 0, 1 retém LEDR(0) aceso.

A saída Mealy bruta detect é registrada, armazenada em flip-flop, ou combinacional, calculada diretamente a partir do estado e da entrada? Que problema de temporização uma saída Mealy combinacional pode causar e como isso se relaciona à retenção em LEDR(0)?

Suponha que o sinal bruto detect, com um pulso, fosse ligado diretamente a LEDR(0) em vez de ser retido. No clock lento de cerca de 1,33 s, o que você provavelmente veria na câmera quando 1011 fosse detectado e por que essa evidência seria pouco confiável?

Na etapa 5, você inseriu 1, 0, 1, 0, 1, 1 e a máquina ainda detectou 1011 no final. Explique brevemente como a FSM se recuperou do bit errado em vez de ficar presa ou disparar falsamente.

7

O que você construiu

4 min

Você construiu um controlador de semáforo Moore na DE1-SoC real: suas saídas dependem somente do estado, e ele percorre GREEN -> YELLOW -> RED com um temporizador de permanência. Na extensão opcional, você também explorou um detector Mealy de 1011, cuja saída detect depende do estado e da entrada. Você usou a estrutura padrão de FSM: registrador de estado acionado por clock, bloco combinacional de próximo estado com valor padrão e lógica de saída. Também viu como o reset assíncrono ativo em nível baixo devolve imediatamente uma FSM de clock lento ao estado conhecido e, na extensão, por que uma saída de um pulso é retida para a câmera remota capturá-la.

Qual sequência corresponde ao que você fez em cada exercício desta lição?

Em três ou quatro frases: explique por que o semáforo é uma máquina de Moore, citando a lógica de saída; diferencie os registradores state e timer; descreva a alteração de permanência que você testou; e indique uma etapa em que a polaridade ativa em nível baixo de KEY ou o reset assíncrono foi importante. Se fez o detector opcional, acrescente uma frase explicando por que ele é Mealy ou por que LEDR(0) foi retido.