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.