23
ADDRES BUS DATA BUS CO NTRO L BUS IN TER N A L BUS DATA BUS LA TC H /B U FFER ADDRESS BUS LA TC H /B U FFER CLOCK PRO G RAM COUNTER STACK PO IN TER IN STR U CTIO N R EG ISTER FLAG ALU REG ISTERS PO IN TER S DECODER SEQUENCER Questo schema è lo schema di principio della CPU di tutti i computer. Nella storia ed in commercio sono state fatte migliaia di varianti a questo schema, ma il principio di funzionamento è sempre rimasto quello inventato da Neuman all’inizio degli anni 1940. Fetch ed Execute Il Microprocessore, o meglio la CPU lavora in due fasi fondamentali: Fetch ed Execute. Nella fase di Fetch la CPU preleva l’istruzione da eseguire in memoria. Le istruzioni si trovano disposte in successione in memoria, e sono stivate in memoria nello stesso ordine in cui vanno eseguite. Il Program Counter deve contenere all’inizio dell’esecuzione l’indirizzo

Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Embed Size (px)

Citation preview

Page 1: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

ADDRES BUS

DATA BUS

CONTROL BUS

INTERNAL BUS

DATA BUS LATCH/BUFFER

ADDRESS BUS LATCH/BUFFER

CLOCK

PROGRAM COUNTER

STACK POINTER

INSTRUCTION REGISTER

FLAG

ALU

REGISTERS POINTERS

DECODER SEQUENCER

Questo schema è lo schema di principio della CPU di tutti i computer. Nella storia ed in commercio sono state fatte migliaia di varianti a questo schema, ma il principio di funzionamento è sempre rimasto quello inventato da Neuman all’inizio degli anni 1940.

Fetch ed Execute

Il Microprocessore, o meglio la CPU lavora in due fasi fondamentali: Fetch ed Execute.Nella fase di Fetch la CPU preleva l’istruzione da eseguire in memoria. Le istruzioni si trovano

disposte in successione in memoria, e sono stivate in memoria nello stesso ordine in cui vanno eseguite. Il Program Counter deve contenere all’inizio dell’esecuzione l’indirizzo della prima istruzione del programma da eseguire. Per avere prelevare l’istruzione si deve fare un’operazione di READ. L’indirizzo è contenuto nel program counter che andrà quindi portato sull’ADDRESS BUS attraverso l’ADDRESS BUFFER. Il dato letto in memoria è l’istruzione da eseguire e sarà oggetto delle fase di Execute. L’istruzione letta dalla memoria viene caricata nell’ISTRUCTION REGISTER e quindi eseguita dal DECODER SEQUENCER.

Page 2: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Program Counter

Il Program Counter è un vero è proprio contatore che contiene, o meglio parlando tecnicamente “punta” l’indirizzo dell’istruzione da prelevare.

All’inizio del programma il Program Counter viene precaricato (preset) con l’indirizzo della prima istruzione del programma

In ogni fase di Fetch il contenuto del Program Counter viene mandato sull’Address Bus mentre il contenuto del Program Counter viene incrementato di uno, mediante un impulso che gli arriva a fine Fetch dal Sequencer. Il Program Counter è quindi un vero e proprio contatore da cui il nome.

Address Latch/Buffer

È un latch buffer tristate unidirezionale che manda sull’ADDRESS BUS i dati che si trovano nel bus interno della CPU.

È unidirezionale verso l’uscita, la CPU scrive gli indirizzi, non li riceve mai. Il buffer è comunque tristate perché potrebbero esserci altre CPU o altre unità che potrebbero

mettere degli indirizzi sull’ADDRESS BUS. Deve anche essere latch, perché deve memorizzare l’indirizzo che gli arriva dal bus interno in

modo che l’INTERNAL BUS sia disponibile per il trasferimento del dato da o verso l’esterno..

Data bidirectional Latch/Buffer

È un buffer latch bidirezionale tristate che mette in comunicazione l’INTERNAL BUS ed il DATA BUS.

Deve essere latch per memorizzare il dato sia dal bus interno sia dal bus dei dati proveniente dall’esterno.

Deve essere tristate perché deve essere in grado di scrivere e leggere e comunque si tratta di un bus.

Deve essere bidirezionale perché ovviamente i dati entrano ed escono.

Instruction Register

Il Program Counter contiene l’indirizzo dell’istruzione da prelevare in memoria. Questa istruzione una volta prelevata viene scritta nell’Instruction Register per essere decodificata ed eseguita.

La fase di Fetch appunto è il prelievo dell’istruzione da eseguire in memoria e l’immagazzinamento nell’Instruction Register.

Page 3: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Fetch

