Salta al contenuto
Note per Studenti Datapath e unità di controllo - un sistema digitale non programmabile

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 nn bit si realizza con nn copie della cella; se le microoperazioni vanno eseguite su più bit, parte della logica può essere condivisa tra le celle (shared logic).

Esempio. Registro AA che realizza tre microoperazioni logiche con il dato BB (nn bit), ciascuna attivata da un segnale di controllo: AND: A←A∧B,EXOR: A←A⊕B,OR: A←A∨B.AND:\ A\leftarrow A\wedge B,\qquad EXOR:\ A\leftarrow A\oplus B,\qquad OR:\ A\leftarrow A\vee B . 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 AA è sovrascritto con il risultato; le operazioni sono bitwise, quindi basta progettare un bit.

Metodo. Il registro è una macchina a stati finiti: ingressi di controllo AND,EXOR,ORAND,EXOR,OR, ingresso dati BiB_i, stato presente AiA_i, 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, DiD_i coincide con lo stato futuro. Si fa la tabella per le combinazioni di (Ai,Bi)(A_i,B_i) e dei controlli:

AiBiA_i B_i ANDAND EXOREXOR OROR 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 (Ai‾Bi\overline{A_i}B_i, AiBi‾A_i\overline{B_i}, AiBiA_iB_i; il caso 0000 dà sempre 0) l'uscita è la somma dei segnali di controllo per i quali il bit vale 1. Con H=AND‾ EXOR‾ OR‾H=\overline{AND}\ \overline{EXOR}\ \overline{OR} (hold): Di=Ai‾Bi C1+AiBi‾ C2+AiBi C3,C1=EXOR+OR, C2=EXOR+OR+H, C3=AND+OR+H.D_i=\overline{A_i}B_i\,C_1+A_i\overline{B_i}\,C_2+A_iB_i\,C_3,\quad C_1=EXOR+OR,\ C_2=EXOR+OR+H,\ C_3=AND+OR+H . È utile scrivere l'equazione con due letterali per prodotto sui dati: i coefficienti C1,C2,C3C_1,C_2,C_3 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 Ai,BiA_i,B_i è specifica del bit. Semplificando con l'ipotesi "al massimo uno attivo" si trova C1=EXOR+ORC_1=EXOR+OR, C2=EXOR+OR+AND‾C_2=EXOR+OR+\overline{AND}, C3=AND+OR+EXOR‾C_3=AND+OR+\overline{EXOR}. Controllo: per ogni combinazione (Ai,Bi)(A_i,B_i) e per i quattro casi di controllo (AND, EXOR, OR, nessuno) DiD_i coincide con il risultato atteso.

Sistemi programmabili e non programmabili

Esempio: somma di cinque valori

Specifiche. Un sistema digitale sincrono (ingressi start, res, a a WW bit; uscite z, busy, clock):

  • accetta una sequenza di numeri interi aa e produce una sequenza zz;
  • all'asserzione del segnale start (sincrono) somma i successivi cinque valori di aa;
  • al termine della somma l'uscita zz 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 di start sono ignorate;
  • busy =1=1 durante la somma, 00 in attesa;
  • res azzera 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; con acc_load=1 al fronte di clock si aggiorna con la somma precedente più il nuovo ingresso: ACC←ACC+aACC\leftarrow ACC+a; con acc_clear=1 si azzera;
  • OUT_REG: memorizza il risultato finale, mandato in uscita zz; con out_load=1 al fronte: OUT←ACCOUT\leftarrow ACC.

Una microoperazione (μ\muop) è un insieme di operazioni elementari su più segnali per realizzare una certa azione: ogni μ\muop è una combinazione dei segnali di controllo.

acc_load acc_clear out_load μ\muop
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 (+(−1)+(-1)); un multiplexer sceglie tra il conteggio decrementato e il valore iniziale NCOUNT =5=5 (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 μ\muop
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 μ\muop accumulo μ\muop 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 55.

Come funziona (conta dei cinque valori). Dopo init, cnt=5cnt=5. Con start=1 nello stato ready si accumula già il primo valore (ACC←a1ACC\leftarrow a_1) e si decrementa (cnt=4cnt=4). Nello stato acc con cnt≠0cnt\ne0 si accumulano a2,a3,a4,a5a_2,a_3,a_4,a_5 (cnt=3,2,1,0cnt=3,2,1,0). Con cnt=0cnt=0 (zero=1) un ciclo di op_acc_upd_out copia ACCACC in OUTOUT 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 a=3,1,4,1,5a=3,1,4,1,5 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
aa 3 1 4 1 5 – – –
cntcnt (valore all'inizio del ciclo) 5 4 3 2 1 0 0 5
zero 0 0 0 0 0 1 1 0
ACCACC 0 3 4 8 9 14 14 0
OUT=zOUT=z 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 è 3+1+4+1+5=143+1+4+1+5=14 e compare su zz dal ciclo 9; i sotto-totali di ACCACC sono 3,4,8,9,143,4,8,9,14.

Descrizione VHDL

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 start durante 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

Esercizi su questo argomento

Teoria collegata