Esercizio 3descrizione VHDL di una macchina a stati con ingressi x e y e testbench (tema d'esame giugno 2022)
In questa pagina 4
Testo (tema d'esame giugno 2022, primo appello, esercizio 3). 1) Descrivere in VHDL la macchina a stati finiti con ingressi e e uscita , avente il seguente diagramma degli stati. In tutti i casi non indicati, il sistema non cambia stato e l'uscita è 0. Separare nel codice gli elementi di memoria dalle parti puramente combinatorie. 2) Creare un test bench in VHDL che faccia attraversare tutti gli stati.
Diagramma (letto dalla figura del tema): stato iniziale (freccia con , );
- se and , con ;
- se and , con ;
- se , con ;
- se or , con ;
- senza condizione (l'arco non ha etichetta), con .
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 →, 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 →.
Passo 1: tipo di macchina e tabella
L'uscita è scritta sulle frecce ( sulle transizioni uscenti da ): dipende da stato e ingressi, è una macchina di Mealy. Si interpreta il tema così: l'arco da a non ha condizione ed è percorso al ciclo successivo; il reset () porta a da ogni stato. Tabella (stato futuro / ; ingressi ):
| stato | ||||
|---|---|---|---|---|
( se o : resta in solo con . non cambia stato per e .)
Passo 2: codice VHDL
Tre process: registro di stato con reset (asincrono), stato futuro, uscita. Il reset è specificato dal tema (), si usa quindi asincrono attivo alto.
library IEEE;
use IEEE.std_logic_1164.all;
entity fsm_xy is
port ( clk, rst : in std_logic;
x, y : in std_logic;
z : out std_logic );
end fsm_xy;
architecture beh of fsm_xy is
type state_type is (S0, S1, S2, S3);
signal state, next_state : state_type;
begin
-- elementi di memoria: registro di stato, 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;
-- parte combinatoria: stato futuro
next_state_comb : process (state, x, y)
begin
next_state <= state; -- casi non indicati: non cambia stato
case state is
when S0 =>
if x = '1' and y = '0' then
next_state <= S1;
elsif x = '0' and y = '1' then
next_state <= S3;
end if;
when S1 =>
if x = '1' then next_state <= S2; end if;
when S2 =>
next_state <= S0;
when S3 =>
if x = '0' or y = '1' then next_state <= S2; end if;
end case;
end process;
-- parte combinatoria: uscita (Mealy: dipende anche dagli ingressi)
output_comb : process (state, x, y)
begin
z <= '0'; -- valore di default
if state = S0 and ((x = '1' and y = '0') or (x = '0' and y = '1')) then
z <= '1';
end if;
end process;
end beh;L'assegnazione di default next_state <= state; (e z <= '0';) all'inizio dei process realizza la frase "in tutti i casi non indicati il sistema non cambia stato e l'uscita è 0" e impedisce memoria involontaria: ogni percorso assegna sempre i segnali.
Passo 3: testbench
Si devono percorrere tutti gli stati (e conviene anche tutte le transizioni). Sequenza di ingressi , un valore per ciclo, dopo il reset iniziale:
| ciclo | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| 10 | 00 | 10 | 00 | 01 | 10 | 00 | 11 | 11 | 00 | |
| stato presente | ||||||||||
| 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | |
| stato futuro |
Questa sequenza usa tutte e 8 le transizioni del diagramma: (ciclo 0), che resta (1), (2), (3), (4), che resta (5), (6), che resta (8, 9).
library IEEE;
use IEEE.std_logic_1164.all;
entity tb_fsm_xy is
end tb_fsm_xy;
architecture test of tb_fsm_xy is
signal clk, rst, x, y, z : std_logic;
constant PERIOD : time := 10 ns;
type vec_array is array (0 to 9) of std_logic_vector(1 downto 0);
constant tv : vec_array := ("10", "00", "10", "00", "01", "10", "00", "11", "11", "00");
begin
DUT : entity work.fsm_xy(beh) port map (clk, rst, x, y, z);
generate_clock : process
begin
clk <= '1'; wait for PERIOD/2;
clk <= '0'; wait for PERIOD/2;
end process;
apply_inputs : process
begin
rst <= '1'; x <= '0'; y <= '0';
wait for 3*PERIOD/2; -- reset iniziale, finisce sul fronte di discesa
rst <= '0';
for i in 0 to 9 loop
x <= tv(i)(1); -- primo bit del vettore = x
y <= tv(i)(0); -- secondo bit = y
wait for PERIOD; -- un vettore per ciclo di clock
end loop;
std.env.stop;
end process;
end test;Il clock sale a ns e scende a ; gli ingressi cambiano sui fronti di discesa (), lontano dal fronte di salita (Temporizzazione dei flip-flop - setup, hold e frequenza massima di clockUn flip-flop memorizza il dato corretto solo se l'ingresso è stabile per $t_s$ (setup) prima e $t_h$ (hold) dopo il fronte di clock; l'uscita cambia dopo il tempo di propagazione $t_{pd,FF}$ dal fronte. In un circuito sincrono il periodo deve soddisfare $T\ge t_{pd,FF}+t_{COMB}+t_{s,FF}+t_{slack}$, quindi $f_{max}=1/T_{min}$; abbassare la frequenza risolve le violazioni di setup. Il vincolo di hold $t_{pd,FF,min}+t_{COMB,min}\ge t_h$ non dipende dal clock (e non si risolve rallentandolo). Il clock skew modifica i vincoli.Temporizzazione dei flip-flop - setup, hold e frequenza massima di clock →). Con la sequenza della tabella vale nei cicli 0 e 4 (transizioni e ) e negli altri. Il comportamento atteso della tabella è stato confrontato con un modello della macchina.
Errori comuni
- Dimenticare lo stato (passaggio obbligato) o il suo ritorno non condizionato a .
- Mettere anche nelle transizioni verso .
- Non separare memoria e combinatoria (un solo process con tutto).
- Dimenticare i valori di default:
caseincompleti producono memoria involontaria.
Versione ripasso
- Testo. FSM di Mealy, ingressi , uscita : , , , , ; altrove resta e . VHDL con memoria separata e testbench che attraversa tutti gli stati.
- Codice:
type state_type is (S0,S1,S2,S3); process 1 (rst='1',clk'event and clk='1'state <= next_state); process 2 con defaultnext_state <= state;ecase; process 3:z <= '0'; if state=S0 and (...) then z <= '1';. - Testbench: clock ns, reset periodi, ingressi
tv = "10","00","10","00","01","10","00","11","11","00"(tutte le 8 transizioni),std.env.stop; ai cicli 0 e 4 (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: dimenticato; sulle frecce sbagliate; memoria e combinatoria mescolate.