1) Program Counter su Internal bus2) Internal bus su Address Buffer latch3) Read4) Attesa fine Wait5) Data bus passa in internal bus attraverso data bus buffer latch6) Data bus latch passa nell’Instruction Register7) Incremento del Program Counter

Come si vede per fare un Fetch occorrono 5 comandi e l’attesa di un consenso, passo 4, attesa di fine Wait.

Ognuno di questi comandi è un comando elementare. Questi comandi sono generati dal sequencer dopo l’esecuzione di ogni istruzione per prelevare l’istruzione successiva, in automatico. Tutti questi comandi si chiamano microistruzioni.

Mentre il Fetch è un ciclo sempre uguale, la fase successiva dipenderà da quale istruzione si è prelevata in memoria e va eseguita.

CLOCK

WAIT

flip flop

DECODER

inizio istruzioneflip flop flip flop flip flop flip flop

Page 4: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Decoder Sequencer

Consideriamo i 5 comandi dell’esecuzione del FETCH di cui sopra. Occorre un dispositivo che li generi in successione e con una certa temporizzazione. Il DECODER SEQUENCER genera questi comandi e al passo 4 si ferma fino a che non arriva il consenso che il dato è pronto sul Data Bus dalla memoria.

Quando l’istruzione è disponibile nell’Istruction Register deve iniziare la sequenza di comandi, “Microistruzioni” che servono a compiere l’istruzione. Questa catena di istruzioni si trova nel Sequencer, anzi nel Sequencer ci sono tante catene di microistruzioni quante sono le istruzioni ASSEMBLER della CPU. Il decoder attiva la catena del Sequencer relativa all’istruzione che contiene, da cui il nome decoder.

Il Sequencer da comandi sia all’interno della CPU, sia all’esterno (read, write, riconoscimento di interrupt, ecc.). Il Sequencer riceve consensi dall’esterno, come il WAIT, richieste come Interrupt, e consensi dall’interno dai FLAG.

L’Istruzione può essere più o meno lunga a secondo di quanti dati contiene. Quando arriva la prima parte di essa nell’Istruction Register, il Decoder può stabilire che se è necessario proseguire con altri Fetch e questi vengono eseguiti in automatico prima di passare all’Execute. Ad ogni Fetch si incrementa il Program Counter ovviamente, perché è una istruzione che occupa più parole di memoria e quindi più numeri di Program Counter.

ADDRESS BUSÈ un bus in uscita per la CPU, è la CPU che stabilisce quale indirizzo debba essere scritto o letto in

memoria. Il numero dei fili di questo bus determina la capacità massima della memoria fisica della CPU, il numero massimo di locazioni che la CPU può avere è 2N dove N è il numero dei fili del bus. La memoria montata con la CPU può essere inferiore alla capacità della CPU. A questo punto il programma dovrà essere scritto per una memoria fisica ridotta.

I sistemi operativi di grandi dimensioni riconoscono in automatico la dimensione della memoria montata con la CPU con un programma che controlla fino a quale indirizzo arrivano segnali dalla memoria.

Se si aggiunge un filo al bus degli indirizzi si raddoppia la capacità della memoria fisica.L’address bus può essere utilizzato anche da altre CPU o dalle periferiche stesse per accedere a

segmenti di memoria, quindi l’uscita sull’Address Bus deve essere tristate. Prima dell’Address bus c’è un Latch per memorizzare l’indirizzo quando è disponibile sull’Internal

Bus che deve essere lasciato libero per i successivi trasferimenti.

Data Bus

Ovviamente come si capisce dal nome è il Bus da cui arrivano i dati e su cui escono i dati. Il numero dei fili di questo bus determina l’architettura della memoria ossia da quante celle di un bit deve essere costituita la locazione di un indirizzo di memoria. Ovviamente più sono numerosi i fili del Data Bus e maggiore sarà la velocità di trasferimento dei dati e di lettura delle istruzioni. Oggigiorno si sta arrivando ai limiti fisici teorici delle possibilità del clock, quindi non succede come un tempo quando ogni anno le velocità del clock raddoppiavano o triplicavano. I margini di incremento della velocità del clock sia della CPU che del bus sono minimi e quindi si sta già agendo aumentando il numero di fili del bus dei dati. Un

Page 5: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

bus a 64 fili consente tempi quasi dimezzati per la fase di Fetch di tutte le istruzioni e per le istruzioni di Move di dati.

Control Bus

Vediamo prima i comandi che vanno all’esterno della CPU e i consensi che arrivano dall’esterno alla CPU.

Read : comando di lettura ai banchi di memoriaWrite: comandi di scrittura ai banchi di memoriaWait: di solito è un comando attivo basso, ad open collector. Quando la memoria ha finito

