Esercizio 25trovare gli errori in una descrizione VHDL di una macchina a stati (esercizio sul modello del tema d'esame giugno 2026)
In questa pagina 5
Testo. Nel terzo esercizio del primo appello di giugno 2026 era dato un codice VHDL di una macchina a stati che conteneva un errore: bisognava trovarlo, riscrivere il codice corretto e disegnare il diagramma degli stati finale. Il testo originale non è disponibile (la foto del foglio manca), quindi qui si propone un esercizio costruito sullo stesso modello, con gli errori più tipici.
Si vuole un riconoscitore di due 1 consecutivi (con sovrapposizioni) di Mealy: ingresso x, uscita z che vale 1 quando l'ultimo bit ricevuto e il precedente sono entrambi 1; reset asincrono attivo alto (rst = '1' porta nello stato iniziale), D-FF positive edge triggered. Il codice seguente dovrebbe descriverlo, ma contiene tre errori.
library IEEE;
use IEEE.std_logic_1164.all;
entity det11 is
port ( clk, rst : in std_logic;
x : in std_logic;
z : out std_logic );
end det11;
architecture beh of det11 is
type state_type is (S0, S1);
signal state, next_state : state_type;
begin
reg : process (clk)
begin
if rst = '1' then
state <= S0;
elsif clk'event and clk = '1' then
state <= next_state;
end if;
end process;
comb : process (state)
begin
case state is
when S0 =>
if x = '1' then next_state <= S1; end if;
z <= '0';
when S1 =>
if x = '1' then next_state <= S1; z <= '1';
else next_state <= S0; z <= '0';
end if;
end case;
end process;
end beh;- Trovare e correggere gli errori. 2. Scrivere il codice corretto. 3. Disegnare (tabella) il diagramma degli stati della macchina e controllarlo con la sequenza di ingresso .
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 →, VHDL - istruzioni concorrenti, process e testbenchLe istruzioni concorrenti VHDL sono l'assegnazione di segnale, when-else (logica prioritaria, condizioni valutate in ordine) e with-select (logica parallela: tutti i casi coperti da una sola scelta, others obbligatorio). Un process è un'istruzione concorrente il cui corpo è sequenziale (if, case, loop); parte quando cambia un segnale della sensitivity list (per la logica combinatoria: tutti gli ingressi); i segnali si aggiornano alla sospensione e vince l'ultima assegnazione. Un if senza else (o un caso non coperto) crea memoria non voluta. Il testbench è codice di simulazione con entity vuota, DUT istanziato e un process di stimoli con wait.VHDL - istruzioni concorrenti, process e testbench →, Analisi delle reti sequenziali - tabella e diagramma degli stati, Mealy e MooreAnalizzare una rete sequenziale sincrona significa ricavare, dal circuito, le equazioni di ingresso dei flip-flop (stato futuro) e dell'uscita, la tabella degli stati ($2^{m+n}$ righe per $m$ FF e $n$ ingressi), il diagramma degli stati (cerchi = stati, frecce = transizioni con ingresso/uscita) e la simulazione temporale. Mealy: uscita funzione di stato e ingresso (scritta sulle frecce, può cambiare tra due fronti di clock); Moore: uscita funzione del solo stato (scritta nel cerchio, cambia solo al fronte). Due stati sono equivalenti se danno le stesse uscite e portano a stati equivalenti: si fondono per ridurre i FF.Analisi delle reti sequenziali - tabella e diagramma degli stati, Mealy e Moore →.
Metodo: cosa controllare in ordine
Per ogni process di una macchina a stati:
- Registro di stato: il reset è nella sensitivity list? Il suo test è fuori (asincrono) o dentro (sincrono) il ramo del fronte, come chiede il testo? Il fronte è quello richiesto?
- Logica combinatoria: la lista di sensibilità contiene tutti gli ingressi letti (stato e ingressi)? Ogni segnale (
next_stateez) è assegnato in ogni ramo, per ogni stato e per ogni valore degli ingressi? Un caso non coperto crea un latch. - Uscita: Moore (dipende solo dallo stato) o Mealy (anche dall'ingresso), come chiede il testo.
Gli errori
Errore 1: reset asincrono senza rst nella lista di sensibilità (process reg). Il test if rst = '1' è fuori dal controllo del fronte (giusto per un reset asincrono), ma il process si risveglia solo quando cambia clk: se rst sale a metà del periodo non succede nulla fino al successivo cambio di clk. Il reset non è asincrono in simulazione, e il comportamento descritto non corrisponde a quello sintetizzato. Correzione: process (clk, rst).
Errore 2: x manca dalla lista di sensibilità (process comb). Il process legge x ma si attiva solo se cambia state: se x cambia con lo stato fermo, next_state e z non vengono ricalcolati. In simulazione la macchina sbaglia; il sintetizzatore ignora la lista e crea una rete corretta, per cui simulazione e circuito divergono. Correzione: process (state, x).
Errore 3: next_state non assegnato nel caso S0 con x = '0' (if senza else). Per quel caso next_state conserva il valore precedente: il sintetizzatore inserisce un latch su next_state. Il valore conservato è quello dello stato futuro precedente: se era , la macchina passa in anche con . Correzione: aggiungere else next_state <= S0; (con da si resta in ).
Non sono errori: z <= '0' nel ramo S0 prima dell'if (ogni ramo assegna z); l'assenza di when others nel case perché il tipo enumerato ha solo i due stati S0 e S1, entrambi coperti; il reset a S0 con rst = '1' (attivo alto, come chiede il testo).
Codice corretto
library IEEE;
use IEEE.std_logic_1164.all;
entity det11 is
port ( clk, rst : in std_logic;
x : in std_logic;
z : out std_logic );
end det11;
architecture beh of det11 is
type state_type is (S0, S1);
signal state, next_state : state_type;
begin
-- D-FF positive edge triggered con reset asincrono attivo alto
reg : process (clk, rst)
begin
if rst = '1' then
state <= S0;
elsif clk'event and clk = '1' then
state <= next_state;
end if;
end process;
-- stato futuro e uscita di Mealy (dipende da stato e ingresso)
comb : process (state, x)
begin
case state is
when S0 =>
z <= '0';
if x = '1' then next_state <= S1;
else next_state <= S0;
end if;
when S1 =>
if x = '1' then next_state <= S1; z <= '1';
else next_state <= S0; z <= '0';
end if;
end case;
end process;
end beh;Diagramma degli stati
= "l'ultimo bit non è un (o nessun bit)", = "l'ultimo bit è un ". Le etichette sono :
| stato | ||
|---|---|---|
| (iniziale) | / | / |
| / | / |
Archi: , , , . Sono i due stati minimi: non si possono unire perché con danno uscite diverse.
Controllo con (partendo da ):
| bit | stato prima | uscita | stato dopo | |
|---|---|---|---|---|
| 1 | 0 | 0 | ||
| 2 | 1 | 0 | ||
| 3 | 1 | 1 | ||
| 4 | 0 | 0 | ||
| 5 | 1 | 0 | ||
| 6 | 1 | 1 | ||
| 7 | 1 | 1 |
Uscita : ai bit 3, 6, 7, cioè ogni volta che il bit corrente e il precedente sono (compreso il caso sovrapposto ).
Errori comuni
- Cercare un solo errore e fermarsi: il tema ne conteneva uno, ma conviene rileggere tutto il codice con la lista di controllo.
- Mettere
rstnella lista ma testarlo dentro il ramo del fronte: diventa un reset sincrono. - Dimenticare di ricavare il diagramma dal codice corretto (e non da quello errato).
- Completare con
when othersuncasesu un tipo enumerato già coperto: non serve (serve invece perstd_logic).
Versione ripasso
- Modello d'esame: codice VHDL con un errore da trovare, codice corretto e diagramma degli stati finale (giugno 2026, testo non disponibile).
- Lista di controllo: reset in lista e dentro/fuori dal fronte; lista di sensibilità con stato e ingressi; ogni segnale assegnato in ogni ramo; Moore o Mealy (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 →).
- Errori trovati: (1)
process (clk)con reset asincrono(clk, rst); (2)process (state)che leggex(state, x); (3)ifsenzaelsein latch sunext_state, serveelse next_state <= S0. - Diagramma: , , , ; su l'uscita è .
- Errori: fermarsi al primo errore; reset sincrono al posto dell'asincrono.