Un semplice microprocessore - datapath, ALU e register file
In questa pagina 4
Questa nota e la successiva (Un semplice microprocessore - istruzioni, ciclo singolo e cicli multipliIstruzioni a 16 bit: opcode (7 bit) + DR, SA, SB/OP (3 bit ciascuno) oppure formato di salto con offset a 6 bit (AD sinistro + AD destro, relativo al PC e con estensione di segno). Insieme di istruzioni load/store (solo LD e ST accedono ai dati): MOVA, INC, ADD, SUB, ..., LDI, ADI, LD, ST, BRZ, BRN, JMP. Nel computer a ciclo singolo (due memorie separate) il decoder combinatorio ricava MB, MD, RW, MW, PL, JB, BC dai bit 15, 14, 13, 9 dell'istruzione e $FS$ dai bit 12–9; il periodo di clock è la somma dei ritardi lungo il cammino peggiore (9,8 ns nell'esempio). Nel computer a cicli multipli (memoria unica) servono IR, registri interni R8–R15 e un decoder sequenziale: fetch (INF) + uno o più stati di esecuzione.Un semplice microprocessore - istruzioni, ciclo singolo e cicli multipli →) progettano un computer semplificato ma completamente funzionale, mettendo insieme blocchi già visti: registri, sommatori, multiplexer, decoder, memorie, macchine a stati. Per il quadro architetturale generale: Datapath e microarchitetturaMicroarchitettura come realizzazione dell'ISA; elementi del datapath (PC, memoria istruzioni e dati, banco dei registri, ALU, estensione del segno, multiplexer); percorso di un'istruzione aritmetica, di una load, di una store e di un salto; datapath a ciclo singolo e suo periodo di clock; datapath multiciclo.Datapath e microarchitettura →, Unità aritmetico-logica (ALU)Ruolo dell'ALU, ingressi, uscite e flag; ALU a 1 bit con AND, OR e sommatore selezionati da un multiplexer; estensione a 32 bit, sottrazione, confronto set-less-than e rilevazione dello zero e dell'overflow; tabella dei segnali di controllo; unità di moltiplicazione e virgola mobile.Unità aritmetico-logica (ALU) →, Struttura interna della CPU e registriComponenti interni della CPU (ALU, unità di controllo, banco dei registri, bus interno); registri visibili all'utente e registri di controllo e stato; flag e parola di stato (PSW) con bit di supervisore; quanti registri conviene avere; segmentazione della memoria.Struttura interna della CPU e registri →.
Un elaboratore è formato da:
- un datapath, capace di eseguire le operazioni usate negli algoritmi (somme, operazioni logiche, ecc.);
- una unità di controllo, che comanda il datapath in base al "programma";
- una memoria, che contiene programma e dati.
Si parte dall'Instruction Set Architecture (ISA), l'interfaccia verso il programmatore (le operazioni di base di cui dispone). Il datapath è definito da un insieme di registri, una lista di microoperazioni e una interfaccia di controllo.
Struttura del datapath
Il datapath generico è costruito con elementi di base: registri, bus, multiplexer, decoder. Elementi:
- register file (registri sorgente e destinazione);
- ALU (circuito combinatorio aritmetico-logico) e shifter; insieme formano la unità funzionale (function unit);
- multiplexer per scegliere gli operandi e il dato in uscita;
- bit di segnalazione (status): V overflow, C carry, N negativo, Z zero.
Le operazioni richiedono un singolo ciclo di clock: per esempio legge e , calcola la somma e la scrive in al fronte di clock successivo.
Register file
Un datapath ha tipicamente più di quattro registri (32 o più sono comuni): si realizzano con un register file, memoria veloce che permette un accesso simultaneo a più locazioni. Contiene bit, dove = numero di bit di indirizzo e = bit di ogni locazione. Qui ( registri ) e . Ha:
- due porte di lettura con indirizzi e (uscite bus A e bus B);
- una porta di scrittura con indirizzo , dato D data e abilitazione (write).
Il dato sul bus A è anche l'indirizzo della memoria dati (address out), il bus B è il dato da scrivere in memoria (data out). Il secondo operando della unità funzionale passa per un MUX B: con è il registro (bus B), con una costante (constant in). All'uscita, un MUX D sceglie con tra il risultato della unità funzionale () e il dato letto dalla memoria (data in, ).
ALU
La ALU (Arithmetic Logic Unit, Unità aritmetico-logica (ALU)Ruolo dell'ALU, ingressi, uscite e flag; ALU a 1 bit con AND, OR e sommatore selezionati da un multiplexer; estensione a 32 bit, sottrazione, confronto set-less-than e rilevazione dello zero e dell'overflow; tabella dei segnali di controllo; unità di moltiplicazione e virgola mobile.Unità aritmetico-logica (ALU) →) è un circuito combinatorio che esegue un insieme di operazioni aritmetiche e logiche di base, scelte da linee di selezione ( = selezione del modo, = operazione, più ). Si progetta dividendola in parte aritmetica e parte logica, poi collegate da un MUX 2-to-1 comandato da ( aritmetica, logica).
Circuito aritmetico. Un sommatore ( full adder in cascata, 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 →) con una logica di ingresso su che produce e con riporto in ingresso : .
| 0 | 0 | tutti 0 | (trasferimento) | (incremento) |
| 0 | 1 | (somma) | ||
| 1 | 0 | (sottrazione) | ||
| 1 | 1 | tutti 1 | (decremento) | (trasferimento) |
Si ricordi che "tutti 1" è in complemento a 2, quindi , e che (Numeri con segno, complemento a 2, sottrazione e overflowSottrazione senza segno: se $M\ge N$ nessun prestito in uscita, altrimenti il risultato $M-N+2^n$ è scorretto. Complemento a 1: $2^n-1-N$ (inversione bit a bit); complemento a 2: $2^n-N=$ complemento a 1 $+1$. Numeri con segno: segno e modulo (due zeri, intervallo simmetrico) oppure complemento a 2 (un solo zero, da $-2^{n-1}$ a $2^{n-1}-1$, MSB di peso $-2^{n-1}$). In complemento a 2 somma e sottrazione sono la stessa addizione: $A-B=A+\overline B+1$, riporto in uscita scartato. Overflow: senza segno $\Leftrightarrow C_{out}=1$ nella somma; con segno $\Leftrightarrow C_{in,MSB}\ne C_{out,MSB}$ (due operandi dello stesso segno con risultato di segno opposto).Numeri con segno, complemento a 2, sottrazione e overflow →). Perché sono possibili solo queste quattro operazioni aritmetiche con due linee: vale , , o ed è l'unico ingresso che cambia.
La logica di ingresso può essere un multiplexer, ma conviene una sintesi dedicata. Dalla tabella di verità ( in funzione di ) con la mappa di Karnaugh: Controllo: ; ; ; ✓.
Circuito logico. Per ogni bit un MUX 4-to-1, comandato da un codice a 2 bit, sceglie tra le porte AND, OR, XOR, NOT:
| codice | 00 | 01 | 10 | 11 |
|---|---|---|---|---|
Singolo stadio della ALU = stadio aritmetico + stadio logico + MUX 2-to-1 di uscita.
Funzionalità complessiva (le colonne sono ):
| operazione | funzione | ||||
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | trasferisci | |
| 0 | 0 | 0 | 1 | incrementa | |
| 0 | 0 | 1 | 0 | somma | |
| 0 | 0 | 1 | 1 | somma con riporto 1 | |
| 0 | 1 | 0 | 0 | più complemento a 1 di | |
| 0 | 1 | 0 | 1 | sottrazione | |
| 0 | 1 | 1 | 0 | decremento | |
| 0 | 1 | 1 | 1 | trasferisci | |
| 1 | X | 0 | 0 | AND | |
| 1 | X | 0 | 1 | OR | |
| 1 | X | 1 | 0 | XOR | |
| 1 | X | 1 | 1 | NOT (complemento a 1) |
Per la parte logica () bastano due bit di codice (00 AND, 01 OR, 10 XOR, 11 NOT) e la colonna è indifferente (X), come nella tabella del corso.
Bit di stato. Dal risultato della unità funzionale: = bit di segno (MSB del risultato); se tutti i bit del risultato sono 0 (NOR di tutti i bit); = riporto in uscita dal sommatore; = overflow = riporto entrante nel bit di segno XOR riporto uscente (Numeri con segno, complemento a 2, sottrazione e overflowSottrazione senza segno: se $M\ge N$ nessun prestito in uscita, altrimenti il risultato $M-N+2^n$ è scorretto. Complemento a 1: $2^n-1-N$ (inversione bit a bit); complemento a 2: $2^n-N=$ complemento a 1 $+1$. Numeri con segno: segno e modulo (due zeri, intervallo simmetrico) oppure complemento a 2 (un solo zero, da $-2^{n-1}$ a $2^{n-1}-1$, MSB di peso $-2^{n-1}$). In complemento a 2 somma e sottrazione sono la stessa addizione: $A-B=A+\overline B+1$, riporto in uscita scartato. Overflow: senza segno $\Leftrightarrow C_{out}=1$ nella somma; con segno $\Leftrightarrow C_{in,MSB}\ne C_{out,MSB}$ (due operandi dello stesso segno con risultato di segno opposto).Numeri con segno, complemento a 2, sottrazione e overflow →). Esempio a 8 bit: dà (150, letto come ) con , , , ; dà con , , , .
Shifter
Di solito lo scorrimento è eseguito da un blocco separato dalla ALU (ma può essere integrato). Shifter a 4 bit con multiplexer: per ogni uscita un MUX 3-to-1 con nessuno shift (passa ), shift a destra (passa , con ingresso per il bit entrante), shift a sinistra (passa , ingresso ). Serial output L e R per i bit uscenti.
Barrel shifter a 4 bit: uno shifter con rotazione (i bit che escono da una parte rientrano dall'altra). Ogni uscita è un MUX 4-to-1 le cui ingressi sono i 4 bit dell'operando in ordine ruotato; la selezione determina l'ampiezza della rotazione:
| operazione | ||
|---|---|---|
| 00 | nessuna rotazione | |
| 01 | rotazione di 1 posizione | |
| 10 | rotazione di 2 posizioni | |
| 11 | rotazione di 3 posizioni |
Pregio: lo spostamento di qualsiasi numero di posizioni in un solo ciclo.
Unità funzionale e codici delle microoperazioni
L'unità funzionale = ALU + shifter, con un MUX F che sceglie il risultato (: 0 ALU, 1 shifter). Le microoperazioni possibili sono 15, quindi bastano codici FS a 4 bit invece di far pilotare tutti i 7 segnali di controllo (, , ) alla unità di controllo: si aggiunge una piccola rete combinatoria che ricava i 7 segnali dal codice .
| FS | operazione | FS | operazione |
|---|---|---|---|
| 0000 | 1000 | ||
| 0001 | 1001 | ||
| 0010 | 1010 | ||
| 0011 | 1011 | ||
| 0100 | 1100 | ||
| 0101 | 1101 | ||
| 0110 | 1110 | ||
| 0111 |
( ripete il trasferimento di con diverso; non è usato.)
Control word del datapath
La control word raccoglie tutti i segnali di controllo del datapath: 16 bit.
| campo | DA | AA | BA | MB | FS | MD | RW |
|---|---|---|---|---|---|---|---|
| bit | 3 | 3 | 3 | 1 | 4 | 1 | 1 |
| significato | registro destinazione | registro sorgente A | registro sorgente B | 0: registro, 1: costante | funzione | 0: funzione, 1: data in | 0: niente, 1: scrive |
Codici dei registri: .
Esempi di microoperazioni (notazione simbolica e codifica, X = indifferente):
| microoperazione | DA | AA | BA | MB | FS | MD | RW |
|---|---|---|---|---|---|---|---|
| 001 | 010 | 011 | 0 | 0101 | 0 | 1 | |
| 100 | XXX | 110 | 0 | 1110 | 0 | 1 | |
| 111 | 111 | XXX | X | 0001 | 0 | 1 | |
| 001 | 000 | XXX | 1 | 0010 | 0 | 1 | |
| Data out | XXX | XXX | 011 | 0 | XXXX | X | 0 |
| Data in | 100 | XXX | XXX | X | XXXX | 1 | 1 |
| () | 101 | 000 | 000 | 0 | 1010 | 0 | 1 |
La prima, scritta su 16 bit, è 0010100110010101. Nell'ultima si ottiene lo con uno XOR di un registro con se stesso (). Una sequenza di microoperazioni si simula applicando una control word per ciclo: a ogni fronte il register file memorizza il risultato della microoperazione con .
VHDL: una ALU behavioral
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity alu8 is
port ( A, B : in std_logic_vector(7 downto 0);
FS : in std_logic_vector(3 downto 0);
F : out std_logic_vector(7 downto 0);
Z : out std_logic );
end alu8;
architecture beh of alu8 is
signal r : std_logic_vector(7 downto 0);
begin
process (A, B, FS)
variable ua, ub : unsigned(7 downto 0);
begin
ua := unsigned(A); ub := unsigned(B);
case FS is
when "0000" => r <= A;
when "0001" => r <= std_logic_vector(ua + 1);
when "0010" => r <= std_logic_vector(ua + ub);
when "0011" => r <= std_logic_vector(ua + ub + 1);
when "0100" => r <= std_logic_vector(ua + not ub);
when "0101" => r <= std_logic_vector(ua + not ub + 1);
when "0110" => r <= std_logic_vector(ua - 1);
when "0111" => r <= A;
when "1000" => r <= A and B;
when "1001" => r <= A or B;
when "1010" => r <= A xor B;
when "1011" => r <= not A;
when "1100" => r <= B;
when "1101" => r <= '0' & B(7 downto 1); -- shift a destra
when "1110" => r <= B(6 downto 0) & '0'; -- shift a sinistra
when others => r <= (others => '0');
end case;
end process;
F <= r;
Z <= '1' when r = "00000000" else '0';
end beh;Errori comuni
- Dimenticare che sottrarre significa (il è il ).
- Scambiare bus A e bus B: il bus A è anche l'indirizzo di memoria, il bus B il dato da scrivere.
- Confondere shift (perde bit) e rotazione (barrel shifter).
- Credere che la ALU sia sequenziale: è combinatoria, il risultato arriva al registro al fronte di clock.
- Scrivere nella control word i codici dei registri con la numerazione sbagliata (, non ).
Versione ripasso
- Computer semplificato: datapath + unità di controllo + memoria; ISA = interfaccia del programmatore. Operazioni a un ciclo.
- Datapath: register file (, ; letture , , scrittura , ); bus A = indirizzo di memoria, bus B = dato in uscita; MUX B (: registro/costante); unità funzionale = ALU + shifter (); MUX D (: risultato/data in); stato V, C, N, Z.
- ALU: parte aritmetica con (): , , , , , , ; parte logica: AND, OR, XOR, NOT (MUX 4-to-1); MUX 2-to-1 ().
- Shifter: MUX 3-to-1 per stadio; barrel shifter (rotazione: = ampiezza).
- FS (4 bit): , , , , , , , , AND, OR, XOR, , , , .
- Control word 16 bit: DA(3) AA(3) BA(3) MB(1) FS(4) MD(1) RW(1). : (Un semplice microprocessore - istruzioni, ciclo singolo e cicli multipliIstruzioni a 16 bit: opcode (7 bit) + DR, SA, SB/OP (3 bit ciascuno) oppure formato di salto con offset a 6 bit (AD sinistro + AD destro, relativo al PC e con estensione di segno). Insieme di istruzioni load/store (solo LD e ST accedono ai dati): MOVA, INC, ADD, SUB, ..., LDI, ADI, LD, ST, BRZ, BRN, JMP. Nel computer a ciclo singolo (due memorie separate) il decoder combinatorio ricava MB, MD, RW, MW, PL, JB, BC dai bit 15, 14, 13, 9 dell'istruzione e $FS$ dai bit 12–9; il periodo di clock è la somma dei ritardi lungo il cammino peggiore (9,8 ns nell'esempio). Nel computer a cicli multipli (memoria unica) servono IR, registri interni R8–R15 e un decoder sequenziale: fetch (INF) + uno o più stati di esecuzione.Un semplice microprocessore - istruzioni, ciclo singolo e cicli multipli →).
- Errori: senza ; bus A/B scambiati; shift = rotazione.