l’operazione di lettura o scrittura rilascia questo comando che va alto e la CPU sa che può leggere il dato sul bus in caso di lettura, oppure in caso di scrittura sa che può continuare e fare le microistruzioni successive.

Interrupt: le periferiche possono generare un segnale di richiesta di essere servite alla CPU. Ci possono essere uno o più fili di interrupt. Un segnale si questo filo fa sapere alla CPU che c’è una periferica che richiede dei dati o offre dei dati.

Interrupt aknowledge: la CPU accetta la richiesta di Interrupt della periferica quando è in condizioni di farlo e secondo un certo ordine di priorità. Quando accetta la richiesta emette un segnale sul Control Bus che avverte la periferica che può iniziare la procedura di Interrupt. Anche in questo caso si possono avere uno o più fili a seconda della CPU e dei sistemi scelti.

Bus Request: in certi casi può essere molto più veloce lasciare l’accesso della memoria libero ad una periferica che dovrà essere di tipo “intelligente” in modo che la periferica possa leggere o scrivere direttamente sulla memoria senza passare nella CPU i dati che deve trasferire. Questo può avvenire mentre la CPU elabora internamente dei dati, quindi si possono trasferire dati con consumo si tempo zero per la CPU. Questa tecnica si chiama DMA, Direct Memory Access.

Bus Aknowledge: quando la CPU lascia il bus libero lo comunica sul Control Bus e la periferica sa di avere Address Bus, Data bus, e parte del Control Bus disponibile. Per il control Bus sono i fili di Read, Write e implicitamente di Wait. Il Wait è in ogni caso comandato dalla memoria.

Input/Output: la CPU può sempre prendere ed inviare dati direttamente dalle o alle periferiche. Per fare questo usa sempre il Data Bus per il movimento dei dati e parte dell’Address Bus per indirizzare le periferiche. Solo una parte perché le periferiche sono ovviamente in numero molto inferiore alle locazioni di memoria. Il comando di Input Output comunica alle periferiche che l’indirizzo sull’Address Bus è un indirizzo di periferica e non di locazione di memoria, e quindi la periferica indirizzata si attiva. La memoria viene disattivata o mediante un comando Enable/Disable oppure non vengono attivati i segnali Read/Write a seconda della CPU.

Vediamo ora i comandi e consensi del Control Bus all’interno della CPU. Quando siamo all’interno non ci sono problemi di Wait, sia perché essendo gli spazi molto ridotti

non ci sono problemi di attesa, sia perché nel caso che ci siano tempi di attesa, come nel caso di operazioni matematiche, essi sono noti e determinati, quindi la CPU sa già quanti colpi di clock sono necessari perché venga determinata una operazione matematica per esempio.

I comandi all’interno sono del tipo:Trasferisci dal registro al bus interno

Trasferisci dal bus interno al registroTrasferisci dal latch al bus esterno (Address Bus e Data Bus)Trasferisci dal bus esterno(Address Bus e Data Bus) al latch

Page 6: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Fai operazione matematicaFai operazione logica

Condizionamento di esecuzione: è previsto che la CPU faccia o non faccia certe operazioni a seconda dello stato di certi bit che di solito sono i Flag. Se si osserva lo schema il registro dei Flag manda comandi sul control bus oltre che riceverne, perché i suoi Bit condizionano l’esecuzione di certe operazioni.

Microistruzioni

Tutti i comandi che partono dal Sequencer e vanno sul Control Bus sia all’interno della CPU che all’esterno sono microistruzioni. Ogni microistruzione è cablata ad hardware.

L’Execute di ogni istruzione è una sequenza di microistruzioni che possono essere condizionate o meno dai Flag all’interno o dai consensi dall’esterno, il Wait è l’esempio più immediato.

Quindi il Sequencer ha N sequenze cablate tante quante sono le istruzioni Assembler della CPU. Ognuna di queste avrà un certo numero di passi, di comandi e di condizionamenti.

Il Decoder mette in funzione la catena di microistruzioni del caso. Ogni istruzione avrà un suo numero di passi, un passo ad ogni colpo di clock, mentre certi passi per

procedere avranno bisogno di avere consensi dall’esterno e quindi in questo caso si potranno perdere dei colpi di clock in attesa.

Alcune istruzioni hanno delle ramificazioni e fanno una certa sottocatena di istruzioni o un’altra sottocatena a seconda dello stato di un Flag.

Alcuni processori hanno delle istruzioni libere che possono essere programmate con varie microistruzioni dal cliente. Questo tipo di programmazione si chiama Firmware.

Il Fetch dell’istruzione è sempre uguale ma ci possono essere istruzioni per cui basta un prelievo di istruzione per avere tutto il necessario mentre alcune istruzioni hanno necessità di più letture in memoria.

