Calcolatori Elettronici 1
by Pizzi
TEORIA 1:
Generazione 0 (Meccanica):
• Pascal (1650 ~): addizioni e sottrazioni
• Leibniz (1700 ~): anche moltiplicazioni e divisioni
• Babbage (1850 ~): macchina differenziale – analitica. Prima macchina programmabile.
Macchine elettromagnetiche:
• Zuse (1930 ~): macchina a relè.
• Atanasoff (1940 ~): aritmetica binaria, memoria a condensatori.
• Aiken (1940 ~): versione a relè della macchina di Babbage.
Generazione 1 (Valvole termoioniche):
• Colossus (1940 ~).
• Eniac (1946 ~): 18000 valvole, peso di 30 tonnellate, 140 Kw di assorbimento, programmabile
tramite 6000 interruttori e pannelli cablati, 20 registri da 10 cifre.
• Von Neumann (1950 ~): programma memorizzato, aritmetica binaria, istruzioni a 16 bit. Costituita da
5 parti:
1. una memoria principale contenente 4096 parole da 40 bit
2. l’unita aritmetico logica (ALU), contenente uno speciale registro da 40 bit
3. l’unità di controllo
4. dispositivi di input
5. dispositivi di output
• IBM (1953): lancio del calcolatore IBM 701, dal quale ne scaturirono altri. Aveva una memoria da 2 K
word di 36 bit
Generazione 2 (transistor):
• TX0 e TX2 furono le prime due macchine sperimentali. Uno dei progettisti della TX2 fondò una
propria società, la DEC (Digital Equipment Corporation) che produsse il PDP-1 (1961): memoria con
4 K word di 18 bit, prezzo meno di un decimo dell’IBM 7090 (successivo al 701) con prestazioni
simili. Ciò diede il via alla produzione di massa.
• Il successore del PDP-1 fu il DEC PDP-8 (1965). Aveva l’interconnessione a bus e l’architettura
incentrata su l’ I/O. Ne furono prodotti oltre 50000 esemplari. Fu il primo minicomputer.
• Nacquero i supercomputer: macchine molto potenti, 10 volte più veloci del 7090. Avevano un
architettura molto sofisticata e un parallelismo interno alla CPU.
Generazione 3 (circuiti integrati):
• Ci fu un’evoluzione per quanto riguarda l’hardware: introducendo la microprogrammazione, come
compromesso tra l’ hardware e il software; consisteva in un livello intermedio per far sì che i
programmi fossero interpretati direttamente dall’hardware, riducendo drasticamente le parti
elettroniche. Furono introdotte unità veloci floating-point. Furono inseriti processori ausiliari per la
gestione dell’ I/O.
• Ci fu un’evoluzione anche per il software: fu inventato il sistema operativo. Fu inserita la
multiprogrammazione, ossia l’esecuzione concorrente di più programmi. Vennero virtualizzate le
risorse, creando la memoria virtuale, grazie alla quale vennero eliminate le limitazioni della memoria
fisica.
• L’ IBM creò la serie IBM System/360, la prima famiglia di elaboratori. Queste macchine avevano lo
stesso linguaggio ed erano compatibili totalmente tra loro. La compatibilità tra calcolatori prese il
nome di architettura, quindi i nuovi calcolatori dovevano avere una sola architettura. Avevano
maggiori prestazioni ma con costo minore ed uno stesso sistema operativo, l’ OS/360. Questa nuova
tipologia di calcolatori permise l’aggiunta o la correzione di istruzioni anche dopo la consegna della
macchina. Successivamente fu creato il successore del DEP PDP-8, il DEP PDP-11; aveva parole di
memoria a 16 bit, un’architettura a bus e ne furono prodotti milioni di esemplari.
Generazione 4 (PC):
• IBM (1980): fu il diretto discendente del minicomputer. Aveva un’architettura a bus e parole, e
istruzioni a 16 bit. Ci fu un abbattimento dei costi ed un’enorme espansione dell’utenza. Dai Centri di
elaborazione si passò all’ Informatica distribuita. L’ espansione del PC avvenne per 3 fattori
principali: l’aumento delle capacità delle CPU, la discesa dei costi della memoria e dei dischi.
• LEGGE DI MOORE: un calcolatore raddoppia le sue caratteristiche ogni 18 mesi.
TEORIA 2:
Per programmare un calcolatore a livello hardware si usano due livelli di linguaggio: il livello L0, eseguito
direttamente dai circuiti elettronici, ossia dalla macchina fisica M0; il livello L1, interpretato dal livello L1 ed
eseguito dalla macchina virtuale M1. Ci sono due modi per eseguire il linguaggio macchina L1 in L0: la
traduzione e l’interpretazione: per quanto riguarda la traduzione, l’intero programma L1 viene convertito in un
programma L0, il programma L1 viene eliminato e viene caricato in memoria il programma L0;
l’interpretazione, invece, fa sì che ogni istruzione del linguaggio L1 viene esaminata, decodifica ed eseguita
immediatamente, senza generare un programma tradotto. Più il linguaggio è di livello alto, più è facile da
programmare in quanto è più adatto all’uomo; viceversa, più un linguaggio è di livello basso, ossia adatto
all’hardware, più è adatto alla macchina e difficile da programmare. Di conseguenza da L1 scaturirà L2 per
M2 e così via… Interpreti e traduttori sono stati creati dai programmatori di sistema.
•
Livello 0: logica digitale
• Livello 1: blocco di circuiti che eseguono
istruzioni macchina
• Livello 2: livello linguaggio macchina, codice
binario
• Livello 3: sistema operativo
• Livello 4: linguaggio assemblativo (di basso
livello). Ogni istruzione, operazione può
essere trasformato in linguaggio binario.
• Livello 5: linguaggi di alto livello
Il livello più basso prende il nome di livello logico
digitale, dove gli oggetti principali sono le porte.
Le porte sono costituite da componenti analogici,
come i transistor, e possono essere modellate come
dispositivi digitali. Ogni porta ha segnali di input
corrispondenti a 0 o 1. L’insieme di porte che
possono memorizzare 0 o 1 prende il nome di
registro. Ogni registro è in grado di memorizzare
un singolo numero binario non più grande di un
certo valore. I registri sono collegati all’ALU
(Unità Aritmetico Logica) grazie a un data path
(collegamenti elettrici per il trasferimento dati)
che trasporta i dati. La funzione principale è
leggere il contenuto di due registri, sommarlo
nell’ALU e memorizzarne il risultato in altri
registri. Su alcune macchine il funzionamento del
data path viene controllato da un microprogramma
o direttamente dall’hardware. Un’istruzione che compare ad un livello può comparire anche ad altri livelli. Dal
livello 4 in su, si abbandona la programmazione del linguaggio macchina numerico per programmi di
applicazioni con problemi da risolvere. Quest’ultima tipologia di programmi contiene pure parole e
abbreviazioni. Un calcolatore viene progettato come una serie di livelli, ognuno dei quali si basa sul livello
precedente. L’insieme di tipi di dati, operazioni e caratteristiche di ogni livello prende il nome di architettura,
ossia le caratteristiche visibili al programmatore. Lo studio riguardante la progettazione dell’ architettura si
chiama architettura dei calcolatori.
I primi calcolatori nel ’40 possedevano solamente due livelli: il livello ISA, dove veniva eseguita tutta la
programmazione, e il livello logico digitale. Nel 1951 fu introdotto il calcolatore a 3 livelli per semplificare
l’hardware. Il livello intermedio era un interprete non modificabile (il microprogramma) che interpretava i
programmi del livello ISA. Di conseguenza l’hardware fu ridotto eliminando circuiti, perché doveva eseguire
un instruction set limitato (quello del livello intermedio) e non più l’ampio instruction set del livello ISA.
Inizialmente i calcolatori erano “open shop”, ossia il programmatore doveva far funzionare la macchina
personalmente, senza sistema operativo. Una volta diffusa la microprogrammazione i progettisti si resero
conto che si potevano aggiungere nuove istruzioni macchina all’hardware per mezzo della programmazione.
I vantaggi della microprogrammazione erano la semplicità di correggere errori (in quanto ogni istruzione
veniva divisa in una sequenza di mini istruzioni) e la facilità di aggiungere nuove istruzioni.
La parte fondamentale di un calcolatore è la CPU (Control Processing Unit). Il suo compito consiste
nell’eseguire i programmi immagazzinati nella
memoria centrale, leggendo, esaminando ed
eseguendo sequenzialmente le istruzioni. I
componenti sono collegati per mezzo di un bus,
che è un insieme di fili paralleli utilizzati per il
trasferimento di indirizzi, dati e segnali di
controllo. Il processore è composto da un’unità
di controllo che legge le istruzioni della memoria
centrale e ne determina il tipo; dall’ ALU, che
serve per eseguire operazioni come l’addizione;
da vari registri. I più importanti sono: il PC
(Program Counter) che indica l’istruzione da
recuperare ed eseguire; l’IR (Instruction
Register), che memorizza le istruzioni da
eseguire in quel momento. Inizialmente c’era
anche un altro registro, l’AC (Accumulator),
che memorizzava i risultati aritmetici, ma venne
eliminato in quanto rallentava la comunicazione
dei dati. Ci sono inoltre anche altri registri, per
memorizzare il tipo di istruzione attuale,
l’indirizzo dell’operando dell’istruzione, l’attuale
operando… I registri sono collegati a due registri
di input (A e B) che servono per memorizzare i
dati di ingresso dell’ALU mentre esegue i calcoli. L’ALU esegue addizioni, sottrazioni ed altre semplici
operazioni sugli ingressi e memorizza il risultato nel registro di uscita. In seguito il contenuto del registro sarà
immagazzinato in memoria. La gran parte delle istruzioni si può dividere in due categorie: registro-memoria
oppure registro-registro. Nel primo caso le parole (dati) vengono prese dal registro e messe in memoria, nel
secondo caso si prende un valore di un registro e si memorizza in un altro registro. Un esempio è ciò che fa
l’ALU, prendendo due operandi da registri e memorizzando il risultato in un altro registro. Ciò prende il nome
di ciclo del data path. La CPU esegue ogni istruzione tramite un ciclo (Fetch-Decode-Execute):
1. Carica l’istruzione dalla memoria e mettila nell’ IR (Fetch)
2. Cambia il PC per indicare l’istruzione seguente
3. Determina il tipo di istruzione appena letta (Decode)
4. Se l’istruzione usa una parola in memoria determina l’indirizzo
5. Carica la parola in un registro della CPU
6. Esegui l’istruzione (Execute)
7. Torna al primo punto e ricomincia per l’istruzione successiva
Per quanto concerne l’esecuzione di istruzioni bisogna stabilire se è meglio far eseguire le istruzioni
direttamente dalla CPU o se è meglio che vengano prima interpretate. Nel primo caso (esecuzione diretta)
l’hardware esegue direttamente le istruzioni, però ciò comporta un numero di istruzioni limitato, la
progettazione dell’ hardware più complessa, ma una migliore efficienza. Nel secondo caso (interpretazione)
si fanno eseguire all’hardware solamente alcune operazioni elementari, le istruzioni macchina, con ciascuna
operazione scomposta in una successione di operazioni base. I vantaggi di quest’ultimo metodo sono un
repertorio maggiore di istruzioni, un hardware più compatto perché non deve eseguire istruzioni macchina, e
un progetto più flessibile perché non c’è bisogno di modificare l’hardware aggiungendo istruzioni.
La prima tipologia di processori creata fu la CISC (Complex Instruction Set Computer). Questa tipologia si
basava sull’interpretazione delle istruzioni: si aveva un repertorio esteso di istruzioni, in parte contenute
anche nella memoria. Per questa ragione, per eseguire un istruzione, servivano centinaia di cicli macchina.
Successivamente, negli anni ’80, vennero creati i processori con architettura RISC (Reduced Instruction Set
Computer), che si opponevano ai primi in quanto sostenevano che era meglio disporre di un numero limitato
di istruzioni, contenute nei registri, da eseguire direttamente, ma con ogni istruzione eseguita solamente da
un ciclo macchina. Con l’esecuzione diretta delle istruzioni i progettisti pensavano che questa seconda
tipologia di CPU fossero più veloci delle macchine CISC, in quanto sebbene servissero 4 o 5 istruzioni nella
macchina RISC invece di una nella CISC, le istruzioni RISC erano potenzialmente 10 volte più veloci perché
non venivano interpretate. I computer moderni basarono la loro progettazione sull’architettura RISC, ossia
con l’esecuzione diretta delle istruzioni più frequenti. Le istruzioni vennero fatte eseguire direttamente dall’
HW in quanto, eliminando l’interpretazione, aumentava la velocità di esecuzione. I calcolatori moderni sono
costruiti per ottimizzare le loro prestazioni, ossia eseguire più istruzioni possibili al secondo, misurate in
MIPS (milioni di istruzioni al secondo). Per far ciò, occorre che le istruzioni abbiano una struttura regolare,
con una lunghezza fissa e un numero limitato di campi, per poter essere decodificate. Uno dei migliori modi
per suddividere l’istruzione in semi-istruzioni è fornire registri agli operandi di scrittura (store) e lettura (load).
Dato che l’accesso alla memoria è molto lento, una volta letta una parola, si può tenere in un registro fino a
quando serve. Il modo per aumentare le prestazioni è quello del parallelismo, ossia l’esecuzione di due o più
operazioni contemporaneamente. Il parallelismo ha due forme principali: a livello di istruzioni e a livello di
processore. Nel primo caso il parallelismo viene utilizzato all’interno di ogni istruzione per ottenere più
istruzioni al secondo, nel secondo caso CPU multiple lavorano insieme allo stesso problema.
Per non far leggere le istruzioni dalla memoria (per la lentezza dell’operazione) vennero introdotti dei registri
dove venivano memorizzate le istruzioni lette dalla memoria per poterle eseguire quando necessario. Questi
registri prendono il nome di prefetch buffer. Il prefetching divide l’esecuzione delle istruzioni in due fasi:
lettura dalla memoria ed esecuzione. Questo concetto viene esteso dalla pipeline. Invece di dividere
l’esecuzione delle istruzioni in due fasi, il pipeline la divide in molte fasi, ognuna delle quali viene gestita da
un pezzo dell’ HW. Il numero di fasi, ossia il numero di stadi, indica quante esecuzioni si possono eseguire
contemporaneamente con la pipeline. Per esempio una pipeline a 5 stadi consiste in:
1. legge l’istruzione dalla memoria e la mette in un buffer finché non serve (fetch)
2. decodifica l’istruzione determinandone il tipo e gli operandi richiesti (decode)
3. individuazione e recupero operandi richiesti dai registri o dalla memoria (indirizzamento
istruzione)
4. esecuzione dell’istruzione (execute)
5. invio risultati a un registro appropriato (memorizzazione del risultato in un registro).
La pipeline consente un compromesso tra latenza (tempo per eseguire un’istruzione) e ampiezza di banda
del processore (MIPS della CPU). Con una velocità di ciclo T nsec e un numero di stadi n, la latenza sarà di
nT nsec, mentre l’ampiezza di banda sarà di 1000/T
MIPS.
Architetture superscalari: Per aumentare il
parallelismo bisogna aumentare il numero di pipeline.
Questa tipologia, oltre che dai processori RISC, fu
adottata da Intel con il processore 486, dotato di due
pipeline. In questo caso vengono lette due istruzioni
alla volta e messe in due pipeline differenti, ognuna
con una propria ALU. Per poter essere eseguite in
parallelo, le due istruzioni non devono essere in
conflitto sull’uso delle risorse (per esempio lo stesso
registro) e devono essere indipendenti. Se le due
istruzioni sono incompatibili, viene eseguita soltanto la
prima. Il Pentium 486 utilizzando questa tecnologia,
riusciva a essere il doppio più veloce degli altri
processori aventi la stessa frequenza di clock. Con
una CPU di alto livello si ha una pipeline sola, ma con
unità funzionali multiple. Lo stadio S3 invia istruzioni
molto più velocemente di quanto lo stadio S4 le
esegue.
Parallelismo tra CPU: per avere velocità più elevate, l’unico modo è avere calcolatori con CPU multiple. Un
modo per avere una struttura parallela regolare è utilizzare l’array d’array, ossia una matrice. Su questa
concezione si basa l’array processor, composto da un gran numero di processori identici che eseguono la
stessa sequenza di istruzioni su un insieme di dati diverso. Il primo array processor fu l’ILLAC IV. Un’altra
tipologia è il vector processor. Come l’array processor, è molto efficiente nell’esecuzione di operazioni su
coppie di elementi di dati ma, contrariamente all’array processor, tutte le operazioni di addizione vengono
eseguite in un unico sommatore dotato di molte pipeline. Tutti e due lavorano su array di dati ed eseguono
singole istruzioni però, mentre l’array processor lo fa con tanti sommatori quanti sono gli elementi nel vettore,
il vector processor può leggere dalla memoria una sola istruzione (concetto di registro vettoriale). Gli array
processor sono in grado di eseguire operazioni sui dati con prestazioni migliori rispetto al vector processor,
ma richiedono molto più HD perchè la vettorizzazione viene eseguita grazie all’unità vettoriale, ma per il
resto si possono utilizzare processori tradizionali.
Il primo sistema parallelo con CPU multiple è il multiprocessore, un sistema con più CPU che condividono
una memoria comune. L’implementazione più semplice è un unico bus che collega tutte le CPU e la
memoria. Il bus, in questo sistema, è il collo di bottiglia, in quanto tutte le memorie tendono ad appropriarsi
del bus per accedere alla memoria. Un altro sistema consiste nel fornire a ogni CPU un po’ di memoria
locale, non accessibile dalle altre CPU. L’accesso a questa memoria non avviene per mezzo del bus
principale e quindi si riduce molto il traffico.
La memoria principale: La memoria è
quella parte di calcolatore dove vengono
immagazzinati programmi e dati. L’unità
base della memoria è un numero binario
chiamato bit, che rappresenta la cifre 0 o 1.
8 bit formano un byte. Le memorie si
compongono di un numero di celle (o
locazioni) ognuna delle quali memorizza una
parte di informazione. Ogni cella ha un
numero, chiamato indirizzo, che serve per
accedere all’informazione. Se una memoria
ha n celle, i loro indirizzi andranno da 0 a n 1. Tutte le celle di memoria contengono lo
stesso numero di bit. Se una cella è
composta da k bit, è in grado di contenere
(spazio di indirizzamento) 2k combinazioni di
bit. Il numero di bit nell’indirizzo determina il
numero massimo di celle direttamente
indirizzabili dalla memoria ed è indipendente
dal numero di bit per cella. Lo standard
richiede celle di un byte. I byte vengono
raggruppati in parole. Il motivo per cui
vengono utilizzate le parole (anziché singoli
byte) è perchè le istruzioni funzionano su parole. I byte di una parola si possono enumerare da sinistra a
destra e viceversa. Il primo caso prende il nome di big endian (tipologia IBM), il secondo di little endian
(tipologia Intel). I problemi sorgono quando una delle macchine cerca di inviare un record all’altra per mezzo
di una rete. La trasmissione inverte l’ordine dei caratteri nella parola, ma anche i byte del numero intero. La
soluzione migliore, per ovviare a questo problema, è invertire i byte della parola dopo che è stata fatta la
copia. La colonna a destra rappresenta i bit meno significativi.
Correzione degli errori: Le memorie dei calcolatori possono
commettere errori a causa di disturbi. Per prevenire ciò, alcune
memorie usano codici di identificazione o correzione degli errori.
L’uso di questi codici consiste nell’aggiungere a ogni parola dei bit
in eccesso per il controllo. Quando si legge una parola, i bit in
eccesso vengono controllati per vedere se si sono verificati errori.
Se una parola della memoria consiste di m bit, verranno aggiunti r bit di ridondanza, detti bit di controllo. La
lunghezza totale sarà n (n = m + r), ossia si avrà un codice a n bit. Date due parole di codice qualsiasi, è
possibile determinare quanti bit corrispondenti sono diversi. E’ sufficiente calcolare l’EXCLUSIVE OR bit a bit
delle due parole e contare il numero di bit 1. Il numero minimo di bit diversi tra due codifiche valide si chiama
distanza di Hamming (= h ). Per individuare d errori di un bit serve un codice con distanza h = d + 1. Per
correggere d errori di un bit serve un codice con distanza h = 2d + 1. Quando una parola con parità sbagliata
viene letta dalla memoria, viene segnalata una condizione di errore. Se il codice ha distanza h = 5, significa
che si possono correggere errori doppi (d = 2) e rilevare errori quadrupli (d = 4). Ognuna delle 2m codifiche
valide ha n codifiche errate a distanza 1 da ciascuna delle valide. Queste si formano invertendo ognuno degli
n bit nella parola. In questo modo, ogni codifica richiede n + 1 configurazioni per 2m codifiche valide. Il bit di
controllo prende il nome di bit di parità e fa sì che il numero complessivo di 1 nella codifica sia sempre pari (o
dispari). Per rilevare errori serve un solo bit, per la correzione i bit aumentano a seconda della lunghezza
della parola. Il bit di parità aggiunge 0 ad ogni potenza di 2 contenuta nella parola, se gli 1 del controllo della
posizione sono pari; altrimenti aggiunge 1. Nel primo caso i bit sbagliati sono con 1 dispari, nel secondo con
1 pari. Una parola di 16 bit avrà 5 bit di parità (20, 21, 22, 23, 24). Il primo bit controlla le posizioni (prima
esclusa): 1,3,5,7,9,11,13,15,17,19,21; il secondo: 2,3,6,7,10,11,14,15,18,19; il terzo:
4,5,6,7,12,13,14,15,20,21; il quarto: 8,9,10,11,12,13,14,15; il quinto: 16,17,18,19,20,21. Per trovare l’errore
(il bit invertito) bisogna sommare tutti i controlli delle
posizioni con 1 dispari. ES: 1011101000100110 
001001111010001000110. 1: 6 n1  0; 2: 6 n1  0; 4:
4 n1  0; 8: 3 n1  1; 16: 2 n1  0. Con errore:
001001111010011000110  1: 6 n1, 2: 7 n1, 4: 5 n1, 8:
5 n1, 16: 2 n1  sommo i bit con 1 dispari: 2 + 4 + 8 =
14  bit errato: non 1 ma 0.
La memoria cache: le CPU sono molto più veloci delle memorie. Man mano che si migliorava la velocità
della CPU, la differenza con le memorie aumentava, in quanto veniva accresciuta la capacità delle memorie,
ma non la velocità. Per ovviare a questo problema ci sono due soluzioni: leggere prima un’istruzione ed
eseguirla in un secondo momento, avere macchine che non possono essere fermate. Per quanto riguarda la
prima soluzione non ci furono miglioramenti, in quanto la CPU, per la sua alta velocità, cercava di usare la
parola prima che questa arrivasse; nella seconda soluzione, le macchine richiedono ai compilatori di
generare codice che non usi il risultato della lettura prima del suo arrivo. Le memorie, per andare veloci
come la CPU, si dovrebbero trovare sullo stesso chip della CPU (perché la connessione alla memoria via
bus è molto lenta). Però mettere una grossa memoria su un chip aumenterebbe le dimensioni e diverrebbe
troppo costoso. Per risolvere il problema si combinò una piccola memoria veloce, situata sul chip della CPU
e una memoria grande ma lenta. La memoria piccola e veloce si chiama cache. La cache contiene le parole
più usate dalla memoria. Quando la CPU ha bisogno di una parola, prima controlla nella cache e se non c’è
poi controlla nella memoria centrale. Più la cache è grande, più si riducono i tempi di accesso. Se un dato
accesso alla memoria ha indirizzo A, è probabile che l’accesso seguente si troverà nelle vicinanze di A.
Infatti le istruzioni vengono lette da locazioni consecutive della memoria. Quindi, quando viene indirizzata
una parola, quella e qualcuna di quelle vicine vengono trasportate dalla memoria centrale alla cache, in
modo che la volta seguente la parola sia accessibile più velocemente. Se una parola viene letta o scritta k
volte in un intervallo di tempo, il calcolatore richiederà un accesso alla memoria lenta e poi k - 1 accessi alla
memoria veloce. Più grande è k più migliorano le prestazioni. Ponendo c come tempo di accesso alla cache,
m come tempo di accesso alla memoria e h l’hit ratio (percentuale di successo), h = (k – 1) / k, dalla quale si
ricaverà il tempo medio di accesso alla memoria: a = c + (1 – h )m. Se h  1, tutti gli accessi si farebbero
dalla cache, con il minimo tempo impiegato. Se h  0, si farebbero tutti gli accessi dalla memoria principale,
spendendo un tempo c + m, in quanto prima si controllerebbe tutta la cache senza successo (tempo c) e poi
verrebbe eseguito l’accesso alla memoria (tempo m). Le cache vengono divise in blocchi di dimensioni fisse,
chiamati cache line (linee di cache). Quando si verifica una cache miss (se il dato non è nella cache), tutta
una cache line viene trasferita dalla memoria principale alla cache.
La memoria secondaria: In cima ci sono
i registri della CPU, (non contengono più
di 128 byte) a cui si può accedere a piena
velocità. Poi c’è la memoria cache, che si
aggira tra 32 KB e alcuni MB. Poi c’è la
memoria centrale che va da 16 MB ad
alcune decine di GB. Poi ci sono i dischi
magnetici, dove avviene la
memorizzazione permanente. Man mano
che ci si sposta verso il basso aumenta il
tempo di accesso, mentre la capacità di
memorizzazione aumenta man mano che si scende.
Dischi magnetici: Un disco magnetico si compone di uno
o più piatti di alluminio con un rivestimento
magnetizzabile. Inizialmente i piatti avevano un diametro
di 50 cm, ora dai 3 ai 12 cm. La testina di un disco,
contenente un induttore, è sospesa appena sopra la
superficie ed è sostenuta da un cuscino d’aria. Quando la
corrente passa attraverso la testina, viene magnetizzata la
superficie sottostante e le particelle magnetiche si
allineano verso destra o verso sinistra a seconda della
polarizzazione della corrente di pilotaggio. Quando la
testina viene passata sopra un’area magnetizzata, viene
indotta una corrente nella testina che permette la lettura
dei bit memorizzati. Quando il disco compie un giro completo e viene scritta una sequenza di bit, ossia un
cerchio concentrico intorno all’asse di rotazione, la sequenza prende il nome di traccia (track). Ogni traccia è
divisa in settori di lunghezza fissa che contengono tipicamente 512 byte di dati. Ai dati segue un codice di
correzione degli errori, un codice Hamming o il codice Reed-Solomon, in grado di correggere errori multipli.
Fra settori consecutivi c’è un piccolo spazio (intersector gap). Il contenuto di un HD si riduce solitamente del
15% dopo la prima formattazione, in quanto non si tiene conto del codice di correzione degli errori e
dell’intersector gap. Un disco contiene dalle 800 alle 2000 tracce per centimetro, dove ogni traccia è larga
dai 5 ai 10 micron (1 micron = 1/1000 mm). Una traccia non è altro che un piccolo anello di materiale
magnetico con una piccola zona vuota “di controllo” che lo separa dalle tracce circostanti. Gran
parte dei dischi è costituito da piatti multipli impilati verticalmente. Ogni superficie è dotata di un braccio e di
una testina. Tutti i bracci si muovo in gruppo e funzionano contemporaneamente. L’insieme delle tracce in
una data posizione radiale si chiama cilindro. Per leggere o scrivere un settore, il braccio deve prima
muoversi verso la zona radiale corretta (quest’azione si chiama ricerca, seek). Una volta posizionata la
testina, c’è un intervallo chiamato latenza di rotazione finché il settore desiderato non ruota sotto la testina.
Gran parte dei dischi ruotano a 7200 RPM. I tempi di trasferimento dati sono da 5 a 20 MB/sec. Un problema
è che i dischi, ruotando da 60 a 120 giri/sec, si scaldano e si espandono cambiando la loro geometria fisica.
Alcune unità devono ricalibrare periodicamente i loro meccanismi di posizionamento per compensare questa
espansione, forzando le testine completamente all’interno o all’esterno. Chiaramente le tracce esterne sono
più lunghe di quelle interne. Per risolvere questo problema, i cilindri vengono suddivisi in zone e il numero
dei settori per traccia viene aumentato man mano che si procede verso l’esterno. Così facendo i settori sono
tutti della stessa misura. Ad ogni unità viene associato un controllore del disco, un chip che controlla l’unità.
Alcuni controllori contengono una CPU completa.
Floppy disk: Il dischetto o floppy disk nasce per la necessità di distribuire software. E’ un mezzo piccolo e
mobile che ha questo nome in quanto i primi dischetti erano realmente flessibili. I primi furono inventati da
IBM. Le caratteristiche dei dischi generali corrispondono ai dischi magnetici, ma le testine, invece di essere
sospese su un cuscino d’aria, toccano i dischetti. Per questo il supporto magnetico delle testine si consuma
rapidamente. Per ridurre l’usura, i personal computer ritirano le testine e interrompono la rotazione quando
un’unità non sta leggendo o scrivendo. Le misure vanno dai 5.25 ai 3.5 pollici e contengono al massimo 1.44
MB.
Dischi IDE: I dischi dei pc si svilupparono dal disco Seagate da 10 MB, del PC XT IBM. Il controllore era in
grado di gestire due unità. Il BIOS inviava le istruzioni macchina per caricare i registri del controllore del
disco, che iniziavano i trasferimenti. La tecnologia migliorò con le unità IDE (Integrated Drive Eletronics).
Grazie al BIOS venivano indirizzati i settori indicando i loro numeri di testina, cilindro e settore, dove la
numerazione delle testine e dei cilindri cominciava con 0 e quella dei settori con 1. Il disco IDE poteva avere
al massimo 16 testine, 63 settori e 1024 cilindri. Un’unità di questo tipo ha una capacità di 528 MB.
Successivamente, le unità IDE divennero EIDE (Extended IDE), che supportavano uno schema di indirizzi
chiamato LBA (Logical Block Address) che esegue la numerazione dei settori partendo da 0 fino a un
massimo di 224 -1. I controllori migliorarono, in quanto erano in grado di controllare quattro unità.
Dischi SCSI: I dischi SCSI (Small Computer System Interface) non sono diversi dagli IDE per quanto
riguarda l’organizzazione dei cilindri, tracce e settori, ma sono dotati di un’interfaccia diversa e hanno
velocità di trasferimento superiori. Poiché hanno elevate velocità di trasferimento, vengono usati da diverse
workstation UNIX, Sun, HP, Macintosh e Intel. Ogni dispositivo SCSI ha due connettori: uno per l’input e
l’altro per l’output. L’output di un dispositivo viene collegato all’input di quello successivo per mezzo di cavi. Il
controllore si trova su una scheda inseribile all’inizio del cavo. Il cavo più comune SCSI a 8 bit ha 50 fili, 25
sono fili di massa accoppiati uno ad uno con gli altri 25 per migliorare l’immunità ai disturbi per avere una
maggiore velocità. Di questi 25 fili, 8 vengono usati per i dati, 1 per la parità, 9 per il controllo e il resto per
l’alimentazione o sono riservati per usi futuri. I controllori SCSI possono funzionare sia come iniziatori che
come esecutori. Solitamente il controllore, che funge da iniziatore, invia un comando ai dischi e alle altre
periferiche, ossia gli esecutori.
RAID: Le CPU hanno avuto un incremento esponenziale negli ultimi 10 anni, raddoppiando circa ogni 18
mesi. Ciò non è accaduto per i dischi. Di conseguenza, il divario tra CPU e dischi si è accresciuto con il
passare del tempo. Nel 1988 venne sviluppato un modo per migliorare l’affidabilità e le prestazioni dei dischi:
l’industria sviluppò una nuova categoria di I/O che prese il nome di RAID (Redundant Array of Inexpensive
Disks), definiti così in quanto erano in contrasto con i dischi usati in quel periodo, gli SLED (Single Large
Expensive Disk). Un RAID è composto da una scatola piena di dischi e da un controllore RAID, che
costituisce il controllore dei dischi. Poiché i dischi SCSI offrono buone prestazioni, costi bassi e la possibilità
di avere fino a 7 unità su un unico controllore (15 per SCSI larghi), la gran parte dei RAID contiene un
controllore SCSI RAID ed una scatola di dischi SCSI, che appare al sistema operativo come un unico grande
disco fisso. Così facendo, non sono stati necessari cambiamenti del software avendo così una completa
compatibilità con gli SCSI. I RAID appaiono al software come un unico disco e, inoltre, i dati vengono
distribuiti tra le unità, permettendo il funzionamento in parallelo. I RAID sono di 6 livelli:
1. Il primo livello è il livello 0. Consiste nel vedere il disco
singolo, da parte del RAID, come se fosse diviso in
strisce, ognuna di k settori, con i settori da 0 a k -1 che
2.
3.
4.
5.
6.
costituiscono la striscia (strip) 0, i settori da k a 2k -1 che costituiscono la striscia 1 e così via. La
distribuzione dei dati su unità multiple si chiama striping. Se, per esempio, il software invia il
comando di leggere un blocco di dati che consiste esattamente in quattro strisce consecutive, il
controllore RAID suddividerà questo comando in quattro comandi separati, uno per ogni disco,
e li eseguirà in parallelo. Il RAID a livello 0 funziona meglio con richieste grandi. L’affidabilità è
peggiore di uno SLED. Un RAID ha un MTBF (Mean Time Between Failures, il tempo medio tra i
guasti) di 20000 ore su ogni disco. Questo livello non è un vero e proprio RAID perché è privo di
ridondanza.
Il RAID di livello 1 è un vero e proprio
RAID. Tutti i dischi sono duplicati,
ossia se ci sono quattro dischi
principali, ci saranno quattro dischi di
backup. Ad ogni write la striscia viene
scritta due volte, a ogni read si legge
una delle due copie distribuendo il
carico su più unità. Le prestazioni di scrittura sono uguali al RAID 0, mentre quelle di lettura
sono raddoppiate. La tolleranza di errori è eccezionale: se un disco non funziona, basta usare la
copia.
Il RAID di livello 2 funziona sulla base
delle parole, o addirittura dei byte. Su
una parola di 7 bit, il bit 1, 2 e 4 sono
bit di parità. La parola di 7 bit con
codice di Hamming viene scritta con
un bit per unità. Questo schema
richiede che tutte le unità ruotino in
sincronismo e ha un senso solo con molte unità (più ci sono unità, più ci sono bit di controllo,
infatti con 32 unità e 6 di parità, l’overhead è del 19%). Questa tipologia è complessa da gestire.
Il RAID di livello 3 è una versione semplificata
del RAID di livello 2. Qui un bit di parità viene
calcolato per ogni parola di dati e viene scritto in
un’unità di parità. Come nel RAID di livello 2, le
unità devono essere sincronizzate perfettamente
in quanto le parole di dati vengono suddivise in
unità multiple. Il bit di parità può correggere
l’errore di un bit. Se un’unità smette di funzionare, il controllore assume che tutti i suoi bit sono 0.
Il RAID di livello 4 lavora con strisce, non
con parole individuali con parità e non
richiede la sincronizzazione delle unità. Su
un’unità vengono salvati i bit di parità, ma
sempre a strisce. Se un’unità non funziona, i
byte persi si possono ricalcolare dall’unità di
parità. Ciò aiuta per la perdita di unità, ma le sue prestazioni sono scarse per piccoli
aggiornamenti. Se un settore viene cambiato, è necessario leggere tutte le unità per ricalcolare
la parità da riscrivere.
Il RAID di livello 5 è uguale a quello di livello
4, ma è migliore in quanto i bit di parità non
sono un limite se la quantità di lavoro è alta.
Questo perché i bit di parità sono distribuiti
in maniera uniforme su tutte le unità.
CD-ROM: I dischi ottici hanno densità di registrazione superiore ai dischi
magnetici. Nel 1980 la Philips, insieme alla Sony, sviluppò i CD
(Compact Disc), che sostituirono i dischi in vinile a 33 1/3 giri in
pochissimo tempo. Tutti i CD (libro rosso per lo standard ISO) hanno un
diametro di 120 mm ed uno spessore di 1.2 mm con un foro di 15 mm al
centro. Il CD audio fu il primo mezzo di memorizzazione digitale prodotto
per il mercato di massa. I CD vengono prodotti usando un laser a raggi
infrarossi ad alta potenza che brucia fori di 0.8 micron di diametro, in un
disco master ricoperto di vetro. Da questo master viene ricavato uno
stampo con incavi in corrispondenza dei fori fatti dal laser. In questo
stampo viene iniettata resina liquida di policarbonato che forma un CD
con la stessa sequenza di fori del master in vetro. In seguito viene depositato un sottile strato di alluminio
riflettente sul policarbonato, che verrà ricoperto con uno strato protettivo e, in seguito, con un’etichetta. Le
depressioni, “cunette”, nel substrato di policarbonato si chiamano pits, mentre le aree non bruciate si
chiamano lands. I pits e i lands vengono scritti con una spirale unica continua che inizia vicino al foro
centrale. La spirale compie 22.188 giri attorno al disco (circa 660 per ogni mm). Se venisse srotolato
sarebbe lungo 5.6 Km. Per far sì che la musica suoni a velocità costante, bisogna far sì che pits e lands
scorrano a una velocità lineare costante. La velocità di un CD quindi deve essere gradualmente diminuita
man mano che la testina si sposta dall’interno del CD verso l’esterno. La velocità di rotazione va dai 530 giri/
minuto al centro, ai 200 giri/minuto all’esterno. Dopo i CD audio nacquero i CD-ROM per salvare i dati. I CDROM hanno le stesse dimensioni fisiche dei normali CD per essere compatibili meccanicamente e
otticamente con i CD audio e sono prodotti con le stesse macchine a stampo di policarbonato. Il formato
base di un CD-ROM si basa sulla codifica di ogni byte con un simbolo di 14 bit. Un gruppo di 42 simboli
consecutivi forma un frame (sequenza di bit) di 588 bit. Ogni struttura contiene 192 bit di dati e i rimanenti
396 vengono usati per la correzione di errori e per il controllo. In un settore del CD-ROM sono contenuti 98
frame (libro giallo per lo standard ISO). Ogni settore di CD-ROM inizia un preambolo di 16 byte, di cui i primi
12 servono al lettore CD per riconoscere l’inizio di un settore i 3 byte successivi contengono il numero del
settore e l’ultimo byte codifica la modalità di registrazione. Nei CD ci sono tre schemi di correzione errori:
all’interno del simbolo, all’interno del frame e all’interno di ogni settore. Per questo motivo lo spazio
utilizzabile di un CD-ROM è solo del 28%. Le unità CD-ROM a velocità base funzionano a 75 settori/sec,
cioè i dati sono forniti ad una velocità di 153.600 byte/sec. Un CD audio standard ha spazio per 74 minuti di
musica, un CD-ROM ha spazio fino a 650 MB. Un CD-ROM, per essere utilizzato su calcolatori diversi
necessita di un file system, chiamato High Sierra. Ogni sistema ha 3 livelli: il primo usa nomi fino a 8 caratteri
con l’estensione opzionale di altri 3 caratteri. I nomi del file possono contenere solo lettere maiuscole, numeri
e sottolineature. Il secondo livello accetta nomi con 32 caratteri e il livello 3 accetta file non contigui.
CD-Recordable: I CD-ROM differiscono dai dischi magnetici perché una volta scritti non si possono
cancellare. I CD-R assomigliano ai normali CD-ROM, ma sono dorati in superficie anziché argentati. Sui CDR (libro arancione per lo standard ISO) la riflettività dei pits e dei lands deve essere simulata. Ciò si ottiene
aggiungendo uno strato di colore tra il policarbonato e lo strato riflettente dorato. Al suo stato iniziale lo strato
di colore è trasparente per lasciar passare la luce laser che verrà riflessa dallo strato dorato. Il nuovo formato
dei CD-R, il CD-ROM XA, permette ai CD-ROM di essere scritti in modo incrementale, ossia con la
multisessione. Un gruppo di settori consecutivi scritti nello stesso momento si chiama traccia. Ogni traccia
deve essere scritta con un’unica operazione continua senza interruzioni. Di conseguenza, il disco fisso da
cui provengono i dati deve essere abbastanza veloce. Se i file da copiare sono distribuiti su tutto il disco
fisso, i tempi di ricerca potrebbero interrompere il flusso di dati in scrittura. Per ovviare a questo problema il
software permette di racchiudere tutti i dati in un’unica immagine CD-ROM, di grandezza pari allo spazio
massimo supportato dal CD, prima di scriverlo. Ciò però raddoppia il tempo di scrittura effettivo e richiede
uno spazio sul disco pari a quello dell’immagine.
CD-Rewritable: I CD-RW (CD-ReWritable) hanno la stessa capacità e la stessa grandezza di un CD-R
normale. Si differenziano per il colore, che è ciano. Le unità dei CD-RW usano laser con tre potenze diverse.
Ad alta potenza il laser scioglie la lega e trasforma lo stato cristallino in amorfo (scrittura). Alla potenza
media la lega si scioglie e si riforma lo stato naturale cristallino (cancellatura). Allo bassa potenza (lettura) lo
stato del materiale viene rilevato, ma non si verifica nessuna fase di transizione.
DVD: I DVD (Digital Versatile Disk) si basano sui normali CD ma hanno delle innovazioni:
• Pits più piccoli (0.4 micron contro 0.8 micron dei CD)
• Una spirale più serrata (0.74 micron fra tracce contro 1.6 micron dei CD)
• Raggio laser rosso (a 0.65 micron contro 0.78 dei CD)
Questi miglioramenti aumentano la capacità di un DVD di 7 volte, fino a giungere a 4.7 GB. Un’unità DVD 1x
funziona a 1.4 MB/sec (contro 150 KB/sec dei CD). Un DVD è in grado di contenere 133 minuti di video in
formato MPEG-2.
Ne esistono 4 formati: lato unico, strato unico (4.7 GB); lato unico, strato doppio (8.5 GB), lato doppio, strato
unico (9.4 GB), lato doppio, strato doppio (17 GB).
Input/Output: Un sistema
informatico ha tre componenti
principali: la CPU, le memorie
(primaria e secondaria) e i
dispositivi di I/O.
•
•
•
•
I bus: la parte principale è costituita da un grosso circuito stampato, chiamato scheda madre. La
scheda madre contiene un chip CPU, alcuni connettori dove si deve inserire la memoria principale e
vari chip di supporto. Inoltre ci sono un bus e alcune prese su cui inserire i connettori delle schede di
I/O. Ogni dispositivo di I/O è composto da due parti: una contenente quasi tutte le parti elettroniche,
chiamata controllore, e una contenente il dispositivo di I/O stesso. Il controllore si trova, di solito, su
una scheda inserita sul bus, esclusi i controllori che non sono opzionali (come la tastiera), che si
trovano sulla scheda madre. Il controllore visiona il dispositivo di I/O e ne gestisce l’accesso al bus.
L’unità di I/O inizia ha inviare i dati come flusso di bit seriali al controllore. Quest’ultimo suddividerà il
flusso in blocchi e scriverà ogni blocco nella memoria. Un controllore che legge o scrive dati da e per
la memoria senza interventi della CPU si dice che sta effettuando un Direct Memory Access (DMA).
Una volta completato il trasferimento, il controllore effettua un interrupt, forzando la CPU a
sospendere il programma in corso e ad iniziare la procedura interrupt handler, per controllare che
non vi siano errori. Quando l’interrupt handler ha finito, la CPU riprende l’esecuzione del programma.
Il bus non viene usato solo dai controllori di I/O, ma anche dalla CPU per leggere istruzioni e dati. Se
la CPU e un controllore di I/O vogliono usare il bus tutti e due insieme, l’arbitro del bus decide di
cedere il bus al controllore di I/O, perché facendo aspettare un dispositivo di I/O si rischia di perdere
i dati. Questo processo si chiama cycle stealing (rubare un ciclo) e rallenta il calcolatore. Man mano
che le CPU, le memorie e i dispositivi di I/O diventavano più veloci, il bus non era più in grado di
gestire il carico. Per cercare di trovare una soluzione, l’IBM lancio con il PS/2 un nuovo bus più
veloce, anche se la gran parte dei produttori continuava ad usare il vecchio bus, l’ISA (Industry
Standard Architecture). Il bus che lasciò il segno fu il PCI (Peripheral Component Interconnect),
progettato da Intel lasciando i brevetti di pubblico dominio per incrementare la produzione. La CPU è
collegata con un controllore della memoria per mezzo di un collegamento ad alta velocità. Il
controllore parla direttamente alla memoria e al bus PCI, così il traffico tra CPU e memoria non
passa attraverso il bus PCI. Le periferiche ad elevata larghezza di banda (cioè a elevato flusso di
dati), come i dischi SCSI, si possono collegare direttamente al bus PCI. Inoltre il bus PCI ha un
ponte che lo collega al bus ISA, in modo che si possono ancora usare i controllori ISA ed i loro
dispositivi.
Tastiere e mouse: Le tastiere trasmettono un codice del carattere ogni volta che si preme un tasto.
Genera un’interruzione della CPU, mentre le combinazioni di tasti sono gestite dal SW. Il mouse,
che usa le tecnologie meccanica (pallina) o optomeccanica (laser di lettura), invia 3 byte ogni volta
che il mouse fa un certo spostamento.
Monitor: i CRT (Cathode Ray Tube) sono monitor che contengono il tubo catodico e l’alimentatore.
Sono gli stessi usati dei televisori ma con prestazioni migliori. Molto ingombranti. Gli LCD (Liquid
Crystal Display) sono monitor composti da due lastre di vetro in parallelo, la cui intercapedine
sigillata contiene un cristallo liquido. Sulle lastre sono attaccati elettrodi trasparenti. Una luce illumina
la lastra posteriore e gli elettrodi vengono usati per creare campi elettrici nel cristallo liquido. Le
diverse parti dello schermo ricevono voltaggi diversi a seconda dell’immagine. In assenza di campo
elettrico lo schermo LCD è completamente luminoso. Hanno un’ottima grafica ed occupano poco
spazio, ma hanno un costo elevato, un basso contrasto e uno scarso angolo visuale. La tecnologia a
matrice attiva invece di avere due gruppi di fili perpendicolari, è dotata di un piccolo interruttore che
controlla ogni pixel.
Terminali: Sulla scheda si trovano una memoria (la memoria video) e alcuni componenti elettrici per
accedere al bus e generare segnali video. Una scheda video consiste nel richiedere caratteri alla
RAM del video e generare i segnali necessari al funzionamento dello schermo. Si dividono in 3 tipi, a
caratteri, grafici e RS-232-C:
1. I terminali a caratteri (character map) possono far apparire sullo schermo solo caratteri.
Per far apparire i caratteri sullo schermo, la CPU li copia sulla memoria video in byte
alternati. Tipicamente sono da 25 righe per 80 caratteri. I caratteri sono contenuti nella
VRAM e il flusso è contenuto tra la memoria e la VRAM. Non possono gestire alcun tipo
di grafica.
2. I terminali grafici (bit map) hanno due svantaggi principali: richiedono 4 MB di VRAM e
servono 24 bit per pixel per avere un’immagine con ottimi colori. Hanno una risoluzione
fino a 1280 per 960 e hanno l’interfaccia grafica a finestre. Gravano molto sulla CPU.
3. I terminali RS-232-C usano un connettore standard a 25 pin. Permettono di visualizzare
immagini su un terminale lontano per mezzo della linea telefonica. Per far ciò è
necessario un modem (modulatore-demodulatore) per convertire il segnale. Il
calcolatore e il terminale sono dotati di un chip chiamato UART (Universal
Asynchronous Receiver Transmitter) e di logica per avere accesso al bus. Per
visualizzare un carattere, il calcolatore lo prende dalla memoria centrale e lo presenta
all’UART che lo invia sul cavo RS-232-C un bit alla volta. L’UART in realtà è un
convertitore seriale, in quanto trasforma byte in bit. Viene inoltre aggiunto un bit di inizio
e uno di fine ad ogni carattere.
• Stampanti: Le stampanti sono di due tipi: a getto d’inchiostro (inkjet) e laser. Le prime stampano
grazie alla contrazione del capillare per impulsi elettrici nell’avvolgimento. Le testine sono a più
ugelli, dai quali fuoriesce l’inchiostro. Sono poco costose e silenziose, ma lente. I problemi che
hanno sono il trascinamento della carta, l’intasamento degli ugelli, l’elevato costo delle cartucce e la
generazione dell’immagine avviene dal computer. Le stampanti laser invece funzionano con
l’eccitazione elettrostatica del tamburo di selenio in continua rotazione, con pennello laser. Il toner
viene trasferito sulla carta mentre il tamburo gira. La stampante laser è silenziosa, veloce e precisa.
La generazione dell’immagine viene fatta dalla stampante stessa grazie a un processore e parecchi
MB di RAM e ROM, dove è contenuto un set di caratteri, interni alla stampante. Questi dispositivi
sono programmati in postscript. Le stampanti a colori si dividono in due tipi: codice a stampa a 4
colori, CYMK (Cyan, Yellow, Magenta, Black), oppure codice a stampa a 3 colori monitor RGB (Red,
Green, Blue). Un problema è la sublimazione, ossia la fusione di inchiostri solidi con pigmenti, che si
depositano sul foglio.
• Modem: Una linea telefonica semplice non è adatta
alla trasmissione di segnali digitali. I segnali su due
livelli vengono distorti durante la trasmissione per
mezzo di una linea telefonica, adatta par la voce
umana, e quindi si possono verificare errori di
trasmissione. Poiché le oscillazioni di un’onda
sinusoidale sono completamente prevedibili, un’onda
non trasmette alcuna informazione. Variando però
l’ampiezza, la frequenza o la fase si possono
trasmettere una sequenza di 1 o di 0. Questo
processo si chiama modulazione. Vengono usati due
voltaggi per 1 e per 0. Una persona che sentisse la
trasmissione di dati digitali a bassa velocità,
sentirebbe un rumore forte per 1 e nessun rumore per
0. Nella modulazione di frequenza la tensione è
costante, ma la frequenza è diversa per 1 e per 0. Nella modulazione di fase semplice, l’ampiezza e
la frequenza non cambiano, ma la fase portante viene invertita di 180° quando i dati passano da 0 a
1 o viceversa. Poiché le linee telefoniche adatte alla voce umana forniscono un canale solo, i bit
devono essere inviati in modo seriale, uno dopo l’altro. Il modem accetta i caratteri dal calcolatore
sotto forma di segnali a due livelli, un bit per volta e trasmette i bit in gruppi di uno o due, sotto forma
di modulazione d’ampiezza, frequenza o fase. Per segnalare l’inizio o la fine di ogni carattere, un
carattere da 8 bit viene fatto precedere da un bit di inizio e uno di fine, per un totale di 10 bit. I
modem moderni hanno una velocità di trasmissione di 57.600 bit/sec, solitamente a bande molto
inferiori, modulando l’ampiezza, la frequenza e la fase. Quasi tutti sono full-duplex, cioè trasmettono
in tutte e due le direzioni contemporaneamente. Le linee digitali ISDN permettono una trasmissione
di 128 Kbits/sec senza modem e fino a 30 canali.
Codici: codice ASCII a 7 bit, poi esteso a 8. Codice UNICODE a 16 bit.
TEORIA 4:
Porte logiche: In un circuito ci sono due valori logici: il segnale tra 0 e 1 volt rappresenta lo 0 binario, quello
tra 2 e 5 volt rappresenta l’1 binario. I dispositivi elettronici che calcolano questi valori sono le porte.
Algebra booleana: Una funzione booleana di n variabili ha 2n combinazioni possibili di valori di input. La
funzione si può descrivere completamente con una tabella di 2n righe, in cui ogni riga dà il valore della
funzione per una diversa combinazione di valori di input. Questa tabella si chiama tabella di verità. Secondo
l’algebra booleana M = ABC + ABC + ABC + ABC = 1. Questa funzione ha 3 input e 8 possibili combinazioni
(segnato = sottolineato).
Una funzione booleana si può implementare per mezzo di un circuito. Una volta scritta la tabella di verità per
la funzione, si dispongono gli invertitori per generare il complemento di ogni input, si introduce una porta
AND per ogni termine con 1 nella colonna dei risultati, poi le porte vanno collegate agli input appropriati e
l’output di tutte le porte AND deve essere inviato in una porta OR. Sia le porte NAND che quelle NOR si
chiamano complete, perché le funzioni booleane si possono calcolare usando una qualsiasi delle due.
Equivalenza dei circuiti: grazie
all’algebra booleana e alle leggi di
DeMorgan si possono ridurre le porte
in un circuito e riducendo di
conseguenza il costo e il consumo
energetico del medesimo. Per ridurre
un circuito, un progettista deve trovare
un altro circuito che calcoli la stessa
funzione dell’originale, ma con meno
porte. Secondo DeMorgan, per
esempio, ABC = A + B + C.
Un’altra porta usata è la XOR:

