Salta al contenuto
Note per Studenti Un semplice microprocessore - istruzioni, ciclo singolo e cicli multipli

Un semplice microprocessore - istruzioni, ciclo singolo e cicli multipli

In questa pagina 5

Dopo il datapath (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 →) si completa il calcolatore con la unità di controllo e la memoria. Il quadro generale delle architetture è in Instruction Set ArchitectureChe cosa definisce un insieme di istruzioni; elementi di un'istruzione; tipi di operandi e di operazioni; macchine a 0, 1, 2 e 3 indirizzi con lo stesso calcolo svolto in ciascuna; architetture load/store.Instruction Set Architecture →, Formato delle istruzioni e modalità di indirizzamentoModalità di indirizzamento (immediato, diretto, indiretto, a registro, indiretto a registro, con spiazzamento, relativo al PC, indicizzato e scalato, a pila) con indirizzo effettivo ed esempi; formati fissi e variabili; i formati R, I e J di MIPS e il formato a 32 bit di ARM con il calcolo dei campi.Formato delle istruzioni e modalità di indirizzamento →, Ciclo fetch-executeRegistri PC, IR, MAR e MBR; ciclo dell'istruzione diviso in fetch ed execute; i quattro tipi di operazioni; diagramma degli stati del ciclo con calcolo degli indirizzi degli operandi e controllo delle interruzioni; esempio su una macchina ad accumulatore.Ciclo fetch-execute →, Unità di controlloCompiti dell'unità di controllo e micro-operazioni; segnali di controllo del datapath con tabella per le classi di istruzioni; controllo cablato (combinatorio o a stati finiti) e controllo microprogrammato (memoria di controllo, microistruzioni orizzontali e verticali); confronto.Unità di controllo →.

Il calcolatore e il Program Counter

Il computer prende in ingresso una sequenza di istruzioni contenute in una memoria (RAM o ROM). Ogni istruzione comprende l'operazione da effettuare, gli operandi, la destinazione e, in alcuni casi, la prossima istruzione. Il Program Counter (PC) contiene l'indirizzo della prossima istruzione, che può essere ottenuto in due modi: con un contatore (+1+1, istruzione successiva) oppure con un caricamento parallelo (parallel load) per cambiare il flusso (salti).

Eseguire un'istruzione significa attivare la sequenza appropriata di microoperazioni: nel datapath e come trasferimenti da e verso la memoria. La unità di controllo:

  1. preleva (fetch) un'istruzione dalla memoria;
  2. la decodifica;
  3. la esegue con una sequenza di una o più microistruzioni.

Un'istruzione è un insieme di bit che specifica completamente un'operazione in modo sintetico; l'instruction set è l'insieme di tutte le istruzioni; l'ISA ne è il catalogo con la descrizione completa. Si vedono due strutture di controllo: ciclo singolo e cicli multipli.

Instruction set architecture

Tre componenti: elementi di memoria, formato delle istruzioni, specifiche delle istruzioni.

Elementi di memoria visibili all'utente: la memoria istruzioni e la memoria dati (nell'esempio 215×162^{15}\times16 bit ciascuna; potrebbero essere fisicamente la stessa memoria), il register file (8×168\times16, operandi delle operazioni logico-aritmetiche), il program counter. A seconda della microarchitettura ci possono essere altri elementi usati internamente e non visibili.

Formato delle istruzioni