In questo secondo caso la catena di microistruzioni dell’Execute dell’istruzione comprende fasi ulteriori di Fetch con relatici incrementi del Program Counter prima di avere l’Execute vero e proprio.

Register/Pointer

I registri sono Array di Flip-Flop con possibilità di parallel-in, parallel-out, shift a destra e sinistra, rotate destro e sinistro. Vengono usati come memoria temporanea o come elementi base per le operazioni della ALU. Possono essere usati anche come contatori.

Di solito è possibile testare il singolo bit, metterlo ad 1, metterlo a 0. I pointer sono invece fatti a contatore con la possibilità di incrementare o decrementare il valore di

uno senza dovere passare all’unita ALU. Vengono utilizzati per muovere blocchi di dati, come puntatori dell’indirizzo corrente.

Page 7: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Stack e Stack Pointer

Un’esigenza comune di qualsiasi programmatore è quella di potere fare dei sottoprogrammi, delle routine. Se una funzione viene usata più volte la si mette in un sottoprogramma e si richiama il sottoprogramma tutte le volte che è necessario senza starlo a riscrivere ogni volta. Vedremo poi che in effetti un programma senza sottoprogrammi ma in un corpo unico è più veloce ma diventerebbe ingestibili, molto più grande in memoria. A volte per esigenze di tempo di esecuzione si fa proprio questo ma si tratta per lo più di casi sporadici con programmi relativamente brevi.

Dal punto di vista della CPU invece, succede che si salta dal programma principale ad un sottoprogramma che è scritto in un altro punto della memoria, e poi al termine di questo si torna all’istruzione successiva a quella da cui si è partiti per fare il salto.

La prima operazione è un CALL ad un sottoprogramma, mentre l’ultima è un RETURN.Quando si fa un CALL si deve quindi memorizzare il punto da cui si è partiti, anzi meglio il punto

cui si deve tornare che sarà l’istruzione successiva al CALL. Questo indirizzo viene memorizzato nello STACK che è una zona di memoria destinata solo a questo scopo, in cui non devono essere scritti o dati o parti del programma altrimenti tutto il sistema delle routine fallisce.

Può succedere che il primo sottoprogramma ne richiami un altro e questo ne richiami un terzo e così via fino a profondità di sottoprogrammi molto elevate. A questo punto il numero di indirizzi da memorizzare per i vari RETURN è molto elevato. Per gestire tutto questo si usa lo STACK POINTER.

Lo STACK POINTER contiene l’indirizzo dell’ultima locazione di STACK che è stata scritta. Quando si fa un CALL quindi si incrementa lo STACK POINTER di uno perché punti una

posizione dello STACK libera, si salva il contenuto del PROGRAM COUNTER nella relativa posizione dello STACK e si mette nel PROGRAM COUNTER l’indirizzo del CALL. Questa operazione si chiama PUSH .

Quando si arriva ad un RETURN il contenuto della locazione di STACK puntata dallo STACK POINTER viene caricato nel PROGRAM COUNTER, e lo STACK POINTER viene decrementato di 1. questa operazione si chiama POPE.

Page 8: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Esempi di lavoro dello Stack, Stack Pointer, Program Counter

……………….. 1000 ………………. 2000……………………………….. 1001……………… 2001………………100 CALL 1000 ……………………. ……………………101 ………….. 1100 ……………….. 2150 RETURN………………… 1101 RETURN200 CALL 2000201……………………………..………………..

Le istruzioni fino al passo 100 vengono eseguite sequenzialmente in ordine come sono scritte, ma al passo 100 abbiamo un CALL al passo 1000 dove si ha un sottoprogramma. Si deve quindi aggiornare lo Stack Pointer su una nuova posizione incrementandolo di 1, si salva il contenuto del Program Counter nella locazione dello Stack puntata dallo Stack Pointer e si carica l’indirizzo segnato nel CALL nel Program Counter.

Se lo Stack Pointer indica per convenzione 0 perché fino ad ora non è stato aperto nessun sottoprogramma. Lo stato dei registri, dopo l’esecuzione 100 sarà quindi:

PROGRAM COUNTER STACK POINTE R STACK 11000 0001 101

Si fa notare come lo Stack contenga 101 ossia l’indirizzo cui si deve tornare una volta finita l’esecuzione del sottoprogramma. Il Program Counter comunque al momento del PUSH contiene già 101 perché appena finito il Fetch il Program Counter viene aggiornato all’indirizzo dell’istruzione successiva automaticamente.

Dal passo 1000 in poi il Progam Counter viene incrementato automaticamente fino al passo 1100 quando si ha il RETURN. A questo punto si esegue un POPE. La locazione dello Stack puntata dallo Stack Pointer viene caricata nel Program Conter e lo Stack Pointer viene decrementato.

