Salta al contenuto
Note per Studenti Macchine a stati finiti in VHDL

Macchine a stati finiti in VHDL

In questa pagina 5

Un sistema sequenziale (Latch, registri e parametri temporaliUn circuito sequenziale ha uno stato memorizzato in due modi: retroazione positiva (due inverter in anello, bistabile, i latch statici) o immagazzinamento di carica (circuiti dinamici). Un latch è sensibile al livello del clock (trasparente quando il clock è attivo, memorizza quando non lo è), un registro (flip-flop) è sensibile al fronte e si realizza con due latch sulle fasi opposte (master-slave). Il latch SR a porte NOR/NAND non ammette la combinazione S = R = 1 perché passando da lì alla memoria lo stato finale è imprevedibile. Parametri temporali del registro: ritardo clock-uscita t_c-q, tempo di setup t_su (dato stabile prima del fronte), tempo di hold t_hold (dato stabile dopo il fronte). Periodo minimo: T_min = t_c-q + t_p,logic(max) + t_su; vincolo di hold: t_cd,reg + t_cd,logic > t_hold. La pipeline spezza la logica con registri per aumentare la frequenza (a spese della latenza).Latch, registri e parametri temporali →) si modella come macchina a stati finiti (FSM, finite state machine): un numero finito di stati, un registro che ne memorizza uno, e logica combinatoria che ne calcola l'evoluzione. È anche il modello dell'unità di controllo di un processore (Blocchi logici di un microprocessore - ALU, bus e logica tri-stateUn microprocessore semplice è formato da un'unità di controllo (decodifica le istruzioni e abilita gli altri blocchi), una ALU (operazioni aritmetiche e logiche), la memoria e i registri, collegati da bus (linee condivise unidirezionali o bidirezionali). La ALU combina un sommatore con un'unità logica e un multiplexer di selezione dell'operazione: la sottrazione è A + B̄ + 1 (XOR su B e riporto in ingresso a 1), le flag (zero, riporto, segno, overflow) descrivono il risultato. Un bus è una linea pilotata da più sorgenti: per evitare conflitti ogni uscita collegata è tri-state (il segnale enable la mette in alta impedenza) oppure open-drain (solo PDN: ciascuna può imporre 0, serve un pull-up per l'1).Blocchi logici di un microprocessore - ALU, bus e logica tri-state →).

Modelli di Mealy e di Moore

Con S(k)S(k) stato al periodo kk e X(k)X(k) ingresso: S(k+1)=F(S(k),X(k))(funzione di stato prossimo),S(k+1)=F\big(S(k),X(k)\big)\quad(\text{funzione di stato prossimo}), YMealy(k)=G(S(k),X(k)),YMoore(k)=G(S(k)).Y_{Mealy}(k)=G\big(S(k),X(k)\big),\qquad Y_{Moore}(k)=G\big(S(k)\big).

  • Moore: l'uscita dipende solo dallo stato: cambia soltanto dopo un fronte di clock (cioè quando cambia lo stato), ed è priva di glitch dovuti agli ingressi. Nel diagramma l'uscita è scritta dentro lo stato.
  • Mealy: l'uscita dipende da stato e ingresso: può cambiare appena cambia l'ingresso (anche tra due fronti) e di solito richiede meno stati per lo stesso comportamento. Nel diagramma l'uscita è scritta sull'arco (x/y).

