Datapath e unità di controllo - un sistema digitale non programmabile
In questa pagina 4
Si mettono insieme i blocchi visti (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 →, Registri a scorrimento e contatoriPiù sorgenti per un registro di destinazione si gestiscono con un MUX che sceglie la sorgente (e un encoder se i segnali di controllo sono 1-hot) più il Load. Lo shift register è una catena di FF con uscita di ognuno collegata all'ingresso del successivo: ingresso e uscita seriali, caricamento parallelo (Shift ha priorità su Load), versione bidirezionale con un MUX 4-to-1 per stadio (S1S0: 00 hold, 01 shift left, 10 shift right, 11 load). Usi: conversione serie/parallelo, interfacce, linee di ritardo, generatori pseudo-casuali. Contatori: ripple (asincrono, il clock di ogni FF è l'uscita del precedente, ritardo crescente) e sincrono (stesso clock, più veloce; EN e CO per la cascata).Registri a scorrimento e contatori →, Sommatori binari - half adder, full adder e ripple carryHalf adder (2 ingressi): $S=X\oplus Y$, $C=XY$. Full adder (3 ingressi, con riporto in ingresso $Z$): $S=X\oplus Y\oplus Z$, $C=XY+XZ+YZ=G+PZ$ con $P=X\oplus Y$, $G=XY$; si realizza con due half adder e una OR. Il ripple carry adder a $n$ bit concatena $n$ full adder: il riporto "ondeggia" dal LSB al MSB, quindi il ritardo cresce linearmente con $n$. È un circuito iterativo (gerarchico e regolare). Il moltiplicatore a 2 bit usa 4 AND e 2 half adder.Sommatori binari - half adder, full adder e ripple carry →, Multiplexer e funzioni logiche realizzate con decoder e multiplexerIl multiplexer (MUX) $2^n$-to-1 ha $2^n$ ingressi dati, $n$ ingressi di selezione e un'uscita che copia l'ingresso selezionato: $Y=\sum_i m_i(S),I_i$. Si realizza con decoder + AND di enable + OR (costo 22 per il 4-to-1) o direttamente (costo 18). Un MUX $2^n$-to-1 realizza qualunque funzione di $n$ variabili (ingressi dati = colonna della tabella di verità); con un MUX $2^{n-1}$-to-1 si usano le $n-1$ variabili come selezione e gli ingressi dati valgono $0$, $1$, $X$ o $\overline X$ (l'ultima variabile). I MUX a vettori selezionano gruppi di bit.Multiplexer e funzioni logiche realizzate con decoder e multiplexer →) in due esempi di progetto: una cella di registro e un sistema digitale completo diviso in datapath e unità di controllo.
Cella di registro
Una cella di registro è un flip-flop corredato di logica combinatoria per svolgere microoperazioni sul contenuto del registro. Un registro a bit si realizza con copie della cella; se le microoperazioni vanno eseguite su più bit, parte della logica può essere condivisa tra le celle (shared logic).
Esempio. Registro che realizza tre microoperazioni logiche con il dato ( bit), ciascuna attivata da un segnale di controllo: Si assume che al massimo uno dei tre segnali valga 1; se valgono tutti 0 il registro resta invariato (hold). A ogni fronte attivo il contenuto di è sovrascritto con il risultato; le operazioni sono bitwise, quindi basta progettare un bit.
Metodo. Il registro è una macchina a stati finiti: ingressi di controllo , ingresso dati , stato presente , stato futuro il valore da sovrascrivere (Sintesi delle reti sequenziali - riconoscitore di sequenza e codifica degli statiSintesi di una rete sequenziale sincrona: specifiche $\to$ diagramma degli stati $\to$ tabella (riduzione degli stati equivalenti) $\to$ codifica binaria degli stati $\to$ scelta del FF (D PET) $\to$ equazioni di ingresso dei FF e delle uscite $\to$ minimizzazione $\to$ circuito e verifica. Lo stato riassume la parte di storia utile; per i riconoscitori si ha uno stato per ogni prefisso riconosciuto, riusando gli stati (sovrapposizioni). Reset: stato iniziale noto. Codifica Gray (numero minimo di FF) vs 1-hot (un FF per stato, logica più semplice): per il riconoscitore 1101 Gray costa circa la metà.Sintesi delle reti sequenziali - riconoscitore di sequenza e codifica degli stati →). Con FF D, coincide con lo stato futuro. Si fa la tabella per le combinazioni di e dei controlli:
| nessuno (hold) | ||||
|---|---|---|---|---|
| 00 | 0 | 0 | 0 | 0 |
| 01 | 0 | 1 | 1 | 0 |
| 10 | 0 | 1 | 1 | 1 |
| 11 | 1 | 0 | 1 | 1 |
Per ogni mintermine dei dati (, , ; il caso dà sempre 0) l'uscita è la somma dei segnali di controllo per i quali il bit vale 1. Con (hold): È utile scrivere l'equazione con due letterali per prodotto sui dati: i coefficienti dipendono solo dai segnali di controllo e sono uguali per tutti i bit, quindi si realizzano una sola volta e si condividono tra le celle; solo la parte con è specifica del bit. Semplificando con l'ipotesi "al massimo uno attivo" si trova , , . Controllo: per ogni combinazione e per i quattro casi di controllo (AND, EXOR, OR, nessuno) coincide con il risultato atteso.
Sistemi programmabili e non programmabili
- In un sistema programmabile gli ingressi della unità di controllo portano un flusso di istruzioni (un programma). Ogni istruzione attiva una sequenza di microoperazioni nel datapath e specifica quali, con quali dati e dove memorizzare i risultati. Il programma sta in una memoria (RAM o ROM) e la unità di controllo contiene un registro, il program counter (PC), che indica l'indirizzo dell'istruzione da prelevare nel ciclo successivo. Esempio: la CPU (Un semplice microprocessore - datapath, ALU e register fileUn calcolatore semplificato ma completo ha datapath, unità di controllo e memoria. Il datapath contiene un register file ($2^m$ registri da $n$ bit, due porte di lettura A e B e una di scrittura), un MUX B (registro o costante), una unità funzionale = ALU + shifter e un MUX D (risultato o dato dalla memoria); segnala V, C, N, Z. La ALU unisce un circuito aritmetico (sommatore con logica di ingresso per $B$: $0$, $B$, $\overline B$, tutti 1, più $C_{in}$) e uno logico (AND, OR, XOR, NOT) tramite un MUX. Le 15 microoperazioni si scelgono con un codice FS a 4 bit; la control word del datapath è di 16 bit (DA, AA, BA, MB, FS, MD, RW).Un semplice microprocessore - datapath, ALU e register file →).
- In un sistema non programmabile la unità di controllo non esegue istruzioni: determina le microoperazioni solo in base ai segnali di ingresso e ai segnali di stato del datapath. Svolge un unico compito; è una macchina a stati in cui aggiornamento dello stato e calcolo delle uscite sono realizzati con logica fissa (come i chip degli orologi digitali).
Esempio: somma di cinque valori
Specifiche. Un sistema digitale sincrono (ingressi start, res, a a bit; uscite z, busy, clock):
- accetta una sequenza di numeri interi e produce una sequenza ;
- all'asserzione del segnale
start(sincrono) somma i successivi cinque valori di ; - al termine della somma l'uscita si aggiorna al valore della somma;
- poi il sistema entra in attesa fino a una nuova asserzione di
start; durante una somma eventuali nuove asserzioni distartsono ignorate; busydurante la somma, in attesa;resazzera subito l'uscita e reinizializza (in modo sincrono) il sistema.
Partizione. Si divide in datapath, che esegue le somme, e unità di controllo, che gestisce la sequenza. Il datapath si divide in due sottoblocchi: uno che accumula i numeri, uno che li conta.
Datapath, sottoblocco 1: accumulo
Un sommatore e due registri dotati di load e clear:
ACC_REG: memorizza il valore intermedio della somma; conacc_load=1al fronte di clock si aggiorna con la somma precedente più il nuovo ingresso: ; conacc_clear=1si azzera;OUT_REG: memorizza il risultato finale, mandato in uscita ; conout_load=1al fronte: .
Una microoperazione (op) è un insieme di operazioni elementari su più segnali per realizzare una certa azione: ogni op è una combinazione dei segnali di controllo.
acc_load |
acc_clear |
out_load |
op |
|---|---|---|---|
| 0 | 0 | 0 | op_acc_idle |
| 0 | 1 | 0 | op_acc_clr |
| 1 | 0 | 0 | op_acc_acc |
| 0 | 0 | 1 | op_acc_upd_out |
Il segnale out_clear non compare in tabella perché è collegato direttamente all'ingresso res.
Datapath, sottoblocco 2: conteggio
Un registro CNT_REG (con load e clear) tiene il conteggio corrente; un sommatore lo decrementa di 1 (); un multiplexer sceglie tra il conteggio decrementato e il valore iniziale NCOUNT (cnt_reload); un comparatore con 0 produce il segnale zero, che è un segnale di stato (uscita del datapath, ingresso della unità di controllo).
cnt_load |
cnt_clear |
cnt_reload |
op |
|---|---|---|---|
| 0 | 0 | 0 | op_cnt_idle |
| 1 | 0 | 0 | op_cnt_cnt (decrementa) |
| 1 | 0 | 1 | op_cnt_reload (ricarica 5) |
Unità di controllo
La unità di controllo è una macchina a stati finiti i cui ingressi sono start e il segnale di stato zero, e le cui uscite sono i segnali di controllo e busy. Tre stati, macchina di Mealy (le uscite dipendono anche dagli ingressi). Sulle frecce: ingressi start, zero / uscite (microoperazioni, busy); x don't care.
| stato | start, zero |
op accumulo | op conteggio | busy |
stato futuro |
|---|---|---|---|---|---|
| ready | start=0 |
op_acc_idle |
op_cnt_idle |
0 | ready |
| ready | start=1 |
op_acc_acc |
op_cnt_cnt |
1 | acc |
| acc | zero=0 |
op_acc_acc |
op_cnt_cnt |
1 | acc |
| acc | zero=1 |
op_acc_upd_out |
op_cnt_idle |
1 | init |
| init | x | op_acc_clr |
op_cnt_reload |
1 | ready |
Il segnale res è collegato a out_clear e porta la macchina nello stato init, che azzera ACC_REG e ricarica il contatore a .
Come funziona (conta dei cinque valori). Dopo init, . Con start=1 nello stato ready si accumula già il primo valore () e si decrementa (). Nello stato acc con si accumulano (). Con (zero=1) un ciclo di op_acc_upd_out copia in e si passa a init, che azzera l'accumulatore e ricarica il contatore: si torna in ready.
Simulazione (res=1 nel ciclo 0; start=1 nei cicli 3 e 7, con nei cicli 3–7; il secondo start è ignorato perché il sistema è occupato):
| ciclo | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|
| stato | ready | acc | acc | acc | acc | acc | init | ready |
start |
1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| 3 | 1 | 4 | 1 | 5 | – | – | – | |
| (valore all'inizio del ciclo) | 5 | 4 | 3 | 2 | 1 | 0 | 0 | 5 |
zero |
0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
| 0 | 3 | 4 | 8 | 9 | 14 | 14 | 0 | |
| 0 | 0 | 0 | 0 | 0 | 0 | 14 | 14 | |
busy |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
(Per ogni ciclo si riportano i valori all'inizio del ciclo, cioè prima del fronte di clock.) La somma finale è e compare su dal ciclo 9; i sotto-totali di sono .
Descrizione VHDL
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity sum5 is
generic ( NCOUNT : integer := 5; W : integer := 8 );
port ( clk, res, start : in std_logic;
a : in std_logic_vector(W-1 downto 0);
z : out std_logic_vector(W-1 downto 0);
busy : out std_logic );
end sum5;
architecture beh of sum5 is
type state_type is (ready, acc, init);
signal state, next_state : state_type;
signal acc_load, acc_clear, out_load, cnt_load, cnt_reload : std_logic;
signal acc_reg, out_reg : unsigned(W-1 downto 0) := (others => '0');
signal cnt : integer range 0 to NCOUNT := 0;
signal zero : std_logic;
begin
zero <= '1' when cnt = 0 else '0';
z <= std_logic_vector(out_reg);
-- datapath: registri ACC_REG, OUT_REG, CNT_REG
datapath : process (clk)
begin
if clk'event and clk = '1' then
if res = '1' then out_reg <= (others => '0'); -- out_clear = res
elsif out_load = '1' then out_reg <= acc_reg; end if;
if acc_clear = '1' then acc_reg <= (others => '0');
elsif acc_load = '1' then acc_reg <= acc_reg + unsigned(a); end if;
if cnt_load = '1' then
if cnt_reload = '1' then cnt <= NCOUNT; else cnt <= cnt - 1; end if;
end if;
end if;
end process;
-- unità di controllo: registro di stato (res porta in init)
state_register : process (clk)
begin
if clk'event and clk = '1' then
if res = '1' then state <= init; else state <= next_state; end if;
end if;
end process;
-- unità di controllo: stato futuro e segnali di controllo (Mealy)
control : process (state, start, zero)
begin
acc_load <= '0'; acc_clear <= '0'; out_load <= '0';
cnt_load <= '0'; cnt_reload <= '0'; busy <= '0';
next_state <= state; -- default: resta nello stato
case state is
when ready =>
if start = '1' then
acc_load <= '1'; cnt_load <= '1'; busy <= '1'; next_state <= acc;
end if;
when acc =>
busy <= '1';
if zero = '0' then
acc_load <= '1'; cnt_load <= '1';
else
out_load <= '1'; next_state <= init;
end if;
when init =>
acc_clear <= '1'; cnt_load <= '1'; cnt_reload <= '1'; busy <= '1'; next_state <= ready;
end case;
end process;
end beh;I valori di default all'inizio del process di controllo evitano memoria involontaria: ogni uscita è assegnata in ogni percorso (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 comuni
- Confondere segnali di controllo (dalla unità di controllo al datapath) con segnali di stato (dal datapath alla unità di controllo, come
zero). - Dimenticare che il primo valore si accumula già nel ciclo di
start: i valori sono cinque, non sei. - Pensare che
startdurante la somma la riavvii: viene ignorato. - Non condividere la logica di controllo tra le celle di un registro.
- Confondere sistema programmabile (esegue un programma, ha il PC) e non programmabile (un solo compito).
Versione ripasso
- Cella di registro = FF + logica per le microoperazioni; registro = celle + logica condivisa. Esempio / / (al massimo un controllo; hold se nessuno): , , , .
- Programmabile (PC, istruzioni da memoria, CPU) vs non programmabile (CU solo da ingressi e segnali di stato; un compito).
- Somma di 5 valori:
start,res,az,busy. Datapath:ACC_REG(: ; clear),OUT_REG(: ),CNT_REG(decrementer, MUX conNCOUNT=5, comparatorezero). op:op_acc_idle/clr/acc/upd_out,op_cnt_idle/cnt/reload. - CU (Mealy, 3 stati): ready —
start→ acc (accumula , cnt 4); acc —zero=0→ acc; acc —zero=1→ init (upd_out); init → ready (acc_clr,cnt_reload).res→ init. Es. (Un semplice microprocessore - datapath, ALU e register fileUn calcolatore semplificato ma completo ha datapath, unità di controllo e memoria. Il datapath contiene un register file ($2^m$ registri da $n$ bit, due porte di lettura A e B e una di scrittura), un MUX B (registro o costante), una unità funzionale = ALU + shifter e un MUX D (risultato o dato dalla memoria); segnala V, C, N, Z. La ALU unisce un circuito aritmetico (sommatore con logica di ingresso per $B$: $0$, $B$, $\overline B$, tutti 1, più $C_{in}$) e uno logico (AND, OR, XOR, NOT) tramite un MUX. Le 15 microoperazioni si scelgono con un codice FS a 4 bit; la control word del datapath è di 16 bit (DA, AA, BA, MB, FS, MD, RW).Un semplice microprocessore - datapath, ALU e register file →). - Errori: controllo/stato scambiati; cinque valori (non sei);
startignorato se occupato.