PROGRAM COUNTER STACK POINTE R STACK 1101 0000 101

Si fa notare come il contenuto della locazione 0 dello Stack non venga cancellata perchè è un’operazione inutile, essa verrà riscritta quando si farà un altro CALL ed è esattamente quello che succederà al passo 200. dopo il passo 200 avremo esattamente questa situazione:

PROGRAM COUNTER STACK POINTE R STACK 12000 0001 201

mentre dopo l’esecuzione del passo 2150 avremo:

PROGRAM COUNTER STACK POINTE R STACK 1201 0000 201

Page 9: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

esempio n.2

……………… 1000 ………………… 2000………….100 CALL 1000 1001…………………. 2001…………101…………… ……………………… …………..102…………….. 1100 CALL 2000 2200 CALL 4000 1101……………. 2201 …………. ……………………. ……………….. 1140 RETURN 2400 RETURN

4000………….4001………… …………..4500 CALL 80004501 …………. ………………..4530 RETURN

8000………….8001………… ………….. ………………..8400 RETURN

Al passo 100 si ha il primo CALL e quindi in primo PUSH:

PROGRAM COUNTER STACK POINTER STACK 11000 0001 101

al passo 1100 si ha il secondo CALL senza che sia chiuso il primo quindi:

PROGRAM COUNTER STACK POINTER STACK 1 STACK 22000 0002 101 1101

Al passo 2200 si ha il terzo CALL senza che siano chiusi i due precedenti :

PROGRAM COUNTER STACK POINTER STACK 1 STACK 2 STACK 3 4000 0003 101 1101 2201

Al passo 4200 si ha il quarto CALL senza che siano chiusi i precedenti

PROGRAM COUNTER STACK POINTER STACK 1 STACK 2 STACK 3 STACK 48000 0004 101 1101 2201 4501

Page 10: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Al passo 8400 si incomincia a chiudere l’ultimo sottoprogramma quindi si fa il primo POPE:

PROGRAM COUNTER STACK POINTER STACK 1 STACK 2 STACK 3 STACK 44501 0003 101 1101 2201 4501

Al passo 4530 si chiude il terzo sottoprogramma:

PROGRAM COUNTER STACK POINTER STACK 1 STACK 2 STACK 3 STACK 42201 0002 101 1101 2201 4501

Al passo 2400 si chiude il secondo sottoprogramma:

PROGRAM COUNTER STACK POINTER STACK 1 STACK 2 STACK 3 STACK 42201 0001 101 1101 2201 4501

Al passo 1140 si chiude il primo sottoprogramma:

PROGRAM COUNTER STACK POINTER STACK 1 STACK 2 STACK 3 STACK 4101 0000 101 1101 2201 4501

come si vede quando si torna al programma principale lo Stack Pointer contiene 0, non punta nessuna locazione.

I FLAGSono registri di un solo bit che vengono scritti dalla ALU in seguito ad operazioni matematiche o

logiche. Il loro numero varia a secondo delle CPU e della loro complessità. Elenchiamo i principali:

SIGN indica il segno del risultato dell’ultima operazione matematica, se è positivo o negativo se il numero è scritto nella forma complemento a 2.

ZERO indica se il risultato dell’ultima operazione matematica o logica è 0, o se il test di un bit di un registro è 1

NONZERO indica se il risultato dell’ultima operazione matematica è diverso da 0, o se il risultato di un’operazione logica è 1, o se il test di un bit di un registro è 1

CARRY indica se il risultato dell’ultima operazione matematica ha generato riporto, può valere sia per l’addizione che per la sottrazione.

BORROW indica se l’ultima sottrazione ha generato riporto.

Page 11: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

HALF CARRY indica se c’è stato riporto dai 4 bit più leggeri serve per la gestione dei numeri in BCD

PARITY indica se c’è stato errore di parità nei dati che arrivano alla CPU

OVERFLOW indica se l’operazione matematica ha generato un risultato più grande del numero di bit a disposizione.

I FLAG condizionano l’esecuzione di certe istruzioni, è per questo che nello schema generale c’è la freccia che indica movimento dal registro dei FLAG al Sequencer. Sono generati direttamente dalla ALU.

INTERRUPT