Il registro di stato è un banco di registri D con retroazione dallo stato prossimo (VHDL - logica sequenziale e registriIn VHDL la logica sequenziale si descrive con processi sensibili al clock. Un registro D (flip-flop sul fronte) si scrive process(clk) con if rising_edge(clk); un latch è un processo sensibile al livello (if clk='1' then q<=d) senza altri rami. Il reset è sincrono se testato dentro rising_edge(clk) (la lista di sensibilità contiene solo clk), asincrono se testato prima, con RST nella lista di sensibilità (if rst='1' then ... elsif rising_edge(clk)). Registri a n bit con generic, registri a scorrimento (con load), contatori (up/down, con enable) si ottengono con la stessa struttura. In un progetto sincrono tutti i registri usano lo stesso clock (nessun clock generato da logica: si usano abilitazioni), i segnali esterni asincroni come i pulsanti si campionano con uno o più flip-flop (debouncing) e le cifre di un display si multiplexano con un contatore.VHDL - logica sequenziale e registri →). Gli stati si codificano con ⌈log⁡2n⌉\lceil\log_2n\rceil bit (codifica binaria), con un solo bit a 11 (one-hot: nn flip-flop ma logica semplice e veloce, la scelta tipica nelle FPGA) o in Gray; in VHDL si usa un tipo enumerato e il sintetizzatore sceglie la codifica.

Struttura VHDL a due processi

vhdl
architecture RTL of FSM1 is
  type STATE_T is (idle, counting);
  signal state_reg, state_next : STATE_T;
begin
  -- processo sequenziale: registro di stato, reset asincrono
  process (RST, CLK)
  begin
    if RST = '1' then
      state_reg <= idle;
    elsif rising_edge(CLK) then
      state_reg <= state_next;
    end if;
  end process;

  -- processo combinatorio: funzione di stato prossimo e di uscita
  process (state_reg, START)
  begin
    state_next <= state_reg;               -- valore di default: resta nello stato
    case state_reg is
      when idle =>
        CHECK <= '0';
        if START = '1' then state_next <= counting; end if;
      when counting =>
        CHECK <= '1';
        if START = '0' then state_next <= idle; end if;
    end case;
  end process;
end RTL;

Questa è una macchina di Moore a doppio processo: CHECK è assegnata nei rami del case come funzione del solo state_reg (in idle vale '0', in counting vale '1'; la dipendenza da START riguarda solo state_next). Se CHECK dipendesse anche da START sarebbe di Mealy. Il valore di default state_next <= state_reg; evita di inferire un latch (e rende il codice più compatto). Il processo sequenziale ha la lista di sensibilità (RST, CLK) perché il reset è asincrono; la parte combinatoria ha tutti i segnali letti (state_reg, START).

Il comportamento dell'esempio, per START =0,1,1,0,0,1,1=0,1,1,0,0,1,1 (un valore per ciclo, stato letto prima del fronte):

ciclo START state_reg CHECK stato prossimo
0 0 idle 0 idle
1 1 idle 0 counting
2 1 counting 1 counting
3 0 counting 1 idle
4 0 idle 0 idle
5 1 idle 0 counting
6 1 counting 1 counting

L'uscita (Moore) segue START con un periodo di ritardo, perché passa attraverso il registro di stato.

Stile a processo singolo: un solo processo sequenziale con case e rising_edge(CLK) in cui anche le uscite sono registrate (assegnate al fronte): l'uscita è sincrona e priva di glitch ma in ritardo di un ciclo in più.

