ARCHITETTURA DI UN ELABORATORE ELETTRONICO
Il termine “architettura” riferito ai calcolatori indica l’organizzazione
logica dei loro componenti interni e le modalità in cui essi cooperano
in modo armonioso per eseguire operazioni più o meno complesse.
Pertanto l’architettura di un computer può essere dedotta dalla
conoscenza della struttura interna e dal modo in cui è possibile fare
cooperare le unità fisiche tramite un repertorio di comandi, detti
istruzioni, che definiscono il linguaggio della macchina.
Funzionamento della macchina di von Neumann
I moderni calcolatori elettronici, dai compatti personal computer ai
grandi server di Internet, funzionano tutti in base al principio del
programma memorizzato, enunciato per la prima volta nel 1945 dal
matematico John von Neumann.
Secondo questo principio, il computer deve contenere al suo interno le
istruzioni sulle operazioni da eseguire - il programma - e i dati su cui
esse operano. Solo in un secondo momento viene eseguito l’intero
calcolo, senza necessità di intervento da parte dell’uomo.
Pertanto in ogni computer è presente:
• una memoria centrale, che è un dispositivo in grado di contenere
le istruzioni costituenti il programma, i dati su cui operano e i
risultati intermedi e finali dei calcoli;
• una unità centrale di elaborazione o CPU (da Central Processing
Unit), che è il blocco funzionale che esegue le elaborazioni;
• delle interfacce di ingresso/uscita (I/U), collegate alla CPU, che
consentono al computer rispettivamente di acquisire informazioni
dall’ambiente esterno e di fornirgliene.
L’unità centrale è poi collegata con le varie sezioni del computer
mediante linee di comunicazione dette bus.
La maggior parte dei componenti
di un computer si trova oggi su
un’unica scheda di circuito
stampato, detta scheda madre o
di sistema.
Essa offre un supporto meccanico
e un collegamento elettrico ai
diversi componenti elettronici,
tramite tracce conduttive incise
su lamine di rame e depositate
su un substrato isolante.
Memoria centrale
La memoria centrale è suddivisa, dal punto di vista funzionale, in
una memoria di sola lettura o ROM (da Read Only Memory), e in
una di lettura e scrittura o RAM (da Random Access Memory).
Attualmente è realizzata con circuiti a semiconduttore, secondo una
delle tecnologie seguenti:
• TTL (da Transistor-Transistor Logic)
• ECL (da Emitter-Coupled Logic)
• n-MOS o c-MOS.
La ROM è una memoria permanente, di sola lettura, programmata
direttamente in fabbrica e non modificabile dall’utente.
Essa contiene i programmi di sistema, detti anche servizi base di
ingresso/uscita o BIOS (da Basic Input/Output Services), per cui è
detta anche ROM-BIOS.
I BIOS eseguono le operazioni elementari del computer, consentono
di comunicare con i componenti hardware del sistema e svolgono
un lavoro di supervisione e supporto, fornendo i servizi essenziali
necessari ai programmi applicativi.
In particolare essi si suddividono in tre categorie principali:
1. programmi eseguiti in fase di accensione per controllare tutti i
componenti hardware presenti, operazione detta autotest
all’accensione o POST (da Power On Self-Test), e per
inizializzare registri e parametri; sono queste routine che
determinano il ritardo che si verifica tra il momento in cui si
accende il computer e il momento in cui si può iniziare a lavorare;
2. programma di caricamento del sistema operativo dal disco di avvio
(di solito un disco fisso);
3. programmi che forniscono un controllo preciso e dettagliato delle
varie componenti del computer, quali le periferiche di I/O e le unità
disco.
Nei primi personal computer IBM la memoria ROM conteneva anche
l’interprete del linguaggio di programmazione BASIC, che veniva
attivato all’accensione e costituiva il solo ambiente operativo
disponibile.
Dal punto di vista fisico, la memoria ROM è costituita da una matrice di
celle che contengono i bit di informazione e dai circuiti di decodifica e
selezione necessari per estrarre l’informazione da una o più celle, a
seconda della lunghezza di parola della memoria (1, 4 od 8 bit,
l’ultimo valore essendo il più comune).
Supponiamo di volere realizzare una ROM costituita dalle seguenti 8
parole di 4 bit:
Dal punto di vista concettuale, potremmo realizzare una griglia di fili
conduttori da 8 righe e 4 colonne, e codificare ciascun 1 con un
contatto elettrico, e ciascuno 0 con un isolamento agli incroci dei fili:
In pratica, conviene realizzare i contatti inserendo dei diodi alimentati
in modo opportuno nei punti dei contatti elettrici (cioè dove vanno
memorizzati gli 1), ottenendosi un codificatore a matrice di diodi.
Naturalmente, una volta realizzata o scritta, una ROM deve poi essere
letta. Per questa operazione è sufficiente, in linea di principio, inviare
un segnale di tensione nella riga che si vuole leggere, e rilevare su
quali fili di colonna si presenti un segnale in uscita.
In pratica la riga da leggere riceve la tensione dall’uscita di una porta
AND a 3 ingressi, che costituisce la sezione finale di un
decodificatore di riga.
La selezione della porta AND di volta in volta attiva (che cioè deve
produrre un segnale in uscita) viene effettuata inviandole in ingresso
tre segnali di tensione (cioè tre bit 1).
I tre ingressi di ciascuna porta sono costituiti dalle otto combinazioni
che si possono ottenere dai tre bit forniti dalle tre linee di indirizzo A0,
A1, A2 in ingresso al decodificatore.
Naturalmente, solo la porta che riceve la combinazione di tre bit 1
produce un segnale in uscita.
In tal modo, nelle quattro linee di uscita Y1, Y2, Y3, Y4 si rilevano
segnali di tensione in corrispondenza dei bit 1 (cioè dei diodi) della
riga letta.
La precedente memoria ROM ha quindi la seguente tavola di verità:
Memoria di lettura e scrittura (RAM). A differenza della ROM, la
memoria di lettura e scrittura è di tipo volatile, in quanto perde i dati
memorizzati al cessare dell’alimentazione.
La sigla RAM sta per memoria ad accesso casuale, sebbene la prima
dicitura sia più pertinente, in quanto anche la memoria ROM, dal
punto di vista dell’accesso, è una memoria ad accesso casuale.
Nei personal computer la RAM ha una capacità di 512-1.024
Megabyte, e può essere realizzata secondo diverse tecnologie:
DRAM, SRAM, NOVRAM o intermedie tra esse.
Memoria RAM dinamica (DRAM). La memoria RAM dinamica o
DRAM (da Dynamic RAM), introdotta da Intel nel 1971, è di gran
lunga la più diffusa per la realizzazione delle memorie centrali dei
computer, ed è realizzata esclusivamente in tecnologia MOS.
Sfrutta come elemento di memoria la capacità della porta di un
transistore MOS, e dato che la resistenza tra porta e canale è assai
elevata, la carica si mantiene per parecchi millisecondi.
Per garantire la memorizzazione dei dati durante il funzionamento è
perciò necessario ripristinare la carica a intervalli regolari (ciclo di
refresh), di solito ogni 2 - 4 millisecondi.
Grazie alla semplicità della
cella elementare di
memorizzazione, costituita
da un solo transistore MOS,
un chip DRAM permette
elevatissime capacità di
memorizzazione (fino a 4
Megabit), assai maggiori di
quelle delle SRAM.
Una seconda caratteristica che differenzia la DRAM dalle altre
memorie a semiconduttore è che le linee di indirizzo sono
multiplexate per ridurre il numero dei piedini del chip.
Ciò comporta che la temporizzazione di una DRAM sia molto più
complessa di quella di una SRAM, sia per la tecnica di indirizzamento
sia per la necessità dei cicli di rinfresco. Le memorie DRAM sono in
genere organizzate con parole da 4 od 8 bit.
Lo schema seuente mostra come venga implementata in pratica una
memoria DRAM da 4 Megabit, con parole da 8 bit.
Memoria RAM statica (SRAM). La memoria RAM statica o SRAM
(da Static RAM) è costituita da celle realizzate a flip-flop. Ciascuno
di essi è costituito da 6 transistori MOS, e mantiene l’informazione
fin tanto che il chip è alimentato, senza bisogno di un circuito di
rinfresco.
Rispetto alla memoria DRAM
ha un tempo di accesso più
breve (10 ns contro 60) e
anche un tempo di ciclo più
breve (da una decina di ns
se in tecnologia ECL a un
centinaio di ns se in
tecnologia c-MOS), in quanto
non richiede una pausa tra
accessi successivi.
È anche più costosa da
produrre, per cui il suo uso è
limitato alle memorie cache.
Una memoria
SRAM è
costituita da
una matrice
di celle, pari
al numero di
bit, e da
circuiti di
selezione e
controllo,
come mostra
lo schema a
lato.
Memoria RAM non volatile (NOVRAM). Un tipo particolare di
memoria di lettura/scrittura è costituito dalla memoria RAM non
volatile o NOVRAM (da Not Volatile RAM), che mantiene il
contenuto anche in assenza di alimentazione elettrica.
Una NOVRAM è costituita da una memoria SRAM collegata a una
memoria di sola lettura cancellabile e programmabile (EPROM).
Allo spegnimento del sistema la sezione RAM scarica il suo
contenuto nella EPROM, che a sua volta lo riversa nella RAM alla
riaccensione.
La EPROM fa parte di una numerosa categoria di memorie
elettroniche permanenti, che possono essere scritte dall’utente
mediante apparecchiature specifiche chiamate programmatori.
Vediamo le principali.
• PROM (da Programmable ROM). Sono programmabili una sola
volta e impiegano una tecnologia a micro-fusibili, che possono
essere bruciati in modo irreversibile mediante l’applicazione di
opportuni segnali. Lo stato di ogni microfusibile è associato a un
singolo bit della PROM.
•EPROM (da Erasable PROM). Sono programmabili e cancellabili
mediante esposizione alla luce ultravioletta; si basano sull’iniezione
di una carica elettrica sulla porta isolata di un transistore MOS che
ha la funzione di memorizzare lo stato del bit a esso associato. Il
mantenimento della carica è garantito per tempi dell’ordine di alcune
decine di anni (in opportune condizioni operative).
Possono essere integralmente cancellate mediante l’esposizione a
radiazione ultravioletta di una particolare lunghezza d’onda; a tale
fine vengono alloggiate in un contenitore ceramico con una
finestrella di quarzo trasparente, attraverso il quale il chip interno
viene esposto alla luce.
•EAROM (da Electrically Alterable ROM) o EEPROM (da Electrically
Erasable PROM). Sono programmabili e cancellabili mediante
opportuni segnali elettrici. Vengono utilizzate di solito per mantenere
dati, programmi o parametri di configurazione modificabili dall’utente
durante il funzionamento del sistema.
Normalmente consentono di cancellare e riprogrammare dati a
livello di singolo byte. Consentono 10-100mila cicli di
cancellazione/scrittura.
•memorie flash. Sono simili alle
EEPROM, ma vanno cancellate a blocchi
(e non un byte alla volta). Per tale
ragione sono usate per integrare o
rimpiazzare i dischi rigidi nei computer
portatili, o come dotazione originaria o
come scheda aggiuntiva da inserire in
uno slot di tipo PCMCIA.
Consentono oltre 100mila cicli di
cancellazione/scrittura.
Unità centrale di elaborazione
La CPU può essere realizzata
da più schede contenenti
circuiti integrati e connessioni
elettriche (come nei grandi
mainframe), oppure da un
singolo circuito integrato detto
microprocessore (come nei
personal computer).
Dal punto di vista
funzionale essa è
costituita da:
• una unità di controllo
• una unità di calcolo
• vari registri
• una memoria interna.
I registri. Il principale elemento circuitale di una CPU è detto registro.
Esso è un circuito digitale in grado di memorizzare
temporaneamente una parola costituita da un certo numero di bit,
detto capacità del registro, analogamente a quanto accade in una
locazione di memoria.
I registri più diffusi hanno capacità di 16 bit, ma vi sono anche
componenti in grado di memorizzare da 4 a 64 bit; alcuni registri
inoltre hanno una capacità variabile (in genere da 1 a 64 bit) che
può essere selezionata in funzione delle esigenze di progetto.
La maggior parte dei registri usa come elementi di memorizzazione
dei circuiti detti flip-flop (gli stessi impiegati nelle celle di memoria
delle RAM statiche).
Un registro contiene in genere un dato prelevato dalla memoria per
essere elaborato dalla CPU ma, a differenza di una locazione di
memoria, esso è di solito usato per manipolare un dato, oltre che
per memorizzarlo.
Ad esempio, la parola binaria contenuta in un registro può subire le
seguenti manipolazioni:
• scorrimento di una posizione di bit a destra o a sinistra,
corrispondenti rispettivamente alla divisione o moltiplicazione per la
base del numero caricato nel registro;
• incremento o decremento di 1;
• cancellazione o reset del contenuto.
I trasferimenti e le manipolazioni di dati su un registro sono
determinati da singole istruzioni, ciascuna delle quali indica
un’operazione da eseguire. Ad esempio, vi sono istruzioni che
fanno
• caricare un registro da una locazione di memoria;
• trasferire la parola contenuta in un registro a una locazione di
memoria;
• scorrere, incrementare, decrementare o cancellare il contenuto di
un registro.
Dal punto di vista funzionale, i registri si possono dividere in
• registri speciali se hanno funzioni particolari e contengono
informazioni specifiche, e
• registri di uso generale se possono contenere dati o indirizzi.
Alcuni registri sono accessibili direttamente al programmatore, altri
sono usati dalla CPU per proprie operazioni interne.
I principali registri speciali sono il contatore di programma, il registro
indirizzi di memoria, il registro istruzioni.
Il contatore di programma o PC (da program counter), detto
anche contatore di istruzioni, memorizza una parola binaria usata
come indirizzo della locazione di memoria in cui è contenuta la
prossima istruzione da eseguire (si dice anche che esso “punta” a
quella locazione di memoria).
Si tenga presente che le istruzioni di un programma sono
memorizzate in locazioni di memoria consecutive.
Per esempio, se la prima istruzione di un programma è contenuta
nella locazione di memoria 15, il PC è caricato con l’indirizzo 15;
questo è inviato alla memoria attraverso il bus indirizzi, causando il
prelievo o caricamento, la decodifica e l’esecuzione dell’istruzione
contenuta nella locazione 15.
Dopo l’esecuzione il PC è incrementato di 1 tramite il registro
incremento/decremento indirizzi, in modo da puntare al
successivo indirizzo 16. Fanno eccezione le istruzioni di salto e di
richiamo di sottoprogrammi.
Il PC può anche essere azzerato; in tal caso la prima istruzione del
programma può essere caricata nella locazione 0.
Il registro indirizzi di memoria o MAR (da Memory
Address Register), detto anche buffer indirizzi, memorizza
l’indirizzo cui si deve accedere, e che contiene:
• un’istruzione o un dato, se si riferisce alla memoria RAM o ROM,
oppure
• un dato, se si riferisce a una porta di ingresso/uscita.
Quando si
deve accedere
a un’istruzione,
il MAR riceve
l’ingresso dal
PC (vedi
figura).
Quando si deve accedere a un dato, il MAR è caricato con la parola
binaria che punta alla locazione di quella parola in RAM; questo
indirizzo fa parte dell’istruzione.
Si noti che un contatore di programma e un buffer indirizzi a 20 bit
applicano alla RAM o alla ROM un indirizzo in grado di accedere a
220 = 1.048.576 byte di RAM e/o di ROM.
Il registro istruzioni o IR (da Instruction Register) è usato per
memorizzare temporaneamente la parola istruzione che la CPU
preleva dalla locazione di memoria indirizzata dal contatore di
programma e che gli arriva attraverso il bus dati.
L’istruzione è una parola binaria - detta anche codice operativo - che
specifica una determinata operazione e viene decodificata dalla
unità di controllo per stabilire quale funzione vada eseguita.
La capacità del registro è uguale al numero di bit che compongono
un’istruzione. Dato che contiene l’informazione relativa
all’operazione in corso di esecuzione, l’IR è detto anche registro
dell’istruzione corrente.
Le istruzioni elementari che un microprocessore può eseguire
costituiscono il suo repertorio di istruzioni (in ingl.: instruction set), e
si possono raggruppare nei seguenti gruppi principali:
1. dati, quali move, input, output, load, e store
2. aritmetiche (su numeri interi), quali add e subtract
3. logiche, quali and, or e not
4. controllo di flusso, quali goto, if ... goto, call, e return
L’unità di controllo è quella parte della CPU che ne dirige le
operazioni. Essa consiste in circuiti che controllano il flusso di
informazioni attraverso il processore e coordinano le attività delle
altre unità al suo interno.
Opera inviando segnali di temporizzazione e controllo alle altre parti
del computer, e può essere considerata una macchina a stati finiti.
Attualmente l’unità di controllo è implementata come un
microprogramma memorizzato in una apposita memoria
(generalmente una ROM oppure una PLA).
Un microsequenziatore seleziona le parole del microprogramma, i
cui bit controllano direttamente le diverse sezioni del computer,
quali i registri, la ALU, i bus e le interfacce di ingresso/uscita.
Le funzioni svolte dalla unità di controllo variano ampiamente in
base all’architettura della CPU, ma di solito comprendono le
attività di:
• prelievo
• decodifica
• esecuzione e
• memorizzazione dei risultati
delle istruzioni presenti in memoria. Tali operazioni costituiscono il
cosiddetto ciclo macchina.
Nei processori più avanzati, quali i RISC (Reduced Instruction-Set
Computer) l’unità di controllo svolge numerose altre funzioni, per
cui viene di solito suddivisa in più unità specializzate.
Per la scansione sequenziale delle operazioni svolte da una CPU è
necessario un segnale di temporizzazione o di clock.
Nei primi microprocessori tale segnale era generato da un circuito
esterno opportunamente completato da una rete oscillante, o meglio
con un oscillatore al quarzo che determinava la frequenza operativa.
I microprocessori più recenti invece contengono al loro interno un
circuito per la generazione dei segnali di clock e richiedono la sola
connessione di una rete esterna o di un cristallo al quarzo.
Il periodo dei segnali è attualmente inferiore a 10 nanosecondi
(miliardesimi di secondo), che corrisponde a frequenze superiori a
100 MegaHertz (milioni di Hertz). Lo schema di una CPU
elementare è riportato in figura.
L’unità di calcolo o unità aritmetico-logica (ALU, da Arithmetic Logic
Unit) è costituita da alcuni registri e da un circuito logico digitale che
esegue le varie operazioni aritmetiche e logiche comandate dalla
sezione di controllo.
Il principale registro di una ALU è l’accumulatore, la cui capacità è
uguale a quella di una locazione di memoria: un microprocessore a
32 bit ha un accumulatore a 32 bit.
L’accumulatore può essere caricato dalla memoria e il suo
contenuto può essere memorizzato in qualsiasi locazione di
memoria; in alcuni microprocessori anche le operazioni di
ingresso/uscita con le unità periferiche avvengono attraverso
l’accumulatore.
L’ALU può elaborare due ingressi, provenienti uno dall’accumulatore
e uno dalla memoria o da un altro registro.
Con riferimento alla figura, si
supponga di volere sommare due
numeri binari. A tale fine:
• si carica uno di essi (l’augendo)
nell’accumulatore tramite
un’istruzione CARICA
L’ACCUMULATORE, che preleva il
numero da una locazione di
memoria, quindi
• si esegue un’istruzione ADD che
preleva un’altra parola
(l’addendo) dalla memoria, la
pone in un registro temporaneo
e la somma al contenuto
dell’accumulatore.
La somma è memorizzata ancora nell’accumulatore, dove
sostituisce l’augendo preesistente (si può determinare anche una
diversa destinazione per il dato in uscita dalla ALU).
Questa procedura è la stessa per qualsiasi operazione aritmetica o
logica: ad esempio in una sottrazione si carica il minuendo
nell’accumulatore, il sottraendo nel registro temporaneo e
quindi lo si sottrae. Eseguita l’operazione, la differenza si trova
nell’accumulatore, dove sostituisce il minuendo.
In realtà, l’uscita dell’accumulatore alimenta il latch dell’accumulatore,
che è un altro registro che conserva il contenuto dell’accumulatore e
fornisce alla ALU uno dei due ingressi (l’altro provenendo dal
registro temporaneo).
In un’altra architettura molto
diffusa, la cosiddetta registroregistro, si possono indicare le
provenienze di entrambi gli
operandi e il registro di
destinazione.
Naturalmente, questo approccio
richiede una espansione del
repertorio di istruzioni del
microprocessore, in modo da
contenere anche i campi della
provenienza e della destinazione
degli operandi.
In ogni caso, il funzionamento
della ALU viene determinato
da un segnale inviato dalla
unità di controllo, mentre il
risultato in uscita comprende
anche informazioni aggiuntive
inviate a uno speciale registro
detto registro di stato.
Il registro di stato è un altro registro della ALU, costituito da
8 bit ciascuno dei quali è detto flag e solo alcuni dei quali sono
utilizzati.
I valori dei flag indicano il verificarsi di determinate situazioni
conseguenti all’esecuzione di un’operazione aritmetica da parte
della ALU.
Infatti quando questa esegue un’operazione aritmetica si producono due
dati:
• il risultato vero e proprio (inviato all’accumulatore), e
• un vettore binario (inviato al registro di stato) le cui
componenti danno una serie di informazioni sul tipo di risultato
ottenuto.
I bit contenuti più di frequente nel registro di stato hanno i nomi
e i significati indicati in tabella.
La parola binaria contenuta nel registro di stato è detta anche parola
di stato del processore o PSW (da processor status word).
Osserviamo che nelle figure precedenti abbiamo indicato un solo
accumulatore; tuttavia le CPU più recenti hanno 4, 8 o anche 16
accumulatori, detti di solito registri di uso generale, ciascuno dei
quali può usare la ALU e fungere da locazione di memoria
temporanea per i dati e i risultati intermedi dei calcoli.
Tali registri multipli semplificano e rendono più veloce l’esecuzione
di una data operazione da parte di un programma. Il fatto che più
accumulatori condividano una stessa ALU permette maggiore
flessibilità e velocità nel manipolare i dati e nel selezionare le loro
sorgenti e destinazioni rispetto a un solo accumulatore.
Memoria cache. I microprocessori più recenti sono dotati di una
piccola memoria, detta cache, che conserva le istruzioni e i dati usati
più spesso oppure più di recente, in modo da rendere più veloce
l’accesso alle informazioni richieste.
Quando le istruzioni o i dati richiesti dal microprocessore sono presenti
nella cache, il tempo necessario per richiamarli è di gran lunga
inferiore a quello che sarebbe necessario se quelli stessi fossero
presenti nella memoria principale.
Se viene usata in modo opportuno, la cache determina un netto
miglioramento delle prestazioni, riducendo il tempo di esecuzione di
un’istruzione.
Naturalmente, al crescere della quantità di cache installata nel sistema,
aumentano le probabilità che il processore vi trovi le informazioni
necessarie.
Secondo indagini recenti, è risultato che nel 95% dei casi le istruzioni e
i dati richiesti da un programma si trovano nella cache.
La presenza della cache può non avere effetti di rilievo nel caso di
programmi molto piccoli o progettati in modo disordinato, ma se
viene usata in modo intelligente si ottiene un miglioramento delle
prestazioni.
Per ottimizzare le prestazioni della memoria cache non vi sono regole
precise, e l’utente in genere non ha modo di modificarne l’utilizzo.
Il tipo di cache più semplice è quella diretta, che conserva in un solo
blocco i dati delle aree più usate della memoria centrale.
Un tipo più sofisticato è la cache associativa, in grado di conservare
2, 4 o anche 8 blocchi di dati prelevati da altrettante aree di
memoria principale usate più di frequente.
Una cache può essere poi unificata se contiene istruzioni e dati,
oppure divisa se costituita da due porzioni separate, una per le
istruzioni e l’altra per i dati. La seconda soluzione è maggiormente
adottata nei sistemi più recenti.
In anni recenti è stata inserita nella scheda madre una seconda cache,
più grande e più lenta, detta cache di secondo livello
Pipeline
Oltre alla memoria cache, un altro accorgimento che si usa per
rendere più veloce il funzionamento di un microprocessore è la
pipeline (letteralmente: tubazione).
Mentre le prime CPU elaboravano le successive istruzioni del
programma in modo sequenziale attraverso le fasi di prelievo,
decodifica ed esecuzione,
quelle successive, dotate di pipeline, eseguono simultaneamente più
istruzioni, ciascuna a uno stadio diverso nella sua sequenza di
elaborazione, con un aumento del numero di istruzioni elaborate per
secondo.
In particolare la tecnica consente, a parte i primi e gli ultimi cicli, di
eseguire in un ciclo tante istruzioni quante sono le fasi in cui è
stata frazionata l’esecuzione di una istruzione.
Pertanto si può aumentare tale numero di fasi – detto profondità
della pipeline – realizzando le cosiddette pipeline estese.
In figura è mostrato lo schema di una pipeline a 5 stadi.
Naturalmente l’approccio a pipeline può dare luogo a situazioni critiche
quando s’incontrano istruzioni di salto.
Per risolvere queste ultime si adottano varie strategie, quali i salti
ritardati, la previsione dei salti e l’esecuzione di altre istruzioni
durante i tempi dei salti ritardati.
Stack. Lo stack (pila, catasta) è una struttura realizzata per la
memorizzazione temporanea di indirizzi e dati contenuti in alcuni
registri del microprocessore - tipicamente contatore di programma,
registro istruzioni e accumulatore - se la normale sequenza di
esecuzione di un programma viene interrotta, in genere per eseguire
un sottoprogramma o per gestire una interruzione.
Può essere realizzato tramite particolari registri dedicati (stack
hardware) oppure all’interno della memoria RAM (stack software). Lo
stack hardware ha il vantaggio di essere molto veloce, ma una
capacità limitata dal numero di registri impiegati, e quando si è
riempito deve essere copiato in una zona di memoria.
Lo stack software, sebbene possa essere definito come una zona
qualsiasi di RAM, è localizzato di solito nella parte identificata dagli
indirizzi alti di memoria: ad esempio in un microprocessore con 1
Megabyte di RAM, lo stack inizia all'indirizzo 1.048.576; la sua
ampiezza è variabile e dipende da come esso viene utilizzato:
raramente supera alcune centinaia di byte.
Puntatore di stack. L’indirizzo della prima locazione libera dello stack,
detta cima dello stack, è contenuto in un registro detto puntatore di
stack o SP (da stack pointer).
Il suo contenuto, analogamente al contatore di programma, punta a una
locazione di RAM; pertanto esso deve essere in grado di indirizzare
qualsiasi locazione di RAM, ed è quindi un registro a 20 bit (vedi figura).
Il contenuto di un registro è memorizzato nello stack tramite
l’istruzione PUSH e prelevato tramite l’istruzione POP.
Poiché ogni dato occupa una locazione di memoria, quando una
parola è inserita (push) nello stack il puntatore di stack è
decrementato di 1, cosicché i successivi dati provenienti dai registri
sono memorizzati in locazioni di indirizzi progressivamente
decrescenti.
Ad esempio, se un’istruzione PUSH memorizza una parola nella
locazione 1.048.575, il puntatore di stack è decrementato a
1.048.574, cosicché la successiva istruzione PUSH memorizzerà
un nuovo dato nella locazione con questo indirizzo.
Pertanto il puntatore di stack punta sempre alla locazione di
indirizzo immediatamente inferiore a quello dell’ultima parola
memorizzata nello stack.
Quando un dato è estratto (POP o PULL) dallo stack, il puntatore
di stack è incrementato di 1, cosicché i dati vengono richiamati
in ordine inverso a quello con cui sono stati memorizzati, cioè
iniziando dall’ultimo memorizzato.
Per questa ragione lo stack ha un’organizzazione di tipo “ultimo
entrato - primo uscito”, detta anche LIFO (da last in - first out).
Nelle CPU che operano in multiprogrammazione l’uso del
puntatore di stack è di fondamentale importanza: in tal caso
è utile avere a disposizione più puntatori di stack, che consentono
di gestire separatamente più aree di memoria come pile distinte.
Si possono avere, per esempio, tre puntatori di stack usati dal
sistema operativo, e uno usato dai programmi utente.
Bus del microprocessore
La CPU è collegata alla memoria e alle interfacce per le unità
periferiche tramite circuiti di collegamento detti bus interni.
Questi sono costituiti da un certo numero di linee parallele (di solito 8,
16 o 32) ciascuna delle quali offre un percorso fisico per ogni bit del
dato da trasmettere.
In tal modo tutti i bit di una parola binaria sono trasferiti
simultaneamente dalla sorgente alla destinazione (trasmissione
parallela).
I microprocessori
hanno di solito tre
bus interni: un
bus dati, un bus
indirizzi e un bus
di controllo.
Esiste poi un bus esterno, detto bus di espansione, che consente di
aggiungere dispositivi hardware a un personal computer usando
connettori standard.
Bus dati. Il bus dati fornisce il percorso fisico per tutti i trasferimenti di
dati tra registri della CPU, memoria RAM/ROM e sezione di
ingresso/uscita; questi trasferimenti avvengono in tempi di pochi
nanosecondi.
In particolare, sul bus dati transitano:
• le istruzioni prelevate dalla memoria e dirette al registro istruzioni;
• i dati che provengono dalla memoria o da un dispositivo periferico
tramite la sezione di ingresso/uscita e sono diretti agli
accumulatori o ad altri registri;
• i dati trasferiti da un accumulatore alla RAM in un’operazione di
memorizzazione, oppure a un dispositivo periferico quale un tubo
a raggi catodici.
Dato che consente il passaggio dei dati in entrambe le direzioni, il
bus dati è di tipo bidirezionale.
Per evitare conflitti di livelli logici sulle linee il bus deve essere
collegato a una sola sorgente di dati per volta, ma può essere
collegato a una o più destinazioni contemporaneamente.
Per abilitare selettivamente le varie sorgenti connesse al bus si
usano circuiti detti multiplatori di bus e/o piloti di linea a tre stati.
Questi ultimi sono componenti paragonabili a interruttori, che
permettono di collegare o no una linea logica a un’altra, a seconda
dello stato di una linea di controllo.
Bus indirizzi. Per comunicare con il mondo esterno un
microprocessore deve avere capacità di indirizzamento, in modo da
selezionare solo il dispositivo con il quale intende comunicare in un
dato istante.
A tal fine è usato il bus indirizzi, che permette i trasferimenti nel solo
verso CPU  circuiti esterni. Per tale ragione esso è di tipo
unidirezionale.
Normalmente il bus indirizzi ha una larghezza maggiore del bus dati,
a esempio 32 bit, potendo così indirizzare 232 = 4.294.967.296 ($
Giga) locazioni o indirizzi diversi.
Bus di controllo. La semplice selezione di un dispositivo non è
sufficiente per stabilire se l’operazione richiesta sia di lettura o di
scrittura: per completare le informazioni scambiate con il mondo
esterno il microprocessore dispone perciò di altre linee, dette bus di
controllo, pilotate direttamente dall’unità di controllo.
I segnali che esso trasporta determinano in ogni ciclo macchina il tipo
di operazione che la CPU svolge.
Nel caso più semplice è presente una sola linea di lettura/scrittura
(read/write, o RW), il cui stato logico definisce l’operazione da
eseguire: lettura (R/W=0) o scrittura (R/W=1).
In altri casi è presente una seconda linea ingresso/uscita/memoria
(input/output/memory, o IO/M), che indica se l’operazione è relativa
a porte di ingresso/uscita (IO/M=1) o alla memoria (IO/M=0).
In altri casi l’operazione è indicata tramite quattro linee, che possono
essere:
• IO/R
• IO/W
• MEMR
• MEMW
(I/O read) per lettura da ingresso/uscita,
(I/O write) per scrittura da ingresso/uscita,
(Memory read) per lettura da memoria,
(Memory write) per scrittura da memoria.
Le quattro linee possono essere anche I/O, MEM, IN, OUT e la
loro selezione, a coppie, consente di ottenere le stesse funzioni.
Bus di espansione. Il bus di espansione o di ingresso/uscita, nel
quale s’inseriscono le schede di espansione, è una estensione della
CPU, in quanto aggiungendo su esso delle schede si estendono le
capacità della CPU stessa.
La rilevanza di questo rispetto al BIOS è che le schede più vecchie
sono meno in grado di fare fronte ai moderni bus che operano a
velocità più elevate rispetto a quelle originarie di 8 MegaHertz o
valori di poco superiori.
Inoltre, quando si accede al bus, l’intero computer rallenta fino alla
velocità del bus, cosicché è spesso opportuno alterare la velocità
del bus o gli stati di attesa tra esso e la CPU per rendere più
veloci le operazioni.
I principali bus di espansione utilizzati dai personal computer sono
stati, in ordine cronologico,
• ISA (da Industry Standard Architecture), introdotto nel 1984 con il
primo pc IBM; oramai sorpassato.
• MCA (da Micro Channel Architecture), standard proprietario IBM del
1987, incompatibile con gli altri;
• EISA (da Extended Industry Standard Architecture), evoluzione di
ISA, del 1988; anch’esso sorpassato;
• VLB (da VESA Local Bus), introdotto nel 1992; oramai sorpassato;
• PCI (da Peripheral Component Interconnect), introdotto dalla Intel a
metà del 1993;
• USB (da Universal Serial Bus) introdotto nel gennaio 1996;
• HyperTransport, introdotto nell’aprile 2001;
• CSI (da Common System Interface) annunciato dalla Intel per il
2008.