La CPU può interpellare la periferica mettendo il suo indirizzo sull’Address Bus e il comando di I/O. Se ci sono molte periferiche la CPU dovrà fare ciclicamente una verifica dello stato delle periferiche per controllare se hanno dati da trasmettere o se sono pronte a riceverne. Questo modo di procedere si chiama POLLING. Ogni volta la CPU dialoga con una periferica si deve espletare un certo dialogo preliminare che varia da caso a caso in cui le due parti si accordano su cosa si sta trasmettendo o ricevendo e con quale protocollo. Questi preliminari che si chiamano HANDSHAKING (stretta di mano) portano via un certo tempo e sovente può succedere che si faccia l’Handshaking e poi non ci sia nulla da trasferire oppure che la periferica non sia pronta per l’Handshaking stesso. Questo comporta una perdita di tempo ed un rallentamento delle prestazioni della CPU.

Per rimediare a queste perdite di tempo si è inventato l’INTERRUPT. L’Interrupt è una richiesta che la periferica invia alla CPU o quando ha qualcosa da mandare o quando è pronta a ricevere ulteriori dati. In questo modo si verifica l’Handshaking solo quando è necessario e la CPU dedica molto meno tempo al dialogo con le periferiche.

I modi con cui si realizza l’Interrupt sono svariati.

Interrupt vettorialeQuando una periferica ha da comunicare con la CPU emette un segnale di Interrupt. La CPU

quando è in grado di iniziare il dialogo con la periferica risponde con un segnale di accettazione dell’Interrupt: INTERRUPT AKNOWLEDGE. La periferica sa di potere essere servita e mette sul Data Bus un vettore che è suo caratteristico che la identifica altrimenti la CPU non può sapere chi ha generato l’Interrupt. La CPU salva l’indirizzo contenuto nel Program Counter come se fosse arrivato un CALL ossia fa una PUSH, e mette nel Program Counter un indirizzo che di solito è formato in parte dal vettore mandato dalla periferica ed una parte da un vettore interno che è la pagina di Interrupt.

Ovviamente ogni sottoprogramma si Interrupt deve terminare con una istruzione di Return o equivalente. Di solito il Return da Interrupt è diverso da quello di Return da un CALL.

Ossia i bit più leggeri arrivano sul Data Bus dalla periferica e quelli più pesanti sono una costante interna che è la pagina degli Interrupt. Ovviamente questa zona di memoria non deve essere scritta da nessuna parte del programma. La pagina di Interrupt può essere una costante della CPU in questione o può invece essere stabilita con il software all’inizio del programma stesso.

Rimane il problema che c’è un filo solo su cui tutte le periferiche chiedono l’Interrupt, e quindi c’è una situazione conflittuale. Per ovviare questo ci sono diverse soluzioni che fanno in modo che esista una gerarchia per fare la richiesta di Interrupt.

Page 12: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Daisy chain Tutte le periferiche sono collegate tra di loro con sue fili: con un filo la periferica disabilita

l’Interrupt le periferiche con priorità inferiore, sull’altro filo viene lei disabilitata da quelle a priorità più alta. Quando una periferica è disabilitata da quella superiore, a sua volta disabilita quelle di livello inferiore, quando chiede lei stessa l’Interrupt disabilita le periferiche di livello inferiore.

Una periferica di livello superiore può interrompere l’Interrupt di una periferica di livello inferiore e si fa un ulteriore PUSH.

Priorità impostata a softwareUn'altra via è quella di impostare il livello di Interrupt a software. La CPU in fase iniziale comunica

ad ogni periferica il suo livello di Interrupt. Quando una periferica emette un Interrupt, tutte le altre sono inibite dall’emettere Interrupt. Quando questo viene riconosciuto e la periferica mette il vettore di Interrupt sul Data bus, le periferiche lo riconoscono e sanno se si sta eseguendo un Interrupt con priorità più alta o bassa della loro.

Con questo sistema il livello di priorità può essere modificato a software a seconda delle esigenze, ma le periferiche devono essere più evolute.

Interrupt con più filiAlcune CPU hanno più fili, per cui ogni periferica ha il suo comando individuale di Interrupt. La

CPU quindi non ha bisogno di ulteriori informazioni quando riceve un segnale di Interrupt, sarà lei a decidere con quale periferica mettersi in comunicazione.

Interrupt con più fili codificatiNel caso di molte periferiche questo sistema imporrebbe di produrre delle CPU con numeri molto

elevati di fili. Per ridurre il numero di fili, si invia alla CPU non la richiesta diretta ma la sua codificazione ossia con N fili si hanno 2N periferiche. Ogni periferica ha un filo solo, tutti i fili assieme entrano in un codificatore che trasmette il codice della periferica a priorità più alta che sta richiedendo l’Interrupt.

Mascheratura dell’InterruptQuando la periferica riceve un Interrupt, lo serve, in condizioni normali al termine dell’EXECUTE

dell’istruzione in corso. Ci sono delle parti di programma o dei sottoprogrammi che fanno ampio uso dei registri della CPU che se venissero interrotti da un Interrupt darebbero poi risultati sbagliati. Esiste quindi nelle CPU quasi sempre la possibilità di rendere a software la CPU insensibile alle richieste di Interrupt.

