• Non ci sono risultati.

Il VHDL non prevede un’istruzione del linguaggio che descriva semantica- mente un registro. Fisicamente, un progettista `e abituato a lavorare con componenti elettronici basilari come flip-flop o registri, ma in VHDL non esi- ste un componente con memoria primitivo. L’unica soluzione per realizzare componenti con memoria `e utilizzare un processo: grazie alla sequenzializ- zazione delle istruzioni e alla modalit`a di variazione dei segnali nel tempo (come esaminato in 3.1) `e possibile implementare un set di istruzioni che ne modelli il comportamento.

Un primo esempio di registro modellato in VHDL `e il flip-flop D, riportato nel seguente codice:

2.3.5 Registri 51 entity Dtype is port( d, ck : in bit; q : out bit ); end;

architecture behaviour of Dtype is begin process begin wait on ck until ck = ‘1’; q <= d; end process; end;

Il modello appena descritto, se simulato, ha un comportamento equivalente ad un registro edge-triggered (ossia ad un flip-flop). In realt`a, quella mostrata non `e l’unica forma in cui pu`o essere rappresentato un registro: esistono quattro differenti template, ovviamente basati su processi.

Basic template

E’ il template pi`u semplice, il suo corpo `e costituito da un processo con solo due istruzioni sequenziali:

process begin wait on ck until ck = ‘1’; q <= d; end process; Short template

Il secondo template opera esattamente come il primo, in simulazione, e si basa sul fatto che la clausola on pu`o essere omessa: in questo caso il com-

pilatore sottintende una clausola on contenente tutti i segnali utilizzati poi nella condizione until.

process begin wait until ck = ‘1’; q <= d; end process; IF statement template process begin wait on ck; if ck = ‘1’ then q <= d; end if; end process;

Questo template si basa sull’uso di una condizione IF..THEN. L’istruzione di wait non ha una clausola until come nei casi precedenti: ci`o significa che il processo sar`a attivato ad ogni evento sul segnale di clock, indipendentemente dal tipo di evento (in altre parole, sia sul fronte positivo, sia sul fronte nega- tivo). L’istruzione IF quindi agir`a da filtro, considerando solamente i fronti positivi del clock. Se il segnale clock `e basso, allora l’istruzione di assegna- mento non sar`a eseguita: il segnale q manterr`a il suo valore. Ci`o significa che il fronte negativo non ha effetto sulla variazione del valore dell’uscita, quindi il processo modella semanticamente un flip-flop. Si approfondir`a ulteriormente la semantica del mantenimento nella sezione 3.1.

Sensitivity-list template

Un processo pu`o avere una sensitivity list anzich`e una condizione di wait per specificare il set di segnali che causano l’attivazione del processo stesso. La forma di questo template `e data dal seguente codice:

2.3.5 Registri 53 process (ck) begin if ck = ‘1’ then q <= d; end if; end process;

In questo esempio, il processo rimane sospeso finch`e non avviene un evento su uno dei segnali della sensitivity list. Questo attiva il processo che esegue per una sola volta e quindi si sospende nuovamente. Anche in questo template, il processo `e attivato su entrambi i fronti del clock, ma la condizione IF interna filtra via i fronti negativi.

Il sensitivity-list template `e equivalente all’IF-statement template, ma con l’istruzione di wait spostata in fondo al processo. Ci`o significa che i due template sono equivalenti in sintesi, ma differenti nella simulazione. Questa differenza pu`o essere sfruttata in modo che le simulazioni si inzializzino cor- rettamente senza alcun impatto sul risultato della sintesi.

La regola generale `e che l’istruzione di wait possa essere posizionata ovunque nel processo, sebbene in generale sia posta o all’inizio o alla fine dello stesso. Alcuni sintetizzatori potrebbero non supportare tutte le possibili permuta- zioni, ma dovrebbero almeno supportare quelle ai due estremi.

I processi con l’istruzione di wait alla fine sono interamente eseguiti all’av- vio della simulazione (inizializzazione automatica), mentre i processi con il wait all’inizio non lo sono (e quindi l’inizializzazione al valore corretto delle variabili interne va fatta manualmente).

Registri a pi`u bit

E’ possibile modellare anche registri di pi`u bit, in maniera tale da campionare ad esempio il valore di un bus. La realizzazione di un registro ad 8 bit, ad esempio, `e mostrata dal seguente codice:

entity Dtype is port(

d : in signed(7 downto 0); ck : in bit;

q : out signed(7 downto 0) );

end;

architecture behaviour of Dtype is begin process begin wait on ck until ck = ‘1’; q <= d; end process; end;

Ma il modello non si limita solamente a campionare un segnale, qualsiasi numero di segnali pu`o essere gestito nello stesso processo:

process begin wait on Ck until Ck = ‘1’; q0 <= d0; q1 <= d1; q2 <= d2; end process; Gated Register

I modelli visti fino ad ora non prevedono un segnale che abiliti o disabiliti il campionamento, praticamente seguono l’ingresso ad ogni fronte positivo del clock eci`o non sempre `e utile. Per questa ragione `e necessario ampliare ulteriormente il modello, introducendo due modalit`a di controllo: clock gating e data gating.

2.3.5 Registri 55 Clock Gating

Questa modalit`a prevede di inserire un segnale di controllo che agisca sul clock ed eventualmente lo mascheri, affinch`e il registro non possa aggiornare il suo stato. Tuttavia questa `e una soluzione che non dovrebbe essere utilizzata, principalmente per due motivi. Il primo di essi `e che gli strumenti di testing automatico, in fase di sintesi, utilizzano tecniche di scanning circuitale che necessitano di poter pilotare tutti i segnali di clock presenti. Il secondo motivo `

e che gli algoritmi utilizzati nella sintesi logica per la minimizzazione non garantirebbero il funzionamento glitch-free della logica di pilotaggio.

Data Gating

Questa `e la soluzione pi`u sicura ed utilizzata per dotare un registro di un segnale di enable. Il data gating `e cos`ı chiamato perch`e si inserisce sull’input dei dati al registro e non sul clock, quindi il registro continua ad essere nor- malmente alimentato dal clock, che non viene mai fermato. Il funzionamento avviene fornendo, con un ramo in retroazione, all’ingresso dati del flip-flop il valore dell’uscita, quando il segnale di enable `e inattivo.

Il circuito in figura 2.14 utilizza un multiplexer per rendere possibile tale realizzazione; il codice VHDL che modella tale circuito `e il seguente:

entity Dtype is port( d, ck, en : in bit; q : out bit ); end;

architecture behaviour of Dtype is begin

process begin

wait on ck until ck = ‘1’; if en = ‘1’ then

q <= d; end if; end process; end;

Figura 2.14: Flip flop D con data gating

Nella simulazione, il valore di q `e mantenuto finch`e un nuovo valore non gli `e assegnato. In tal caso, l’assegnamento `e bypassato finch`e il segnale di enable `

e disattivato. Ci`o `e equivalente a riassegnare, al nuovo ingresso, il vecchio valore dell’uscita.

Reset

Ci sono due modalit`a per modellare un registro dotato di reset; un modo asincrono ed uno sincrono. E’importante fare una distinzione tra le due for- me ed utilizzare quella pi`u corretta alla circostanza.

Un reset asincrono scavalca il clock ed agisce immediatamente, modificando il valore del registro e quindi la sua uscita. Al contrario, i reset sincroni hanno effetto solo al fronte positivo del clock e devono quindi essere mantenuti fino al campionamento, per essere rilevati. I reset sincroni possono essere pilota- ti da qualsiasi segnale di controllo all’interno del circuito, quindi tutti quei dispositivi che possono essere resettati da segnali di controllo generati da un

2.3.5 Registri 57 circuito appartenente alla rete, dovrebbero essere dotati di reset sincrono. Il modello VHDL prevede che, anzich`e alimentare direttamente l’ingresso del registro con la sua uscita, sia fornito all’ingresso il valore di reset predefinito se il segnale di reset `e attivo. L’equivalente circuitale `e in fig.2.15, mentre il codice che lo rappresenta `e il seguente:

entity FFD is port( d, ck, res : in bit; q : out bit ); end; architecture behaviour of FFD is begin process begin wait until ck = ‘1’; if res = ‘1’ then q <= ‘0’; else q <= d; end if; end process; end;

Un segnale di reset asincrono dovrebbe essere sempre pilotato da un input primario, nell’ambito di un sistema asincrono, per poi essere reso sincrono al clock (similmente a quanto accade nei calcolatori). I segnali di reset interni al circuito dovrebbero essere sempre sincroni.

Ci sono due buone ragioni affinch`e componenti dotati di reset asincrono non vadano impegati in circuiti che genereranno segnali di reset sincroni: la prima ragione `e l’introduzione di comportamento asincrono in un circuito, per sua natura, sincrono. Ci`o renderebbe il circuito molto sensibile ai glitch che si

Figura 2.15: Flip flop con data gating e reset sincrono

verificherebbero nella logica di reset. La seconda motivazione `e i timing ana- lysers e i test automatici per la sintesi non possono pilotare correttamente reset asincroni sui componenti.

Un esempio di codice, in grado di modellare un registro con reset asincrono, ` e il seguente: entity FFD is port( d, ck, res : in bit; q : out bit ); end; architecture behaviour of FFD is begin process (ck, res) begin if res = ‘1’ then q <= ‘0’;

2.3.6 Driver 59