Progettazione: dal diagramma al codice

  1. Specifiche →\to diagramma degli stati (nodi: stati; archi: condizioni sugli ingressi; uscite nei nodi o sugli archi).
  2. Tabella di transizione: per ogni stato presente e ingresso, stato prossimo e uscita.
  3. Codice VHDL: tipo enumerato, processo di registro, processo combinatorio.
  4. Verifica con testbench (Simulazione, testbench, vincoli di temporizzazione e flusso su FPGAUn progetto VHDL si verifica per simulazione con un testbench: una entity senza porte che istanzia il circuito sotto test (UUT), genera il clock (process con wait for e inversione), applica gli stimoli e controlla le uscite con assert/report/severity (note, warning, error, failure) o leggendo vettori da file (textio). Il flusso su FPGA è: descrizione VHDL, simulazione funzionale, sintesi (rete di LUT e flip-flop), implementazione (piazzamento e instradamento), analisi di temporizzazione, generazione del bitstream e programmazione della scheda. I vincoli (file XDC) assegnano i pin e definiscono il clock (periodo); l'analisi di temporizzazione verifica per ogni cammino registro-registro lo slack di setup, T − (t_c-q + t_logica + t_routing + t_su), e di hold; con slack negativo la frequenza è troppo alta: f_max = 1/(T − WNS).Simulazione, testbench, vincoli di temporizzazione e flusso su FPGA →).

Esempio (Mealy, dalle slide). Quattro stati A,B,C,DA,B,C,D, ingresso xx, uscita yy:

stato x=0x=0 x=1x=1
A A / 0 B / 0
B A / 0 C / 0
C D / 0 C / 0
D A / 0 A / 1

(formato: stato prossimo / uscita). Si arriva in DD solo dopo almeno due 11 consecutivi seguiti da uno 00; l'uscita è 11 solo se in DD arriva un 11: la macchina riconosce la sequenza "due o più 11, uno 00, un 11". Con x=1,1,0,1,0,1,1,1,0,1,1,0,0,1x=1,1,0,1,0,1,1,1,0,1,1,0,0,1 gli stati attraversati sono A,B,C,D,A,A,B,C,C,D,A,B,A,A,BA,B,C,D,A,A,B,C,C,D,A,B,A,A,B e l'uscita y=0,0,0,1,0,0,0,0,0,1,0,0,0,0y=0,0,0,1,0,0,0,0,0,1,0,0,0,0: riconosce due volte la sequenza (in corrispondenza del quarto e del decimo ingresso). Il codice VHDL ha il processo P1P1 (combinatorio: case STATO_PRES, if FSM_IN = '0' ..., che assegna STATO_FUT e Y) e il processo P2P2 (registri). Poiché Y dipende da FSM_IN, è una macchina di Mealy.

Altre macchine tipiche dei laboratori

  • Contatore come FSM con 2N2^N stati (stato prossimo == stato +1+1).
  • Controllore del display a 88 cifre: il contatore di scansione fa da stato.
  • Interfaccia di comunicazione (I2C del sensore di temperatura del laboratorio): FSM con stati di start, invio indirizzo, lettura bit, stop; si parte dal diagramma e si implementa con il tipo enumerato.

Errori comuni

  • Non assegnare state_next in tutti i rami (latch inferito): si usa il valore di default.
  • Chiamare Moore una macchina la cui uscita dipende dall'ingresso (sarebbe Mealy).
  • Dimenticare lo stato di reset (le FSM devono partire da uno stato noto).
  • Mettere nel processo combinatorio solo lo stato nella lista di sensibilità e non gli ingressi.
  • Usare un tipo enumerato in uno stato non raggiunto: stati inutilizzati con codifica binaria possono "bloccare" la macchina (rimedio: when others => state_next <= idle;).

Versione ripasso

  • Modelli: S(k+1)=F(S,X)S(k+1)=F(S,X); Moore Y=G(S)Y=G(S) (cambia solo al fronte, uscita nello stato); Mealy Y=G(S,X)Y=G(S,X) (cambia con l'ingresso, uscita sull'arco, meno stati).
  • Codifica: binaria, one-hot (tipica nelle FPGA), Gray; in VHDL tipo enumerato.
  • Due processi: sequenziale (RST asincrono: state_reg<=idle; rising_edge: state_reg<=state_next) + combinatorio (state_next<=state_reg; default; case state_reg, uscite). Esempio idle/counting: CHECK funzione del solo stato ⇒\Rightarrow Moore a doppio processo; uscita in ritardo di un ciclo su START.
  • Processo singolo: uscite registrate, glitch-free, un ciclo in più.
  • Progetto: diagramma →\to tabella →\to codice →\to testbench. Esempio Mealy (A,B,C,DA,B,C,D): riconosce "≥2\ge2 uni, uno zero, un uno" (uscite agli ingressi 44 e 1010 di 1,1,0,1,0,1,1,1,0,1,1,0,0,11,1,0,1,0,1,1,1,0,1,1,0,0,1).
  • Errori: state_next non assegnata; Moore vs Mealy; reset mancante; sensibilità incompleta; stati inutilizzati.

Esercizi su questo argomento

Teoria collegata