Circuiti per calcolare la funzione XOR:
Circuiti integrati: le porte
servono ha creare circuiti
integrati (IC, integrated circuit) o
chip. Un circuito integrato è un
pezzo rettangolare di silicio su cui
sono state costruite alcune porte.
Sui lati più lunghi vi sono due file
parallele di piedini. Ogni piedino è
collegato con l’input o l’output di
una porta che si trova sul chip,
con l’alimentazione o con la
massa. I circuiti con due file di
piedini sono chiamati DIP (Dual
Inline Packages), oppure chip. I
DIP più diffusi hanno dai 14 ai 68
piedini. I chip si possono dividere
in classi basate sul numero di
porte che contengono:
• Circuito SSI (Small Scale Integrated): 1 – 10 porte
• Circuito MSI (Medium Scale Integrated): 11 – 100 porte
• Circuito LSI (Large Scale Integrated): 101 – 100.000 porte
• Circuito VLSI (Very Large Scale Integrated): > 100.000 porte
Il tempo che impiega l’output per essere elaborato non
appena il chip riceve gli input si chiama ritardo di
porta (gate delay) finito, che comprende sia il tempo di
propagazione del segnale nel chip che il tempo di
commutazione (switching). I ritardi vanno da 1 a 10
nsec.
Vcc è l’alimentazione, mentre GND (ground) è la
messa a terra.
Circuiti combinatori: circuito con più input e output, dove gli output sono determinati solo dagli input del
momento. Circuito privo di elementi di memoria, così che l’output non può essere influenzato da questi.
Multiplexer: Un multiplexer ha 2n input,
un dato di output e n input di controllo.
L’input selezionato è inviato all’output. Il
circuito accanto ha 8 linee di input (Dn) e
tre di controllo (A, B, C). Quest’ultime
codificano un numero di 3 bit che
specifica quale delle 8 linee è
commutata sull’ingresso della porta OR,
quindi dell’output. Il multiplexer permette
di convertire i dati da paralleli a seriali.
Mettendo 8 bit sulle linee di input e poi
ciclando le linee di controllo in modo
sequenziale da 000 a 111, gli 8 bit di
ingresso vengono messi sulla linea di
output in serie. Un esempio di
multiplexer è la tastiera.
Decodificatore: Un decodificatore ha n
ingressi e 2n uscite. Una sola uscita assume
un valore vero in corrispondenza a ciascuna
delle 2n configurazioni di input. 
 Comparatore: Un comparatore ha due input A e B,
