VHDL - latch, flip-flop e reset sincrono e asincrono
In questa pagina 5
Qui si descrivono in VHDL gli elementi sequenziali di base visti in Elementi di memoria - latch SR, latch D e flip-flop DUn circuito sequenziale ha uscite che dipendono da ingressi e stato (memoria); è un circuito combinatorio con elementi di memoria in retroazione; stato presente = uscite dei FF, stato futuro = ingressi dei FF. Sincrono (clock) o asincrono. Latch SR (NOR): S=1,R=0 set; S=0,R=1 reset; 00 memoria; 11 proibito. Latch D: C=1 trasparente (Q=D), C=0 memoria, sensibile al livello. Flip-flop D edge-triggered = due latch D in cascata (master-slave) con clock opposti: cambia solo sul fronte attivo e non è trasparente. Si assume D flip-flop positive-edge-triggered.Elementi di memoria - latch SR, latch D e flip-flop D →. Si ricorda (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 →) che dentro un process le istruzioni sono sequenziali e che un segnale non assegnato in tutti i rami mantiene il valore: è proprio questa la memoria.
Latch SR con enable
Dataflow, con le porte NAND (ingressi attivi alti e controllo ):
library IEEE;
use IEEE.std_logic_1164.all;
entity SRlatch is
port ( S, R, C : in std_logic;
Q, Q_n : out std_logic );
end SRlatch;
architecture dataflow of SRlatch is
signal S_n, R_n : std_logic;
begin
S_n <= S nand C;
R_n <= R nand C;
Q <= S_n nand Q_n;
Q_n <= R_n nand Q; -- retroazione: Q e Q_n si pilotano a vicenda
end dataflow;La retroazione è nel codice: le due uscite compaiono anche a destra delle assegnazioni. Leggere una porta di modo out è consentito da VHDL-2008; nelle versioni precedenti si introducono dei segnali interni che poi si assegnano alle uscite.
Behavioral, con un case sulla coppia (condizione come abilitazione, nessun else):
architecture behavioral of SRlatch is
signal SR : std_logic_vector(1 downto 0);
begin
SR <= S & R;
process (SR, C)
begin
if C = '1' then
case SR is
when "00" => null; -- memoria: nessuna assegnazione
when "01" => Q <= '0'; Q_n <= '1'; -- reset
when "10" => Q <= '1'; Q_n <= '0'; -- set
when "11" => Q <= '1'; Q_n <= '1'; -- proibito
when others => Q <= 'X'; Q_n <= 'X';
end case;
end if; -- C = '0': nessuna assegnazione, memoria
end process;
end behavioral;Lo null e l'if senza else fanno non assegnare le uscite: restano al valore precedente, cioè il latch conserva lo stato.
Latch D
entity Dlatch is
port ( D, C : in std_logic;
Q, Q_n : out std_logic );
end Dlatch;
architecture arch of Dlatch is
begin
process (D, C)
begin
if C = '1' then -- nessun else: per C = '0' le uscite mantengono il valore
Q <= D;
Q_n <= not D;
end if;
end process;
end arch;Proprietà (latch D in VHDL). La lista di sensibilità contiene sia sia : con ogni cambio di riattiva il process e si propaga all'uscita (trasparenza).
Esempio. process (D, C) begin if C = '1' then Q <= D; end if; end process; con C='1' e D='1' dà Q='1'; con C='0' Q conserva il valore.
Flip-flop D positive-edge-triggered
library IEEE;
use IEEE.std_logic_1164.all;
entity dff is
port ( CLK, D : in std_logic;
Q : out std_logic );
end dff;
architecture simple of dff is
begin
process (CLK)
begin
if CLK'event and CLK = '1' then -- fronte di salita
Q <= D;
end if;
end process;
end simple;Definizione (fronte di salita in VHDL).
CLK'eventè vero quandoCLKha appena cambiato valore;CLK'event and CLK = '1'identifica il fronte di salita (con'0'si avrebbe un flip-flop negative-edge-triggered). In VHDL moderno si scrive spessorising_edge(CLK)(equivalente a meno dei passaggi da valori non definiti). Il process è sensibile solo aCLK: non compare nella lista, perché un cambio di da solo non deve fare nulla.
Esempio. Se CLK passa da '0' a '1' con D='1', il process con CLK'event and CLK = '1' assegna Q <= '1'; con '0' il fronte attivo sarebbe quello di discesa.
Reset asincrono e reset sincrono
Definizione (reset asincrono). Reset asincrono (agisce subito, in qualunque istante, anche senza fronte di clock).
RSTè nella lista di sensibilità ed è testato per primo:architecture async_reset of dff is begin process (RST, CLK) begin if RST = '1' then -- ha priorità sul clock Q <= '0'; elsif CLK'event and CLK = '1' then Q <= D; end if; end process; end async_reset;
Esempio. Con RST='1' il process si attiva subito e Q va a '0' anche senza fronte di clock.
(con RST aggiunto alla entity: port (CLK, RST, D : in std_logic; Q : out std_logic)).
Definizione (reset sincrono). Reset sincrono (sincronizzato con il clock: ha effetto solo sul fronte attivo; richiede un fronte di clock per essere efficace). La lista contiene solo
CLKeRSTè testato dentro il ramo del fronte:architecture sync_reset of dff is begin process (CLK) begin if CLK'event and CLK = '1' then if RST = '1' then Q <= '0'; else Q <= D; end if; end if; end process; end sync_reset;
Esempio. Con RST='1' tra due fronti di clock Q non cambia; al fronte successivo Q diventa '0'.
Come riconoscerli leggendo il codice (quiz frequente):
| codice | circuito |
|---|---|
process(CLK) + if (CLK'event and CLK='1') + dentro if (RST='1') |
FF positive-edge, reset sincrono |
process(RST, CLK) + if RST='1' ... elsif (CLK'event and CLK='1') |
FF positive-edge, reset asincrono |
CLK'event and CLK='0' |
negative-edge |
RST = '0' per resettare |
reset attivo basso |
nessun RST, solo if C='1' then Q<=D; |
latch D |
Un caso da leggere con attenzione: process(CLK) ... if (CLK'event and CLK='0') then if (RST='1') then Q<='0'; else Q<=D; è un FF negative-edge con reset sincrono attivo alto (non basso: RST='1' resetta).
Load enable
Proprietà (flip-flop con load enable). Per un flip-flop che aggiorna lo stato solo quando richiesto si aggiunge una condizione senza
else:if CLK'event and CLK = '1' then if load = '1' then Q <= D; end if; -- se load = '0' Q conserva il valore end if;
Esempio. Con load='0' al fronte di salita Q conserva il valore; con load='1' e D='1' Q diventa '1'.
È la forma "a load enable" del registro, preferibile alla gestione del clock (Registri e microoperazioniUn registro a $n$ bit è formato da $n$ flip-flop (più porte) con clock comune; il caricamento si controlla con clock gating (OR con il clock: risparmia potenza ma introduce ritardi e clock skew) oppure, meglio, con load enable (MUX + D FF: $Q\leftarrow D$ se EN=1, $Q\leftarrow Q$ altrimenti). Un sistema digitale complesso si divide in datapath (registri e blocchi aritmetico-logici) e unità di controllo (FSM che invia i segnali di controllo e riceve i segnali di stato). Le microoperazioni, scritte in RTL (es. $K_1:R_2\leftarrow R_1$), sono di trasferimento, aritmetiche, logiche (con maschere: AND azzera, OR pone a 1, XOR complementa) e di scorrimento.Registri e microoperazioni →).
Testbench di un circuito sincrono
Si simula applicando il clock e ingressi opportunamente sfasati. Regole (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 →): cambiare gli ingressi lontano dal fronte attivo (per esempio sul fronte di discesa nel caso PET) e leggere le uscite quando sono stabili. Si usano due process in parallelo:
- il generatore del clock (non si ferma mai: ricomincia da capo quando finisce);
- il process che applica gli ingressi (incluso il reset), che alla fine termina la simulazione con
std.env.stop;(VHDL-2008) o con un semplicewait;.
library IEEE;
use IEEE.std_logic_1164.all;
entity test_dff is
end test_dff;
architecture test of test_dff is
signal clk, rst, input, output : std_logic;
begin
DUT : entity work.dff(async_reset) port map (CLK => clk, RST => rst, D => input, Q => output);
generate_clock : process
begin
clk <= '1'; wait for 5 ns; -- semiperiodo alto
clk <= '0'; wait for 5 ns; -- semiperiodo basso: periodo 10 ns
end process;
apply_inputs : process
begin
rst <= '0'; input <= '0';
wait for 15 ns;
input <= '1';
wait for 10 ns;
rst <= '1';
wait for 20 ns;
rst <= '0';
wait for 10 ns;
input <= '0';
wait for 10 ns;
input <= '1';
std.env.stop;
end process;
end test;Fronti di salita del clock a ns. Con il reset asincrono l'uscita evolve così:
| istante (ns) | 0 | 20 | 25 | 50 | 60 |
|---|---|---|---|---|---|
| evento | fronte, | fronte, | fronte, | fronte, | |
| dopo l'evento | 0 | 1 | 0 (subito, senza fronte) | 1 | 0 |
(Tra e ns i fronti trovano e resta a 0.) Con il reset sincrono e gli stessi stimoli, ma con da a ns: a partire da ns; a ns non succede niente ( è salito ma non c'è fronte); al fronte di ns ; al fronte di ns (, ) . Differenza visibile: l'asincrono azzera a ns, il sincrono a ns.
Errori comuni
RSTfuori dalla lista di sensibilità in un reset asincrono (non reagisce al reset da solo).- Reset asincrono scritto dentro il ramo del clock: diventa sincrono.
process (CLK, D)per un flip-flop: se non si usa il fronte è un latch.if ... thensenzaelsein un process combinatorio: memoria involontaria.- Cambiare gli ingressi del testbench sullo stesso istante del fronte di salita (violazioni di setup/hold).
Versione ripasso
- Memoria in VHDL: un segnale non assegnato in tutti i rami di un process mantiene il valore precedente; è così che si descrive un elemento di memoria (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 →).
- Latch SR con enable: in dataflow, , , , (retroazione). In behavioral un
casesulla coppia dentroif C='1': connull(memoria), reset, set, proibito. - Latch D:
process (D, C) begin if C='1' then Q <= D; Q_n <= not D; end if; end process;. La lista contiene e : con l'uscita segue (trasparenza); con conserva il valore. - Flip-flop D positive-edge-triggered:
process (CLK) begin if CLK'event and CLK='1' then Q <= D; end if; end process;. Il process è sensibile solo aCLK, perché un cambio di da solo non deve fare nulla. Con'0'si ottiene il negative-edge;rising_edge(CLK)è la forma moderna. - Reset asincrono:
RSTnella lista di sensibilità e testato per primo:if RST='1' then Q<='0'; elsif CLK'event and CLK='1' then Q<=D; end if;. Agisce anche senza fronte di clock. - Reset sincrono: lista con il solo
CLK;RSTè testato dentro il ramo del fronte, quindi ha effetto solo sul fronte di clock. - Riconoscimento dal codice:
RSTnella lista significa reset asincrono;RSTsolo dentro il ramo del fronte significa sincrono;CLK'event and CLK='0'significa negative-edge;RST='0'per resettare significa reset attivo basso; unif C='1' then Q<=D;senza fronte e senzaelseè un latch;if load='1'dentro il ramo del fronte, senzaelse, è un load enable. - Testbench di un circuito sincrono: un process genera il clock (
clk <= '1'; wait for 5 ns; clk <= '0'; wait for 5 ns;, periodo 10 ns); un altro applica gli ingressi e il reset, lontano dal fronte attivo, e termina constd.env.stop;. Esempio: con il reset asincrono va a 0 a 25 ns, senza fronte; con il reset sincrono va a 0 solo al fronte di 30 ns (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 →). - Load enable: il registro con load enable carica solo sul fronte con
load='1'; conload='0'il valore è conservato (Registri e microoperazioniUn registro a $n$ bit è formato da $n$ flip-flop (più porte) con clock comune; il caricamento si controlla con clock gating (OR con il clock: risparmia potenza ma introduce ritardi e clock skew) oppure, meglio, con load enable (MUX + D FF: $Q\leftarrow D$ se EN=1, $Q\leftarrow Q$ altrimenti). Un sistema digitale complesso si divide in datapath (registri e blocchi aritmetico-logici) e unità di controllo (FSM che invia i segnali di controllo e riceve i segnali di stato). Le microoperazioni, scritte in RTL (es. $K_1:R_2\leftarrow R_1$), sono di trasferimento, aritmetiche, logiche (con maschere: AND azzera, OR pone a 1, XOR complementa) e di scorrimento.Registri e microoperazioni →). - Errori:
RSTnon nella lista di sensibilità nel reset asincrono; reset asincrono scritto dentro il ramo del clock (diventa sincrono);process (CLK, D)per un flip-flop (diventa un latch); ingressi del testbench cambiati sul fronte di salita; reset attivo basso letto come attivo alto.
Esercizi su questo argomento
- Esercizio 3 · descrizione VHDL di una macchina a stati con ingressi x e y e testbench (tema d'esame giugno 2022)
- Esercizio 6 · descrizione VHDL di una macchina di Moore con uscita a due bit (tema d'esame luglio 2022)
- Esercizio 9 · descrizione VHDL con ingresso a due bit x1x0 (tema d'esame settembre 2022)
- Esercizio 12 · descrizione VHDL di una macchina di Mealy con ingressi a e b e testbench (tema d'esame febbraio 2023)
- Esercizio 15 · descrizione VHDL behavioral di una macchina a tre stati e testbench (tema d'esame settembre 2025)
- Esercizio 23 · quiz su VHDL, assegnazioni, process e flip-flop (temi d'esame 2022-2026)
- Esercizio 25 · trovare gli errori in una descrizione VHDL di una macchina a stati (esercizio sul modello del tema d'esame giugno 2026)