I bit sono divisi in campi. L'opcode specifica l'operazione; gli operandi (registri o memoria) sono indicati in modo esplicito (bit dedicati) o implicito (inclusi nell'opcode). Tre formati, a 16 bit:

formato bit 15–9 bit 8–6 bit 5–3 bit 2–0
Registro opcode (7) DR (registro destinazione) SA (sorgente A) SB (sorgente B)
Immediato opcode (7) DR SA OP (operando immediato)
Salto (jump/branch) opcode (7) AD sinistra SA AD destra

Gli 8 registri si indicano con 3 bit. Nel formato immediato l'operando ha solo 3 bit: i 13 restanti sono riempiti con zeri (zero fill, zf). Il formato di salto serve ad alterare il flusso:

  • branch (ramo): condizionato dal contenuto di un registro (per esempio R[SA]=0R[SA]=0); è PC-relativo: PC←PC+offsetPC\leftarrow PC+\text{offset} con offset AD di 3+3=63+3=6 bit esteso in segno (se, sign extension) per poter saltare avanti e indietro (complemento a 2). Intervallo limitato di indirizzi (vicini al PC);
  • jump (salto): intervallo più ampio, il contenuto di un registro è la destinazione.

Set di istruzioni

(RD, RA, RB = registri; OP = operando; AD = indirizzo; mnemonico = rappresentazione simbolica dell'opcode, tradotta in binario dall'assembler; bit di stato aggiornati: N,ZN,Z.)

istruzione opcode mnemonico descrizione
Move A 0000000 MOVA RD,RA R[DR]←R[SA]R[DR]\leftarrow R[SA]
Increment 0000001 INC RD,RA R[DR]←R[SA]+1R[DR]\leftarrow R[SA]+1
Add 0000010 ADD RD,RA,RB R[DR]←R[SA]+R[SB]R[DR]\leftarrow R[SA]+R[SB]
Subtract 0000101 SUB RD,RA,RB R[DR]←R[SA]−R[SB]R[DR]\leftarrow R[SA]-R[SB]
Decrement 0000110 DEC RD,RA R[DR]←R[SA]−1R[DR]\leftarrow R[SA]-1
AND 0001000 AND RD,RA,RB R[SA]∧R[SB]R[SA]\wedge R[SB]
OR 0001001 OR RD,RA,RB R[SA]∨R[SB]R[SA]\vee R[SB]
XOR 0001010 XOR RD,RA,RB R[SA]⊕R[SB]R[SA]\oplus R[SB]
NOT 0001011 NOT RD,RA R[SA]‾\overline{R[SA]}
Move B 0001100 MOVB RD,RB R[DR]←R[SB]R[DR]\leftarrow R[SB]
Shift right 0001101 SHR RD,RB R[DR]←sr R[SB]R[DR]\leftarrow sr\,R[SB]
Shift left 0001110 SHL RD,RB R[DR]←sl R[SB]R[DR]\leftarrow sl\,R[SB]
Load immediate 1001100 LDI RD,OP R[DR]←zf OPR[DR]\leftarrow zf\,OP
Add immediate 1000010 ADI RD,RA,OP R[DR]←R[SA]+zf OPR[DR]\leftarrow R[SA]+zf\,OP
Load 0010000 LD RD,RA R[DR]←M[R[SA]]R[DR]\leftarrow M[R[SA]]
Store 0100000 ST RA,RB M[R[SA]]←R[SB]M[R[SA]]\leftarrow R[SB]
Branch on zero 1100000 BRZ RA,AD se R[SA]=0R[SA]=0: PC←PC+se ADPC\leftarrow PC+se\,AD, altrimenti PC←PC+1PC\leftarrow PC+1
Branch on negative 1100001 BRN RA,AD se R[SA]<0R[SA]<0: PC←PC+se ADPC\leftarrow PC+se\,AD, altrimenti PC+1PC+1
Jump 1110000 JMP RA PC←R[SA]PC\leftarrow R[SA]

Per tutte le istruzioni (salvo salti presi) vale anche PC←PC+1PC\leftarrow PC+1, per preparare il ciclo successivo. È un'architettura load/store: LD e ST sono le uniche istruzioni con accesso alla memoria dati; tutte le altre operano sui registri.

Osservazione sui codici. I quattro bit meno significativi dell'opcode (bit 12–9 dell'istruzione) coincidono con il codice FSFS della unità funzionale (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 →): ADD =0000010→FS=0010=0000010\to FS=0010 (A+BA+B), SUB =0000101→FS=0101=0000101\to FS=0101 (A+B‾+1A+\overline B+1), AND →1000\to1000, LDI →1100\to1100 (F=BF=B con BB = costante), ADI →0010\to0010. I tre bit alti (15, 14, 13) distinguono il tipo: 000000 operazioni su registri, 001001 LD, 010010 ST, 100100 operazioni con costante, 110110 salti condizionati, 111111 salto incondizionato.

Esempio di rappresentazione in memoria

indirizzo contenuto istruzione effetto
25 0000101 001 010 011 SUB (opcode 5), DR=1, SA=2, SB=3 R1←R2−R3R_1\leftarrow R_2-R_3
35 0100000 000 100 101 ST (opcode 32), SA=4, SB=5 M[R4]←R5M[R_4]\leftarrow R_5
45 1000010 010 111 011 ADI (opcode 66), DR=2, SA=7, OP=3 R2←R7+3R_2\leftarrow R_7+3
55 1100000 101 110 100 BRZ (opcode 96), AD=101 100=44=44, SA=6 se R6=0R_6=0: PC←PC−20PC\leftarrow PC-20

