Salta al contenuto
Note per Studenti Esercizio 6 · descrizione VHDL di una macchina di Moore con uscita a due bit (tema d'esame luglio 2022)

Esercizio 6descrizione VHDL di una macchina di Moore con uscita a due bit (tema d'esame luglio 2022)

Esame
In questa pagina 4

Testo (tema d'esame luglio 2022, secondo appello, esercizio 3). Descrivere in VHDL la macchina a stati finiti con ingressi xx e yy e uscita ww, avente il seguente diagramma degli stati. In tutti i casi non indicati, il sistema non cambia stato. Separare nel codice gli elementi di memoria dalle parti puramente combinatorie.

Diagramma (dalla figura del tema): stati S0S_0 (w=00w=00), SAS_A (w=01w=01), S2S_2 (w=11w=11), SBS_B (w=10w=10), con S0S_0 stato iniziale (reset rst=1rst=1);

  • S0→SAS_0\to S_A se x=1x=1 and y=0y=0;
  • S0→SBS_0\to S_B se x=0x=0 and y=1y=1;
  • SA→S2S_A\to S_2 se x=1x=1;
  • SB→S2S_B\to S_2 se x=0x=0 or y=1y=1;
  • S2→S0S_2\to S_0 (arco senza etichetta: nessuna condizione).

Teoria usata: VHDL - macchine a stati finiti e testbench sequenzialeUna macchina a stati finiti (FSM) si descrive in VHDL, in stile behavioral, con un tipo enumerato per gli stati e tre process: (1) registro di stato con reset (asincrono) e aggiornamento state<=next_state sul fronte; (2) stato futuro come funzione combinatoria di stato e ingresso (case state, default next_state<=state); (3) uscita come funzione combinatoria di stato (Moore) o di stato e ingresso (Mealy). Il testbench ha il process del clock e il process degli ingressi (reset iniziale, sequenza di test che percorre tutti gli stati).VHDL - macchine a stati finiti e testbench sequenziale →, VHDL - latch, flip-flop e reset sincrono e asincronoIn VHDL un elemento di memoria si descrive con un process il cui ramo non assegna sempre il segnale: latch D = process(D,C) con if C='1' then Q<=D; flip-flop positive-edge-triggered = process(CLK) con if CLK'event and CLK='1'. Reset asincrono: RST nella sensitivity list e testato per primo (if RST='1' ... elsif fronte); reset sincrono: solo CLK in lista e RST testato dentro al ramo del fronte (serve un fronte per averne effetto). Il testbench di un circuito sincrono ha un process che genera il clock e uno che applica gli ingressi lontano dal fronte attivo.VHDL - latch, flip-flop e reset sincrono e asincrono →.

Passo 1: Moore, uscite e tabella

Il valore di ww è scritto dentro lo stato: macchina di Moore, quindi ww dipende solo dallo stato e il process dell'uscita ha nella lista di sensibilità solo state. Uscita ww a due bit: std_logic_vector(1 downto 0).

stato ww xy=00xy=00 0101 1010 1111
S0S_0 00 S0S_0 SBS_B SAS_A S0S_0
SAS_A 01 SAS_A SAS_A S2S_2 S2S_2
S2S_2 11 S0S_0 S0S_0 S0S_0 S0S_0
SBS_B 10 S2S_2 S2S_2 SBS_B S2S_2

(SA→S2S_A\to S_2 se x=1x=1, cioè per xy=10xy=10 e 1111. SB→S2S_B\to S_2 se x=0x=0 o y=1y=1: tutte le combinazioni tranne xy=10xy=10.)

Passo 2: codice

vhdl
library IEEE;
use IEEE.std_logic_1164.all;

entity fsm_moore is
  port ( clk, rst : in  std_logic;
         x, y     : in  std_logic;
         w        : out std_logic_vector(1 downto 0) );
end fsm_moore;

architecture beh of fsm_moore is
  type state_type is (S0, SA, S2, SB);
  signal state, next_state : state_type;
begin
  -- memoria: registro di stato con reset asincrono
  state_register : process (clk, rst)
  begin
    if rst = '1' then
      state <= S0;
    elsif clk'event and clk = '1' then
      state <= next_state;
    end if;
  end process;

  -- combinatoria: stato futuro
  next_state_comb : process (state, x, y)
  begin
    next_state <= state;                        -- default: non cambia stato
    case state is
      when S0 =>
        if x = '1' and y = '0' then
          next_state <= SA;
        elsif x = '0' and y = '1' then
          next_state <= SB;
        end if;
      when SA =>
        if x = '1' then next_state <= S2; end if;
      when SB =>
        if x = '0' or y = '1' then next_state <= S2; end if;
      when S2 =>
        next_state <= S0;
    end case;
  end process;

  -- combinatoria: uscita di Moore (solo lo stato)
  output_comb : process (state)
  begin
    case state is
      when S0 => w <= "00";
      when SA => w <= "01";
      when S2 => w <= "11";
      when SB => w <= "10";
    end case;
  end process;
end beh;

Il case dell'uscita elenca tutti e quattro gli stati: nessuna memoria involontaria. Un'alternativa compatta è un with state select w <= "00" when S0, "01" when SA, "11" when S2, "10" when SB; fuori da un process.

Passo 3: comportamento atteso (per un eventuale testbench)

Il testo qui non chiede il testbench, ma conviene sapere la sequenza che percorre tutte le 8 transizioni, con ingressi xyxy applicati ai fronti di discesa dopo il reset:

ciclo 0 1 2 3 4 5 6 7 8
xyxy 10 00 10 00 01 10 01 11 00
stato presente S0S_0 SAS_A SAS_A S2S_2 S0S_0 SBS_B SBS_B S2S_2 S0S_0
ww (stato presente) 00 01 01 11 00 10 10 11 00
stato futuro SAS_A SAS_A S2S_2 S0S_0 SBS_B SBS_B S2S_2 S0S_0 S0S_0

Essendo Moore, ww cambia solo sul fronte di salita, con la sequenza 00→01→11→00→10→11→0000\to01\to11\to00\to10\to11\to00 (nell'ordine in cui si attraversano gli stati). Rispetto a una macchina di Mealy non ci sono variazioni di ww tra due fronti.

Errori comuni

  • Mettere x e y nella lista di sensibilità del process dell'uscita (o usarli): la renderebbe una Mealy.
  • Dimenticare l'arco S2→S0S_2\to S_0 non condizionato.
  • Confondere le condizioni di SBS_B: si esce con x=0x=0 oppure y=1y=1, non con entrambe.
  • Scrivere w <= 01; senza virgolette: un vettore di bit va tra doppi apici.

Versione ripasso

Esercizi su questo argomento

Teoria collegata