ognuno di 4 bit e produce 1 se gli input sono uguali, 0 se
sono diversi. Il circuito si basa sulla porta XOR che da 0 se
gli input sono tutti e due 0 o 1, altrimenti restituisce 1.
Array logici programmabili: Un
chip molto grande per creare
somme di prodotti è il PLA
(Programmable Logic Array). Ha
12 input, il complemento di ogni
input viene generato internamente,
creando in tutto 24 segnali di input.
Il centro del circuito è una matrice
(array) di 50 porte AND. Quale
segnale riceve una porta AND
viene determinato da una matrice
di 24 x 50 bit fornita dall’utente,
bruciando uno o più fusibili dei
1200 del circuito. Praticamente
questo circuito viene programmato
bruciando i fusibili, inviando un
voltaggio elevato al chip. L’output
del circuito è costituito da 6 porte
OR, ognuna delle quali ha fino a 50 input che corrispondono ai 50 output delle porte AND. Il chip ha in totale
20 piedini: 12 di input, 6 di output, 1 per l’alimentazione e 1 per la messa a terra.
Circuiti aritmetici: Questi circuiti sono MSI combinatori usati per il calcolo aritmetico.
Shifter: Questo circuito, ha n input
e n output, sempre in numero pari.
Escluso agli estremi, le porte AND
sono disposte a coppie, una per bit.
Quando C=1, la parte destra di ogni
coppia viene attivata e trasforma il
bit da input a output. Poiché la porta
AND destra è collegata all’input
della porta OR alla sua destra, si
verifica uno spostamento a destra.
Quando C=0, è la parte sinistra
della porta AND che si attiva e si
verifica uno spostamento verso
sinistra.
Semiaddizionatore (Half Adder): E’ un
elemento essenziale della CPU. Ha due
output che corrispondono alla somma dei due
input A e B, e il riporto della posizione
successiva (carry). Il mezzo sommatore è
adeguato al calcolo dei bit meno significativi.
Addizionatore completo (Full Adder):
E’ composto da due semisommatori.
L’output somma è 1, se ci sono un
numero dispari di 1 tra A, B, e carry in. Il
carry out è 1 se A e B sono entrambi 1 o
se uno di loro e il carry in è 1. I due
mezzi sommatori insieme generano la
somma e il riporto. Per costruire un
sommatore di 16 bit, si replica il circuito
16 volte. Il carry out di un bit si usa
come carry in del vicino di sinistra, il
carry in del bit più a destra è collegato a
0. Questo tipo di sommatore si chiama sommatore con riporto in serie, perché nel caso peggiore, cioè la
somma di soli 1 binari, la somma non può essere completata finché il riporto non si è propagato dal bit più a
destra a quello più a sinistra. Esistono anche sommatori che non hanno questo ritardo.
Unità aritmetico logica: Questo
circuito serve per eseguire AND, OR
e la somma di due parole macchina.
Un circuito di n bit è composto di n
circuiti identici. Questa ALU è in
grado di calcolare A AND B, A OR
B, B, oppure A + B. In basso a
sinistra c’è un decodificatore da 2 bit
per generare segnali di abilitazione
alle quattro operazioni. Nell’ angolo
superiore sinistro c’è l’unità logica
per calcolare A AND B, A OR B,
oppure B, ma solo uno di questi
risultati viene inviato alla porta finale
OR, a seconda delle linee di
abilitazione che escono dal
decodificatore. Dato che solo un
output del decodificatore sarà 1, solo una delle porte AND, che controllano la porta OR, sarà abilitata.
L’angolo inferiore destro contiene un sommatore per calcolare A + B, compresa la gestione dei riporti,
perché è possibile che questi circuiti vengano collegati insieme per eseguire operazioni su parole intere. Un
ALU a n bit è realizzata con n ALU a un bit unite da connettori.
Clock: In molti circuiti è importante il tempo in cui si verificano determinati eventi, in quanto da quell’evento
potrebbero scaturirne altri. Per permettere la giusta relazione fra i tempi è necessario inserire nel circuito un
clock per permettere la sincronizzazione. Un clock è un circuito che emette una serie di impulsi con una
larghezza specifica e un intervallo preciso fra impulsi consecutivi. L’intervallo di tempo prende il nome di
ciclo di clock. Le frequenza degli impulsi è solitamente tra 1 e 500 Mhz. Se gli eventi devono accadere in un
determinato ordine, il ciclo sarà diviso in sottocicli. Per conseguire questo scopo, basta inserire nel circuito
del clock un circuito contenente un ritardo conosciuto, generando così un segnale di clock secondario
spostato di fase rispetto a quello principale. Si possono avere anche più segnali di clock spostati di fase
rispetto a quello principale.
Memoria: La memoria viene usata per memorizzare sia le istruzioni da eseguire sia i dati.
Latch: il latch è costituito da due porte
NOR. Il latch di tipo SR ha due input,
S (setting) per fissare il latch, R
(resetting) per azzerarlo. Ha due
output, Q e Q, che sono
complementari. Diversamente dai
circuiti combinatori, gli output non
vengono determinati solo dagli input
del momento. Non può esserci uno stato dove entrambi gli output sono 0 o tutti e due uguali a 1. Per R = S =
0 il latch ha due stati stabili. Quando S è temporaneamente 1, il latch finisce nello stato Q = 1. Con R = 1, Q
= 0. Il circuito tiene in memoria l’ultimo input, se S o R. Su questa base si costruisce la memoria.
Latch di tipo SR sincronizzato: A questo latch è stato
aggiunto l’input clock, che solitamente è 0. Con il clock = 0,
le due porte AND hanno un output 0, indipendentemente
da S e R, e il latch non cambia stato. Quando il clock = 1,
l’effetto delle porte svanisce e il latch diventa stabile ad S e
R. Il segnale di clock non deve essere controllato da un
clock. L’unico stato consistente per R = S = 1 è Q = Q = 0, ma non appena i due input tornano a 0, il latch
deve passare ad uno dei suoi stati stabili. Se uno dei due input torna a 0 prima dell’altro, vince quello che
rimane 1 più a lungo, perché solo quando un input è 1 forza lo stato; se i due input tornano a 0
contemporaneamente, il latch entra in uno qualunque dei suoi stati stabili.
Latch di tipo D sincronizzato: Un buon metodo per
risolvere il problema R = S = 1 consiste nell’impedire che
questa situazione si verifichi. Invece di dar passare due
input S e R, si fa passare un unico input D. L’input della
porta AND inferiore è il complemento di quella superiore,
non c’è il problema di avere due input = 1. Con il clock = 1,
se D = 1, Q = 1; altrimenti, con D = 0, Q = 0.
Flip-Flop: in molti circuiti c’è la necessità di controllare un
determinato segnale in un particolare momento e memorizzarlo.
Nei flip-flop, la transizione non accade se il clock è 1, ma durante
la transizione da 0 a 1 (fronte di salita) o da 1 a
0 (fronte di discesa). Pertanto, la lunghezza
dell’impulso di clock non è importante se le
transizioni si verificano velocemente. Un flip-flop
è azionato dal fronte, mentre un latch è azionato
dal livello. La porta AND non restituisce sempre
0 come sembra. Ciò grazie al ritardo di
propagazione. Il segnale di input, misurato nel
punto a è un impulso di clock lungo. Il segnale b
è sia invertito che leggermente ritardato. Anche
il segnale c è ritardato, ma solo del tempo di
propagazione del segnale, però è un ritardo
trascurabile, quindi il segnale a è identico a c.
Quando gli input b e c vengono messi in AND, si
avrà un breve impulso. L’output della porta
AND è spostato dal ritardo causato dalla
porta. Questo ritardo nel tempo implica
che il latch di tipo D verrà attivato a un
ritardo fisso dopo il fronte di salita del
clock, ma non influenza la larghezza
dell’impulso. Quasi tutti i latch e i flip-flop
hanno anche Q come output e alcuni hanno due input addizionali Set o Preset (che forzano lo stato a
diventare Q = 1) e Reset o Clear (che forzano lo stato a diventare Q = 0). L’ultima immagine è un flip-flop di
tipo D.
Registri: Un registro è costituito da almeno due flipflop di tipo D indipendenti e con segnali clear e
preset. Benché siano contenuti nello stesso chip a
14 piedini, i flip-flop sono ben distinti. Le linee di
clock sono riunite e controllate da un solo piedino.
Questo perché, quando il piedino del clock è 0, i flipflop diventano 0. Il piedino 11 è invertito all’input e
poi rinvertito a ogni segnale CK perché un segnale
di input potrebbe non avere abbastanza potenza per
controllare i flip-flop; l’invertitore viene usato come
amplificatore.
Organizzazione
della memoria: La
costruzione di
memorie più grandi
richiede
un’organizzazione
diversa, che permette
di indirizzare le
singole parole. E’
illustrata in seguito
una memoria con
quattro parole di 3 bit.
Ogni operazione
legge o scrive una
parola completa di 3
bit. Anche se la
capacità totale di una
memoria di 12 bit
supera di poco un flipflop ottale, essa
richiede meno piedini
e ha una configurazione che può essere estesa a memorie più grandi. E’ dotata di 8 linee di input e 3 di
output. Tre input sono dati: I0, I1, I2; due di indirizzo: A0, A1; tre di controllo: CS (Chip Select), RD (read o
write) e OE (Output Enable). Per selezionare questo chip di memoria, la logica esterna deve portare CS alto
e mettere RD alto (1 logico) per leggere e basso (0 logico) per scrivere. Le linee di indirizzo indicano quale
delle quattro parole di 3 bit si deve leggere o scrivere. In caso di scrittura, vengono caricati i bit sulle linee di
input dei dati e non vengono usate le linee di output. Le quattro porte AND per la selezione della parola
formano un decodificatore. Gli invertitori dell’input sono stati montati in maniera tale che ogni porta viene
abilitata (output alto) da un indirizzo diverso. Ogni parola controlla una linea di selezione della parola.
Quando il chip viene selezionato per la scrittura, la linea CS*RD sarà alta, abilitando una delle porte di
scrittura. L’output della porta di scrittura controlla tutti i segnali CK per la porta selezionata, caricando i dati di
input nei flip-flop di quella parola. Viene scritta solamente la parola selezionata da A0 a A1 se CS è alto e RD
basso. Per la lettura invece la linea CS*RD deve essere bassa, in modo che tutte le porte di scrittura siano
disabilitate e nessuno dei flip-flop venga modificato. La linea della parola prescelta abilita le porte AND
collegate con i bit Q della parola selezionata. In questo modo i dati sono presenti alle porte OR mentre le
altre tre parole generano 0. L’output è identico alla parola selezionata, in quanto le altre tre parole non
contribuiscono all’output. Per poter collegare le linee di output dei dati anche durante la lettura, serve un
dispositivo chiamato buffer non invertente.
C’è un input di dati, un output e un input di
controllo. Quando l’input di controllo è alto, il
buffer si comporta come un filo. Quando
l’input di controllo è basso, il buffer si
comporta come un circuito aperto. Funziona
al contrario il buffer invertente. Quando CS, RD e OE sono tutti alti, anche il segnale di abilitazione
dell’output è alto, in modo da abilitare il buffer a mettere una parola sulle linee di output. Quando uno
qualsiasi di CS, RD o OE è basso, gli output di dati sono staccati dal circuito.
Chip di memoria: Il lato positivo della memoria è
la facilità di estendere le sue dimensioni. La
tecnologia dei circuiti integrati si adatta bene per la
produzione di chip con la struttura interna
bidimensionale e ripetitiva. Migliorando la
tecnologia, si può sempre mettere un numero
crescente di bit su un chip. Per ogni dimensione di
memoria vi sono modi diversi di organizzare un chip. Le dimensioni di memoria vengono solitamente
riportate in bit e non in byte. A seconda dei piedini, serve una tensione alta o bassa. Per questo si dice che
un segnale è attivo (asserted) anziché alto o basso, se il suo valore ha effetto sul segnale, altrimenti è
negato. Un segnale attivo alto è indicato con S, quello basso con S. Dato che un calcolatore è dotato di molti
chip di memoria, serve un segnale che selezioni il chip necessario in quel momento, in modo che reagisca
solo quel chip. Il segnale CS (Chip Select) serve a questo scopo. Per distinguere se un dato deve essere
scritto o letto si usa il segnale WE (Write Enable). Il segnale OE (Output Enable) viene usato per controllare
l’output che, se non è attivo, viene staccato dal circuito. I chip grandi di memorie vengono usati per creare
matrici n per n che sono indirizzate per riga e per colonna. Quest’organizzazione riduce il numero di piedini,
ma rallenta l’indirizzamento del chip, poiché sono necessari due cicli di indirizzo, uno per riga e uno per
colonna. Per recuperare parte della velocità, certi chip di memoria permettono l’accesso a bit consecutivi,
fornendo un solo indirizzo di riga e una sequenza di indirizzi di colonna.
RAM e ROM: Le memorie che possono leggere o scrivere si chiamano RAM (Random Access Memory). Le
RAM sono di due tipi, statiche e dinamiche. Le RAM statiche (SRAM) sono implementate con circuiti simili
ai flip-flop di tipo D. Il contenuto di queste memorie viene memorizzato fintanto che c’è alimentazione. Le
RAM statiche sono molto veloci. Le RAM dinamiche (DRAM) non utilizzano i flip-flop. Una RAM dinamica è
costituita da un insieme di celle, ognuna delle quali contenente un transistor e un piccolo condensatore. I
condensatori si possono caricare o scaricare permettendo la memorizzazione di 0 o di 1. Poiché la carica
elettrica tende a disperdersi rapidamente, la RAM dinamica deve essere ricaricata ogni pochi millisecondi
per non perdere i dati. Per questo motivo le RAM dinamiche richiedono interfacce più complesse di quelle
statiche, ma hanno il vantaggio di avere grandi capacità. Le RAM dinamiche richiedono un transistor e un
condensatore per bit, anziché sei transistor per ogni bit delle RAM statiche. Questo fa sì che le DRAM hanno
densità molto alte, anche se sono più lente. Tra i tipi di DRAM ci sono la FPM (organizzata come matrice di
bit) e la EDO (con pipeline a 2 livelli per l’accesso alla memoria); ambedue sono asincrone. La SDRAM
(Synchronous DRAM) è una combinazione di memoria RAM dinamica e statica ed è controllata da un clock
sincrono. Altri tipi di RAM sono le SIMM (Single Inline Memory Module) e le DIMM (Double Inline Memory
Module). Le prime sono costituite da 72 piedini, 32 bit, 8 -16 chip e 32 MByte; le seconde da 168 piedini, 64
bit, 16 chip e 128 MByte. Per il salvataggio di dati in mancanza di alimentazione, si usano le memorie ROM
(Read Only Memory), dove i dati non si possono cambiare o cancellare. I dati di una ROM vengono inseriti
durante la produzione della memoria, usando materiale fotosensibile e una maschera per ottenere una
sequenza corretta di bit. L’unico modo per cambiare il programma ROM è sostituire tutto il chip. Un prodotto
che deriva dalla ROM è la PROM (Programmable ROM), che differisce dalla ROM in quanto può essere
programmata dall’utente, ma una sola volta. Una PROM contiene una serie di piccoli fusibili, ognuno dei
quali può essere disattivato selezionando la sua riga e la sua colonna e poi inviando un alto voltaggio a uno
specifico piedino del chip. Un ulteriore sviluppo fu la EPROM (Erasable PROM), che può essere
programmata dall’utente, ma anche cancellata. Le EPROM hanno una finestra di quarzo a contatto con il
chip; se la finestra viene esposta ad una forte luce ultravioletta per un quarto d’ora, tutti i bit vengono messi a
1. Dall’ EPROM si sviluppa L’EEPROM, che può essere cancellata per mezzo di impulsi elettrici anziché per
raggi ultravioletti. Però hanno lo svantaggio di essere 1/64 di una EPROM normale e una velocità dimezzata.
Uno sviluppo della EEPROM portò alla memoria flash. Questa memoria si può cancellare a blocchi, senza
toglierla dal circuito, e si può riscrivere.
TEORIA 5:
Chip delle CPU: Tutte le CPU moderne sono
raccolte su un unico chip. Ogni chip CPU è
dotato di un insieme di piedini, attraverso i quali
avviene tutta la comunicazione fra il chip e il
mondo esterno. I piedini su un chip sono di tre
tipi: indirizzo (locazione della parola), dati (invio
parola: memoria  CPU) e controllo (parola
desiderata). Questi piedini sono collegati a
piedini simili sulla memoria e sui chip di I/O per mezzo di un insieme di fili paralleli chiamati bus. Per leggere
un’istruzione, la CPU mette prima l’indirizzo di memoria dell’istruzione sui suoi piedini di indirizzo. Poi attiva
una o più linee di controllo per informare la memoria su quello che vuole fare, ad esempio leggere una
parola. La memoria risponde mettendo la parola richiesta sui piedini dei dati della CPU e attivando un
segnale di esecuzione del comando. Quando la CPU riceve questo segnale, accetta la parola ed esegue
l’istruzione. La CPU comunica con la memoria e con i dispositivi di I/O attivando e leggendo segnali sui suoi
piedini. Due dei parametri chiave che determinano le prestazioni della CPU sono i piedini dell’indirizzo e il
numero dei piedini dei dati. Un chip con m piedini di indirizzo è in grado di indirizzare fino a 2m locazioni di
memoria. Un chip con n piedini di dati, è in grado di leggere o scrivere una parola di n bit in un’unica
operazione. I piedini di controllo regolano il flusso e la sincronizzazione di dati da e verso la CPU, e hanno
anche altre applicazioni. Tutte le CPU hanno piedini per l’alimentazione (3.3 o 5 volt), terra e segnale di
clock. Nei piedini di controllo rientrano:
1. Controllo del bus
2. Interrupt
3. Arbitraggio del bus
4. Segnali del coprocessore
5. Stato
6. Varie
I piedini di controllo della CPU sono in gran parte output della CPU al bus e indicano cosa farà la CPU. I
piedini di interrupt sono attivati dai dispositivi di I/O per la CPU. La CPU è in grado di dire a un dispositivo di
I/O di cominciare un’operazione e poi fare qualcos’altro, mentre il lento dispositivo di I/O esegue il lavoro.
Quando l’ I/O è stato effettuato, il chip del controllore di I/O attiva un segnale su uno dei piedini per
interrompere la CPU e far sì che esamini lo stato del dispositivo di I/O per controllare se si sono verificati
errori. I piedini di arbitraggio del bus sono necessari per regolare il traffico del bus e impedire che due
dispositivi lo usino completamente.
Bus dei calcolatori: Un bus
è il collegamento elettrico
comune fra più dispositivi. I
bus si possono dividere in
categorie a seconda della loro
funzione. Si possono usare
all’interno della CPU, per
trasportare dati verso e
dall’ALU, o all’esterno della
CPU, per collegarla alla
memoria o a dispositivi di I/O. I primi PC avevano un singolo bus esterno o bus di sistema. Quest’ultimo era
composto dalle 50 alle 100 tracce di rame sulla scheda madre, con connettori sistemati ad intervalli regolari
per collegare la memoria e le schede di I/O. I PC moderni sono costituiti di un bus tra CPU e memoria e
(almeno) un altro bus con i dispositivi di I/O. L’insieme di regole che gestisce il funzionamento di un bus, a
cui devono attenersi tutti i dispositivi collegati, prende il nome di protocollo del bus. Alcuni dispositivi che si
collegano a un bus si dicono attivi (master) e possono decidere di iniziare un trasferimento, mentre i passivi
(slave) si limitano a stare in attesa di una richiesta. Ci sono anche dispositivi che possono comportarsi sia da
slave che da master. I segnali generati dai dispositivi potrebbero non essere abbastanza forti per pilotare un
bus, per questo i master sono collegati al bus per mezzo di un chip, il bus driver, che non è altro che un
amplificatore digitale. Per la stessa ragione, gli slave sono collegati al bus tramite il chip bus receiver. Per i
dispositivi che possono essere sia master che slave, si usa un dispositivo chiamato bus transceiver. Questi
chip di interfaccia del bus sono necessari per permettere ai dispositivi di scollegarsi o di essere collegati in
modo leggermente diverso, chiamato open collector. Quando due o più dispositivi su una linea open
collector attivano la linea nello stesso momento, avviene l’OR booleano di tutti i segnali.
Larghezza del bus: Più
linee di indirizzo ci sono in
un bus e più memoria può
essere indirizzata
direttamente dalla CPU. Se
un bus ha n linee di
indirizzo, una CPU può
utilizzarlo per indirizzare 2n
diverse locazioni di
memoria. Per gestire grosse dimensioni, i bus richiedono molte linee. Il problema è che i bus larghi
richiedono più fili rispetto a quelli stretti, connettori più grandi e inoltre occupano anche più spazio fisico.
Questo renderebbe i bus molto costosi. Per questo motivo c’è un compromesso fra dimensioni massime
della memoria e costi del sistema. Il PC IBM contenente una CPU 8088 e un bus di indirizzo di 20 bit,
permetteva di indirizzare 1 MB di memoria. Il seguente chip di CPU (l’80286) aveva aumentato lo spazio di
indirizzamento a 16 MB, aggiungendo 4 linee di bus alle 20 preesistenti, per avere una compatibilità con i
modelli precedenti. Con il modello 80386 furono aggiunte altre 8 linee di indirizzo con ancora più linee di
controllo. Il bus di quest’ultima CPU, il bus EISA, sarebbe stato molto più semplice se avesse avuto 32 linee
dall’inizio. Ci sono due modi per aumentare la larghezza di banda dei dati di un bus: diminuire la durata del
ciclo di bus (con più trasferimenti/sec) o aumentare la larghezza del bus di dati (più bit/trasferimento). Nel
primo caso ci sono delle difficoltà dovute alle velocità leggermente diverse dei segnali, problema conosciuto
come bus skew, che aumenta con l’aumentare della velocità del bus. Adottando la prima soluzione, ossia
aumentano la velocità, si renderebbe il bus incompatibile con i modelli precedenti. L’unica soluzione è
aggiungere più linee di dati. Per risolvere il problema dei bus troppo larghi, si ricorre al multiplexed bus,
dove si hanno linee di indirizzo e di dati insieme, anziché averle separate. Ciò permette la riduzione della
larghezza del bus, ma diminuisce la velocità del sistema.
Bus clocking: I bus si dividono in due categorie: il bus sincrono (gestito da un oscillatore) e il bus asincrono.
Nel primo caso il segnale è costituito da un’onda quadra con una frequenza compresa tra 5 e 100 MHz.
Bus sincroni: Con
un clock di 40 MHz il
bus avrà un ciclo di
25 nsec. Se si
assume che la
lettura della
memoria richiede 40
nsec dal momento
in cui l’indirizzo è
stabile, con questi
parametri sono
necessari tre cicli di
bus per leggere una
parola, da T1 a T4.
Nel disegno,
nessuna linea
ascendente o
discendente è
perfettamente
verticale, in quanto nessun segnale elettrico è in grado di cambiare il suo valore in tempo zero (nell’esempio
con 1 nsec). Le linee di clock, ADDRESS (indirizzo), DATA (trasferimento dati), MREQ (accesso alla
memoria), RD (attivata la lettura, negata la scrittura), WAIT (tempo di attesa) vengono rappresentate usando
la stessa scala di tempi. Durante l’esecuzione di T1, la CPU mette l’indirizzo della parola desiderata sulle
linee di indirizzo. Dopo che le linee di indirizzo si sono stabilizzate, vengono attivate MREQ e RD. Poiché la
memoria richiede 40 nsec dopo che l’indirizzo si è stabilizzato, non è in grado di fornire i dati richiesti durante
T2. Quest’azione porta all’aggiunta di stati d’attesa (cicli del bus aggiuntivi) finché la memoria ha terminato e
poi nega WAIT. Dopo aver letto i dati, la CPU nega MREQ e RD. Nel primo vincolo, nel caso peggiore la
memoria avrà solo 46.5 nsec (62.5 – 11TAD – 5TDS) dal momento in cui appare l’indirizzo finché deve
produrre i dati. Come secondo vincolo, nel caso peggiore il chip della memoria avrà solo 37 nsec (2T – 8TM –
5TDS) dopo l’attivazione di MREQ e RD per mettere i suoi dati sul bus.
Bus asincrono: I bus sincroni
hanno dei problemi. Un
problema è la totale funzionalità
come multipli del clock del bus.
Se una CPU e una memoria
sono in grado di completare un
trasferimento in 3.1 cicli, la
durata effettiva va portata a 4.0,
perché non si possono usare
cicli frazionati. Un altro
problema è che, una volta scelto il ciclo del bus, la memoria e sono state progettate le schede di I/O, non si
possono avere miglioramenti tecnologici. Questo perché, se il bus sincrono è accompagnato da una serie di
dispositivi, alcuni veloci e alcuni più lenti, il bus sincrono deve adattarsi a quelli lenti. Una tecnologia mista
funziona meglio con un bus asincrono, cioè senza il clock. Quando il master del bus ha fornito l’indirizzo,
attivato MREQ, RD e qualsiasi altro segnale che serva, attiva poi un segnale speciale, chiamato MSYN
(Master SYNchronization). Quando lo slave lo vede, esegue il lavoro più velocemente possibile. Una volta
terminato il lavoro, viene attivato SSYN (Slave SYNchronization). Non appena il master vede che SSYN è
attivo, memorizza i dati disponibili e nega MREQ, RD e MSYN. Quando lo slave vede la negazione di MSYN,
sa che il ciclo è finito e nega SSYN e si torna alla situazione originaria dove tutti i segnali sono negati. Il ciclo
che avviene con il bus asincrono prende il nome di full handshake:
1. MSYN viene attivato
2. SSYN viene attivato in risposta a MSYN
3. MSYN viene negato in risposta a SSYN
4. SSYN viene negato in risposta alla negazione di MSYN
Arbitraggio del bus: Tutti i
chip di I/O devono diventare
master del bus per poter
leggere o scrivere sulla
memoria o per poter
causare interrupt. Il
meccanismo di arbitraggio
può essere centralizzato o
decentralizzato. Se l’arbitraggio è centralizzato, il chip arbitro è spesso racchiuso nello stesso chip della
CPU. L’arbitro, che determina di chi è il turno per utilizzare il bus, contiene un’unica linea di richiesta wiredOR, che può essere attivata da uno o più dispositivi in qualunque momento. L’arbitro non sa quanti
dispositivi hanno richiesto il bus, ma può solamente stabilire se è stato richiesto o meno. Quando l’arbitro
vede una richiesta del bus, viene messo un assegnamento (grant) attivando la linea di grant del bus. Questa
linea è collegata con tutti i dispositivi di I/O in serie. Quando il dispositivo più vicino all’arbitro vede
l’assegnamento, controlla per vedere se è stata fatta una richiesta. Se la risposta è positiva, il dispositivo
prende il controllo del bus, ma non trasmette l’assegnamento. Se quel dispositivo non ha fatto richiesta,
l’assegnamento viene trasmesso al dispositivo successivo e così via. Questo schema si chiama daisy
chaining e si basa sulla
priorità di un dispositivo,
in dipendenza con la
sua vicinanza fisica
dall’arbitro. Per risolvere
il problema di priorità in
base solamente alla
vicinanza fisica, molti
bus hanno diversi livelli
di priorità. Se vengono richiesti più livelli di priorità contemporaneamente, l’arbitro invia un assegnamento
solo per quello con priorità più alta. Fra dispositivi con la stessa priorità si usa il daisy chaining. Alcuni arbitri
hanno una linea di accettazione (acknowledge); appena è stata attivata questa linea, vengono negate le
linee di richiesta e di assegnamento. Altri dispositivi possono richiedere il bus mentre altri lo stanno usando.
Quando il trasferimento corrente è terminato, il nuovo master del bus è già stato selezionato e può
cominciare a usare il bus non appena è stata negata la linea di accettazione. Questo schema richiede una
linea di bus addizionale
e un circuito logico più
complesso in ogni
dispositivo. Nei sistemi
in cui la memoria si
trova sul bus principale,
la CPU deve competere
con tutti i dispositivi di I/
O del bus. Per questo la CPU ha una priorità più bassa, accedendo al bus solo quando non è richiesta da
nessuno. Ciò perché, mentre la CPU può aspettare, i dispositivi di I/O rischiano di perdere i dati in avvio. Per
quanto riguarda il bus con arbitro decentralizzato, un calcolatore ha un tot di linee, ordinate per ogni priorità.
Quando un dispositivo vuole usare il bus deve attivare la sua linea di richiesta. Tutti i dispositivi osservano
tutte le linee di richiesta e al termine di ogni ciclo un dispositivo sa se ha la priorità più alta e quindi se
utilizzare il bus. Questo metodo di arbitraggio richiede più linee di bus, ma risparmia il costo dell’arbitro e
limita il numero di dispositivi al numero delle linee di richiesta. Con questa tipologia i bus possono avere solo
3 linee. La prima è la linea wired-OR per richiedere il bus, la seconda si chiama BUSY e viene attivata dal
master corrente, la terza viene usata per l’arbitraggio del bus ed è collegata in daisy chain attraverso tutti i
dispositivi. Quando nessun dispositivo vuole il bus, il segnale di attivazione della linea di arbitraggio viene
propagato attraverso tutti i dispositivi. Per ottenere il bus, un dispositivo inizialmente deve controllare se il
bus non è usato e se il segnale dell’arbitraggio che sta ricevendo, IN, è attivo. Se IN è negato, non può
diventare un master del bus e nega OUT. Se IN è attivo, il dispositivo nega OUT e asserisce BUSY.
Funzionamento del bus:
Solitamente viene
trasferita una parola per
volta. Quando si usa il
caching, però, è meglio
leggere una linea di cache
intera tutta in una volta.
Spesso il trasferimento di
blocchi interi può essere
più efficiente di piccoli
trasferimenti in successione. Quando inizia la lettura di un blocco il master indica allo slave quante parole
vanno trasferite. Invece di ritornare semplicemente una parola, lo slave invia una parola durante ogni ciclo
finché il numero non si esaurisce. Il segnale BLOCK indica la richiesta di trasferimento di un blocco. Con un
multiprocessore che ha più CPU su lo stesso bus, si usa una variabile di memoria corrispondente a 0
quando nessuna CPU usa la struttura dati e a 1 quando è in uso. Se una CPU vuole avere accesso alla
struttura dati, deve leggere la variabile e, se è 0, la deve portare a 1. Se più CPU vedono che la variabile è 0,
ognuna la riporta a 1 e pensa di essere l’unica CPU che sta usando la struttura dati. Per evitare questa
situazione, i multiprocessori hanno uno speciale ciclo del bus chiamato leggi-modifica-scrivi (read-modifywrite) che permette a qualsiasi CPU di leggere una parola dalla memoria, controllarla, modificarla e
riscriverla nella memoria. Un altro importante ciclo del bus serve a gestire gli interrupt. Quando la CPU invia
un ordine a un dispositivo di I/O, solitamente si aspetta un interrupt quando il lavoro è terminato. La
segnalazione di interrupt richiede il bus. Dato che più dispositivi potrebbe causare un interrupt
contemporaneamente, la soluzione consiste nell’assegnare una priorità ai dispositivi e usare un arbitro
centralizzato per dare priorità ai dispositivi che hanno problemi di tempo critico. Il chip Intel 8259A permette
di collegare fino a otto controllori di I/O con otto input IRx (Interrupt Request). Quando uno qualsiasi dei
dispositivi vuole
chiedere un interrupt,
è
sufficiente che attivi la
sua linea di input.
Quando vengono
attivati uno o più
input, l’8259A attiva
INT (INTerrupt) che controlla direttamente il piedino di input della CPU. Quando la CPU è in grado di gestire
l’interrupt, rimanda un impulso all’8259A su INTA (INTerrupt Acknowledge). A quel punto l’8259A deve
specificare quale input ha causato l’interrupt inviando il numero di identificazione di quell’input sul bus dei
dati. Quest’operazione richiede un ciclo speciale del bus. La CPU poi utilizza quel numero come indirizzo in
una tabella di puntatori, chiamati vettori di interrupt, per trovare l’indirizzo della procedura da eseguire per
gestire la richiesta di interrupt, dopodiché viene negato INT. Quando ci sono più di otto dispositivi di I/O, si
possono mettere in cascata più 8259A, fino a un massimo di 64 dispositivi, unendo gli input di un 8259A con
gli output di un altro 8259A.
Il Pentium II: Il Pentium II è un discendente diretto della CPU 8088 utilizzata dal PC IBM. Anche se il
Pentium II ha 7.5 milioni di transistor, anziché i 29000 dell’ 8088, sono estremamente compatibili. Il Pentium
II è a 32 bit con lo stesso ISA di livello utente del 80386. Dal punto di vista HW il Pentium II è superiore in
quanto riesce a indirizzare 64 GB di memoria fisica e a trasferire dati dalla e alla memoria in unità di 64 bit. A
livello di microarchitettura, il Pentium II è essenzialmente un Pentium Pro con l’aggiunta delle istruzioni
MMX. Le istruzioni del livello ISA vengono lette prima dalla memoria e suddivise in microoperazioni simili a
RISC. Queste microoperazioni vengono memorizzate in un buffer e possono essere cominciate nello stesso
ciclo. Il Pentium II è dotato di una cache a due livelli. La cache di primo livello si trova sul chip, con 16 KB per
le istruzioni e 16 KB per i dati, ed è unita alla cache di secondo livello, su un altro chip, con 512 KB di spazio.
La linea di cache è di 32 byte. La cache di secondo livello funziona a metà della frequenza di clock della
CPU, quest’ultima con frequenza da 233 MHz in su. Il Pentium II ha due bus esterni principali, ambedue
sincroni. Un bus serve per accedere alla memoria principale DRAM e l’altro, un PCI, serve per interagire con
i dispositivi di I/O. Un sistema Pentium II può avere una o due CPU che condividono la stessa memoria. Il
problema di avere due CPU è che se una CPU legge una cache e la modifica senza scriverla nella memoria,
quando l’altra CPU cercherà di leggerla otterrà un valore sbagliato. Per ovviare a questo problema si usa lo
snooping. La differenza sostanziale tra il Pentium II e i suoi predecessori è il package. Mentre tutti i
processori, dall’8088 al Pentium Pro, erano semplici chip uniti con piedini in uno zoccolo, il Pentium II si
trova in una cartuccia che Intel chiama SEC (Single Edge Cartridge). La SEC è una cartuccia di plastica (6.3
x 14 cm) contenente CPU, cache di secondo livello, un connettore per i segnali e 242 connettori. Uno dei
problemi del Pentium II è la gestione dell’alimentazione. La quantità di calore prodotta dipende dalla
frequenza del clock, ma è tra 30 e 50 Watt. E’ una quantità enorme per un chip, per questo la SEC monta un
dissipatore. Inoltre, per non consumare troppa energia, quando il processore non deve essere usato per un
tot di tempo, viene spento il clock e le unità interne, conservando però i valori di cache e di registro.
La piedinatura logica del Pentium II:
I connettori a 242 piedini della SEC si dividono in 170 per i segnali, 27 per l’alimentazione, 35 di massa e 10
di riserva per un uso futuro. Alcuni segnali logici usano due o più piedini e quindi ci sono 53 tipi diversi di
piedini. In figura i nomi dei segnali sono rappresentati come testo ASCII. I segnali bassi, invece di indicarli
con la “barra”, vengono indicati con # (BPRI  BPRI#). Il primo gruppo di segnali viene usato per
l’arbitraggio del bus. BPRI# permette a un dispositivo di effettuare una richiesta di alta priorità. LOCK#
permette a una CPU di bloccare il bus per impedire all’altra di prenderlo prima che abbia terminato. Gli
indirizzi sono di 36 bit, ma i 3 indirizzi meno significativi devono essere sempre 0, e quindi non sono stati
assegnati loro piedini. Per questo A# ha 33 piedini. Tutti i trasferimenti sono allineati a 8 byte. Con 36 bit di
indirizzo, la memoria massima è di 236 byte, ovvero 64 GB. Quando viene messo un indirizzo sul bus, si
attiva ADS# per indicare alla destinazione che le linee di indirizzo sono valide. Il tipo di ciclo del bus è
codificato sulle linee REQ#. Due segnali di parità proteggono A# e uno ADS# e REQ#. Il gruppo Snoop si
usa nei multiprocessori per permettere ad una CPU di scoprire se una parola che serve si trova nella cache
in un’altra CPU. Il gruppo Response contiene segnali usati dallo slave per inviare informazioni al master.
RS# contiene il codice di stato, TRDY# segnala che lo slave è pronto ad accettare i dati dal master. Anche
questi sono controllati da bit di parità. L’ultimo gruppo serve per il trasferimento dati. D# viene usato per
mettere 8 byte di dati sul bus. Una volta messi i dati, DRDY# viene attivato per annunciare la loro presenza.
DBSY# indica se il bus è occupato al momento. RESET# si usa per azzerare la CPU in caso di disastro
totale. Per quanto riguarda gli interrupt, il Pentium II è uguale all’8088, oppure utilizza il dispositivo APIC
(Advanced Programmable Interrupt Controller). Il Pentium II può funzionare a diversi voltaggi, ma deve
sapere a priori qual’è il voltaggio; per la selezione automatica del voltaggio vengono usati i segnali VID. I
segnali di compatibilità servono per far credere ai dispositivi, che si trovano sul bus, di lavorare con l’8088. Il
gruppo Diagnostic contiene segnali per i test e le diagnosi di errori. Il gruppo di Initialization gestisce l’avvio
del sistema. Il gruppo di Power management permette alla CPU di andare in uno stato di “sonno profondo”.
Pipelining sul bus della memoria del Pentium II:
Il Pentium II è molto più veloce rispetto a una DRAM. Per impedire alla CPU di restare senza dati è
essenziale avere il massimo throughput possibile con la memoria. Per questo il bus di memoria del Pentium
II funziona in pipeline e arriva a un massimo di 8 transazioni contemporanee. La pipeline della memoria del
Pentium II si divide in sei fasi:
1. Fase di arbitraggio del bus
2. Fase di richiesta
3. Fase di segnalazione dell’errore
4. Fase di snoop
5. Fase di risposta
6. Fase dei dati
Non tutte le transazioni richiedono tutte le fasi. La fase di arbitraggio del bus determina qual è il prossimo
master del bus tra quelli possibili. La fase di richiesta permette che si metta l’indirizzo sul bus e si faccia la
richiesta. La fase di segnalazione dell’errore permette allo slave di segnalare che l’indirizzo contiene un
errore di parità. La fase di snoop permette a una CPU di osservare cosa fa un’altra eventuale CPU in sistemi
multiprocessori. La fase di risposta indica al master se riceverà i dati che desidera. La fase dei dati permette
di inviare i dati. Ogni fase del bus di memoria utilizza segnali del bus diversi, così ogni fase è completamente
indipendente dalle altre. Nella figura non c’è l’arbitraggio del bus in quanto già lo si possiede.
UltraSPARC II: L’UltraSPARC II è
un processore della famiglia Sun a
64 bit. Sfrutta l’architettura RISC. Ha
un instruction set multimediale VIS,
che è stato progettato per le
applicazioni grafiche e la decodifica
MPEG in tempo reale. Diversamente
dalla SEC del Pentium II,
l’UltraSPARC II è un chip a sé
stante, con 5.4 milioni di transistor.
Questa CPU ha 787 piedini, numero
elevato dovuto all’uso di 64 bit per gli
indirizzi e 128 bit per i dati. Molti di
questi piedini non vengono usati.
Infatti questo processore è stato
progettato con 787 piedini solo per
usare un package standard
industriale. L’ UltraSPARC II ha due
cache interne: 16 KB per le istruzioni e 16 KB per i dati. Anche questa CPU, come il Pentium II, utilizza una
cache di secondo livello esterna al chip ma, mentre nel PENTIUM II si trova nella SEC, con l’ UltraSPARC II
viene venduta separatamente. Le cache di secondo livello per un UltraSPARC II vanno da 512 KB a 16 MB,
ma potrebbe essere più lenta per la distanza con la CPU. La SRAM usata per la cache di secondo livello non
viene prodotta dalla Sun. Gran parte delle piattaforme Sun sono dotate di un bus sincrono a 25 MHz,
chiamato SBus. I dispositivi di I/O si possono collegare a questo bus. Questo tipo di bus però è troppo lento
per la memoria, quindi Sun ha creato un meccanismo diverso che permette a più CPU UltraSPARC II di
comunicare con più memorie: l’ UPA (Ultra Port Architecture). Si può implementare l’UPA come un bus, uno
switch o una combinazione dei due. Quando la CPU ha bisogno di una parola di memoria, guarda prima
nelle cache di primo livello, se non la trova, la cerca nella cache di secondo livello. Tutta la memoria
principale è divisa in linee di cache (blocchi di 64 byte). Le 256 linee di istruzioni più usate e le 256 linee di
dati più usate si trovano nella cache di primo livello. Le linee di cache che vengono utilizzate molto spesso,
ma che non possono essere contenute nella cache di primo livello per mancanza di spazio, vengono tenute
nella cache di secondo livello. Le linee di cache che si trovano nella cache di secondo livello devono essere
a conoscenza del sistema. Quest’informazione è contenuta nella seconda SRAM chiamata “Tag della cache
di secondo livello”. Nel caso in cui la CPU non trovi quello che cerca nella cache di primo livello, invia un
identificatore della linea che sta cercando (indirizzo del tag) alla cache di secondo livello. La tag informa se
la linea si trova nella cache di secondo livello. Se la linea si trova nella cache, la CPU la recupera. I
trasferimenti di dati sono larghi 16 byte, quindi occorrono quattro cicli per leggere un’intera linea nella cache
di primo livello. Se la linea di cache non si trova nella cache di secondo livello, si deve leggere la memoria
principale per mezzo dell’UPA. L’UPA viene implementato grazie a un controllore centralizzato. I segnali di
controllo e di indirizzo inviati dalla CPU vanno al controllore. Per accedere alla memoria, la CPU deve prima
utilizzare i piedini di arbitraggio del bus per ottenere l’autorizzazione. Una volta ottenuto il permesso, la CPU
attiva i piedini dell’indirizzo di memoria, specifica il tipo di richiesta e attiva il piedino di “indirizzo valido”
(piedini bidirezionali). Ci possono essere più transazioni con l’UPA attive contemporaneamente perché l’UPA
è in grado di gestire due flussi di transazioni indipendenti. Quando i dati arrivano alla memoria, possono
essere organizzati in 8 byte per volta, con un codice di correzione dell’errore di 16 bit. Tutti i dati in arrivo
vanno all’ UDB II (UltraSPARC Data Buffer), che li memorizza temporaneamente. L’UDB serve per
disaccoppiare ancora di più la CPU dalla memoria, in modo che possano lavorare in modo asincrono.
Il picoJava II: Un sistema
informatico molto grande è
l’embedded, di cui fanno
parte telefonini, televisori,
giochi elettronici, ecc. I
calcolatori di questa
categoria sono caratterizzati
per il basso costo.
Tradizionalmente i processori embedded sono stati programmati in linguaggio assemblatore. Il linguaggio
assemblatore in un secondo momento fu sostituito da Java, in quanto è facile da programmare, ha un codice
di modeste dimensioni e una piattaforma indipendente. Lo svantaggio di usare Java nelle applicazioni
embedded è la necessità di avere un grosso interprete che esegue il codice JVM generato dal compiler e la
lentezza del processo di interpretazione. Sun e altre aziende hanno affrontato questo problema producendo
una CPU avente una JVM come instruction set nativo. Ciò fa sfruttare i vantaggi del linguaggio Java, ossia la
portabilità e la veloce esecuzione da parte dell’ HW specializzato. La CPU è la Sun picoJava II, che è alla
base del chip Sun microJava 701. Il picoJava II è un singolo chip con due bus di interfaccia, uno per la
memoria, di 64 bit, e l’altro aderente al protocollo PCI, di 32 bit. E’ dotato di una cache di primo livello che
potrebbe non stare sullo stesso chip della CPU, con un massimo di 16 KB per le istruzioni e 16 KB per i dati.
La CPU non ha una cache di secondo livello e contiene 2 milioni di transistor. Il vantaggio di usare il bus PCI
è la mancanza di bisogno di utilizzare un nuovo bus. Con il sistema microJava 701 si usa una memoria
PROM flash, che contiene la gran parte o tutto il programma. Un altro chip contiene le interfacce di I/O seriali
e parallele che ci sono su un PC. Inoltre la CPU ha 16 linee di I/O programmabili che si possono collegare
con pulsanti, interruttori e spie e ciò sostituisce un controllore di I/O. Il chip inoltre ha tre timer programmabili.
Il microJava 701 viene venduto in package standard, BGA (Ball Grid Array), da 316 piedini. Di questi 316, 59
piedini sono collegati al bus PCI, altri 123 piedini sono riservati al bus della memoria, 7 piedini per il
controllo, 3 per i timer, 11 per l’interrupt, 10 per i test e 16 per I/O programmabili. Inoltre ci sono piedini per
l’alimentazione, per la messa a terra e alcuni liberi.
Il bus ISA: Il PC
bus IBM
rappresenta lo
standard sui
sistemi che si
basavano
sull’8088. Aveva
63 linee di
segnale, 20 per
l’indirizzo della
memoria, 8 per i
dati, una per la
lettura della
memoria, una per
la scrittura della memoria, una per la lettura dell’ I/O e una per la scrittura dell’I/O. Fisicamente il bus veniva
cablato sulla scheda madre. Quando l’IBM introdusse il PC/AT basato sull’80286 sorse il problema della
compatibilità. E’ come se si fosse progettato un nuovo bus di 16 bit completamente nuovo e non era
adattabile a nessuna scheda. La soluzione adottata fu di estendere il bus PC, aggiungendo un secondo
connettore sul fondo della scheda accanto a quello principale e progettare un circuito AT in modo che
funzionasse con entrambi i tipi di schede. Il primo connettore contiene 62 linee, il secondo 36 e si trova sul
PC/AT. Delle 36 linee, 31 servono per avere più linee di indirizzo, di dati, di interrupt e più canali DMA, oltre
all’alimentazione e la messa a terra. Il resto gestisce le differenze fra trasferimenti da 8 bit e da 16 bit.
Quando l’IBM mise sul mercato la serie PS/2 come successore del PC e del PC/AT, fu deciso di creare un
nuovo bus. Il nuovo bus fu l’ISA (Industry Standard Architecture) che è essenzialmente il PC/AT funzionante
a 8.33 MHz. Uno dei vantaggi che aveva, era la compatibilità con le schede esistenti e fu progettato in
grande quantità in quanto l’IBM concesse liberamente la licenza.
Il bus PCI: Sul PC IBM originale,
gran parte delle applicazioni
avevano un’interfaccia a caratteri
fino all’avvento delle interfacce
grafiche Windows. Il bus non
aveva problemi con queste
applicazioni. I problemi sorsero
con l’aumentare delle applicazioni,
soprattutto con i giochi
multimediali che visualizzavano
video in movimento completo a
schermo intero. Uno schermo
1024 x 768 con colori veri
(3byte/pixel) contiene 2.25 MB di
dati. Per ottenere fluidità nel
movimento, occorrono almeno 30
schermate/sec, con una velocità
di dati di 67.5 MB/sec. In realtà
serve una velocità maggiore
perché, per visualizzare un video
da hard disk, CD o DVD, i dati devono passare attraverso il bus per arrivare alla memoria. Poi, per
visualizzare i dati, devono viaggiare di nuovo per mezzo del bus fino all’adattatore grafico. Per questo serve
una larghezza di banda del bus di 135 MB/sec solo per il video. Il bus ISA a una velocità massima di 8.33
MHz ed è in grado di trasferire 2 byte per ciclo per una larghezza di banda massima di 16.7 MB/sec. Il bus
EISA può muovere 4 byte per ciclo per ottenere 33.3 MB/sec. Nel 1990 Intel progettò un nuovo bus: il PCI
(Peripheral Component Interconnect bus). Per incoraggiare la produzione furono messi i brevetti a
disposizione di tutti. Oggi ogni calcolatore basato su Intel ha un bus PCI. Il bus PCI originale trasferiva 32 bit
per ciclo e funzionava a 33 MHz (tempo di ciclo di 30 nsec) con una larghezza di banda di 133 MB/sec. Nel
1993 fu introdotto il PCI 2.0, nel 1995 il PCI 2.1. L’ultimo della serie fu il bus PCI 2.2, adatto anche ai
calcolatori mobili (soprattutto per risparmiare la corrente della batteria). Il bus PCI 2.2 funziona fino ad un
massimo di 66 MHz ed è in grado di gestire trasferimenti fino a 64 bit per una larghezza di banda di 528 MB/
sec. Questo bus, pur essendo molto veloce, non è ai livelli del bus di memoria e non è compatibile con tutte
le schede ISA. La soluzione trovata da Intel fu di progettare calcolatori a tre o più bus. La CPU parla con la
memoria per mezzo di uno speciale bus di memoria. Un elemento fondamentale di quest’architettura è il chip
ponte (bridge). Il ponte PCI collega CPU, memoria e bus PCI. Il ponte ISA collega il bus PCI a quello ISA e
supporta uno o due dischi IDE. I sistemi Intel sono dotati di slot liberi per aggiungere periferiche. Il grosso
vantaggio è che la CPU ha larghezza di banda elevatissima verso la memoria, grazie al bus di memoria; il
bus PCI ha larghezza di banda molto alta per le periferiche veloci come i dischi SCSI. Esistono anche ponti
da PCI a PCI e in un sistema si possono avere più ponti da PCI a ISA. Il bus PCI, nato per i moderni
calcolatori a 3.3 volt, supporta anche i vecchi a 5. I connettori sono gli stessi, tranne che per due pezzetti di
plastica che impediscono di inserire il bus PCI da 3.3 volt in uno di 5 e viceversa. Le schede da 32 bit hanno
120 piedini; quelle da 64 bit hanno 120 piedini più altri 64. Infine il bus PCI può funzionare indifferentemente
a 33 o 66 MHz. Il bus PCI è sincrono. Tutte le transazioni avvengono tra un master, chiamato iniziatore, e
uno slave, chiamato target. Per cercare di ridurre il numero di piedini PCI, le linee di indirizzo e di dati
condividono gli stessi fili. In questo modo servono solo 64 piedini. Con questa tipologia di struttura, nel ciclo
1, durante un’operazione di lettura, il master mette l’indirizzo sul bus. Nel ciclo 2 il master toglie l’indirizzo dal
bus in modo che lo possa utilizzare lo slave. Nel ciclo 3 lo slave invia i dati richiesti. Durante le operazioni di
scrittura, il master mette sia l’indirizzo che i dati sul bus in momenti diversi. La transazione minima è di tre
cicli.
Arbitraggio del bus PCI: Un dispositivo deve acquisire il bus PCI prima di usarlo. L’arbitraggio del bus PCI
usa un arbitro centralizzato, che si trova su un chip bridge. Ogni dispositivo PCI ha due linee che lo
collegano con l’arbitro. Una è REQ#, e viene usata per richiedere il bus; l’altra è GNT#, e viene usata per
ricevere l’assegnazione (grant) del bus. Ogni grant del bus è valido solo per una sola transazione. Se un
dispositivo vuole far partire una seconda transazione e nessun altro dispositivo ha chiesto il bus, allora può
ripetere il suo turno. Solitamente viene inserito uno ciclo vuoto fra due transazioni consecutive.
Segnali del bus PCI: Il bus PCI ha dalle 120 alle 180 linee ed ha segnali obbligatori (32 bit) e segnali
opzionali (64 bit). Segnali obbligatori:
• Il segnale CLK controlla il bus (la frequenza). Gran parte degli altri segnali sono sincronizzati con
questo
•
•
I 32 segnali AD sono riservati all’indirizzo e ai dati (per le transazioni di 32 bit)
Il segnale PAR è il bit di parità per AD
• C/BE# viene usato per due scopi diversi: nel ciclo 1 per il comando del bus; nel ciclo 2 per la mappa
dei byte che indica quali byte della parola di 32 bit sono usati nella transazione.
• FRAME# viene attivato dal master del bus per iniziare una transazione
• Durante una lettura viene attivato IRDY# contemporaneamente a FRAME#. Questo indica che il
master è pronto ad accettare i dati di ingresso.
• IDSEL è lo spazio di configurazione del PCI (256 byte) che altri dispositivi possono leggere.
• DEVSEL# annuncia che lo slave ha notato il suo indirizzo sulle linee AD ed è pronto alla transazione
• TRDY# viene attivato dallo slave durante le letture per annunciare che i dati si trovano sulle linee AD
e durante le scritture per annunciare che è pronto a ricevere i dati.
• STOP# serve per vedere se ci sono errori gravi e si desidera abortire la transazione in atto
• PERR# serve per segnalare un errore di parità dei dati nel ciclo precedente
• SERR# segnala gli errori all’inizio del sistema.
• REQ# e GNT# si utilizzano per l’arbitraggio del bus e non vengono attivati dal master corrente, ma
dal prossimo dispositivo che desidera diventare master del bus
• RST# serve per azzerare il sistema per mezzo del pulsante <RESET> da parte dell’utente o se un
dispositivo individua un errore fatale
Segnali opzionali:
• REQ64# e ACK64# permettono al master di chiedere l’autorizzazione per effettuare una transazione
a 64 bit e permettono allo slave di accettare.
• AD, PAR64# C/BE# sono estensioni dei corrispondenti segnali obbligatori
• LOCK permette al bus di essere riservato per più transazioni
• INTx vengono utilizzati per richiedere l’interrupt
• JTAG servono per la procedura di test IEEE 1149.1 JTAG
• M66EN è usato per comunicare con le schede la velocità del clock che deve cambiare durante il
funzionamento del sistema
• SBO# e SDONE servono per i multiprocessore
Transazione del bus
PCI: Nella figura è
riportata una transazione
di lettura, un ciclo a vuoto
e una transazione di
scrittura. Durante T1 il
master mette l’indirizzo di
memoria su AD e il
comando del bus su
C/BE#, in corrispondenza
del fronte di discesa del
clock. Dopodiché, il
master attiva FRAME# per avviare la transazione. Durante T2 il master non pilota il bus per evitare
interferenze. Il master cambia C/BE# per indicare quale byte della parola selezionata vuole abilitare. In T3 lo
slave attiva DEVSEL# in modo da comunicare al master di essere pronto alla ricezione. Inoltre, lo slave
mette i dati sulle AD e afferma TRDY# per indicare che ha eseguito. Se lo slave non è in grado di rispondere
così velocemente, attiverà DEVSEL# per indicare che è pronto ma terrà TRDY# negato finché non sarà in
grado di ricevere i inviare i dati. Questa procedura permette di introdurre stati di attesa.
Universal Serial Bus: Il bus PCI va bene per collegare il calcolatore con periferiche ad alta velocità, ma è
troppo costoso per avere un’interfaccia PCI per ogni dispositivo di I/O a bassa velocità. Nel 1990 si riunirono
sette aziende (Compaq, DEC, IBM, Intel, Microsoft, NEC, Northern Telecom) per affrontare questo problema
e trovare un modo migliore per collegare i dispositivi di I/O lenti con il calcolatore. Lo standard che venne
creato fu l’USB (Universal Serial Bus). Tale dispositivo aveva i seguenti obiettivi:
1. l’utente non deve essere obbligato a configurare interruttori o jumper su schede o dispositivi
2. l’utente non deve essere obbligato ad aprire il calcolatore per istallare nuovi dispositivi di I/O
3. un unico cavo per collegare tutti i dispositivi
4. i dispositivi di I/O dovrebbero essere alimentati dal cavo
5. si dovrebbero poter collegare a un singolo calcolatore fino a 127 dispositivi
6. il sistema dovrebbe supportare dispositivi che funzionano in tempo reale
7. si devono poter istallare dispositivi mentre il calcolatore è in funzione
8. non ci dovrebbe essere la necessità di far ripartire il sistema una volta che è stato istallato un nuovo
dispositivo
9. la costruzione del nuovo bus e dei suoi dispositivi di I/O dovrebbe essere poco costosa
L’USB soddisfò tutti questi obiettivi. La larghezza di banda totale dell’USB è di 1.5 MB/sec; questo limite è
stato fissato per mantenere i costi. L’USB è costituito da un root hub che si collega al bus principale. Questo
hub è dotato di prese per i cavi che si possono collegare direttamente ai dispositivi di I/O oppure ad altri hub
di espansione, per ottenere altre prese. I cavi hanno prese diverse dalla parte dei dispositivi e dalla parte
dell’hub. Il cavo si compone di quattro fili: due per i dati, uno per l’alimentazione (5 volt) e uno per la messa a
terra. Quando viene collegato un nuovo dispositivo di I/O, il root hub identifica il dispositivo e interrompe il
sistema operativo. Il sistema operativo esamina il tipo di dispositivo e quanta larghezza di banda richiede;
assegna un indirizzo unico (1 – 127) al nuovo dispositivo e carica questo indirizzo e altre informazioni nei
registri di configurazione che si trovano all’interno del dispositivo stesso. Ogni dispositivo è in grado di
dividere la sua connessione fino a 16 sottodivisioni per diversi tipi di dati. Ogni 1.00 – 0.05 msec, il root hub
invia a tutti i broadcast un frame per mantenere i dispositivi sincronizzati. Un frame è associato a una
connessione e si compone di pacchetti. Il primo frame inviato va dal root hub al dispositivo e prende il nome
di SOF (Start Of Frame). L’USB supporta quattro tipi di frame: control, isochronous, bulk e interrupt. I frame
di tipo control vengono usati per configurare dispositivi, inviare loro comandi e informarsi sul loro stato. I
frame di tipo isochronous servono per i dispositivi che funzionano in tempo reale, come i microfoni, i
telefoni,ecc. Essi hanno un ritardo molto prevedibile, ma non ritrasmettono in caso di errore. I frame di tipo
bulk servono per i trasferimenti di grosse quantità di dati da o verso dispositivi che funzionano in tempo
reale, come le stampanti. I frame di tipo interrupt sono necessari in quanto l’USB non supporta l’interrupt. Un
frame è composto da uno o più pacchetti nelle due direzioni. Esistono quattro tipi di pacchetti.
I pacchetti token vanno alla radice del dispositivo e servono al controllo del sistema (uno di questi è il SOF,
che potrebbe essere l’unico se non c’è lavoro). Il pacchetto di tipo token IN è la richiesta che chiede al
dispositivo di rimandare i dati. Il pacchetto di tipo token OUT indica che seguiranno i dati per il dispositivo.
Oltre al token SOF, IN e OUT, c’è il token SETUP e viene usato per la configurazione. I pacchetti data
servono per trasmettere fino a 64 byte di informazioni in qualsiasi direzione; consistono in campi di
sincronizzazione di 8 bit, comprendenti dati e un CRC (Cyclic Redundancy Code) di 16 bit per individuare gli
errori. I pacchetti handshake si dividono in: ACK (il pacchetto di dati precedenti è stato ricevuto
correttamente), NAK (è stato individuato un errore CRC) e STALL ( si prega di attendere – sono occupato).
Infine ci sono i pacchetti special.
Chip di I/O: Il chip più importante di questo tipo è l’UART (Universal Asynchronous Receiver Transmitter)
che può leggere un byte dal bus dei dati e inviare su una linea seriale un bit per volta al terminale, oppure
leggere dati da un terminale. Questo chip permette varie velocità di trasmissione. Un USART (Universal
Synchronous Asynchronous Receiver Transmitter) può gestire la trasmissione asincrona utilizzando una
serie di protocolli ed eseguendo tutte le funzioni dell’UART.
I chip PIO: Uno dei chip PIO (Parallel I/O) tipici è
l’Intel 8255A. Questo chip è dotato di 24 linee di I/
O che si possono interfacciare con qualsiasi
dispositivo TLL compatibile come tastiere,
interruttori, ecc. Il dispositivo più semplice per
usare l’8255A è trattarlo come un dispositivo a tre
porte indipendenti di 8 bit, A, B, C. A ogni porta è
associato un registro latch di 8 bit. Per scrivere su una porta, la CPU mette un numero di 8 bit nel registro
corrispondente e il numero di 8 bit appare sulle linee di output dove resta finché il registro non viene riscritto.
Per usare una porta per l’input, la CPU legge semplicemente la porta corrispondente. L’8255A, oltre ad
avere 24 piedini per le tre porte, ha 8 linee collegate direttamente al bus dei dati, una linea di selezione del
chip, linee di scrittura e lettura, 2 linee di indirizzo e una linea per azzerare il chip. Le due linee di indirizzo
selezionano uno dei quattro registri interni, corrispondenti alle porte A, B, C e al registro di stato. Il PIO si
può selezionare in due modi: o come dispositivo di I/O o come parte della memoria. Nel primo caso va
selezionato utilizzando una linea di bus esplicita facendo riferimento a un dispositivo di I/O e non a una
memoria. Nel secondo caso, si devono assegnare al PIO 4 byte di spazio di memoria per le tre porte e per il
registro di controllo.