Prima di iniziare la parte di programma critica si disabilita a software l’Interrupt, per riabilitarlo quando questa parte del programma è terminata. Questa operazione si chiama mascheratura dell’Interrupt.

Maskable Interrupt , non Maskable InterruptGeneralmente nelle CPU c’è anche un Interrupt che non può essere ignorato dalla CPU, che si

chiama NON MASKABLE INTERRUPT. Quando arriva questo segnale di solito viene messo nel Program Counter l’indirizzo di partenza all’accensione. Quindi questo Interrupt viene usato come Reset spesso, per avere un Reboot del sistema o per crash o per mancanza di alimentazione.

I miglioramenti della CPU

La CPU è rimasta sempre concettualmente quella inventata da NEUMANN negli anni ’40, ma sono state apportate varie modifiche per avere prestazioni migliori.

Page 13: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

PREFETCHAbbiamo visto che ci sono due operazioni fondamentali: il prelievo dell’istruzione e la sua

esecuzione, ossia FETCH ed EXECUTE.Se si riuscisse a prelevare l’istruzione durante la fare di EXECUTE i tempi di esecuzione totale

dimezzerebbero all’incirca. Per fare questo si è inventato il Prefetch.Durante l’Execute di alcune istruzione il bus sia interno che esterno sono liberi, perché il tutto

avviene tra la ALU ed i registri ad essa direttamente collegati. Questo è il caso di operazioni matematiche complesse. In questo tempo si può benissimo fare il Fetch dell’istruzione successiva ma si deve avere il posto in cui mettere questa istruzione all’interno della CPU. A questo scopo si deve raddoppiare l’Instruction Register in modo che a fine Execute si possa subito passare all’Execute successivo.

Nella pratica poi si usano Instruction Register non solo raddoppiati ma anche con 10 , 20 Instruction Register completi, per avere il maggior numero di possibilità di non dovere fare dei Fetch soli. Questo perché alcune istruzioni sono di esecuzione interna molto lunga e permettono di fare molti Fetch, mentre altre non ne permettono nessuno. Si pensi ad una istruzione che carica dei dati dalla memoria ai registri interni: non lascia mai i Bus sia interno che esterno liberi. Avendo più Instruction Register la probabilità di avere tempi di solo Fetch si riducono ovviamente.

Per potere fare il Prefetch occorre che ci sia un’ulteriore intelligenza di gestione di esso. In effetto oltre agli Instruction Register supplementari si deve avere un minimo processore che comanda il Prefetch.

Quando ci sono istruzioni ci CALL o di salto, JUMP, il Prefetch viene vanificato perché si salta quasi sicuramente ad istruzioni che sono fuori di quelle contenute nell’ARRAY di Instruction Registers.

Memorie CACHE

Attualmente i processori più veloci hanno il clock con un periodo di 300 picosecondi, 300 x10-12 , mentre le memorie più veloci hanno tempi di accesso di 3 nanosecondi, 3 x10-9. Inoltre oltre al tempo di accesso della memoria stessa si deve tenere conto del tempo di percorrenza del Bus esterno che so prende almeno un nanosecondo. Se la CPU legge o scrive un dato in memoria avrà quindi un WAIT che dura almeno 12 colpi di clock. Per ridurre questo tempo di attesa che rallenta enormemente la potenzialità della CPU si mette tra la CPU una memoria CACHE. La memoria CACHE è una memoria più piccola ma moltom più veloce e disposta fisicamente vicino alla CPU per contenere in tempi di attraversamento del Bus esterno. In questa memoria si trovano le istruzioni ed i dati più in uso in quel momento.

Ovviamente le istruzioni di CALL e di Jump possono portare fuori CACHE ma si sa che se la Cache è abbastanza grande la probabilità di un salto che porti fuori di essa è molto ridotta e quindi l’esecuzione dei programmi è molto accelerata. Negli anni scorsi sono state fatte alcune versioni economiche di processori che non avevano la cache ma con risultati disastrosi: i tempi di esecuzione diventavano lunghissimi.

Per quanto la si faccia piccola e la si metta vicino al processore non si riesce a raggiungere la velocità che si ha internamente al processore, per cui oltre alla Cache esterna molti processori hanno una o anche due Cache interne, una più grande e più lenta ed una più piccola che va alla velocità del processore esterno. Tutto questo per ridurre il più possibile i tempi di WAIT.

Ovviamente per gestire le varie Cache occorre una ulteriore “intelligenza” che tenga conto di dove si debba leggere un’istruzione o un dato: in quale livello di CACHE, o nella RAM, o nelle memorie di massa.

