Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
IMPLEMENTAZIONE DELLE ISTRUZIONI
I primi due passaggi da eseguire, comuni a tutte le istruzioni, sono:
- Mandare il PC all'indirizzo di memoria successivo ed individuare a che istruzione corrisponde il contenuto di tale indirizzo (fetch);
- Leggere uno (nel caso della load word) o due registri specificati dai campi dell'istruzione corrente.
Quindi, indipendentemente dal tipo di istruzione, nel primo ciclo di clock si memorizza l'istruzione nell'IR, (PCout - Memoria - IR) si aumenta il PC (PCout - ALU - PCin), e vengono attivati i segnali di scrittura per PC e IR. Alla fine del periodo di clock, quindi in corrispondenza del fronte, PC e IR vengono scritti e i valori sono disponibili nel ciclo di clock successivo.
Il primo elemento di cui sicuramente si necessita, quindi, è un'unità di memoria che immagazzini l'indirizzo del PC, oltre ad un sommatore per incrementarlo:
Quindi, mentre il PC viene incrementato,
l'istruzione corrente viene memorizzata nell'Instruction Register, registro non accessibile al programmatore.
L'incremento del PC, in particolare, è implementato come di seguito:
Si passa quindi alla seconda fase, quella di decodifica, nella quale il processore MIPS legge i campi dell'istruzione e ne identifica il tipo mediante opcode e/o funct. In questa fase ancora non è noto il tipo di istruzione, quindi vengono sempre eseguiti il caricamento dei registri in output dal register file e il calcolo dell'indirizzo di branch.
Per eseguire un'istruzione di tipo R, che opera tra due registri depositando il risultato in un terzo, si rendono necessari un register file (che, come descritto nel paragrafo dedicato, fornisce in output il contenuto dei due registri di cui viene letto l'indirizzo in input) ed un ALU che esegua l'operazione specificata da funct.
Nel caso delle istruzioni load/store, che si
presentano nella forma generale: lw $t1, offset_value($t2)
sw $t1, offset_value($t2)
viene computato un indirizzo corrispondente al risultato della somma tra il contenuto del registro tra parentesi ed il valore dell'offset a 16 bit contenuto nell'istruzione. Se l'istruzione è una load, viene letto il valore da trasferire dalla memoria e scritto, mediante il register file, nel registro. Se l'istruzione è una store word, si legge il valore contenuto in $t1 e si deposita $t1 nell'indirizzo della memoria.
Si rende quindi necessaria l'implementazione del register file e dell'ALU in Fig. 33. Oltre a ciò, si necessita di un'unità di estensione del segno che renda il valore a 16 bit specificato nel campo offset un numero a 32 bit, oltre ad un'unità di memoria da cui leggere o su cui scrivere, provvista di segnali di controllo sia per la scrittura che per la lettura e di un indirizzo in input.
Fig. 34 Per eseguire il

Per creare un datapath in grado di implementare le istruzioni di tipo R e quelle di memoria vengono combinati i pezzi in Fig. 33 e Fig. 34 mediante multiplexor e opportuni segnali di controllo: Fig. 36