L'offset di BRZ è 1011002101100_2 che in complemento a 2 a 6 bit vale −20-20: se R6=0R_6=0 il programma torna a 55−20=3555-20=35. Se R4=70R_4=70 e R5=80R_5=80, l'istruzione in 35 scrive 8080 all'indirizzo 7070 (dove prima c'era 192192).

Computer a ciclo singolo

Il computer a ciclo singolo carica ed esegue ogni istruzione in un solo ciclo di clock. Blocchi: PC, memoria istruzioni (non viene scritta), decoder delle istruzioni, register file, MUX B, unità funzionale, memoria dati (scritta con MWMW), MUX D, un blocco di controllo del PC e un'unità di estensione (extend) che aggiunge i bit a sinistra dell'offset. Nella parte di controllo l'unica memoria è il PC, aggiornato a ogni ciclo:

  • normalmente PC←PC+1PC\leftarrow PC+1;
  • jump: PC←PC\leftarrow valore del bus A;
  • branch: PC←PC+PC\leftarrow PC+ offset esteso in segno (se la condizione è vera).

Decoder delle istruzioni. È una rete combinatoria che dai bit dell'istruzione produce i segnali di controllo del datapath. Alcuni bit passano diretti: DADA = bit 8–6 (campo DR), AAAA = bit 5–3 (SA), BABA = bit 2–0 (SB), FSFS = bit 12–9. Gli altri segnali (MB,MD,RW,MW,PL,JB,BCMB,MD,RW,MW,PL,JB,BC) dipendono dai bit 15, 14, 13 e 9. Tabella di verità (X = indifferente):

tipo di istruzione 15 14 13 9 MB MD RW MW PL JB BC
operazione della unità funzionale su registri 0 0 0 X 0 0 1 0 0 X X
lettura memoria (LD) 0 0 1 X 0 1 1 0 0 X X
scrittura memoria (ST) 0 1 0 X 0 X 0 1 0 X X
operazione su registro e costante 1 0 0 X 1 0 1 0 0 X X
salto condizionato su zero (BRZ) 1 1 0 0 X 0 0 0 1 0 0
salto condizionato su negativo (BRN) 1 1 0 1 X 0 0 0 1 0 1
salto incondizionato (JMP) 1 1 1 X X 0 0 0 1 1 X

Significato: MBMB (0 registro, 1 costante), MDMD (0 risultato, 1 dato dalla memoria), RWRW (scrive il register file), MWMW (scrive la memoria dati), PL (load PC: il PC non incrementa ma si carica), JB (jump: il PC prende il bus A, altrimenti PC + offset), BC (condizione: 0 zero, 1 negativo). La control word a ciclo singolo è di 20 bit: DA (3) AA (3) BA (3) MB FS (4) MD RW MW PL JB BCDA\,(3)\ AA\,(3)\ BA\,(3)\ MB\ FS\,(4)\ MD\ RW\ MW\ PL\ JB\ BC.

Come esegue un'istruzione (sempre nello stesso ciclo): il PC indirizza la memoria istruzioni; l'istruzione è decodificata; si leggono i registri SASA e SBSB; la unità funzionale calcola; il risultato (o il dato letto dalla memoria) torna al register file (scritto sul fronte di clock); il PC è aggiornato. Esempi:

  • ADD (tipo registro): MB=0MB=0, MD=0MD=0, RW=1RW=1, FS=0010FS=0010;
  • LD RD,RA: l'indirizzo è il bus A (R[SA]R[SA]), MD=1MD=1, RW=1RW=1;
  • ST RA,RB: indirizzo = bus A (R[SA]R[SA]), dato = bus B (R[SB]R[SB]), MW=1MW=1, RW=0RW=0.

Ritardo nel caso peggiore. Il periodo di clock deve essere almeno la somma dei ritardi di tutti i blocchi lungo il cammino critico, perché in un ciclo il segnale attraversa tutti in sequenza. Esempio con ritardi tipici:

blocco PC memoria istruzioni register file (lettura) MUX B unità funzionale o memoria dati MUX D register file (scrittura)
ritardo (ns) 0,2 4 0,6 0,2 4 0,2 0,6