Page 14: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Estensione dell’uso delle memorie cache

Il problema della diversa velocità è presente per quasi tutte le periferiche, infatti esse hanno una velocità di accesso che è spesso molto più bassa di quella del Bus. Attualmente tutte le periferiche sono provviste di memoria Cache più o meno grande, anzi la dimensione della Cache è uno dei fattori di valutazione delle prestazioni della periferica.

Le stampanti hanno una Cache in cui accumulano i dati da stampare, le porte di ingresso/uscita hanno una Cache in cui accumulano o i dati da trasmettere o quelli ricevuti.

Le memorie di massa, hard disk, lettori di dischi ottici, hanno un Cache in cui vengono caricati le parti di memoria adiacenti ai dati richiesti, mentre ormai la Cache del floppy disk memorizza il floppy disk per intero, oppure questo viene memorizzato sulla RAM stessa per intero. Questo ultimo sistema si chiama RAM disk.

Memoria fisica e memoria virtuale

La memoria fisica è quella indirizzabile direttamente ossia memoria RAM.La memoria virtuale è la memoria globale che può indirizzare la CPU, quindi comprende

ovviamente la memoria fisica e le memorie di massa, ed ovviamente più grande.Per convenzione la memoria virtuale è divisa in pagine, anche queste di dimensione convenzionale.

La memoria fisica stessa di solito è in grado di contenere più pagine. Quando la CPU lavora vengono caricate nella memoria fisica le pagine su cui sta lavorando, ossia i File aperti, quelli su con cui si sta lavorando. La memoria fisica quindi viene “segmentata” in varie parti di programmi diversi. Quando occorrono nuove pagine di memoria virtuale e non c’è più memoria fisica disponibile avviene uno “Swap”, ossia un segmento di memoria fisica viene rimesso, aggiornato se si tratta di dati, sull’hard disk e viene al suo posto caricato il nuovo segmento utilizzato dalla CPU. Questa segmentazione e scambio viene gestita dal sistema operativo, e le prestazioni di questa gestione sono un indice importante di funzionalità e precisione del sistema operativo.

Le operazioni matematiche

Sommatore semplice

* * * *11001101 +10011100 =------------

101101001

Se noi sommiamo due numeri binari abbiamo una cifra di risultato e una di riporto per la somma da aggiungere alla somma delle due cifre successive. quindi praticamente dobbiamo essere in grado di fare una somma di tre cifre alla volta, tre cifre che possono essere 1 o 0. Se abbiamo tre 0, il totale è 0 con riporto 0; se c’è un solo 1, il totale è 1 con riporto 0; se ci sono due 1, il totale è 0 con riporto 1; se ci sono tre 1, il totale è 1 con riporto 1. Da questo consegue la allegata tavola di verità per un rete combinatoria

Page 15: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

con tre ingressi: due addendi ed il riporto dello stadio precedente, e due uscite: il totale ed il riporto per lo stadio successivo.

Da questa tavola di verità si possono ricavare le due relative mappe di Karnaugh e le relative reti logiche semplificate.

Come si vede per fare la somma bastano due reti combinatorie molto semplici.

addendo 1

addendo 2

riporto stadio

precedente

totale

riporto per stadio

successivo

0 0 0 0 00 0 1 1 00 1 0 1 00 1 1 0 11 0 0 1 01 0 1 0 11 1 0 0 11 1 1 1 1

INGRESSI USCITE

0 1 11 10

0 0 1 0 1

1 1 0 1 0

0 1 11 10

0 0 0 1 0

1 0 1 1 1

mappa per il totale

mappa per il riporto

Page 16: Questo Schema è Lo Schema Di Principio Della CPU Di Tutti i Computer

Per fare la somma di due addendi ad n bit occorrono 3 shift register a n bit. Ad ogni colpo di clock si fa la somma di due bit e del riporto dello stadio precendente. Occorrono quindi tanti colpi di clock quanti sono i bit degli addendi. il risultato potrà avere n+1 a bit a seconda se l’ultimo stadio generi riporto o no.

Questo tipo di hardware viene utilizzato solo nei processori di fascia bassa, infatti è il tipo di sommatore più lento ed economico. Lo si trova quindi solo nei processori molto economici o nelle calcolatrici con le sole 4 operazioni: non si riuscirebbe a pigiare i tasti ad una velocità tale da intasarle.

Negli altri casi si usano sommatori che fanno la somma di 4, 8, 16, 24 bit, a seconda dei casi, ad ogni colpo di clock.

Per ottenere questo risultato si fa una serie di reti logiche come in figura:

SHIFT REGISTER

FLIP FLOP

clock

RETE LOGICA SOMMATORE

SHIFT REGISTER

SHIFT REGISTER