Il datapath in Fig. 37 può invece eseguire istruzioni di tipo R, load/store, operazioni aritmetiche e branch in un singolo ciclo di clock. Non può però integrare il jump.
Tale istruzione, che necessita un multiplexor aggiuntivo che seleziona tra l'indirizzo target del jump ed uno tra l'indirizzo di branch e PC+4 (ovviamente controllato da un segnale apposito), si può implementare come
in Fig. 38. L'indirizzo di jump si ottiene, come spiegato nel paragrafo dedicato, shiftando a sinistra di 2 i 26 bit meno significativi dell'istruzione di jump, giustapponendoli poi ai 4 bit più significativi di PC+4. 27
La configurazione completa di un datapath multiciclo MIPS è:
SEGNALI DI CONTROLLO
Il datapath in Fig. 39 si serve di segnali di controllo a 1 o 2 bit, a seconda del numero degli input di ciascun multiplexor. Le tabelle seguenti specificano gli effetti delle diverse configurazioni.
Segnali di controllo a 1 bit:
Segnali di controllo a 2 bit:
ESECUZIONE E CICLI DI CLOCK
Dato il datapath in Fig. 39, si procede a capire cosa viene eseguito ad ogni ciclo di clock, dato che ciò determinerà i segnali da asserire. Per l'esecuzione di un'istruzione sono necessari da 3 a 5 cicli di clock.
FETCH
Le istruzioni richieste dalla fase di fetch sono:
IR = Memory[PC];
PC = PC + 4;
Quindi viene inviato il PC come indirizzo alla
memoria centrale, viene eseguita una read e siscrive l'istruzione nell'IR, dove viene immagazzinata. Viene inoltre incrementato di 4 il PC.Per eseguire questa fase, i segnali MemRead e IRWrite verranno asseriti, mentre IorD verrà impostato a 0. Nel passaggio di incremento, ALUSrcA vale 0, ALUSrcB vale 01 ed ALUOp è impostato a 00. Quando il risultato dell'incremento viene immagazzinato nel PC, PCSourcerimane 00 e si asserisce PCWrite. Tale valore non sarà visibile fino al successivo ciclo di clock.
DECODEEseguita la fetch, al ciclo di clock successivo vengono letti i registri specificati nei campi rs ert ed il loro contenuto viene memorizzato nei registri temporanei A e B.Viene inoltre calcolato l'indirizzo target di branch mediante l'ALU, ed il risultato si salva inALUOut (il valore risultante verrà poi ignorato se l'istruzione non corrisponde ad un branch).Si noti come in questa fase, analogamente alla precedente, non si
conosce l'istruzione da eseguire, quindi i passi sono gli stessi per tutti i tipi di comando (anche se risultano superflui in determinati casi). Il fatto che nel secondo ciclo sia già disponibile l'istruzione in IR ma non si conosca il suo tipo deriva dal modello utilizzato: quello di Moore, che prevede che le uscite del sistema di controllo dipendano solo dallo stato corrente e non dagli ingressi (IR).
L'esecuzione precoce di queste azioni è resa possibile dalla consistenza del formato delle istruzioni e permette di ridurre il numero di cicli di clock necessari al passo execute.
A = Reg[IR[25:21]];
B = Reg[IR[20:16]];
ALUOut = PC + (sign-extend (IR[15-0]) << 2); << = shift 30
EXECUTE
Durante questa fase le operazioni che il datapath andrà ad eseguire sono specificate dalla classe di istruzioni. Durante questo ciclo di clock l'ALU si serve degli operandi ottenuti nel passo precedente (per tutte le istruzioni tranne la jump), ed esegue una
delle seguenti quattro funzioni, a seconda del tipo di istruzione:<ul>
<li>Memory reference: ALUOut = A + (sign-extend (IR[15-0])); L'ALU effettua un'addizione per ottenere un indirizzo di memoria. Il segnale ALUSrcA viene impostato a 1 e ALUSrcB a 10, mentre ALUOp vale 00;</li>
<li>Istruzione aritmetico-logica (R-type): ALUOut = A op B; L'ALU esegue l'operazione tra registri specificata nel campo funct. Il segnale ALUSrcA viene impostato a 1 e ALUSrcB a 00, mentre ALUOp vale 10;</li>
<li>Branch (beq): if (A == B) PC = ALUOut; L'ALU è impiegata per verificare l'uguaglianza del contenuto dei registri mediante una sottrazione. Il segnale Zero indica se il salto all'istruzione target viene eseguito o meno. ALUSrcA viene impostato a 1 e ALUSrcB a 00, mentre ALUOp vale 01. PCWriteCond viene asserito per aggiornare il PC in caso di salto. Se PCSource è impostato a 1, il valore del PC arriva da ALUOut. L'esecuzione dell'istruzione è terminata;</li>
<li>Jump: PC <em>[valore del PC arriva da ALUOut]</em>;</li>
</ul>
(PC[31:28], IR[25:0] << 2);
Il PC viene sostituito dall'indirizzo di salto. Il segnale PCSource viene utilizzato per selezionare l'indirizzo di salto come PC, mentre PCWrite, quando asserito, permette la scrittura di tale indirizzo nel PC. L'esecuzione dell'istruzione è terminata.
EXECUTE - LOAD/STORE/R-TYPE
In questo passaggio, un'istruzione di load/store esegue l'accesso in memoria, mentre una di tipo aritmetico/logica scrive il risultato per darlo in output. Quando un valore viene preso dalla memoria, viene salvato nel registro MDR (Memory Data Register) e sarà reso disponibile al successivo giro di clock.
# Istruzioni di accesso in memoria:
MDR = Memory[ALUOut] //load
Memory[ALUOut] = B //store
Se l'istruzione è una load, la word viene prelevata dalla memoria e salvata nel MDR. Se invece si tratta di una store, il dato da trasferire in memoria proviene da B. In entrambi i casi, l'indirizzo è quello
ottenuto nel passo precedente e salvato inALUOut
. I segnali da asserire saranno MemRead
per la load e MemWrite
per la store, e anche IorD
varrà 1. Se l'istruzione è una store, la sua esecuzione è terminata;
31# Istruzione aritmetico-logica (R-type):
Reg[IR[15-11]] = ALUOut;
Il contenuto di ALUOut
, ossia il risultato dell'operazione eseguita al passo precedente, viene salvato nel registro destinazione (operazione di write-back). RegDst
viene impostato a 1, RegWrite
deve essere asserito, MemToReg
deve valere 0 per scrivere nel registro destinazione l'output dell'ALU. L'esecuzione dell'istruzione è terminata.
EXECUTE - LOAD
In questo passaggio, la load si completa scrivendo (write-back) il valore prelevato dalla memoria nel registro designato:
Reg[IR[20-16]] = MDR;
Il dato salvato nell'MDR nel precedente ciclo di clock viene quindi immagazzinato nel registro destinazione. Il segnale MemToReg
deve valere 1, RegWrite
vaasserito e RegDst viene impostato a 0.
GESTIONE DELLE ECCEZIONI
Durante l'esecuzione delle istruzioni è possibile che si verifichino eccezioni e/o interruzioni. Al fine di distinguerle, si terrà fede alle definizioni stilate di seguito:
- Eccezione: evento sincrono, generato all'interno del processore e provocato da problemi nell'esecuzione di un'istruzione (es. overflow);
- Interruzione: evento asincrono che giunge dall'esterno del processore, solitamente da un'unità di I/O la cui esecuzione era stata richiesta dalla CPU.
Le eccezioni sono risolte da un gestore di eccezioni (exception handler), le interruzioni si gestiscono tra due istruzioni consecutive.
Per gestire un'eccezione vengono eseguiti i seguenti passaggi:
- Si interrompe l'esecuzione del programma corrente;