Somma =9,8=9{,}8 ns ⇒\Rightarrow fmax≈102f_{max}\approx102 MHz. Anche l'istruzione più semplice (un ADD) impiega l'intero periodo, dimensionato sulla più lenta (LD). Inoltre servono memorie separate per istruzioni e dati (nello stesso ciclo si accede a entrambe), cosa costosa: le due limitazioni si superano con il computer a cicli multipli, e le prestazioni con la pipeline (Pipeline, hazard e architetture RISC e CISCLa pipeline divide l'esecuzione in stadi separati da registri (IF, DOF, EX, WB) che lavorano in parallelo su istruzioni diverse: la latenza di una istruzione non cambia, il throughput aumenta di un fattore minore del numero di stadi (ritardo dei FF, stadio più lento). Con $k$ stadi e $N$ istruzioni servono $k+N-1$ cicli (riempimento e svuotamento). Gli hazard bloccano la pipeline: di dato (operando non ancora scritto: rimedi NOP, stall, forwarding) e di controllo (salti: bolle, branch prediction). RISC: istruzioni semplici, load/store, formato unico, 32 registri con R0$=0$; CISC: istruzioni complesse, più modi di indirizzamento, formato variabile, controllo microprogrammato.Pipeline, hazard e architetture RISC e CISC →).

Computer a cicli multipli

Le istruzioni sono eseguite in un numero variabile di cicli di clock, quindi possono essere più complesse. Servono modifiche a:

  • memoria: si può usare una sola memoria per istruzioni e dati. Spesso per una singola istruzione servono più accessi (l'istruzione stessa e un dato), impossibili in un ciclo;
  • unità di controllo: l'istruzione va mantenuta per più cicli, quindi si aggiunge l'instruction register (IR) con segnale di load; il decoder combinatorio è sostituito da una macchina sequenziale: un registro dello stato di controllo, logica di controllo e uno stato futuro: (stato, opcode, bit di stato) ⇒\Rightarrow control word;
  • datapath: registri duplicati per contenere risultati intermedi, ottenuti in un ciclo e necessari in un ciclo successivo della stessa istruzione. Sono interni e non visibili al programmatore (R8R_8–R15R_{15}); i campi DXDX, AXAX, BXBX (4 bit) scelgono un registro utente (DR/SA/SB) oppure interno, a seconda del bit più significativo.

Control word a cicli multipli (28 bit): NSNS (4, stato futuro) PSPS (2) ILIL DXDX (4) AXAX (4) BXBX (4) MBMB FSFS (4) MDMD RWRW MMMM MWMW. PSPS (program sequence) determina il PC: 0000 mantiene, 0101 incrementa, 1010 salto condizionato, 1111 jump; ILIL (instruction load) carica l'IR; MMMM è il MUX che sceglie l'indirizzo della memoria (PC per il fetch, bus A per i dati).

Macchina a stati. Le istruzioni più semplici richiedono il numero minimo di cicli, due, perché accedono sia all'istruzione sia ai dati: instruction fetch (INF), in cui IR←M[PC]IR\leftarrow M[PC], e instruction execution (EX0), che esegue l'operazione, aggiorna il PC e riporta a INF. Esempi: ADD: INF, poi EX0 con R[DR]←R[SA]+R[SB]R[DR]\leftarrow R[SA]+R[SB] e PC←PC+1PC\leftarrow PC+1.

Istruzioni più lunghe (3 o più cicli): per esempio un load con registro indiretto R[DR]←M[M[R[SA]]]R[DR]\leftarrow M[M[R[SA]]] ha 3 cicli: INF; EX0: R8←M[R[SA]]R_8\leftarrow M[R[SA]] (uso del registro interno R8R_8); EX1: R[DR]←M[R8]R[DR]\leftarrow M[R_8] e PC←PC+1PC\leftarrow PC+1. Gli shift multipli (a destra e a sinistra di più posizioni, definite da OP) richiedono un ciclo di stati EX0–EX4 che usa R8R_8 come registro di lavoro e R9R_9 come contatore che si decrementa finché non vale zero (il segnale di stato ZZ ne rileva l'azzeramento): ogni iterazione sposta di un bit, alla fine R[DR]←R8R[DR]\leftarrow R_8.

Vantaggi: l'orologio può essere più veloce (determinato dal blocco più lento in ogni ciclo, non dall'intera catena) e si può usare una memoria sola; svantaggio: ogni istruzione impiega almeno due cicli. Per riportare a un'istruzione per ciclo con clock veloce si usa la pipeline.

Errori comuni

  • Dire che l'indirizzo di memoria di LD/ST è un campo dell'istruzione: è il contenuto del registro SASA (bus A).
  • Dimenticare l'incremento del PC nelle istruzioni che non saltano.
  • Credere che in un ciclo singolo un'istruzione semplice impieghi meno tempo: il periodo è lo stesso per tutte.
  • Confondere registri interni (non visibili) e registri utente.
  • Leggere l'offset di BRZ come numero senza segno: è in complemento a 2 (44→−2044\to-20).

Versione ripasso

Esercizi su questo argomento

Teoria collegata