Architettura dei Sistemi Integrati

Transcript

Architettura dei Sistemi Integrati
Architettura dei Sistemi Integrati
A.A. 2009/2010
Problematiche progettuali per i sistemi integrati
(Cap. 1 del testo)
I sistemi elettronici a larga scala di integrazione (VLSI) integrano su di una medesima tessera di
Silicio (Chip) un numero sempre crescente di dispositivi elettronici.
Troviamo applicazioni in un gran numero di sistemi di uso quotidiano:
Computer
Telefoni cellulari
Sistemi multimediali (riproduttori musicali, lettori DVD, ricevitori satellitari)
Controllo dei sistemi di bordo nelle autovetture (controllo iniezione, ABS,
climatizzazione ecc.)
Sistemi elettro-medicali
Sistemi domotici per il controllo del comfort e della sicurezza delle
abitazioni
Esistono poi i cosiddetti ASIC: Application-Specific Integrated Circuit, ovvero circuiti integrati per
applicazioni specifiche che sono customizzabili a seconda delle necessità dell’utente.
Molteplici sono i vantaggi che spingono a realizzare un intero sistema con un unico circuito
integrato, invece di assemblare componenti standard:
Riduzione delle dimensioni dell’intero sistema.
Riduzione dei parametri parassiti.
Aumento della frequenza di clock (legata alla riduzione delle capacità
parassite) E’ inoltre possibile trasmettere segnali all'interno di un chip
a frequenze un ordine di grandezza superiori rispetto al caso in cui i
segnali viaggiano su piste di circuito stampato.
Riduzione della potenza dissipata.
Riduzione dei costi del sistema complessivo, possibilità di sviluppare
applicazioni portatili sempre più versatili (telefonini, notebook, PDA
ecc.)
Protezione della riservatezza del progetto.
Il primo dei fattori che contribuiscono allo sviluppo ed alla diffusione dei sistemi VLSI è,
sicuramente, il fatto che la disponibilità di sistemi integrati di complessità sempre più elevata,
spinge allo sviluppo di applicazioni sempre più sofisticate. Inoltre le nuove applicazioni, con il loro
mercato, fungono a loro volta da traino alla progettazione di sistemi VLSI di prestazioni maggiori.
Come esempio possiamo citare lo sviluppo delle applicazioni e dei sistemi operativi per PC, cui ha
fatto da contraltare lo sviluppo di microprocessori e memorie sempre più avanzate.
La necessità di sistemi integrati sempre più sofisticati ha spinto al continuo miglioramento dei
processi tecnologici.
L’evoluzione fu prevista dalla Legge di Moore, enunciata nel 1965 Gordon Moore, (allora a capo
della R&D alla Fairchild Semiconductor, in seguito, nel 1969, co-fondatore della INTEL).
Dall'osservazione del numero di componenti integrati su chip nel periodo 1959-65, Moore postulò
che si sarebbe avuto un aumento esponenziale del numero di dispositivi integrati anche negli anni
a venire.
La legge di Moore, dall'articolo
originalepubblicato nel 1965 su
Electronics
La legge di Moore,
Applicata ai
microprocessori INTEL
Le tecniche di progetto di sistemi VLSI devono confrontarsi con l’elevata complessità dei circuiti da
realizzare (spesso dell'ordine di milioni di porte logiche elementari), con il ridotto time to market
(vista la continua evoluzione tecnologica e di mercato) e inoltre con la necessità di sofisticati
programmi di progettazione assistita al calcolatore (CAD).
Per questo motivo si fa un largo utilizzo di diversi livelli di astrazione progettuali e di tecniche di
progettazione gerarchica.
Livelli di astrazione
Il flusso di progetto di un sistema integrato si completa
attraverso un raffinamento fra diversi livelli di astrazione.
Le specifiche rappresentano una descrizione delle
operazioni che il sistema deve essere in grado di effettuare.
Come specifiche sono inoltre assegnati i parametri di
prestazione del sistema:
la frequenza di clock
la potenza dissipata
l'occupazione di area sul chip
Le specifiche sono essenzialmente un insieme di requisiti
(scritti in linguaggio naturale) e possono risultare
incomplete o contraddittorie.
La descrizione comportamentale consiste nel descrivere
il sistema mediante un programma eseguibile, ottenuto a
partire da linguaggi ad alto livello.
La descrizione del comportamento del sistema è univoca.
E’ possibile simulare il funzionamento del sistema, applicando in ingresso dei vettori di test.
Analizzando i risultati prodotti della simulazione è possibile verificarne la congruenza con le
specifiche assegnate.
I linguaggi per la descrizione dell’hardware utilizzati sono detti linguaggi HDL (Hardware
Description Language): VHDL e VERILOG.
La descrizione Register-Transfer Level (RTL) consiste nel descrivere il sistema è mediante
collegamento di
blocchi combinatori (che realizzano funzioni logiche assegnate) con elementi di memoria (registri).
Si delinea la struttura interna del sistema, della quale è possibile conoscere con precisione il
comportamento del circuito in ogni ciclo di clock. E’ possibile avere delle prime stime,
approssimative, dei parametri di prestazione.
Anche la descrizione RTL viene spesso formalizzata tramite linguaggi HDL.
Nella fase di descrizione a livello gate i blocchi funzionali individuati a livello RTL sono descritti
mediante interconnessione di alcune porte logiche elementari.
L'insieme delle gates utilizzate per descrivere il circuito è denominato libreria, mentre per netlist si
intende il listato che enumera le celle elementari utilizzate e ne descrive le interconnessioni.
In questa fase del flusso di progetto è possibile ottenere delle stime molto più accurate
dell'occupazione di area, della sua velocità e delle dissipazione di potenza.
Il passaggio dalla descrizione RTL a quella a livello gate può essere estremamente complesso
poiché la netlist finale può contenere centinaia di migliaia o milioni di gates.
I programmi di sintesi consentono, in maniera quasi del tutto automatica, di passare da una
descrizione HDL a livello RTL ad una netlist equivalente
La descrizione a livello transistor consiste nel considerare le realizzazioni circuitali delle celle
logiche di libreria mediante dispositivi NMOS e PMOS, ognuno con le proprie dimensioni di canale,
opportunamente interconnessi in modo da formare porte CMOS complesse, strutture a porte di
trasmissione, logiche dinamiche ecc.
Anche a questo livello di astrazione il circuito sarà descritto da una netlist (ad esempio, un listato
SPICE) che può essere simulata per verificare il funzionamento del circuito e per valutarne le
prestazioni.
A livello di layout avviene la descrizione mediante un insieme di rettangoli di polisilicio, di
diffusioni N e P, di metallizzazioni ecc. che nella loro composizione definiscono i transistori e le
linee di interconnessione del chip.
Le informazioni geometriche contenute nel layout servono per realizzare le maschere
fotolitografiche necesarie per la realizzare il circuito integrato.
Il layout consente quindi di valutare esattamente l'area di Silicio richiesta dal circuito.
Solo a livello layout è possibile calcolare con precisione i valori dei parametri parassiti introdotti
dalle interconnessioni. Si può quindi valutare accuratamente la frequenza operativa e la
dissipazione di potenza.
Il layout un circuito VLSI può includere milioni di rettangoli elementari => è fondamentale la
disponibilità di programmi CAD per layout automatico.
Programmi di piazzamento e collegamento di celle elementari: partendo dalla netlist a livello gate e
dalla conoscenza dei dettagli geometrici delle celle standard, generano automaticamente un layout
del circuito complessivo in cui le celle sono allineate su più righe parallele, intercalate da canali di
collegamento.
Il flusso di progetto che partendo dalle specifiche porta fino al layout è di tipo top-down.
Sfortunatamente, molto spesso non è sufficiente un approccio top-down. I parametri di prestazione
sono valutati accuratamente solo a livello layout.
Non possiamo essere sicuri che partendo da una determinata descrizione RTL il
circuito finale verificherà le specifiche assegnate in termini di potenza, area e velocità.
Se le specifiche non sono soddisfatte è necessario apportare dei miglioramenti al progetto,
operando in verso bottom-up. E’ possibile migliorare le prestazioni rimanendo (ad esempio) al
livello layout (ottimizzando il piazzamento ed il collegamento delle celle per
ridurre gli elementi parassiti), ma benché questo comporti uno sforzo aggiuntivo ridotto non è
ottimale in quanto i miglioramenti ottenibili in termini di prestazioni sono alquanto limitati.
Se invece si ritorna a livello RTL, può essere possibile migliorare la Fclock modificando
(ad esempio) la codifica adottata per memorizzare lo stato del controllore che coordina il
funzionamento del sistema, oppure può essere possibile ridurre la P d disabilitando i blocchi
funzionali ininfluenti in determinate modalità operative.
Le modifiche effettuate a livello RTL richiedono uno sforzo progettuale molto maggiore poiché è
necessario passare nuovamente per più livelli di astrazione, prima di ottenere la
nuova versione del circuito.
Le carenze del modello basato sui livelli di astrazione sono molteplici:
Si evidenziano con il progredire della tecnologia a causa dell’evidenziarsi di effetti prima
trascurabili
Il ritardo dovuto alle interconnessioni tende ad essere predominante.(es.: un’architettura di
sommatore potenzialmente più veloce di un’altra a livello gate diviene più lenta a livello
layout.
Elementi globali al sistema integrato come il clock o le linee di alimentazione non appaiono
nei livelli di astrazione più elevati ma possono influenzare notevolmente le prestazioni
complessive.
La dissipazione di potenza in condizioni di riposo (leakage) tende a crescere
drammaticamente al ridursi della feture-size, fino a divenire confrontabile con quella
dinamica. E’ necessaria una conoscenza approfondita degli aspetti circuitali che
consentono di diminuire Pleakage anche nei livelli di astrazione più elevati.
Progettazione gerarchica
Ad ognuno dei livelli di
astrazione vengono adoperate
tecniche di progettazione
gerarchica. Ogni elemento del
progetto viene ricorsivamente
suddiviso in elementi
più semplici, fino a giungere ad
elementi "atomici", di
ridotta complessità.
A lato possiamo vedere due
esempi di progettazione
gerarchica per quanto riguarda
Progettazione gerarchica a livello RTL
la progettazione a livello RTL e
la progettazione a livello layout.
Per la progettazione a livello layout abbiamo:
primo livello gerarchico, il layout è
costituito dalla giustapposizione di celle
identiche (bit slice).
Ogni bit-slice è quindi decomposta in celle
elementari
Il layout delle celle elementari viene realizzato
disegnando i vari rettangoli che rappresentano
transistori e le linee di interconnessione ed
alimentazione.
Costi di un circuito integrato
Progettazione gerarchica a livello Layout
I costi si differenziano in due categorie:
Costi non ricorrenti:
Tempo di progettazione e miglioramento, generazione della maschera
i
Fattore di costo una tantum
Costi ricorrenti:
Trattamento del silicio, package, test
Costi proporzionali al volume
Costi proporzionali all’area del chip
In formule:
Resa del test finale : Dopo essere stati incapsulati i circuiti vengono testati per verificarne il corretto
funzionamento.
Resa: % di circuiti funzionanti rispetto al totale di
circuiti prodotti.
Numero di chip su wafer = rapporto fra area del wafer ed area del chip (circa)
Resa= % chip non difettosi sul wafer
La resa dipende dalle dimensioni del chip: più è grande più è probabile che possa essere presente
un difetto nel chip.
Tecniche di implementazione dei sistemi digitali
(Cap. 8 del testo)
Progettazione Custom
In un progetto Custom il chip viene realizzato artigianalmente e il rettangolo sul layout ne
rappresenta l’elemento atomico. Con questo tipo di progettazione si conseguono massime
prestazioni ma è massimo anche il tempo di progetto.
Quando si utilizza un approccio custom, si progetta un blocco che verrà riutilizzato molte volte
(libreria). I costi fissi di progettazione possono essere ammortizzati su un volume di produzione
elevatissimo (uP, memorie), ma in generale questo approccio è scelto quando il costo non è il
parametro fondamentale, che sono invece le prestazioni.
Progettazione Semi-Custom
Si divide in progettazione Cell-based e Array-based.
Progettazione Cell-based
La progettazione Cell-based è un approccio indispensabile
per ridurre i tempi di progettazione. Vi è però una
penalizzazione in termini di prestazioni.
L’elemento atomico è rappresentato dalle celle (macrocelle) di
libreria, infatti il sistema è realizzato assemblando e
collegando fra loro celle preesistenti. Per questo tipo di
progettazione è necessario un utilizzo intensivo di programmi di sintesi automatica, piazzamento e
collegamento.
Lo schema di principio di una progettazione cell-based con celle standard è presentata qui a lato.
Come si vede tutte le celle hanno la stessa altezza mentre la larghezza è variabile (dipende dalla
funzione logica, dal numero di ingressi, dalle W dei MOS,etc.). Si
ha un livello di metal (ad esempio, m1) per le interconnessioni
orizzontali, ed un altro livello di metal (m2) per i collegamenti
verticali.
I canali di collegamento (routing channels) servono per collegare
i terminali di ingresso-uscita delle celle.
Le linee di alimentazione si collegano automaticamente
affiancando fra loro le celle.
La percentuale di utilizzo è data dal rapporto fra l’area
complessiva e l’area occupata dalle celle. I canali di
Progettazione con celle standard
collegamento riducono la percentuale di utilizzo.
L’utilizzo di un numero maggiore di livelli di metallizzazione
consente di migliorare notevolmente la percentuale di utilizzo.
Ad esempio: nelle celle si utilizza soltanto il primo livello di metal, mentre per le interconnessioni
utilizzo i livelli di metal superiori (da metal2 a metal6) => collegamenti sopra le celle. Con una
tecnologia a 7 livelli di metal si riesce ad ottenere percentuali di utilizzo del 90%. Quanti più livelli di
metal sono disponibili, tanto più si riesce ad aumentare la percentuale di utilizzo.
Osservazioni sulle celle standard: le celle hanno due linee metalliche, una inferiore e una di
alimentazione positiva, la stessa altezza garantisce che quando accostiamo due celle, possiamo
collegare le due linee di alimentazione e di massa. Non tutte le celle hanno lo stesso numero di
dispositivi o la stessa complessità, ecco perché hanno larghezza diversa. Attenzione: queste linee
saranno definite solo per le varie righe. Tra le varie righe, ci sarà una linea di collegamento globale
che porta la Vdd e la GND.
Quindi, la dimensione delle celle non può essere casuale. La lunghezza non può comunque
variare con continuità. Si definisce un passo elementare m. Questo garantisce anche che i vari
contatti andranno piazzati su una definita griglia e non a casaccio in modo che il programma di
collegamento delle celle sappia dove posizionare i vari contatti.
I collegamenti vengono realizzati con due livelli di metal: un primo livello per i collegamenti
orizzontali e un secondo livello per i collegamenti verticali. Così facendo, non ci sono problemi di
“corto”.
Il canale non può essere troppo stretto altrimenti non riusciamo a far passare le linee di
collegamento. Il programma di collegamento e piazzamento sceglierà l’altezza minima che
consentirà il passaggio di tutte le tracce. Nota che se non piazzo le celle, non
posso sapere quali collegamenti devono essere fatti. La bontà del piazzamento
delle celle sarà migliore quanto più piccolo sarà il canale.
Questa cella standard ha una altezza ben definita, ha la Vdd in alto e la massa
in basso, per cui ha gli nmos in basso (dove deve esserci la presa di substrato)
e i pmos in alto (vicino alla vdd). Se ogni cella è ben caratterizzata, dalla
tabella posso valutare i ritardi della cella! Si dice che i ritardi (elementi di
ritardo) vengono annotati con la porta logica.
Esempio: si possono valutare le celle logiche, le alimentazioni tra le varie righe
sono le linee grosse verticali al centro (Vdd e massa), tra una riga di
cella e un’altra c’è il canale, metal1 in viola e metal2 in azzurro. Si ha
che l’altezza del canale tra 2 righe è addirittura maggiore dell’altezza
delle celle stesse!! Un modo per migliorare le cose è far si che il
canale di collegamento possa coincidere con la striscia di celle: i
collegamenti avvengono sopra le celle logiche e ciò si fa solo a
condizione che vengano utilizzate come linee di collegamento dei
livelli di metal che non sono utilizzati per costruire le celle! In altre parole, nelle celle uso metal1 e
metal2 e i collegamenti li faccio con metal3 e metal4. Così, le linee orizzontali e verticali (azzurro e
viola) possono passare anche sulle celle stesse!! I collegamenti di ingresso e uscita quindi
possono stare anche in mezzo alle celle stesse! Le linee di
collegamento poi pioveranno dall’alto. Più livelli di metal ci sono, più
gradi di libertà ci sono.
Nella figura a sinistra è riportata una tecnologia con 7 livelli di metal e si
vede chiaramente come la percentuale di utilizzo sia estremamente
migliorata del 70-80%. Si noti però che cominciano a giocare le
capacità tra le varie linee. Queste danno luogo ad una serie di problemi
che vedremo. Comunque, tutti questi collegamenti rappresentano
capacità. Le tecnologie attuali hanno 7-8 livelli di metal.
Per quanto riguarda la progettazione cell-based con moduli funzionali (macro-celle) notiamo che la
standardizzazione a livello di porta logica è attraente per funzioni logiche generiche ma non è
molto efficace per:
strutture ripetitive (circuiti aritmetici, memorie)
strutture complesse (microprocessori, DSP).
Sfruttando la natura specifica di questi blocchi è possibile ottenere realizzazioni con migliori
prestazioni. Le macrocelle sono o strutture ripetitive o altri blocchi (strutture complesse) che
vengono meglio realizzate a parte o addirittura acquistate.
I moduli funzionali (macrocelle) possono essere distinti in:
hard-macro: pezzi di layout già fatti che vengono ottimizzati
per la tecnologia che stiamo utilizzando
soft-macro: netlist indipendente dalla tecnologia,
ottimizzata per il particolare blocco funzionale. indipendenti dalla
tecnologia, sono netlist fatti a posta per quella applicazione.
Questi vengono quindi generati con generatori a parte (macro
generator). Per esempio, se devo realizzare una memoria.
La disponibilità di macro-moduli ha modificato le tecniche di progettazione di sistemi VLSI negli
ultimi anni.
Circuiti costruiti assemblando macroblocchi, spesso acquistati da terze parti: proprietà intellettuali,
o intellectual property IP.
Una IP non è il solo macroblocco, ma include spesso anche gli strumenti software (ad esempio,
per alla IP di un microprocessore si accompagna un compilatore, un sistema di debugging ecc.).
Inoltre, devono essere forniti modelli di predizione del timing, strumenti per il testing, etc.
Per fare un sistema complesso system on a chip, si prendono queste IP, si collegano e si mettono
su un chip, si fa qualche cosa ad hoc con le celle standard ed il gioco è fatto. (sistemi embedded).
Flusso di progetto di un sistema semi-custom
Come si fa il flusso di progetto di questi sistemi semi
custom?
- Descrizione HDL.
- sintesi logica con netlist
- floorplanning: dato il mio sistema, dove piazzo i vari
componenti? grossolana
- placament: piazzamento vero e proprie delle celle
- collegamento
- simulazione post layout
Se ci sono problemi sul rispetto delle specifiche, si
ripetono dei passi.
I parametri parassiti associati al layout giocano un ruolo predominante per le prestazioni del
sistema.
Nel flusso di sviluppo “standard” non si tiene conto di questi parametri in fase di sintesi logica
Il circuito sintetizzato sembra apparentemente soddisfare i vincoli temporali: in effetti dopo la fase
di place and route si verifica che il circuito non ha le prestazioni richieste.
Processo di “timing closure”: sono necessarie più iterazioni prima che il progetto soddisfi le
specifiche assegnate.
Già in fase si sintesi si effettua un primo place and route di tentativo, per ottenere una stima dei
parametri parassiti del layout.
Progettazione Array-based
La progettazione Array-based, ovvero di tipo matrice, si
distinguono in gate-array e fpga. I costi da ridurre sono soprattutto
quelli delle maschere. I blocchi sono tutti uguali, però sono
completati fino ad un determinato livello, per esempio metal1. Poi,
vengono personalizzati per realizzare la nostra funzione usando i
livelli di metal superiore. Questi chip non personalizzati vengono prodotti per tutti gli utenti che
useranno quell’hardware, poi ognuno si farà i collegamenti che vuole.
Nella realizzazione delle Gate Array, si parla di Sea-of-gates, e l’obiettivo è ridurre i tempi di
realizzazione e ridurre i costi non ricorrenti.
Vengono realizzati lotti di wafer in cui sono stati realizzati i primi passi di processo (ad esempio,
fino alla realizzazione del metal-1). I chip (tutti uguali fra loro) includono delle celle “primitive”. I
chip sono “personalizzati” per realizzare una specifica applicazione utilizzando i livelli di metal
superiori.
Vantaggi: i costi relativi ai primi passi di processo sono ammortizzati fra numerosi progetti
I tempi necessari per la personalizzazione dei chip sono ridotti (è necessario realizzare solo poche
maschere).
I circuiti iniziali somigliano ad un sistema basato su celle standard: le righe di celle sono non
collegate tra loro!! Ci sono un insieme di nmos e di pmos non collegati. In fase di
personalizzazione sfruttiamo i contatti e i livelli
di metal per realizzare la voluta funzione logica.
Per fare la NOR a 4 ingressi si è fatto come in
figura. Il circuito realizzato in questo modo non
è ottimizzato, infatti o faccio una NOR o una
NAND le dimensioni sono sempre le stesse. La
logica cmos però ha questo vantaggio: se uno
collega bene i dispositivi (anche con W e L a
caso) la porta funzionerà sempre! Ovviamente,
i ritardi saranno non ottimali.
Ci saranno però collegamenti inutili.
Svantaggi: Prestazioni limitate (celle non ottimizzate, piazzamento dei
blocchi non ottimizzato ecc.) I SoC attuali richiedono tempi di sviluppo consistenti: il risparmio di
due-tre settimane ottenibile con i gate-arrays non è più così cruciale.
Nelle tecnologie attuali con 7/8 livelli di metal, la metallizzazione è divenuto uno dei passi di
processo più critici e costosi: il risparmio economico dei gate-arrays non è più molto sensibile.
Risultato: i gate-arrays hanno attualmente perso gran parte della loro popolarità.
Un esempio di System-on-chip Customizable è SPEAr™ ST.
Il chip include:
un processore
alcune IP standard
della logica aggiuntiva ed una rete di collegamenti, personalizzabili dall'utente
Per quanto riguarda le FPGA(Field-Programmable Gate Array) esse possono essere programmate
in diversi modi:
basata su fusibile (programmabile una sola volta)
basata su EPROM non-volatile
basata su RAM
Può essere programmata in due modi:
Array-based
Look-up Table
Inoltre è possibile programmare anche lo stile delle interconnessioni.
Gli FPGA più avanzati hanno anche processori già embedded o moltiplicatori.
Costa di più l’fpga o gate array ?
Nel caso di asic, ho costi iniziali elevatissimi per ottenere il primo prototipo (e per fare le
maschere), ma poi ogni altro dispositivo mi costerà pochissimo.
Quindi avrò una pendenza del costo in funzione dei volumi prodotti bassa.
Nel caso dei gate array invece, il costo iniziale sarà più basso ma poi l’area mi costa e la pendenza
è maggiore!!
Per gli FPGA, il costo iniziale è ancora inferiore, però ogni FPGA mi costa sempre uguale quindi la
pendenza è ancora maggiore!
Nell’elettronica di consumo quindi si usa ASIC perché ne devo fare milioni.
Gli FPGA invece si usano come prima versione o come piattaforma per effettuare delle
emulazioni. Quando si ha un sistema molto complicato non è facile farne la simulazione, in alcuni
casi la risposta del sistema è richiesta non in simulazione ma proprio sul circuito. Gli FPGA quindi
si usano per la rapid prototyping.
Un aspetto fondamentale nella progettazione di un system on chip è la scelta di realizzare le
funzionalità richieste mediante blocchi hardware oppure in software, sfruttando il microprocessore
presente sul chip.
In generale si fa una partizione del sistema fra componenti hardware e software: hardwaresoftware co-design.
Per verificare il corretto funzionamento del sistema è infine necessario provvedere ad una cosimulazione (Hardware-software co-simulation) hardware-software in cui è necessario tenere in
conto, contemporaneamente, l'esecuzione di un programma da parte del processore e le
operazioni svolte dalle periferiche e dalla logica aggiuntiva integrata sul chip.
In figura è mostrato un esempio di come si sviluppa oggi un system on chip.
Si valuta in matlab/c il sistema. Capite le specifiche si partiziona la parte sw e la parte hw. Si valuta
quanta memoria serve ecc. Si fa l’hw, si mette insieme tutto su un prototipo, si fa una validazione
finale e poi si esce col chip.
Modelli per il transistore MOS
Cap. 3
Esistono differenti approcci, a seconda delle applicazioni:
Analisi manuale (carta e matita)
Modelli switch-level (simulazione veloce, non molto accurata)
Modelli per simulazione circuitale (SPICE) (accurati, molti parametri). Indispensabili per
sistemi analogici. Per applicazioni digitali: simulazioni di sottocircuiti critici.
È sempre fondamentale effettuare un’analisi carta e penna.
Nella simulazione switch-level viene sostituito un interruttore controllato con una resistenza. Grazie
ad una scelta furba di questa resistenza equivalente, si ottengono risposte abbastanza attendibili
anche con circuiti con decine di migliaia di dispositivi.
Modelli per analisi manuale
Ricordiamo le equazioni per il modello semplificato (level 1) a canale “lungo”:
La tensione di soglia dipende dalla tensione tra source e substrato.
Possiamo riscrivere le equazioni in maniera del tutto equivalente:
Questo modo di scrivere la relazione del MOS è importante.
Graficamente abbiamo:
Le limitazioni di questo modello sono
sicuramente:
1. Dipendenza della tensione di soglia dalla
Vds. La Vt si riduce al crescere di Vds (Drain
Induced Barrier Lowering, DIBL) pertanto Id
cresce sensibilmente al crescere di Vds. Non
è un aspetto molto rilevante per applicazioni
digitali, poiché quasi tutti i dispositivi hanno
L=Lmin.
2. Degradazione della mobilità. La velocità
con la quale si muovono i portatori satura al
crescere della Vds (non è più proporzionale al
campo elettrico). Anche per bassi valori di Vds, la mobilità tende a ridursi al crescere della
Vgs.
A causa di tutto ciò, le
caratteristiche tendono a
saturare molto prima! La
caratteristica tende ad essere
più una retta che una
parabola! La saturazione si ha
a causa del fatto che aumento
la Vds ma si riduce la mobilità.
La caratteristica continua
comunque ad aumentare
perché si riduce la Vt. Nel modello a canale lungo, c’è una corrente che va col quadrato. Quando è
a canale corto, la corrente tende a cresce linearmente, o comunque con qualcosa che va come:
(Vgs-Vt)^k (con k compreso tra ½ e 2).
La Id satura per valori di Vds inferiori rispetto a (Vgs-Vt). In pinch-off, la Id cresce all’incirca
linearmente con Vgs-Vt.
In questa simulazione, il mos è collegato a
diodo. In questo caso, la relazione a
canale lungo è sempre in pinch off tranne
se la V scende sotto la Vt. Nel mos a
canale corto, la relazione diventa
praticamente lineare con la Vgs.
Possiamo modellare questi fenomeni
modificando la formula vista prima:
ora compare un terzo parametro: tensione di saturazione Vsat che è una costante. Il valore di Vsat
è un po’ più grande della Vt.
È un modello empirico che consente di analizzare circuiti con MOS a canale corto con carta e
matita ed è detto modello MOS unificato.
La caratteristica si modifica come in figura.
Nelle caratteristiche del mio dispositivo, individuo 3 zone invece che 2: se Vgs-Vt è inferiore a
Vsat, si hanno le stesse relazioni del modello a canale lungo (siamo nella zona Saturated). Questa
prima zona termina quando Vgs-Vt diventa maggiore di Vsat.
Ora bisogna vedere la Vds: se è minore di Vsat, ancora una
volta siamo nella solita caratteristica (in particolare in triodo). Se
invece è la Vsat la più bassa, siamo in una nuova zona: Velocity
Saturated che è la più grande! In questa zona a velocità
saturata si ha che:
Id=K[2(Vgs-Vt)Vsat-Vsat2](1+λVds)
La Id è funzione lineare di Vgs-Vt. In pratica il dispositivo opera
quasi sempre in questa zona a velocità saturata.
Possiamo vedere di nuovo la caratteristica con il MOS connesso a
diodo:
Per i dispositivi PMOS invece avremo che:
Al posto di Vds => Vsd (grandezza positiva)
Al posto di Vgs => Vsg (grandezza positiva)
Al posto di Vt => Vtp; (grandezza positiva)
Al posto di Kn => Kp (K’p=1/2 ÷1/2.5 K’n)
Quindi le equazioni sono:
Analizziamo ora il problema della conduzione
sotto soglia.
La Id non si annulla bruscamente per Vgs<Vt. In
particolare, che succede se faccio variare Vgs in
prossimità di Vt al di sotto? Scopro che la corrente
segue l’espressione in figura! Ovvero è una
costante! Se in particolare metto Vgs=0, non è
vero che la corrente è nulla! Anzi, c’è una corrente
di perdita pari a: Ise^(-Vt/nVth)!! La corrente di
“Leakage” è diventata oggi molto fastidiosa: si
stima anche un 20% di potenza statica dissipata!!
Per via di questo fatto, oggi ci sono 2 tipi di dispositivi: veloci o a bassa perdita.
Modello per simulazione switch-level
Vediamo quello che è il modello del mos utilizzato in simulazioni switch-level. È un modello
semplificato introdotto per avere simulazioni più rapide e quindi analisi con
decine di migliaia di dispositivi
Sostituiamo al transistor un interruttore ideale (che si chiude quando il
dispositivo va in conduzione) e una resistenza in serie opportuna. Il
problema nasce nel determinare il valore ottimale da assumere per la R. In
pratica, si utilizzeranno diversi valori di R a seconda della regione di
funzionamento del dispositivo. Ce ne vorranno 3 (nel nostro studio).
Vediamo l’NMOS.
Primo caso: NMOS come pull-down
Consideriamo un banale circuito di test: un invertitore CMOS con una capacità di carico.
Consideriamo cosa accade quando l’NMOS conduce: transizione alto
basso dell’uscita.
Se al posto del MOS inseriamo il nostro modello semplificato avremo
un RC! Il tempo di propagazione è questo:
da cui:
Tramite una simulazione SPICE (quanto più accurata possibile) dell’invertitore, ottengo Tphl, dal
quale calcolo Rn.
Questa Rn è determinata per uno specifico MOS con W e L e con una specifica capacità d carico.
Che succede se cambio la W del mio dispositivo?
Se parto da un mos con W 0/L e determino la Rn, per un MOS che avrà W 1/L la Rn1 la posso
ottenere così:
Rn1=Rn0*W0/W1
Attenzione a questo approccio semplificato: in pratica, la tensione di soglia del dispositivo è
funzione della L e della W quindi non c’è esattamente una relazione così lineare tra R e W. Se
andassimo a ragionare per dispositivi per differente L, questo fenomeno è molto significativo!
Normalmente la W è molto più grande della L e gli effetti di canale stretto non sono così forti. Per
quanto riguarda la C di carico invece non ho problemi. Nelle nostre simulazioni spice useremo
valori tipici di W e calcoleremo una R tipica.
Analogamente per Rp, ottenuta però considerando il tempo di propagazione basso-alto tplh.
Si può fare anche una stima analitica di Rn.
Ricaviamo una formula approssimata di Rn per capire da cosa dipende e quali ordini di grandezza
assume. Vediamo dove avviene la commutazione: essa
avviene in regione di velocità saturata. Infatti la Vo va da
Vdd1/2 Vdd.
Se sto in tecnologia 0.24um la Vdd è 2.5V quindi sto
passando da 2.5V a 1.25V. Essendo Vsat circa 1.0V, sto in
regione saturata (vedi figura della caratteristica).
L’espressione della corrente in questa zona è:
Tutto è indipendente da Vds tranne l’ultimo termine. In generale, Vsat al quadrato è abbastanza
piccolo e lo si può trascurare nella parentesi quadra se accade che:
Vsat<2(Vdd-Vt)
ed è quasi sempre vero.
Nel campo di interesse il dispositivo quindi opera in regione di velocità saturata. La corrente non è
proprio indipendente da Vds perché c’è l’ultimo termine con il lambda. Per semplificare tutto, al
posto di (1+λVds) metto un valore costante (un suo valore medio). Ciò ci fa approssimare la
corrente di scarica con un valore costante.
Se la capacità si scarica con una corrente costante la tensione varierà linearmente.
Sostituendo alle derivate le differenze, si può calcolare il tempo di propagazione. Lo si pone poi
pari a 0.69RC ovvero il ritardo che mi dà il modello in cui al posto del MOS metto una R e un
interruttore.
Ricavo quindi il parametro cercato: la R.
Si può semplificare la formula se il termine col lambda è piccolo rispetto ad 1 (sviluppo in serie).
La resistenza è indipendente da C ed è inversamente proporzionale al rapporto W/L (che sta in
Isat).
R quindi è indipendente da C ed è inversamente proporzionale a W/L.
Semplificando ancora, si ha che (trascurando anche Vt rispetto a Vdd):
Questo ci dice che la resistenza è poco dipendente dalla tensione di alimentazione: in particolare
decresce (anche se molto lievemente) all’aumentare della tensione di polarizzazione. Inoltre, la R
dipende inversamente da Vsat. Ricordiamo che la Vsat tende a diventare sempre più piccolo col
migliorare della tecnologia. Ricapitolando: c’è una relazione inversa dal rapporto W/L e una
dipendenza sensibile dalla tensione Vt. Abbiamo visto quando l’nmos opera da pull-down ovvero
che scarica la capacità e dualmente quando un PMOS funziona da pull-up ovvero che carica la
capacità.
Vediamo se con questo modello semplificato possiamo simulare bene una porta NAND a 2
ingressi.
Per questa NAND studiamo il tempo di commutazione alto-basso: ci focalizziamo quindi sugli
NMOS. Ci sono 2 possibili casi che fanno commutare il nostro circuito, dando quindi una
commutazione alto-basso all’uscita. I due casi possibili sono:
a) B=1 A=0  B=1 A=1
b) B=0 A=1  B=1 A=1
Vediamo ora perché c’è differenza tra i due ritardi (dovuta alle Capacità).
Caso a)
Studiamo il nostro circuito sostituendo ai dispositivi le resistenze e gli interruttori corrispondenti.
Per la rete di pull-up, i transistori sono
spenti e quindi non disegno le
resistenze della rete. Devo evidenziare
le capacità: una è quella sul nodo di
uscita Cp, poi c’è quella legata al nodo
interno Cq.
Vediamo ora le condizioni iniziali sulle
due capacità: su Cp c’è Vdd mentre su
Cq c’è Vdd-Vt, che approssimiamo
comunque con Vdd. Quindi, le due
capacità sono entrambe cariche a Vdd.
L’approccio utilizzato per semplificare
l’analisi è quello in cui si introduce una
costante di tempo equivalente: la tensione di uscita è riconducibile ad una evoluzione che ha
una unica costante di tempo
dominante, una tau equivalente. Per
calcolarla, si considerano le capacità
singolarmente e si valuta la resistenza
ai capi della stessa. Poi, si sommano.
Una volta ottenuta la tau equivalente, il
tempo di propagazione sarà:
Tp=0.69τeq.
La tecnica switch level quindi si esegue
in 2 passaggi:
a) sostituisco al posto dei mos delle
resistenze e degli interruttori
b) utilizzo il metodo delle costanti di tempo per calcolare τ eq
Fatto ciò, calcolo Tp=0.69τeq. Stimare questo tempo di propagazione in questo modo è
semplicissimo!
Caso b)
Vediamo ora cosa accade nella nostra porta NAND quando commuta l’ingresso B invece che A.
La dinamica di questo circuito è diversa da
prima perché, se pure le resistenze e le
capacità sono le stesse, ho che le capacità
sono caricate inizialmente a valori diversi!!
L’approccio deve essere diverso. E allora,
proviamo a considerare due casi limite:
a) Cq circa nulla:
τeq = (Rb+Ra)Cp
b) Cq infinita:
τeq = Rp*Cp
(perché la Cq tiene fisso a 0V il nodo Q e Ra si cortocircuita).
In sintesi,
τeq B = (Rb+Ra)Cp
e si ha che: τeq B < τeq A . Questo dice che l’ingresso B è privilegiato e in generale sono privilegiati
i mos più vicini all’uscita! Questo effetto del 2 ordine viene fuori facilmente grazie alla tecnica
switch-level.
In questo caso le condizioni iniziali sui due condensatori sono differenti. Non si può applicare il
metodo delle costanti di tempo come in precedenza.
Se Cq=0: =>
Se Cq=∞ =>
Possiamo allora ottimizzare la porta NAND: scelgo per i due dispositivi A e B della rete N
dimensioni differenti. Potremmo pensare di fare la W di B più piccola di A: questo fatto non
andrebbe a peggiorare i ritardi.
Nel caso peggiore avremo che:
Quindi Ra moltiplica una capacità maggiore.
Si ha che W del MOS pilotato da A maggiore rispetto all’altro MOS, si procede con un progressive
sizing. (dimensionamento progressivo). I dispositivi si fanno più grandi man mano che vado
dall’uscita verso la massa. Nella pratica non è così efficace perché è legata al modo col quale
realizzo il layout dei nostri dispositivi.
Secondo caso: NMOS come pull-up
Vediamo come utilizzare l’NMOS come pull-up. E’ un multiplexer. Gli
interruttori sono in serie questa volta, sono semplici NMOS e conducono uno
alla volta. La capacità di uscita potrà essere caricata o scaricata a seconda
del caso. Questi nmos vengono ad operare come pullup. Gli nmos sono
inefficaci come pull-up, funzionano meglio se devono portare un livello
basso. Modelliamo questo aspetto usando due resistenze differenti a seconda se il dispositivo
opera come pull-up o pull-down. Se opera come pull-down la R l’ho già vista prima.
Se opera come pull-up, la R sarà diversa: R’n. Questa nuova resistenza, per lo stesso identico
dispositivo, sarà sicuramente maggiore perché deve modellare una minore efficacia di
trasferimento di segnale. Facendo una simulazione, calcoliamo la R’n (così come abbiamo fatto
prima).
In formule:
Ripeto:
R’n > Rn.
Infine ricordiamo che la R’n la otteniamo per uno specifico MOS con determinate W e L. Per un
altro MOS, scalerò opportunamente.
Vediamo di stimare analiticamente questa R’n. Il circuito più semplice di test che possiamo
pensare è costituito da un unico NMOS che va a caricare in uscita la capacità inizialmente scarica.
Questo sarà anche il circuito che andremo a simulare.
Il circuito di test è:
Il dispositivo in quale regione opererà? Una volta effettuata la commutazione, il dispositivo vede
sul suo drain la vdd, la gate anche e quindi la Vds coincide con la Vgs (Vds=Vgs=V) inizialmente.
La relazione che lega la I alla V, è quella di figura: prima della Vt il mos è spento. Appena V=VgsVt diventa maggiore di 0 siamo in pinch-off, poi appena supera Vsat siamo in velocità saturata (e la
dipendenza diventa da quadratica a lineare). Si noti però che c’è l’effetto di substrato (body) molto
forte! Abbiamo fatto una
serie di approssimazioni.
Si noti che la V scritta
non è quella ai capi della
capacità, che è invece
Vdd-V. Per vedere cosa
accade alla corrente di
carica nella capacità,
prendo la caratteristica
scritta, la traslo e la ribalto ottenendo la curva di figura.
Calcoliamo ora il tempo di propagazione.
La relazione della corrente scritta vale solo nel campo di nostro interesse (velocità saturata). Si
noti che nella formula c’è la V che compare 2 volte quindi non è esattamente lineare. Trascurando
Vsat, si ha che la corrente è pari all’espressione scritta sopra.
Per avere il tempo di propagazione basso alto, cioè quando si verificano le transizioni:
Vout:
0  Vdd/2
ovvero:
V:
L’equazione differenziale da integrare è:
Vdd  Vdd/2
Nell’integrale assumo l’approssimazione come prima. Avremo:
Da questa ottengo una stima per R’n, ponendo come al solito il tempo di propagazione pari a
0.69RC.
Conviene fare qualche piccola manipolazione/semplificazione: sviluppo in serie di taylor il termine
col λ.
Abbiamo trovato l’espressione per R’n, confrontiamola con l’espressione trovata per R n.
Confronto fra le Rn
e
Facendo il rapporto:
Se confronto ora le due espressioni trovate nei due casi, si ha che si somigliano molto,
tranne che con un termine moltiplicativo. Il termine 2*logaritmo ci aspettiamo sia maggiore
di 1 (perché la R’n deve essere maggiore di Rn). Si noti che la c’è la Vt.
Se:
Vt0
si ha un caso limite
VtVdd/2
si ha che tende ad infinito!
Quindi, la R’n può tendere all’infinito se Vt=Vdd/2!
Questo lo si ha perché nel caso limite, Vdd-Vt è proprio Vdd-Vdd/2 = Vdd/2 e a questo
valore la tensione ai capi della capacità raggiunge in un tempo infinito il valore limite!
Terzo parametro: effetto dei tempi di salita/discesa dei segnali di ingresso
C’è un terzo ed ultimo parametro che dobbiamo considerare.
Questo porta in conto un altro fenomeno che è la dipendenza
dei tempi di propagazione del circuito dalla non idealità del
segnale di ingresso. Se per es. esso non è a gradino ma ha
dei tempi di salita e di discesa non nulli, questi influenzano il
ritardo della nostra porta logica!
Si noti che in questa simulazione cambio la pendenza del
segnale di ingresso. Il ritardo sarà più grande quanto più il
segnale di ingresso è lento. È importante avere una stima di
questo parametro (pendenza del segnale di ingresso), in
entrambi i ritardi. Come possiamo modellare questo fenomeno? Analiticamente, è complicato.
Usiamo delle tecniche euristiche, approssimate
Il circuito di test per trovare questo parametro è quello in basso:
Consideriamo il circuito di test fatto da due invertitori e
concentriamoci sul secondo. Consideriamo il tempo di
propagazione alto basso di questo secondo invertitore. Il
fenomeno appena visto ci dice che questo tphl2 sarà funzione di
tr1 (tempo di salita del primo invert) e sarà maggiore di
tphl2ideale (ovvero il caso in cui l’ingresso è a gradino). Di
quanto sarà maggiore? Dipende da quanto è lento il segnale di
ingresso:
tphl2=f(tr1).
Nel caso in cui il tr1=0 (ovvero ideale),
f(0) = tphl2(step).
Inoltre, sappiamo che
tphl2 > tphl2(step),
quindi è crescente.
Per calcolare tutto dovremmo conoscere il tempo di salita del segnale di ingresso, ma non
sappiamo farlo. Però, il tempo di salita del primo invertitore sarà tanto più grande quanto più
grande sarà il tempo di propagazione del circuito stesso. Questa analisi qualitativa ci dice che
possiamo pensare di esprimere:
tphl2 = g(tplh1)
e mettendo insieme tutto:
tphl2= tphl2(step)*F(tplh1)
in cui:
F(0) = 1
e
F() crescente
Avremo una relazione empirica:
La forma dipende dal simulatore: nel nostro si usa questa scritta sopra.
Il K è un parametro che si esprime come rapporto tra una resistenza statica e la resistenza del
mos calcolata prima. Introduciamo quindi questa resistenza statica RSn.
Così facendo, riusciamo a calcolare il tempo di propagazione del secondo stadio in maniera
semplice perché, conoscendo il tp dello stadio precedente e prese le resistenze, calcolo tutto.
L’unico parametro che ci serve quindi è la RSn.
Si noti che per RSn non si ha una espressione approssimata, l’unico modo è di procedere per via
simulativa. Si prende il circuito di figura, fissati C1 e C2 si simula, si calcolano i tempi di
propagazione, anche quelli ideali e dai valori ottenuti si calcola RSn dalla formula di figura. Il valore
che ne viene fuori dipenderà dai valori delle capacità che scelgo e dallo specifico circuito di test, in
modo particolare dipenderà dalle capacità: l’unica cosa che si può fare è fissare per C1 e C2 dei
valori tipici. Quello che si ottiene è una stima.
In pratica, da una simulazione SPICE si determinano i vari tp.Si applica la relazione precedente
per determinare RSn
Il valore di Rsn dipende dai valori di C1 e C2 (il modello è empirico).
Sommario sul modello switch-level
Tre R per gli NMOS:
Rn (NMOS come pull-down)
R’n (NMOS come pull-up)
RSn (effetto della non-idealità del segnale di ingresso)
Tre R per i PMOS:
Rp (PMOS come pull-up)
R’p (NMOS come pull-down)
RSp (effetto della non-idealità del segnale di ingresso)
In conclusione ho 3 resistenze che portano in conto ciò che è scritto tra parentesi nella slide. Per il
PMOS si hanno 3 resistenze duali che portano in conto i rispettivi effetti. La prima esercitazione
sarà quella di simulare questi circuiti di test e valutare queste resistenze.
Esempio analisi switch-level
1) Calcolo delle capacità
2) Calcolo delle resistenze
.
Capacità di carico porta in conto
l’interconnessione più la gate.
L’ultimo stadio rappresenta la nand a
2 ingressi, per il mos pilotato
specifico entrambe le resistenze e
poi c’è la C di uscita.
3) Tempi di propagazione
Calcoliamo ora i ritardi: 1 stadio: faccio il
prodotto della capacità di carico per la
resistenza equivalente del dispositivo. Il
prodotto è di 54.2 ps. Si ricordi che il tempo
di propagazione è 0.69RC. Questo 0.69
viene spesso incluso nella resistenza dei
dispositivi per evitare di portarselo dietro
ogni volta: la R quindi include lo 0.69. Il
ritardo è C*Rn (con Rn che include 0.69).
questo valore non va modificato perché il
segnale di ingresso è un gradino ideale!
Per il 2 stadio: dobbiamo
tenere conto che l’ingresso
ha un tempo di salita
diverso da 0. Ci calcoliamo
il ritardo nel caso in cui il
segnale di ingresso è
ideale, questo è
semplicemente la somma
delle resistenze per la
capacità di carico (unica).
24fF* 4K che dà 96ps.
Questo ritardo è nel caso
di ingresso a gradino: in
realtà ciò nn è vero, quindi
in realtà il ritardo sarà
maggiore di questo. La
formula empirica è quella
in figura. Il fattore correttivo
porta in conto il ritardo dello stadio precedente e la costante di tempo (vedi bene). Si noti che se lo
stadio precedente fosse stato più lento (per es. perché la C era maggiore) avremmo avuto un
ulteriore ritardo. Complessivamente il ritardo è 109.6ps.
Infine il ritardo dell’ultimo stadio:
calcoliamo prima quello ideale e
poi lo correggiamo. Questa volta
il ritardo dello stadio precedente è
abbastanza grande quindi si avrà
un fattore correttivo alto. Il ritardo
complessivo ideale è 48ps. Il
fattore correttivo qui è 20ps che si
moltiplica per il ritardo
precedente! Quindi si ha in totale
66ps! Passa da 48 a 66ps e
questo è dovuto al fatto che
l’ingresso di questo stadio varia
molto lentamente! Abbiamo
calcolato il ritardo complessivo
del circuito!! L’algoritmo utilizzato è efficace: Le R si calcolano facilmente, anche la capacità. Poi i
vari ritardi si calcolano uno dietro l’altro!
Nell’esercitazione calcoleremo queste resistenze e poi usiamo il simulatore in switch-level.
Variabilità dei parametri
Una cosa importante da sottolineare è la variabilità dei parametri. Quando facciamo un circuito
integrato, i dispositivi che realizziamo non vengono sempre fuori allo stesso modo ma i parametri
(Vt, K’ ecc) evidenziano delle variazioni di tipo casuale legate alle incertezze del processo
costruttivo. Fondamentalmente si individuano 2 tipi di variabilità: quelle nei dispositivi che
appartengono allo stesso chip (quindi due dispositivi che teoricamente dovevano essere identici)
ma, seppur realizzati sulla stessa piastrina di silicio con le stesse caratteristiche W/L, in realtà non
mostrano gli stessi parametri! Ci sono delle tolleranze che possono essere dell’ordine dello 0.1%!
(within die)!
Tra due dispositivi ottenuti in tempi diversi per esempio da due fette di silicio diverse, le variazioni
sono ancora più grandi (variazioni DIE TO DIE)! Questo è evidente perché i due wafer sono stati
processati in condizioni di processo differenti!! Questo fatto crea dei problemi perché noi dobbiamo
essere in grado di garantire che il circuito, il sistema funzioni correttamente nonostante tutte
queste possibili variazioni, queste incertezze sui parametri dei dispositivi. Queste non riguardano
solo i parametri dei dispositivi ma anche i parametri delle interconnessioni, quelli parassiti. Si
sottolinea che con le tecnologie attuali le incertezze tendono a crescere man mano che la
tecnologia progredisce perché si tende a spingere tutto al limite. Oltre a queste incertezze legate al
processo costruttivo, ci sono due parametri che ci danno delle variazioni che sono la temperatura
(perché uno stesso circuito opera a temperatura sempre differente) e la Vdd perché nessun
generatore di tensione è ideale e anche perché la tensione di alimentazione sul circuito non è
costante ma è soggetta ad una serie di disturbi. Quindi, si hanno 3 cose che danno luogo ad una
variazione delle prestazioni del circuito:
1) Processo tecnologico
2) Temperatura
3) Vdd
Che si indicano con PVT (Process, Voltage, temperature)
Dovremo fare in modo da ridurre queste variazioni.
a) Progetto per il caso peggiore: si va a realizzare il circuito in modo tale che soddisfi le
specifiche assegnate anche se i parametri cambiano in modo così sfortunato da andare
tutti nel senso di peggiorare le prestazioni del circuito. Ci mettiamo quindi nel caso
peggiore in cui tutto congiura in peggio e si progetta tutto. Vorremmo che nel 100% dei
casi il circuito funziona bene. Da un lato, questa tecnica permette di avere una resa
massima ma dall’altro lato è facile immaginare che questo approccio dà luogo ad una
progettazione conservativa: la maggior parte dei circuiti prodotti così sarebbero
capaci di funzionare a prestazioni molto superiori! Questo in generale si traduce in uno
spreco di area perché il circuito mediamente è sovradimensionato!!
Si osservi che non è così ovvio individuare il caso peggiore (la combinazione peggiore
dei parametri) ovvero quale è la combinazione che dà luogo al caso peggiore.
b) Progetto basato sull’analisi Montecarlo: si utilizzano delle tecniche statistiche che
fanno in modo da avere una certa percentuale di dispositivi funzionanti (per es. 95%) e
si accetta una piccola percentuale di dispositivi che non è in grado di operare nel caso
più sfortunato dei parametri. L’utilizzo di queste tecniche ci darà una resa inferiore ma i
circuiti che si ottengono sono più efficienti in termini di area occupata.
Complessivamente si risparmia generalmente di più sull’area e si recupera questo 5%
di dispositivi persi. Mediamente quindi in questo caso i dispositivi sono più efficienti. Il
problema è che è molto complicato seguire questa strada, anche dal punto di vista
computazionale. Per le memorie per esempio, la tecnica montecarlo è quella utilizzata
perché una volta progettata la cella, ripeto tutto milioni di volte ed ottengo la memoria.
Nel caso di microprocessori è molto difficile. Questa tecnica si chiama Design for
manifacturability.
Riportiamo un esempio di analisi Montecarlo.
Si assegnano delle tolleranze, dei parametri alle
grandezze, al circuito di partenza e si scelgono
parametri in modo casuale (all’interno sempre
di un range stabilito). Per esempio, per un mos
possiamo definire che la Vt=0.8V +o- 10%, e
viene utilizzata una determinata distribuzione di
probabilità per i valori. Il simulatore determina
numerose simulazioni per i vari parametri.
Vengono effettuate numerosissime simulazioni.
Vengono fuori n valori di tempi di propagazione:
il ritardo di propagazione complessivo di questo circuito è una variabile aleatoria.
Alla fine queste variabili hanno tutte una distribuzione gaussiana. Se ne valuta il valore medio e la
deviazione standard. Si progetterà quindi il
circuito affinché esso rispetti la specifica sul
ritardo massimo. Ci saranno alcune istanze del
circuito che non andranno bene (corrispondenti
all’area sottesa alla gaussiana dopo il Ritardo
Max) ma ne sappiamo a priori la percentuale!!
Per avere statistiche abbastanza ragionevoli
bisogna determinare migliaia di valori al
simulatore. Se il circuito è piccolo ok, se è
complicato il tempo è inaccettabile e quindi
questa tecnica si utilizza per porzioni di circuito o
comunque per circuiti ripetitivi!
L’altro approccio, ovvero il progetto nel caso peggiore, è pessimistico, spreca area ma è più
semplice. Come si determina il caso peggiore?
Si introduce il concetto di angoli di processo.
Data la variabilità dei parametri di processo, quali valori utilizzare in fase di simulazione?
Ogni parametro (K’, VT, _ ecc.) avrà una propria distribuzione che possiamo semplificare con:
un valore medio
un valore minimo
un valore massimo
Questi valori il costruttore li ottiene dalle statistiche sui dispositivi da lui realizzati. Noi fissiamo
l’attenzione su due parametri: K’n e K’p.
Si può realizzare un grafico dove si mettono il K’n e K’p sugli assi. Si evidenzia nel piano un
rettangolo. Ogni dispositivo può occupare uno dei punti all’interno di questo rettangolo. I casi più
critici corrispondono ai vertici di questo rettangolo! Gli angoli
di processo prendono i nomi scritti in figura.
Per un CMOS, il caso peggiore è quello slow n slow p. Se
avessi un pezzo di circuito pseudo-nmos e ne voglio vare una
analisi alla Vol, il caso più critico è quello in cui la Vol verrà
più grande se l’nmos è venuto meno efficiente e il pmos è
venuto più efficiente: slow-n fast-p!! Bisogna fare quindi più
simulazioni a seconda del parametro che vogliamo estrarre.
Per il caso peggiore della Vol faccio una simulazione con una
determinata combinazione, per il ritardo peggiore ne faccio
un’altra con l’altra determinata combinazione! In definitiva, alla fine dei conti quando si produce un
circuito tutto si fa meno che considerare il caso nominale!
Oltre ai parametri relativi al caso nominale, il costruttore fornisce i parametri per i casi fast e slow
I parametri sono quelli dei dispositivi (schede .MODEL) e quelli relativi ai parametri parassiti relativi
alle interconnessioni
Al progettista spetta il compito di determinare il set di parametri da adoperare in fase di design.
Si devono considerare anche i casi peggiori per Temperatura e Tensione di Alimentazione.
Noi, come esempio, simuleremo solo nel caso nominale. Si noti che quando si progetta un
dispositivo, bisogna saper scegliere la scheda model più appropriata.
Interconnessioni
Cap. 4: The Wire: pag. 136-159; 171-174
appunti su: Elmore delay
Cap. 9: Coping with interconnect:
pag. 446-451; 463-474
Le interconnessioni: su uno schema usiamo dei cortocircuiti, conduttori ideali che collegano le
uscite di alcune porte agli ingressi di altre porte. In
pratica, non si hanno dei corti ma ci sono dei
opportuni layers di metallo, poly ecc. Si deve studiare
l’effetto di queste interconnessioni sulle prestazioni
del nostro sistema. Suddividiamo le interconnessioni
a seconda dei segnali o dei compiti che hanno:
a) Dedicate alle alimentazioni (studio a parte
per via di problematiche specifiche)
b) Dedicate ai segnali logici (le vediamo ora): c’è un segnale con particolare importanza, il
clock (segnale di temporizzazione che dà la cadenza a tutto il circuito). Se questo
segnale arriva sfasato in vari punti del circuito, il tutto non funziona. Ci sono, oltre al
clock, altri segnali critici.
I layer utilizzati per fare le interconnessioni sono i livelli di metal (le tecnologie attuali danno a
disposizione numerosi livelli di metal per ridurre l’area occupata), il poly e le diffusioni. Questi layer
non hanno le stesse caratteristiche.
Esempio: in questo caso abbiamo due morsetti A e B accessibili in metal1 e di dover collegare tra
loro i due morsetti. In verticale corrono 3 linee, metal1, metal2
e metal3 che non vogliamo interrompere. Per collegare questi
due nodi potrei pensare di passare in metal4 ma nulla vieta di
fare un collegamento passando sotto ai 3 livelli di metal usando
o il poly o le diffusioni.
Esempio di collegamento in diffusione e in poly visto in
sezione (il metal3 sta in alto, non si vede)
Si ricordi che il poly si fa crescere sull’ossido sottile se deve
realizzare la gate di un mos o sull’ossido spesso quando deve
fare da interconnessione. È del tutto lecito fare in questo
modo.
Le prestazioni che si avranno sono peggiori di quello che
ci aspetteremmo! Si guardi però che il collegamento in poly
può avere luogo all’interno delle celle standard in cui
sappiamo ci si deve limitare ad utilizzare il metal1 e 2. Lì,
non avendo a disposizione altro materiale, si può usare il
poly.
Questi elementi parassiti si modellano con R
L e C, C e L mutue. Questo dà luogo ad una
complessità spaventosa. Una prima
semplificazione la si fa osservando che le L
sono sempre trascurabili: L0.
Ricorda: Stiamo parlando di
interconnessioni su segnali logici. In
realtà, quando dobbiamo fare degli oscillatori
(e quindi realizzare una induttanza) è
complicato. Per quanto riguarda le
resistenze, non è così semplice. In primo
luogo, trascuriamo le R. Per i segnali più
critici però, possiamo subito dire che la R non si può trascurare. Andremo a considerare un
modello basato solo su capacità!
NOTA: Nel vedere il clock o altre interconnessioni lunghe, avremo anche la R.
Per le capacità, ci sono due classi: C che vanno a massa e C che collegano due linee adiacenti. I
fenomeni che inducono sono diversi! Delle capacità che ci sono tra due linee adiacenti, ne vanno
calcolate solo alcune quindi le C che non sono collegate verso massa sono calcolate solo nel caso
di due linee fisicamente vicine tra loro.
È importante sottolineare che i parametri parassiti delle interconnessioni:
Diminuiscono l’affidabilità
Incidono sulle performance e sulla potenza dissipata
Esistono tre classi di parametri parassiti:
Capacitivi
Resistivi
Induttivi
Capacità
Consideriamo la capacità verso il substrato: si calcola considerando due componenti: da un lato
pensiamo di considerare l’interconnessione e il substrato come un condensatore a facce piane e
parallele, quindi calcoliamo la capacità come una capacità per unità di area moltiplicata per l’area
della interconnessione. Questo modello è particolarmente semplificato ed andrebbe bene solo se
le linee di campo andassero verticalmente. Nel nostro caso il sistema è di tipo tridimensionale
(vedi figura a) quindi la capacità sarà maggiore rispetto a quella indicata dallo studio semplificato
appena detto. Si adottano allora delle formule differenti: si somma un contributo alla
C=epsilon*A/d=Ca*A=Ca*L*W. Il contributo da sommare a questa espressione dipende non
dall’area ma dal perimetro della linea e la si scriverà come:
Ct=Ca*A+Cp*P
Nel caso di interconnessione rettangolare si
avrebbe:
C=Ca*L*W+2Cp*(L+W).
I parametri Ca e Cp vengono forniti dal
costruttore espressi rispettivamente in: fF/um2
e fF/um. Questi parametri dipendono dal
materiale che stiamo utilizzando come
interconnessione. Per esempio, la capacità
perimetrale è legata a quanto sarà alta la
nostra linea (più è spessa, maggiore sarà la
capacità perimetrale). Si avranno comunque due parametri per ogni tipo di layer.
Il problema diventa più complesso perché dobbiamo
vedere le capacità tra due linee adiacenti e due linee
che si trovano una sopra ed una sotto (la foto è in
sezione). Ci sono dei sw di estrazione automatica che
determinano le capacità.
Ci sono delle tabelle sono riportate le capacità per
unità di area e di perimetro per i vari layer. Le
capacità cambiano a seconda di quello che c’è sotto
(field=substrato, active= sotto c’è un mos ecc)
Oltre a queste capacità, vale la pena osservare che ci
sono capacità di gate e di diffusione dei MOS. La
capacità di gate è quella data dall’area di gate per la
capacità dell’ossido e non c’è quella perimetrale perché qui lo spessore è talmente sottile che
questo contributo si trascura. Per le capacità delle diffusioni invece ci sono entrambi i contributi,
diversi a seconda se è un P o un N MOS.
Riportiamo un esempio di calcolo di una capacità.
Calcoliamo le varie
componenti. Per la
diffusione n calcoliamo
area e perimetro, poi si
calcola la capacità
dell’area e del perimetro. I
due contributi sono
confrontabili tra di loro. La
capacità totale sarà
ovviamente la somma.
Passiamo al primo livello di
metal: calcolo l’area e il
perimetro, poi le capacità dovuti ad i due contributi. La capacità perimetrale predomina su quella
dovuta all’area. Si noti che quella che si ottiene è 1 ordine di grandezza inferiore a quella ottenuta
per la diffusione N!Questo ci fa vedere che il primo livello di metal è un ordine di grandezza
migliore rispetto alla diffusione. Si noti che il calcolo della capacità per il primo livello di metal è
complicato perché devo tenere conto della tridimensionalità del problema! La capacità ottenuta è
grande o piccola?
Un MOS piccolo ha una capacità di 0.69fF che è ¼ della capacità della interconnessione!! Quindi
la capacità dell’interconnessione è tutt’altro che trascurabile! Soprattutto col fatto che con
l’avanzare della tecnologia queste capacità aumentano!
Un altro esempio è:
Abbiamo due linee di metal 4. Queste
due linee possono far parte di un bus
(non ci si spaventi di fronte ai 600λ). Il
metal4 è lontano rispetto al substrato,
quindi le capacità saranno piccole. I
valori di area e perimetro sono molto
più grandi di prima ma la capacità
totale di una linea verso massa è
rimasta dell’ordine di 2 fF! Grazie
all’utilizzo di questo livello di metal
molto alto rispetto al substrato si
riesce a contenere le capacità. Si noti
che anche questa volta la capacità
perimetrale pesa molto di più rispetto a quella dell’area. Questa capacità è della linea verso
massa. C’è però una capacità tra le due linee!! Questa capacità tra le due linee è ben più grande
perché la distanza tra loro 2 è minore e perché sono molto lunghe! Questa capacità è collegata a
ponte tra i due morsetti. Questa capacità, non essendo collegata a massa, farà nascere altri effetti:
può far si che una commutazione su uno dei due nodi dà luogo ad una commutazione indesiderata
sull’altra linea. Non ho semplicemente un ritardo ma un effetto di disturbo.
Questo problema di capacità tra due linee è tanto più grande quanto più si utilizza un livello di
metal elevato! Se avessi usato metal6 questo fenomeno sarebbe stato ancora più evidente perché
le capacità verso massa si riducono sempre di più e la capacità tra le linee tende a crescere:
CROSS TALK (INTERFERENZA INDESIDERATA TRA DUE LINEE ADIACENTI).
Nella slide precedente abbiamo visto che la capacità tra due linee adiacenti può essere molto
maggiore di quella verso massa. Si manifesta questa cosa quando si hanno dei bus. La Cxy che
non va verso massa dà luogo a
problemi di cross-talk.
Vediamo alcuni esempi di questi
problemi.
Facciamo l’ipotesi che una di queste
due linee effettui una commutazione
(schematizzata con un generatore di
tensione 0-1). Accade che la
transizione sulla linea X produce un
disturbo sulla linea Y: la linea X è un
aggressore e Y è aggredito.
Bisogna distinguere due casi:
a) la linea aggredita è flottante ovvero quando avviene il disturbo non è pilotata da nessuna porta
(che evidentemente sono in alta impedenza): è il caso di logiche dinamiche o registri dinamici;
nella logica domino per esempio, quando il clock passa da 1 in fase di Valutazione, in un latch
dinamico invece quando il dispositivo è in fase di memorizzazione, infatti la capacità è flottante. (Si
noti che quella di cui si è parlato è solo la capacità Y, la capacità X è quella relativa ad un’altra
linea che passa nelle vicinanze di questa ma che fa tutt’altro).
Applicando un gradino alla linea X, in corrispondenza della
transizione il potenziale del nodo X manifesta una analoga
commutazione indesiderata per via del partitore capacitivo
tra Cxy e Cy! Il deltaVy=Vx*Cxy/(Cxy+Cy). Se le capacità
hanno stesso ordine di grandezza, la commutazione
indesiderata è alta! Ed è una situazione critica perché il
potenziale sulla linea Y può assumere un livello logico
prossimo alla regione proibita o addirittura cambiare stato
(passa da 0 a 1 o viceversa). A causa di ciò si hanno errori
logici molto difficili anche da individuare e molto casuali! Per
risolvere questo problema non c’è altra soluzione che tenere
il rapporto Cxy/(Cxy+Cy) molto basso!! Ne discende un
risultato abbastanza rilevante: per questo tipo di circuiti, non è possibile utilizzare celle standard!
NO CELLE STANDARD con place-route automatico perché in questo caso la realizzazione delle
interconnessioni sopra le celle è una cosa fatta normalmente. Quindi, i circuiti dinamici vengono
realizzati e progettati a parte. Nell’approccio basato su celle standard non si utilizzano logiche
dinamiche e registri dinamici! Questi circuiti vengono realizzati se si vogliono massime prestazioni
ma con studio dedicato!
b) il secondo caso è quello in cui il nodo aggredito è pilotato da un altro circuito. In questa nuova
situazione il modello ovviamente cambia. Il circuito che pilota la linea Y (il driver) viene
schematizzato con una resistenza collegata a massa o all’alimentazione. Ovviamente abbiamo
sempre la Cy. Per capire il disturbo che si vede sulla linea Y in questo nuovo caso, bisogna
introdurre il tempo di salita del segnale di ingresso sulla linea X. Nel caso idealizzato in cui c’è un
gradino, la variazione istantanea di tensione che si valuta sul nodo Y è uguale a quello che si
aveva in precedenza! La costante di tempo sarà R*(Cy+Cxy). Il disturbo quindi svanisce nel tempo
e svanisce tanto più rapidamente quanto più è forte il driver di Y. Se il segnale di ingresso non è a
gradino ma ha un tempo di salita maggiore, si ha che tende a ridursi anche l’ampiezza del disturbo
iniziale sulla linea Y. In sintesi, ho che posso fare sia la R grande, sia che la pendenza del segnale
di ingresso non è elevatissima.
Corollario: la resistenza dei MOS deve
essere tenuta bassa per attenuare questo
fenomeno (i mos infatti pilotano queste
linee..): questo fa si che nelle celle
standard non trovo mai dispositivi a
dimensioni minime! Non trovo mai la W
minima.
Avere tempi di salita brevissimi e quindi
segnali velocissimi è vantaggioso in termini
di tempi di propagazione ma è
svantaggioso in questi termini appena visti.
Devo allora:
evitare nodi flottanti,
proteggere i nodi sensibili,
fare i tempi di salita e discesi più grandi possibili,
evitare di fare linee troppo lunghe accoppiate,
usare delle linee o strati usati come schemo!
In pratica, metto una linea collegata a massa
tra le due linee accoppiate, quindi la capacità
viene spostata e quella che era una capacità
di cross t. diventa una capacità verso massa!
Questo ovviamente ha un prezzo in termini di
area e di costi. Quando si hanno due linee
sullo stesso layer utilizzo queste linee di
schermatura, se invece le linee si trovano su
due livelli diversi, devo realizzare uno
schermo posto in mezzo ai due layer! Per
Esempio se la prima linea sta nel metal4,
devo realizzare l’altra nel metal2 e nel metal3 realizzo lo schermo. Queste tecniche comunque
NON riducono la capacità complessiva, anzi spesso la AUMENTANO ma la SPOSTANO. Queste
tecniche vengono utilizzate quando si ha il problema di questi bus.
Oltre alla nascita di questi disturbi, le capacità tra linee adiacenti influenzeranno i ritardi del
circuito. A causa di queste capacità il ritardo diventa poco
facilmente predicibile perché dipende dall’attività del circuito.
Supponiamo di avere questo bus. Ad un certo punto il bus
commuta. Che succede ai ritardi? Abbiamo delle capacità di crosstalk per le quali si può avere una commutazione su entrambi i
morsetti perché commutano tutte e 2 le linee tra cui è connessa.
In pratica il ritardo aumenta se le linee vicine alla linea vittima
commutano in direzione opposta.
L’effetto Miller fa si che:
Entrambi i terminali del capacitore sono switchati in
direzione opposta (0→Vdd, Vdd→0)
La tensione effettiva è raddoppiata ed è necessaria ulteriore
carica.
Consideriamo 3 linee, e vediamo un primo scenario: tutte e 3 le linee commutano nella stessa
direzione da 0 a 1. L’effetto di
questa capacità Cc è NULLO
perché le tensioni ai due morsetti
variano nello stesso modo e il
DeltaV nel tempo è nullo! Quindi,
il tempo di propagazione dipende
solo dalla capacità della linea
verso massa e del fan-out ovvero
dei mos pilotati dalla linea.
Tp = R Cg = Tpo
Supponiamo ora che, dei tre segnali, il secondo e il terzo commutano mentre il primo no. Per la
seconda capacità non ci sono problemi, è come se non ci fosse. La prima invece, ha un morsetto
collegato alla prima linea che sta
ad un potenziale fisso, quindi è
come se stesse collegata a
massa!! E allora questa capacità
si somma a quella della linea e
del fan-out. Il ritardo quindi
aumenta in base a quanto è
grande la Cc rispetto alla Cg (che
è somma della capacità della
linea verso massa e della capacità del fan out). Il ritardo di questo invertitore quindi dipende anche
da quello che fa la linea adiacente superiore!
Tp = R (Cg + Cc) = R Cg (1 + Cc/Cg)
Tp = Tpo (1+r); con: r = Cc/Cg
Abbiamo visto che succede se tutte le linee commutano nello stesso verso e se due commutano
ed una no. Vediamo ora che succede in altri casi: ora, la linea centrale commuta da 1 a 0 in
ingresso mentre le
altre due
commutano in modo
opposto da 0 a 1. La
prima capacità vede
un deltaV doppio
rispetto a prima!
Perché un nodo sale
di Vdd e l’altro
scende di Vdd quindi ha un delta pari a 2Vdd!
Stesso discorso per la seconda capacità! Quindi si ha che l’invertitore che pilota la linea centrale
vede una capacità che è 4 volte la Cc! Questo è quindi il caso peggiore. C’è comunque una
incertezza sul ritardo perché si capisce bene che tutto dipende da cosa accade alla dinamica.
Dovremo fare in modo che tutto funzioni in ogni caso! Questo problema, qui accennato per il bus,
lo ritroveremo quando vedremo la distribuzione del clock che è, come sappiamo, la linea più critica
del sistema. Se il clock arriva con un certo ritardo il sistema può fallire a causa di mancate
sincronizzazioni! Bisogna quindi progettare il sistema in modo che anche se il clock non arriva
esattamente nell’instante desiderato il sistema funziona correttamente.
Tp = g Tpo
(r è il rapporto tra la capacità verso GND e quella vicina).
Resistenze
Lo spessore è un parametro tecnologico e la
resistività dipende da come è fatto il layer: il
termine ro/h è quindi un parametro ed è la
resistenza di strato.
Per il polisilicio ho due valori: infatti, si ha il silicide che
è un metallo ed ha una resistenza molto inferiore. Si
fanno queste configurazioni per ridurre le resistenze
delle interconnessioni!
Per i livelli di metal la resistenza di strato assume i
valori minimi. Il metal5 ha uno spessore di 4volte maggiore rispetto al metal1, ecco perché si
hanno quei valori diversi.
Vediamo come si calcola la resistenza.
Come si calcola la resistenza? È semplice: si
moltiplica la resistenza di strato per il numero di
quadrati dove il numero di quadrati è pari a N=L/W.
Si noti che non è semplice individuare le varie
resistenze perché, per esempio, il quadrato posto
nello spigolo peserà meno di 1 perché la corrente
fluirà tutta in prossimità dello spigolo interno. Si
vedrà che una interconnessione di poly così breve
sarà trascurabile.
Altro esempio è:
Linea molto lunga: 600 lambda. La
resistenza viene pari a 800 ohm e non è
trascurabile.
Come si può ridurre l’effetto di queste resistenze?
a) Approccio tecnologico: si utilizzano materiali migliori per le interconnessioni
b) Riduco le dimensioni delle linee
c) Utilizzo più livelli di interconnessione così da ridurre le dimensioni del circuito e di
conseguenza i collegamenti saranno più brevi e quindi meno resistenze.
Con il progredire della tecnologia, le dimensioni dei dispositivi si riducono di un fattore di scaling:
x >1
Le interconnessioni come sono influenzate dallo scaling?
interconnessioni locali : lunghezza ridotta del fattore x, cioè vanno ridotte di pari passo
interconnessioni intermedie : lunghezza costante, cioè rimangono della loro lunghezza
nonostante lo scaling
interconnessioni globali : lunghezza accresciuta di un fattore y, nostante lo scaling,
perché per esempio ci metto 6 core invece di 2 e il processore è globalmente più grande,
oppure ci metto più memoria, etc.
Cosa accade ai ritardi?
Immaginiamo che la W, la L e la H scalino con la tecnologia: tutte interconnessioni scalano
Se scala solo L: altra situazione
Se ora calcolo la Resistenza nel primo caso (W L ed H scalano insieme) la resistenza aumenta di
x per le interconnessioni locali, per le intermedie aumenta di un fattore x^2 e di x^2*y nel caso di
interconnessione globale!
Vediamo le Capacità considerando solo quella per unità di area (con Area =W*L/t). Con il
progredire della tecnologia quindi diminuisco le capacità ma aumento la resistenza. Quindi, il
prodotto R*C NON varia per le interconnessioni locali, aumenta di x^2 per le intermedie e di x^2*y
nel caso di interconnessioni globali!
Per porre rimedio a questo problema si può non effettuare lo scaling dello spessore della linea: H
invariata. La R migliora di un fattore x ed aumenta di meno nel caso di interconnessioni intermedie
e globali. La capacità in prima approssimazione resta invariata, ma se considero la capacità
perimetrale che in queste formule ho trascurato mi rendo conto che non è proprio vero. E allora,
può essere una soluzione quella di non scalare l’altezza della linea. Si noti però che la capacità di
cross-t. tra due linee adiacenti aumenterà proporzionalmente al fattore H, inoltre ho un problema
tecnologico perché non è semplice fare una cosa di questo tipo! E allora, tutto ciò si traduce in
regole di layout restrittive, nel senso che la regola di separazione minima tra due linee peggiora: se
prima potevo fare due linee di metal distanti solo 3 lambda, col progredire della tecnologia il
lambda diventa 5 e seppure il lambda si è ridotto, può essere che in valore assoluto resta invariato,
ma sicuramente non riesco a ridurlo.
Posso allora fare che per alcuni livelli di interconnessione riduco H, mentre per altri livelli di metal
H lo faccio uguale in modo da sfruttare la minore resistenza. In pratica si mantiene H costante solo
per i livelli di metal superiori dedicato alle interconnessioni più lunghe in cui la R pesa molto.
In generale se non si riduce H:
aumentano le capacità di crosstalk
le capacità perimetrali assumono un peso ancora maggiore.
Si mantiene costante il valore di H soltanto per i livelli di metal superiore (ad esempio,
metal4 e metal5) dedicati alle interconnessioni globali.
Questi livelli di metal sono caratterizzati da:
resistenze di strato inferiori
maggori capacità intra-wire
regole di progetto meno aggressive per quanto riguarda dimensioni minime e separazione
minima.
Ora sappiamo come calcolare le R e le C: come possiamo sfruttare queste informazioni per
valutare i ritardi.
Supponiamo di avere due porte logiche. Un approccio di livello 0 non considera nulla. Un
approccio di livello 1 considera solo le capacità di interconnessione concentrate. Un modello più
accurato porta in conto anche la resistenza delle interconnessioni. Il modello migliore ovviamente
considera che la linea è a parametri
distribuiti. La scelta del modello va fatta in
base al grado di approssimazione che si
vuole avere. Come si calcolano i ritardi in
un sistema RC?
Abbiamo già richiamato in passato il metodo delle
costanti di tempo. Noi abbiamo ora un sistema in
cui ci sono delle resistenze che collegano i vari
nodi e delle capacità verso massa che assumiamo
all’inizio tutte cariche a Vdd. Supponiamo di avere
un solo ingresso che commuta da 1 a 0. A regime,
tutte le capacità andranno a 0. Ma con quale
legge? E come posso approssimare la dinamica
completa con una sola costante di tempo?
Per trovare la risposta usiamo la tecnica Elmore
Delay.
Valutiamo la dinamica di questo sistema. Introduciamo le correnti nei condensatori. Vediamo poi le
tensioni sui nodi considerando che l’ingresso ha già effettuato la commutazione da 1 a 0.
Applichiamo il principio della sovrapposizione e calcoliamo il potenziale V3.
Considero solo la I1 eliminando le altre capacità: la I1 va
solo in R1 e in R3 non circola nulla quindi V3=V1=R1*I1.
Facendo discorsi analoghi per le altre correnti e
sommando i vari contributi si ottiene l’espressione:
che può essere riscritta in termini delle Rkj:
Per calcolare una generica Rkj effettuo la seguente procedura:
Elimino i condensatori
Sostituisco il generatore di ingresso con un cortocircuito
Considerano i due cammini: (dal nodo k a massa); (dal
nodo j a massa)
La Rkj è la somma delle resistenze comuni a i due
cammini.
Ovviamente queste resistenze sono simmetriche rispetto ai pedici
k e j.
Abbiamo quindi:
L’espressione di Vj è un sistema di equazioni differenziali, esatto, ottenuto senza approssimazioni.
C’è una matrice di RC, ovvero di costanti di tempo. Noi cerchiamo una soluzione approssimata che
per definiziona dà luogo ad un errore ma che mi permette di esprimere la dinamica in funzione di
una sola costante di tempo. L’approssimazione è sulle derivate, ovvero assumiamo che le derivate
delle tensioni sui nodi sono proporzionali:
le costanti alfa sono incognite. Se applichiamo questa ipotesi, la Vj scritta prima diventa:
Con questa approssimazione la tensione sul nodo j non dipende dalla tensione degli altri nodi e
dipende da una sola costante di tempo. Queste costanti alfa le otteniamo cercando di minimizzare
l’errore: Q.
Come otteniamo le costanti αkj?
Valuto l’errore che mi da l’approssimazione che ho appena fatto per ottenere l’equazione
approssimata di Vj.
L’errore è ovviamente la differenza della formula esatta e di quella approssimata.
Quest’errore è funzione del tempo, io voglio renderlo piccolo e allora rendo piccolo quello medio
ovvero si sceglieranno delle costanti in modo tale che l’errore mediamente sarà nullo:
Quindi dobbiamo scegliere le αkj in modo tale da annullare l’errore medio. Svolgiamo l’integrale.
Vj e Vk a 0 e all’infinito è semplice calcolarli: all’infinito tutti i nodi si sono scaricati quindi Vj e Vk
all’infinito valgono 0. All’istante 0 invece valgono proprio Vdd. Impongo la seconda parentesi tonda
pari a 0 così da avere errore medio nullo.
Questa cosa si fa imponendo αkj=1 poiché Vj(0) e Vk(0) sono Vdd.
Quindi Emean si annulla per:
αkj=1
e otteniamo:
In definitiva questa tecnica ci dice che la dinamica è retta da un sistema di equazioni differenziali
del primo ordine. Questa dinamica si approssima con una singola costante di tempo calcolabile
con l’espressione appena scritta. L’errore medio così facendo sarà nullo e abbiamo visto come si
calcolano queste Rkj.
Per calcolare la costante di tempo si considera
una generica capacità e la si moltiplica per la
resistenza Rkj che è quella comune ai due
cammini. Si sommano i contributi e si ottiene la
costante di tempo equivalente.
Vediamo qualche esempio di Elmore Delay.
Caso idealizzato in cui una linea è pilotata da un generatore ideale di tensione
ed è aperta all’altro estremo.
Presa una linea, la si può scomporre in tanti ΔL caratterizzata da una R e una
capacità verso massa a SX e a DX, ovvero abbiamo una linea a parametri
distribuiti (R e C per unità di lunghezza). Il caso più semplice è quello in cui la
linea è pilotata a sinistra da un dispositivo attivo. Il ritardo è in questo caso intrinseco. Nel caso
ideale inoltre consideriamo che la R del generatore tenda a 0 e che la C del carico finale della linea
tenda ad infinito.
Decomponiamo la linea in tanti pezzettini ΔL, ognuno caratterizzato da c e r che sono resistenza e
capacità per unità di lunghezza. Ovviamente, più è fitta la discretizzazione più ci si avvicina al caso
reale.
Per valutare questo ritardo utilizziamo la tecnica
Elmore Delay: inizialmente le capacità sono tutte
allo stesso valore, e poi sono tutte C verso massa.
Ricordando che la costante di tempo equivalente è
pari alla sommatoria di: RkjCk, dobbiamo
considerare tutte le capacità.
Partiamo dall’ultima capacità e valutiamo i due cammini: quello che unisce il nodo di uscita con
massa e il nodo della capacità verso massa (nota che la massa si trova dove c’è Vin). Partendo
dall’ultima, la C è CΔL e i due cammini sono identici: la R da considerare è n*r ΔL con n=numero
di pezzettini.
Consideriamo ora la capacità n-1 esima (nel disegno non è riportata): le capacità hanno tutte lo
stesso valore quindi la C è uguale al caso di prima, per valutare la R poi devo considerare i due
cammini: il primo che porta questo nodo a massa e l’altro che collega l’uscita verso massa. La R
comune è pari a (n-1)*r ΔL. Questo discorso si ripete per tutte le capacità distribuite presenti nel
circuito e la sommatoria di questi contributi restituisce la costante di tempo.
Questa è ovviamente la costante di tempo equivalente relativa all’uscita. Si noti poi che n è molto
maggiore di 1, quindi si può scrivere come
dove ncΔL è la capacità totale della linea e nr ΔL è la resistenza totale della linea. Quindi, la
costante di tempo è sostanzialmente il 50% di RC della linea! È ovviamente un termine
approssimato
Si può quindi riportare la nostra linea ad un modello equivalente come in
figura.
Questo modello è a T ed è simmetrico tra ingresso e uscita.
E si ottiene una costante di tempo pari a:
Si faccia attenzione che questo modello semplificato vale per la dinamica dell’uscita rispetto
all’ingresso: se invece volessimo sapere il ritardo a metà della linea piuttosto che alla fine della
linea, dovremmo riapplicare tutto il discorso fatto per ottenere questa t. In dettaglio, bisogna
considerare sia l’effetto delle capacità che stanno a sinistra sia quelle che stanno a destra. Tutte le
capacità che stanno a destra dell’uscita considerata, hanno in comune con l’uscita solo le R che
stanno a sinistra dell’uscita, quindi il contributo alla tau che danno è pari a CΔLRt/2, e saranno
n/2 termini. Per le capacità che si trovano a sinistra dell’uscita invece, si ha che il contributo totale
viene ½*Rt/2*Ct/2. Questo ovviamente è sempre frutto di una tecnica approssimata:
l’approssimazione più evidente la si vede (in questo caso) nei termini che si trovano a destra
dell’uscita considerata che vengono riportate in uscita 1 a 1.
Consideriamo come questo ritardo dipende dalle caratteristiche fisiche della nostra linea: la linea
ha una resistenza di strato ρ2 e una corrispondente resistenza totale pari a ρ2*L/W. Avrà poi una
capacità data dalla capacità perimetrale e da quella col substrato.
da cui si ottiene:
Nell’ultima formula, ultimo passaggio in parentesi (tranne l’1) si ha l’aumento della capacità dovuto
alla capacità perimetrale.
Risultati: la costante di tempo va col quadrato della lunghezza, questo perché la sia la resistenza
che la capacità raddoppiano con la L. Una cosa meno ovvia è che questo ritardo cresce al
decrescere di W: questo è dovuto alla capacità perimetrale, se questa non ci fosse il ritardo
sarebbe indipendente da W (perché la C si dimezza e la R si raddoppia quindi gli effetti si
compenserebbero). Si tenga presente che questo risultato è un ritardo intrinseco ovvero calcolato
in assenza di carico! Nessuna linea si troverà mai in questa situazione.
Analizziamo un altro caso.
Questo caso è quello più realistico, ovvero si ha una porta logica
che pilota una linea e un fan out, rappresentato da un invertitore.
Ora si può analizzare il tutto molto facilmente: al posto del driver
si mette la sua resistenza equivalente Rn, poi la linea si
schematizza col modello a T, poi il carico che si schematizza
come una capacità. La seconda figura rappresenta quindi il
circuito equivalente per la determinazione del ritardo, della tau
equivalente. Questo modello ovviamente è valido per calcolare il
ritardo dal driver fino al carico (dove c’è scritto Vout). Calcoliamo
la costante di tempo dell’uscita: la CG vede come resistenza la
somma di Rn e 2 Rt/2, poi c’è il contributo della Ct che vede la
serie delle sole prime due resistenze. Si può quindi stimare il
ritardo in maniera abbastanza finale.
Se si normalizza rispetto alla tau che si avrebbe senza l’interconnessione (RnCg) si ha
l’espressione:
Quindi, in definitiva il ritardo è “quello che si avrebbe senza l’interconnessione più qualcos’altro che
dipende dall’interconnessione e dai suoi parametri”.
Vediamo quali sono i casi possibili:
Nel modello di ordine 0 trascuriamo l’interconnessione: ciò si può
fare quando i termini in parentesi sono minori dell’unità: Ct<<Cg e
Rt<<Rn ovvero se la capacità e la resistenza della linea sono molto minori del carico, l’effetto
della linea è trascurabile.
Modello di ordine 1: Spesso queste due condizioni non sono
verificate, in particolare la condizione sulle capacità. Quella sulle
resistenze invece si verifica. Se è vero ciò, possiamo trascurare il
terzo e il quarto termine in parentesi. Quindi la tau equivalente si scriverà come:
In sostanza la mia linea diventa una capacità.
Modello di ordine 2: in questo caso non si possono
trascurare nemmeno i termini resistivi, quindi va portato in
conto un modello per l’interconnessione con R e C.
Avremo quindi un espressione della costante di tempo pari a:
Nella stragrande maggioranza dei casi comunque va bene il modello di ordine 1, non è però
sempre così.
Ripetitori
Abbiamo visto che il ritardo intrinseco tende a crescere col quadrato della lunghezza. Questa
tecnica riduce il ritardo spezzando la linea (per esempio a metà) ed introducendo nel centro un
invertitore che prende il nome di repeater. Questa tecnica si utilizza nel caso di linee
estremamente lunghe.
Calcoliamo il ritardo che si ottiene con una linea in metal1 estremamente lunga (1.2cm). Si hanno
104 quadrati con una resistenza di 1Kohm. La capacità diventa in questo caso di 1.39pF.
Supponiamo che il driver abbia una resistenza di 100 ohm e che ci sia una capacità di fF. In
queste condizioni, la tau viene estremamente elevata.
Vediamo la prima soluzione:
Primo approccio: divido la linea a metà e ci metto l’invertitore in
mezzo. In questo caso ognuna delle due linee darà luogo ad
un ritardo pari alla metà di prima ma l’invertitore a sua volta
introduce un ritardo pari al suo ritardo di propagazione.
Vediamo se questo ritardo introdotto è comunque minore del caso precedente.
Si vede che c’è un 2 davanti a tutto perché sono 2 stadi uguali e c’è un fratto2 perché le capacità
sono pari alla metà. Il ritardo è inferiore a prima.
Suddividendo la linea invece in K parti uguali si ha questa nuova formula. In parentesi c’è un
termine che cresce con K (perché introduco
K invertitori) e un termine che decresce con
K (perché spezzo la linea).
Per capire quale K sia meglio fissare, faccio la derivata.
La K ottima calcolata, sostituita nella formula del ritardo, restituisce il ritardo minimo. Si noti che
all’ottimo i due contributi in parentesi si eguagliano.
Nel caso che stavamo osservando, con K pari a 19 il ritardo passa da 856ps (senza repeaters) a
234ps. Si noti che la gran parte del vantaggio si ha già dividendo poche volte la linea, non c’è
bisogno di arrivare a 19 (bastano 2-3-4).
Osservazioni
La costante di tempo trovata è:
In generale bisogna:
Utilizzare il modello più semplice possibile, compatibilmente con la precisione richiesta
Le C hanno un ruolo fondamentale e non possono quasi mai essere trascurate
Le R entrano in gioco quando sono di valore confrontabile con quella del driver
(interconnessioni globali)
Caso particolare: distribuzione del clock: le R sono FONDAMENTALI (un ritardo sul clock,
che sincronizza il funzionamento del sistema, può causare errori di timing)
Per la distribuzione del clock, anche un piccolo ritardo lungo la linea ci può dare fastidio.
Distribuzione delle Alimentazioni
Le alimentazioni vengono distribuite mediante una interconnessione. Per questa abbiamo dei
problemi diversi, non ci sono ritardi di commutazione.
In generale, il problema che si ha se c’è rumore (o
dei disturbi in generale) è questo: sul circuito a
sinistra supponiamo ci sia esattamente la Vdd e la
massa. A destra c’è una porta logica collegata alla
Vdd con delle interconnessioni schematizzate con
delle resistenze, ma non è detto che siano
resistenze. Nelle interconnessioni ci sarà una
certa corrente che sarà tutt’altro che costante. In
prima approssimazione, la corrente nella R
provoca una caduta e quindi l’invertitore di destra vede una tensione massima pari a Vdd-DeltaV
mentre la tensione minima sarà deltaV quindi l’escursione di questo invertitore va da Vdd-deltaV a
deltaV e può succedere che si va a finire nella regione proibita! Il caso critico è quello in cui la
porta di destra pilota un circuito dinamico: se il deltaV è superiore alla soglia, accende il mos e
scarica la C.
Questa distribuzione è strettamente legata a come è organizzato un chip.
Un chip è suddiviso in aree: la parte periferica esterna è dedicata ai terminali di ingresso è uscita.
Questi terminali alcuni sono collegati
all’alimentazione, altri includono i buffer che
pilotano l’uscita o gli stadi di ingresso che
prendono il segnale dall’esterno e lo inviano
al nucleo elaborativo (core). L’area
complessiva del chip è spesso limitata dal
numero di pad per cui l’area finisce per
essere limitata dal fatto che ci sono molti
pad. In altri casi (foto di destra) l’area è limitata dal core.
I problemi che si hanno sulle alimentazioni è la cosiddetta migrazione metallica o
elettromigrazione. In foto c’è una pista che si è rotta per via di questo effetto. Se la J è troppo forte
(J=densità di corrente), col passare del tempo i grani metallici si allontanano dalle zone strette e la
sezione tende a ridursi ancora di più, la J
aumenta ancora e così via fino a quando la
pista metallica non si apre. Nel caso delle
linee dell’alimentazione, la corrente non è
costante. Allora consideriamo il suo valore
medio e la potenza è C*Vcc2f. L’unico
parametro che abbiamo è la W: il costruttore
ci dice che la nostra linea sarà esente da
questo effetto se la densità di corrente è
sufficientemente bassa (1 mA/um), ovvero
se per esempio hai una interconnessione
larga W=1um, non si rompe se ci fai passare max 1mA . Ora, se P=VccI, I=P/Vcc da cui ricavo W.
Facciamo un esempio: P=1W, Vdd=1V, I=1A. La W sarà = 1000um. È una W abbastanza grande.
Si noti che le tecnologie attuali lavorano a basse tensioni di alimentazione e se le potenze in gioco
sono pressoché costanti, la corrente tende ad aumentare e quindi le W devono essere grandi.
Se conosciamo la R della linea e la I che deve circolare nell’interconnessione, il ΔV lo conosciamo
immediatamente come R*I. Fortunatamente, facendo le linee grandi la R è piccola e il ΔV è
accettabile. In questo esempio si ha che la zona critica è al centro, ovvero nella zona più lontana
dal bordo e cioè dove la linea ha lunghezza maggiore. In generale, la caduta resistiva non è un
grosso problema.
I grossi problemi nascono dalle L in serie alle alimentazioni. Queste L ci
danno fastidio perché la caduata va con la derivata della corrente,
quindi anche se il valore della I non è molto grosso ma questa varia
velocemente, si hanno effetti pesanti. Dove sono queste L? Se
rimaniamo sul silicio, le L sono trascurabili. Quelle che danno fastidio
nascono quando colleghiamo il chip col
package.
Nel caso di package DIL, l’induttanza
sta nella bonding wire, ovvero nelle
linee di collegamento che si fanno per
collegare il chip con l’esterno! Inoltre
queste L variano al variare della
lunghezza di questo filo.
Ci sono altri package che cercano di
ridurre questo effetto ma ci sono comunque problemi. Ci sono tecniche più efficienti che sono state
sviluppate per ridurre questi effetti! Non si riescono ad azzerare gli effetti induttivi.
Vediamo come queste L determinano dei disturbi: considerando il circuito a) , carichiamo la
capacità attraverso l’induttanza. Avremo
un disturbo ΔV, stimiamolo (in via del
tutto approssimata). Ipotizziamo che la
tensione di uscita abbia una forma
predeterminata, ovvero rappresentabile
mediante due archi di parabola.
L’approssimazione è arbitraria e ci
semplifica i calcoli. In questa
approssimazione entra in gioco il
parametro tr necessario per effettuare la
transizione completa. Nel primo intervallo
e nel secondo intervallo la Vo(t) sarà
come in slide. Ovviamente, sono scritte
così perché vogliamo che al termine del
transitorio la tensione di uscita raggiunga
la V di alimentazione. Il parametro a si
sceglie facendo in modo che le due funzioni nel punto tr/2 siano uguali..
Una volta scritta la tensione di uscita, si può scrivere la corrente che è quella che carica la capacità
ovvero: vedi slide. Si può calcolare anche il valore massimo, ovvero il valore di picco. Si può quindi
calcolare il valore della tensione V L. Il nostro invertitore vedrà Vdd-ΔV. In pratica si osservano una
serie di oscillazioni e non soltanto il disturbo rettangolare come mostrato nella terza immagine
sopra.
Nella fase in cui l’uscita va dal livello alto al livello basso si avrà una scarica verso massa e il
disturbo sarà quindi sul terminale di massa. Prima era su quello di Vdd, entrambi i terminali allora
saranno affetti di questo rimbalzo. Vediamo l’entità di questi disturbi.
La capacità considerata è molto grande per i circuiti integrati, sarà per esempio una capacità di
uscita. La formula restituisce un disturbo di 0.2V, circa il 10% della Vdd. Questo valore può essere
assorbito sicuramente dai margini di rumore dei nostri circuiti digitali. Se però commutano 8
invertitori invece che 1 solo il disturbo va moltiplicato per 8 e il disturbo complessivo diventa di
1.6V. Si osservi che il caso non è assurdo, perché nei bus sappiamo che ciò accade. Si noti che gli
effetti si sommano perché se è vero da un lato che l’induttanza è unica dal terminale di
alimentazione del package verso Vdd e unica dal terminale di massa alla massa, la corrente che vi
scorre dentro è la SOMMA di tutte le correnti che devono caricare le capacità!! Il vero problema è
che tutta la logica presente nel circuito integrato collegata alla stessa alimentazione risentirà di
questi disturbi!! Poiché la condizione di commutazione contemporanea è comune, bisogna
prendere provvedimenti che limitino questi disturbi. Inoltre, l’entità del disturbo è direttamente
legata alla capacità. Il problema quindi si pone per i terminali di ingresso e uscita.
Per ridurre questi problemi si utilizzano quattro anelli di alimentazione.
Vdd ext, GNDext per i pad di I/O
Vdd int, GNDint per la logica interna
Gli accorgimenti che si adottano non risolvono al 100% il problema. In pratica, faccio in modo che il
nostro nucleo elaborativo del chip (il core, la logica) non veda questi disturbi. Spezzo la linea che
porta l’alimentazione al core. In questo modo, il core dovrà pilotare delle capacità interne che sono
ordini di grandezza più piccoli delle capacità esterne da 10pF circa!! In sostanza, basta spezzare le
alimentazioni ed ho risolto! Il prezzo da pagare è il numero di pin maggiore richiesto. Quindi, in
sintesi si separano le alimentazioni per i buffer di uscita e per il core. Si noti un’altra cosa: può
accadere anche che le alimentazioni per il core e per i buffer sono diverse, quindi separare le
alimentazioni può essere un buon modo per risolvere anche questo problema.
Osservando la slide, si avrà un disturbo per il core e un disturbo per per l’IO che sarà molto più
grande del precedente.
Utilizziamo 4 anelli di alimentazione, ovvero quattro linee di alimentazione. Li chiameremo esterni
ed interni rispettivamente per l’IO e per il core. Si chiameranno anelli perché corrono su tutta la
periferia del chip. Si noti che ci sono altre due linee dedicate all’alimentazione per il core. Si noti
che il vero numero dei terminali di alimentazione in questo esempio non sono 4 come dice la teoria
bensì 8.
Mettendo due terminali di alimentazione piuttosto che uno solo per ogni Vdd e GND, si ottengono
due induttanze in parallelo che sono la metà di una sola! Se mettessi 16 alimentazioni e 16 masse
ottengo dei disturbi che sono 16 volte inferiori rispetto al caso di un sol terminale. Nell’esempio, ho
2 terminali per ogni tensione di riferimento.
a) Le ricette per far fronte ai problemi sono:
separare le alimentazioni e le masse dei circuiti di IO da quelle per il core.
b) usiamo più terminali
c) scegliamo in maniera ottimale quali pin utilizzare per l’alimentazione: osservando la slide
10, non useremo i pin negli spigoli perché hanno un collegamento interno maggiore e
quindi un’induttanza maggiore.
d) cercheremo di aumentare i tempi di salita e di discesa al massimo possibile: i pin di uscita
non li porto alla massima velocità possibile, ma porto la velocità ad un valore compatibile
col funzionamento del sistema complessivo
e) si schedulano le transizioni che commutano: se ho un bus ad esempio, faccio sì che le
commutazioni non sono esattamente simultanee ma introduco dei ritardi piccolissimi.
f) utilizzare delle tecnologie di packaging più avanzate
g) laddove ciò non basti, si possono aggiungere delle capacità di disaccoppiamento sulla
scheda e sul chip. Le capacità di disaccoppiamento cosa sono? Sono condensatori messi
tra il terminale di Vdd ed il terminale di massa. Se sono di valore grande, la loro presenza
riduce in maniera sensibile i disturbi: più grande è la capacità di disaccoppiamento, meglio
sarà! Dove si piazza? Sotto le linee di alimentazione che comunque utilizzerebbero area
sul chip. Il problema esiste allo stesso modo anche sul circuito stampato
Le capacità di disaccoppiamento si pongono:
sulla board (giusto sotto i pin di alimentazione)
sul chip (sotto le linee di alimentazione, vicino a grandi buffer)
Possono essere utilizzate anche tecniche di packaging particolari per ridurre il problema:
Per esempio il processore Intel Core 2 Duo include un dissipatore integrato.
Nei system in package si cerca di fare una integrazione a livello di package: si cerca di integrare
più chip all’interno dello stesso contenitore collegati con il bonding. Questi Chip possono essere
anche di produttori differenti.
Sistemi Combinatori
Layout & gate level
Dopo lo studio sulle interconnessioni, seguiamo l’approccio bottom up per capire come si
organizza il layout di un circuito semplice per vedere poi le celle che
utilizzeremo nelle esercitazioni. Il layout di un circuito integrato riporta tutti i
layer che servono per realizzare il circuito. Per disegnarli bisogna rispettare
delle regole di progetto.
Riporta tutti i layers necessari alla realizzazione delle maschere
fotolitografiche:
Deve rispettare le regole di progetto
Dimensione minima
Distanza minima
Composizione
Almeno in fase iniziale è più opportuno disegnare lo stick diagram ovvero una versione
semplificata del layout: segnamo i vari rettangoli con delle linee di colore diverso o tratteggio
diverso e non ci preoccupiamo delle distanze minime ecc. Quindi lo stick diagram ci dà solo una
informazione su dove piazzare i vari rettangoli.
Scelta la convenzione sulle linee da utilizzare, cosa succede se due di queste
(una verticale ed
una orizzontale)
si intersecano?
Fra
poly
e
metal1 nulla. Se
vogliamo farci un
collegamento tra
queste due linee, bisogna piazzare
un
quadratino.
Se
invece
intersechiamo due linee di poly,
queste saranno per forza collegate
tra loro, ovvero in corto. Se
intersechiamo invece una linea di
poly con una di diffusione, stiamo
creano un mos. Si noti che è illegale intersecare una diffusione n ed una p: anzi, ricordiamo che
una delle regole più stringenti è la distanza tra una linea n ed una p per via della nwell da creare
per realizzare una linea p!
A lato abbiamo lo stick diagram di un invertitore.
Si noti che l’alimentazione e al massa sono scritte con un
punto esclamativo finale (significa VARIABILE GLOBALE).
Le due linee sono parallele tra loro. Le prese di substrato
sono la x sulla vdd e sulla massa. In generale, abbiamo che
si tenta sempre di seguire questa strategia:
una linea orizzontale in alto per l’alimentazione ed una in
basso per la massa. Immediatamente sotto la linea di Vdd ci
saranno i vari PMOS in orizzontale: questo perché si
favorisce il piazzamento di un gran numero di prese di
substrato. Inoltre, anche gli nmos vengono messi in
orizzontale e vicino alla linea di massa così da riuscire a
rispettare facilmente la regola di progetto x la distanza
minima dmin. Non si fa una distribuzione a caso di pmos ed nmos. Inoltre si cerca di fare in modo
che le celle abbiano la stessa altezza h in modo tale che si possono poi alimentare semplicemente
accostandole.
Supponiamo ora di voler collegare i due punti K sullo stick diagram: per risolvere questo problema,
utilizzo il polisilicio (è vero che non è un gran che come collegamento, ma il tratto è piccolissimo)
per fare il collegamento verticale e poi uso il metal per fare il collegamento tra K e K. Infine, si noti
che l’ingresso è in poly e l’uscita in metallo.
Si ricordi che è importante mettere i nomi ai nodi (label) soprattutto per la simulazione.
Ora supponiamo di voler fare il layout di un buffer: approccio
gerarchico. Lo stick diagram è in figura: ci sono due copie,
due istanze della cella realizzata prima. Se la cella si chiama
inv, la prima istanza sarà inv_0 e la seconda onv_1.
Lo stick diagram quindi prevede l’accostamento dei due
rettangoli (si noti che c’è un errore: l’ingresso di ogni istanza è
in poly mentre io li ho collegati con un metal: devo mettere
allora un contatto e fare un collegamento in metal in
OGNUNA delle due istanze). Il nodo interno tra le due istanze
avrà due nomi, alias (sarà out1 o in2).
Progetto dell’addizionatore PICO
Cominciamo a vedere quelle che saranno i vari
blocchi che realizzeremo per le nostre
esercitazioni:
avremo un microprocressore, una alu, etc.
Vediamo l’addizionatore: ha 2 ingressi a n bit, eventualmente un riporto
ad 1 bit (che non utilizzeremo) ed in uscita abbiamo la somma a n bit
(avremmo in teoria anche un riporto di uscita, ma noi non lo utilizziamo).
Un addizionatore veloce si può fare in 3-4 diversi modi. La struttura più
semplice è quella a propagazione del riporto (carry ripple) ma è
anche quella più lenta.
È costituito da una cascata di celle elementari ognuna delle quali
somma 1 bit dei due operandi: il circuito rispecchia l’algoritmo della somma. In sostanza ho
bisogno di un dispositivo che somma 3 bit di ingresso (2 bit + il riporto Cin) e fornisce in uscita 2
segnali (1 che è la somma S e 1 bit di riporto Cout che ha peso
doppio rispetto a S): FULL ADDER. Se non ho necessità di
sommare il riporto, uso un HALF ADDER che somma 2 bit di
ingresso e restituisce in uscita il bit S e il bit di riporto Cout.
Un addizionatore ad n bit richiede n full adder. Basta quindi
progettare un solo full adder e poi metterli in serie.
Full adder: Scriviamoci la tabella di verità del full adder,
ovvero della somma dei tre termini a, b e c. Spesso questo
circuito viene chiamato anche compressore 32 perché il
contenuto informativo espresso su 3 bit me lo esprime su 2
bit!
Per capire come ottenere il Cout, si esprimono i casi in cui si ha 1 e viene come in figura. è in
pratica la or di 3 and. Se metto poi la c in evidenza ottengo l’altra espressione. Si ottiene con una
AndOrInvert seguita con un invertitore. La somma è un XOR, una OR esclusivo. Questa funzione
compare molto spesso nei circuiti digitali ma non si presta bene ad essere integrata! La XOR in
generale è alta quando sono alti un numero dispari di ingressi, è quindi la funzione disparità. Con
una AOI sarebbe molto complicato. Allora, facciamo così: prendiamo la colonna di Cout negato
tanto ce l’abbiamo già gratis: si vede che è identica alla S tranne nel primo e nell’ultimo caso!! E
allora si può scrivere come in slide. Un inconveniente è che per calcolare S devo aspettare che
Cout negato sia disponibile!
Ecco il circuito dell’AOI. Si noti che la C che prima ho messo in
evidenza, ora lo metto vicino all’uscita! In sostanza lo sto
privilegiando perché ricordiamo che abbiamo visto che i mos più
vicini all’uscita devono caricare meno capacità! Questo circuito
comunque può essere ottimizzato: infatti, si nota che la rete pmos
condurrà quando A e B sono accesi e in pratica il ramo di destra
pmos può essere staccato.
L’ingresso C è privilegiato, quando conduce la rete evidenziata?
quando A=0 ed inoltre B=0, in questo caso il parallelo dei PMOS
comandati da A e B è sempre in conduzione.
È possibile ottimizzare la cella carry utilizzando quest’altra
configurazione a sinistra.
Facendo in questo modo, la rete pmos è esattamente DUALE rispetto
alla nmos!!! Il circuito è mirror, a specchio!
I vantaggi che si hanno sono sicuramente in termini di layout
simmetrico, ma soprattutto il numero massimo di dispositivi in serie è
passato da 3 a 2!!! Infine, possiamo ottimizzare l’ingresso C anche
nella rete pmos!
Questo è un esempio di Stick diagram. Si noti che le linee
grigie saranno in metal2: ci sarà comodo in seguito poter
passare in orizzontale una linea di metal1!! In sostanza tutti
i collegamenti verticali vengono fatti o in poly o in metal2. Il
diagramma non è completo, perché vanno collegati A ed A,
B e B.
Lo stick diagram definitivo è quello riportato nella figura sottostante:
A lo facciamo passare in parallelo alla linea di
massa sotto alla massa e B sopra alla linea di
alimentazione. Il segnale C invece lo facciamo
uscire a destra, così come Cout e Cout’ che mi
servirà per calcolare la S. In questa versione gli
ingressi A e B vengono portati su due linee
parallele alle linee di alimentazione, l’ingresso C
sulla sinistra così come Cout e Cout negato.
L’altra funzione logica da realizzare è quella che calcola la funzione
somma. L’altra la possiamo realizzare guardando l’espressione logica:
nella rete di pull down abbiamo il parallelo di due reti, una che realizza
la and di A B e C e una che realizza la And tra NotCout e la or tra A,B
e C. La rete di pull-up poi si realizza per dualità. Il circuito ovviamente
calcola S negato, quindi è necessario un invertitore per ottenere S.
Semplifichiamo: quando conduce il ramo di pull-up evidenziato?
Quando A B e C sono entrambi bassi, allora possiamo spezzare la rete e ottenere questo:
Anche in questo caso le due reti di pull-up e di pull down sono
esattamente simmetriche. I vantaggi nell’usare questa versione della
porta sono: simmetria nel layout e un MOS in serie in meno nella rete
di pull-up. Abbiamo privilegiato un ingresso: NotCout! Infatti i
dispositivi di questo sono vicino all’uscita. Perché? Ovviamente
perché ha un ritardo maggiore, proviene da una rete di carry.
Lo stick diagram lo otteniamo dal circuito
semplicemente. Anche in questo caso, A e B
stanno su due linee parallele all’alimentazione,
proprio come abbiamo fatto per la porta logica
che calcola il carry. Inoltre, C e NotCout li
rendiamo disponibili sulla sinistra della cella, così
da poterli collegare facilmente alla cella carry. Si
nota anche l’invertitore finale che da NotS dà S.
Ora vediamo le due celle, una a fianco all’altra: per come le abbiamo organizzate, sarà semplice
collegare le masse, le alimentazioni, B ed A. Il segnale C potrà essere facilmente applicato ad
entrambe le celle, l’uscita Coutnegato va facilmente con Coutnegato alla cella che fa la somma, il
Cout poi è il riporto uscente che andrà collegato al fulladder successivo, quindi va portato proprio
fuori.
Ricordiamo le espressioni che ci permettono di calcolare il Cout e la somma:
ed andiamo a mostrare lo schema a blocchi complessiva della cella Sum+Carry:
Cout va sul lato superiore della cella perché andrà al fulladder successivo, il C invece va in basso.
Per la realizzazione dell’adder a 8 bit basterà fare un array. Se la cella è progettata bene, fare un
addizionatore a 16 o 64 bit è semplicissimo: basta richiamare il comando array. Ovviamente
cambieranno le prestazioni del circuito, ma a livello di realizzazione di layout è semplicissimo.
Questa è una struttura bit-slice, ovvero realizzato con strisce di bit. La struttura è duttile. In questo
caso abbiamo un flusso di dati. C’è poi un segnale di controllo che è il riporto che si propaga, ed è
proprio ortogonale al flusso di dati: bisogna stare attenti che nel layer questi viaggiano
ortogonalmente al flusso dati.
Struttura bit-slice
DATA-PATH
Sistemi Combinatori
Timing Analysis
Come si fa la timing analysis di sistemi combinatori?
Prendiamo quest’esempio a lato: 5 ingressi e 3 uscite. Come valutiamo il ritardo di questo circuito?
La cosa più semplice è quella di realizzare una simulazione. Ragionando, è facile capire che
questa non è così semplice. Supponiamo di avere questi n (=5)
ingressi: quali saranno le sequenze da applicare per valutare i
ritardi? Per es passo da 00000 a 1101 e facciamo una prima
simulazione. Quale sarà quella che mi darà il massimo ritardo?
Devo effettuare tutte le possibili transizioni degli ingressi!! Con 5
ingressi, dovrò fare 25-1 simulazioni per ogni ingresso fissato!!
Quindi, complessivamente dovrò effettuare 2 5(25-1) simulazioni!
In generale, si hanno da fare 22N simulazioni e con N grande diventa inaccettabile!!
Con 16 bit per esempio devo fare 2 alla 32 simulazioni!! Ci vogliono altre tecniche che riescono a
darci stime dei ritardi, ovvero tecniche che realizzano una analisi statica dei ritardi (static timing
analisys).
Questa analisi procede così: noi per semplicità assumiamo che ogni porta logica sia caratterizzata
da uno specifico valore di ritardo, mentre questi tool potenti hanno a disposizione una
caratterizzazione delle celle. In pratica, tutte le celle devono essere in precedenza analizzate e
simulate per cui per la generica porta saranno scritte delle informazioni in un file specifico
(per es: tp A 10 , B=0, Cin=10fF, tr=50ps 250ps e questo per tutte le combinazioni). Una
parte di caratterizzazione quindi è indispensabile e richiede delle simulazioni che però vengono
fatte una volta per tutte su delle celle piccole, con pochi ingressi. Questa analisi viene fatta per
tutte le condizioni (tempi di salita degli ingressi, tensioni logiche ecc). Ci sono quindi delle librerie
standard molto ricche di informazioni relative alla caratterizzazione. Nel nostro esempio ripetiamo
che il ritardo della cella è unico.
Ci servono altre informazioni oltre ai ritardi delle celle.
Abbiamo informazioni relative ai tempi di arrivo dei segnali di ingresso: in generale i segnali non
arriveranno contemporaneamente perché provengono comunque da altra logica. Rispetto
all’instante di riferimento del clock gli ingressi I3 e
I4 arrivano immediatamente, I5 arriva dopo 60ps e
I1 e I2 arrivano dopo 20ps. In blu quindi sono
espressi in blu.
Poi, servono i tempi richiesti per le uscite. Sono
dei vincoli sulle uscite, ovvero “le uscite dovranno
essere disponibili entro un certo tempo”. A seconda
delle esigenze, questi vincoli saranno più o meno
stringenti. Nel nostro esempio, i tempi richiesti in
rosso li abbiamo fissati a 350ps.
Una volta definiti i tempi di arrivo e i tempi richiesti ed avendo a disposizione i ritardi delle celle,
possiamo procedere all’analisi dei ritardi.
La prima operazione che facciamo è trasformare la
nostra rete logica in un grafo: ogni nodo elettrico
viene trasformato in un nodo del grafo, anche i nodi
interni. La relazione ingresso-uscita la traduciamo in
archi che collegano i nodi di ingresso e i nodi di
uscita. Questi archi sono pesati in base al ritardo
relativo alla porta logica. Per esempio, il nodo I1 è
collegato al nodo A per mezzo della NAND, stesso
discorso per I2. Il peso di questi due archi sarà proprio il ritardo della nand pari a 100. Avendo a
disposizione una caratterizzazione come quella descritta prima, più accurata, non sarà unico il
peso dell’arco. Nel nostro caso otteniamo un grafo
orientato pesato.
A questo punto, possiamo propagare all’interno del grafo i
tempi assegnati, sia quelli di arrivo sia quelli richiesti.
Come propaghiamo i tempi di arrivo? La cosa importante è
che per i nodi in cui ci sono più ingressi e quindi diversi
tempi, prendo il peggiore! Per esempio, per il nodo E, il
valore del tempo di arrivo che metterò su E sarà il
massimo tra quello
dovuto ad A e a C (vedi
quad b)). Osserviamo
che la propagazione dei
tempi di arrivo si realizza
col grafo e procede secondo la schematizzazione vista.
La propagazione dei tempi di arrivo si effettua facilmente,
calcolando quindi il massimo dei tempi di arrivo più i ritardi legati
ai vari archi.
Si può procedere similmente riguardo ai tempi richiesti. In questo caso ci muoviamo da destra
verso sinistra: l’uscita Y3 sappiamo deve essere
disponibile entro il tempo 500. Quindi, il D dovrà
essere disponibile al tempo 500-150=350 e così via.
In questo caso si hanno situazioni come quella
relativa al nodo E: questo
deve soddisfare 2 condizioni
che riguardano il nodo Y3 e
Y2. Per quanto riguarda Y3,
E deve essere disponibile al
massimo al tempo 500150=350. Per quanto
riguarda l’uscita Y2 invece, il tempo deve essere 500-60=440. Il tempo
richiesto per il nodo E sarà il più stringente tra i due. La relazione allora
sarà diversa.
Qui calcoliamo il cammino critico: calcoliamo la differenza tra il tempo richiesto e il tempo di arrivo
(questa differenza si chiama SLACK). Affinché tutte le specifiche saranno rispettate se su tutti i
nodi si avrà uno SLACK > 0 (ovvero il segnale arriva prima di quanto necessario). Il nostro tool ci
dirà, in questo caso, che tutti i vincoli saranno rispettati. Il cammino critico del circuito è quello
evidenziato in verde, in cui lo slack per ogni
nodo assume lo stesso valore pari a 30 ed è il
MINIMO! Essendo comunque un valore positivo,
non c’è bisogno di intervenire. Se però lo slack
fosse stato NEGATIVO, a quel punto bisognava
cambiare qualcosa nel nostro circuito SOLO sul
cammino critico, ovvero SOLO dove i vincoli non
sono rispettati. Un’altra forma di ottimizzazione
può essere questa: se lo slack è positivo (vincoli
temporali rispettati), vediamo se è possibile
usare dispositivi più piccoli e quindi che
occupano meno area, dissipano di meno ecc. E
allora, se nella libreria c’è, uso un dispositivo più
piccolo! Quindi invece di rendere il dispositivo
più veloce, se le specifiche vengono rispettate
posso ottimizzare il circuito in termini di efficienza (area occupata, potenza dissipata). Si sottolinea
che il parametro da osservare per questa analisi è sempre lo SLACK.
slack=Trichiesto – Tarrivo
L’insieme di nodi con slack minimo rappresenta il CAMMINO CRITICO del circuito, il cammino
critico si ottiene senza dover simulare il circuito: STATIC TIMING ANALYSIS.
Vantaggi di questa analisi: l’analisi della rete è veloce, si fa
velocemente anche per sistemi estremamente complicati; se la
libreria è completa (in termini di caratterizzazione dei ritardi vari
ecc), i valori predetti dalla timing analisys sono molto attendibili;
la timing analisis ci dà direttamente delle indicazioni su dove
agire per ottimizzare il circuito! Inoltre, la timing analisys ci dà
direttamente il cammino critico! Inoltre, si può richiedere al
software di provare a cambiare le porte nella speranza di ridurre i ritardi (oppure di cambiare le
dimensioni dei dispositivi).Si noti che, individuato il cammino critico, si può estrarre solo questa
parte di circuito (se per esempio si ha il dubbio che la caratterizzazione nelle librerie non è fatta
bene oppure si vuole analizzare bene in spice a livello transistor per avere informazioni
dettagliate).
Esiste però il problema dei cammini falsi: false path. Vediamo ora un esempio di un possibile
cammino falso. Si hanno 5 ingressi e 2 uscite. Per fare
l’analisi del circuito bisognerebbe assegnare tempi di
arrivo e tempi richiesti. Supponiamo tempi di arrivo tutti
pari a 0 e tempi richiesti tutti uguali. In questo caso, il
ritardo max sembrerebbe essere 50 + 10 + 15 + 10 = 85
MA non è vero! Perché se si osserva il multiplexer,
questo cammino non si attiva MAI per una questione di
logica quindi nel grafo ci sarà ma NON si attiverà mai!
Questi cammini creano dei problemi abbastanza
fastidiosi nei tool di simulazione. Comunque, qui il cammino critico è 20+10+15+10 = 55.
Ora, applichiamo questi concetti per un full adder. Scriviamone il
grafo dei ritardi (vedi slide). Il cammino critico dov è? Dovremmo
mettere il peso degli archi, i tempi di arrivo e richiesti. Però se i
tempi di arrivo ed i tempi richiesti sono uguali (e se i
ritardi dei vari archi sono simili), ad occhio, si ha che il cammino
critico, a partire dagli ingressi, è quello che passa per b,
NotCout, NotS e S.
Che succede per un addizionatore a propagazione di riporto? Il
cammino critico qual è? Sempre nell’ipotesi di archi con peso uguale e tempi di arrivo uguali, si ha
che qui il cammino critico prevede 5 archi! Per un addizionatore a n
bit il cammino critico sarà un cammino che ha n-1 ritardi di riporto e
un ritardo della somma. Si capisce subito che se il ritardo di carry è
notevole, questo sarà il peso più significativo nel ritardo totale. Ecco
perché abbiamo privilegiato i Cout nel realizzare il layout della singola
cella per la somma. Per ogni full adder allora, se vogliamo realizzare
questa applicazione bisogna privilegiare l’ingresso carry rispetto agli
altri.
Tp=(n-1)Tcarry + Tsum
Possiamo allora ottimizzare il nostro addizionatore? Si, basiamoci sulle
funzioni logiche implementate nel full-adder. Qui, abbiamo due porte
logiche che calcolano i negati e noi ci abbiamo inserito i due invertitori
(vedi figura a sinistra). In un addizionatore ad n bit, sulla catena del riporto
ci sono n invertitori (che di volta in volta a partire da NotCout mi danno
Cout) che introducono n ritardi!! Come posso eliminarli?
Prendiamo la tabella di verità del full adder. Questa è simmetrica rispetto alla linea tratteggiata in
figura. In sostanza, se nego gli ingressi, ottengo l’uscita negata!
Come realizzo il circuito migliorato?
Partiamo dall’addizionatore che somma i termini di
peso 0 (i meno significativi). Questo sarà uguale a
prima. Ora, poiché in uscita al primo addizionatore
non ho C1 ma NotC (ho tolto l’invertitore), in ingresso
metto rispettivamente un invertitore per A1 e uno per
B1 così da sommare tutti ingressi negati. Eliminando
anche l’invertitore in uscita all’addizionatore, ottengo
proprio S1! In sostanza, questo circuito nel
complesso mi somma una coppia di bit con un
invertitore in meno rispetto a prima (3 invece di 4) e
quindi occupa meno area però, cosa importante, ho tolto due invertitori dalla linea del riporto!
Nella realtà, non risparmio area perché le celle sono alternativamente uguali, ovvero 1-3-5-7 uguali
e 2-4-6-8 uguali. Sprecherò area, però posso realizzare l’addizionatore totale replicando 4 volte
questo circuito.
Per un carry ripple avrò:
Sistemi Combinatori
Electrical & Logical effort
L’argomento che trattiamo ora è il ritardo dei sistemi combinatori. Soffermiamoci sulla generica
gate. Domandiamoci: come possiamo valutare il ritardo? Come possiamo ottimizzarla in termini di
dimensionamento? Introduciamo allora l’impegno elettrico(electrical effort) e l’impegno
logico(logical effort).
Come esempio applicativo consideriamo la cella carry. Abbiamo visto che il ritardo di questa cella
rappresenta il cammino critico dell’addizionatore a propagazione del riporto. Chiediamoci: qual è la
condizione di ottimizzazione del circuito? Vediamo come si dimensiona la porta.
Assumiamo per semplicità che, a parità di dimensioni, le R dei
PMOS siano il doppio di quelle degli NMOS.
RETE NMOS: identifichiamo il cammino col numero massimo di
dispositivi in serie: in questo caso i cammini sono tutti
equivalenti quindi tutti i dispositivi avranno la stessa Wnc. La
Weq sarà allora Wnc/2, la metà perché ci sono due dispositivi in
serie. La Wnc è per ora un parametro, un grado di libertà.
RETE PMOS: La Weq in questo caso sarà ancora Wpc/2. Ora,
questi due ritardi equivalenti sono legati perché vogliamo che
sia simmetrico (in modo tale da equilibrare tphl e tplh). Il legame
è gamma che dipende dalla tecnologia, sappiamo che l’ordine di
grandezza (campo tipico di validità di gamma) è 1,8-2,5. Supponiamo per semplicità di calcolo
gamma=2. Dalla condizione imposta viene che:
Wpc=2Wnc
Nota che i valori di W non sono ancora tutti definiti, abbiamo ancora un grado di libertà che è
proprio Wnc. Posso sceglierlo pari al minimo o pari ad un valore grande a piacere. A seconda dei
casi, avrò una cella piccola (capace di pilotare piccola capacità) o una cella grande e capace di
pilotare grandi carichi. Per la nostra gate allora abbiamo un grado di libertà. Stesso discorso vale
anche per l’invertitore di figura, in cui ci sono solo 2 mos. Il PMOS viene pari al doppio in modo tale
da equilibrare tphl e tplh.
Il dimensionamento in figura garantisce la simmetria dei tp. Abbiamo quindi due gradi di libertà:
Wnc e Wni
COME SCEGLIAMO QUESTI PARAMETRI?
Per partire, comincio da un invertitore poi estenderemo i risultati ad una porta qualunque.
Nell’invertitore di figura il pmos è il doppio dell’nmos. Inolte, l’invertitore è ad area minima (infatti
Wn è pari a W0). Le L ovviamente sono minime (fuori discussione). Per valutare i ritardi,
consideriamo le capacità di carico che sono la somma di un certo numero di componenti: capacità
interna alla stessa porta logica (dovuta alle diffusioni delle regioni di drain dell’nmos e del pmos,
oltre che alle interconnessioni interne) che è un termine costante perché la porta quella è, e poi c’è
un termine dovuto al fanout, ovvero dipende dalle porte pilotate. Noi trascuriamo le capacità
interne per semplicità. Quale sarà la capacità di ingresso del nostro invertitore? Questa sarà pari
alla somma della capacità di ingresso dell’nmos e del pmos. La R0 in questo caso per l’nmos e per
il pmos è uguale. Il tempo di propagazione è:
Tp = 0.69 Ro (Cext) = 0.69 Ro Cgo (Cext/Cgo)
Nel secondo passaggio divido e moltiplico per la capacità Cgo. La riscrivo allora come:
Tp=Tp0*h
h è detto electrical effort: h=Cext/Cgo (è il rapporto tra la capacità di carico e la capacità di
ingresso dell’invertitore).
Tp0 è un parametro caratteristico della tecnologia, non dipende da nient’altro.
h dipende solo dal dimensionamento della porta logica. Esso sarebbe il ritardo di un invertitore che
pilota un altro stadio perfettamente identico. Questo numero è indipendente dal dimensionamento
del nostro circuito, del nostro invertitore.
Tpo : ritardo intrinseco: 0.69 Ro Cgo
Tpo è un parametro caratteristico della tecnologia,
h : electrical effort: h=Cext/Cgo
h è il rapporto fra la capacità di carico e la capacità di ingresso della gate.
Tp0 quindi porta in conto la tecnologia (e quindi il costo), h porta in conto il dimensionamento.
Se aumentiamo le dimensioni del nostro invertitore di un fattore X che succede?
La capacità di ingresso sarà maggiore di X, la R equivalente si ridurrà del fattore X. Il prodotto
allora resta costante.
Se aumento il sizing allora, Tp0 rimane costante e h si riduce.
La formula Tp=Tp0*h ci fa capire che è
facile calcolare il ritardo. Infatti, Tp0 lo
calcolo una volta per tutte poiché è vero
per tutta la tecnologia utilizzata, l’h
invece lo calcolo volta per volta.
Facendone il prodotto ottengo il ritardo
dell’invertitore, o comunque della gate
considerata.
Tpo è un parametro caratteristico della tecnologia mentre h è il rapporto fra la capacità di carico e
la capacità di ingresso della gate => h dipende dal sizing.
Vediamo cosa accade se invece dell’invertitore consideriamo una porta logica, tipo una nand a 2
ingressi. Dimensioniamola in modo da renderla equivalente all’invertitore dimensionato prima:
Nell’invertitore avevamo un solo dispositivo di dimensione W 0, qui ne
ho 2 in serie quindi la loro dimensione sarà pari a 2W 0 che in serie
equivalgono a W 0. Per i PMOS, la W sarà ancora pari a 2W 0 in modo
tale che quando conduce un solo pmos esso è equivalente
all’invertitore di prima. La capacità che vedo su uno degli ingressi della
nand è maggiore. In particolare è maggiore di 4/3. Il ritardo della nostra
nand, quando piloto una certa capacità di uscita, sarà Tp. Come prima,
moltiplico e divido per la C di ingresso Cg,nand.
Il tutto lo riscrivo come Tp0*h*g dove g una costante e prende il nome di logical effort. Questo g
mi dice di quanto è più lenta una porta logica rispetto ad un invertitore a parità di
dimensionamento. Infatti, in questo caso la nand è dimensionata in modo equivalente all’invertitore
ma è più lenta di un fattore 4/3!
Il logical effort ricordo è il rapporto tra capacità di carico e capacità di ingresso. Per le varie porte
vale:
.
Nel caso di una NAND a 3 ingressi NAND3 per renderla equivalente all’invertitore, gli NMOS
hanno 3W perché ce ne sarannoo 3 in serie, i PMOS invece saranno uguali a prima perché nel
caso peggiore ne conduce sempre uno solo.
Calcoliamo la capacità relativa ad un ingresso e la capacità di ingresso dell’invertitore. Il rapporto
ci dà g. Se considerassi una porta a N ingressi, si ha che la capacità complessiva è pari a 2+ N e
h diventa 2+N/3 per una generica NAND a N ingressi.
Vediamo cosa accade per la NOR.
Dimensioniamo la porta affinché abbia la stessa resistenza di ingresso dell’invertitore:
Per gli NMOS la W è W0, per i PMOS sarà 4W0. L’h sarà 4+1/3.
Se fosse una NOR a N ingressi, la W dei pmos sarebbe 2N, quindi g sarà 2N+1/3.
Vediamo un esempio di ciò che abbiamo detto. Le nand sono X volte più grandi di quella ad area
minima. Quale sarà il ritardo di questo circuito?
Tp0 sarà un certo numero, g dipende dalla logica (NAND
a 2 ingressi: g=4/3) e h dipende da x. Per Cwire elevata,
conviene prendere una X elevata. Ad ogni modo, questo
ritardo non potrà essere mai inferiore a 4/3Tp0. Quindi, in
sintesi, per collegamenti con capacità elevate conviene
prendere dispositivi grossi, in maniera tale da ottenere un
ritardo che non dipende dalla capacità delle
interconnessioni. Se le capacità delle interconnessioni sono brevi, si può scegliere un
dimensionamento per i dispositivi non elevato così da ridurre l’area occupata.
In formule, avremo che il ritardo della prima NAND si scriverà:
Aumentando x, riduco Tp
Il Tp minimo è 4/3 Tpo
E’ necessario utilizzare celle con MOS grandi, quando si devono pilotare capacità elevate
Calcoliamo, come esempio, il ritardo su un cammino in cui abbiamo una cascata di diverse porte
logiche che in questo caso hanno tutte un dimensionamento uguale (x=1). Il ritardo per ogni porta
logica Tp=Tp0*gihi.
Il ritardo sul cammino è:
con:
quindi avremo in definitiva:
Domanda: possiamo ottimizzare il ritardo con un dimensionamento differente? Nell’esempio in
figura, il fattore di dimensionamento sarà 1 per la prima, 2 per la seconda, 3 ecc..
Esiste un dimensionamento ottimo!
Definiamo il logical effort complessivo che è pari alla produttoria dei vari coefficienti g ricavati
prima.
Definiamo anche l’electrical effort complessivo che è invece la produttoria delle h. Questa H è
molto semplice da calcolare! Infatti:
Si noti che:
Si può dimostrare che il dimensionamento ottimo si ha quando i ritardi di tutti gli stadi sono
uguali tra loro!
g1h1=g2h2= .. =(gh)opt
quindi:
il ritardo minimo è quindi:
Ricordiamo che i ritardi sono Tp0*g*h, quindi si deve avere che sono tutti uguali i vari g*h! Si
ottiene che il (gh)opt è pari alla radice ennesima di GH. In questo caso, il ritardo minimo sarà pari a
n volte il ritardo della singola porta logica della cascata.
Questa formula ci permette di ottenere il dimensionamento ottimale, ovvero la x ottimale per le
varie porte.
Infatti, se per il l’invertitore 1 deve accadere che hg=1,93, esplicitando h1 e g1 si ricava X2. A
seguire si ricava X3. Infine, X4. Ciò che accade è che la cella che viene fatta più grande è
l’invertitore finale.
Applichiamo il concetto appena visto al full-adder.
NMOS: la dimensione la scriviamo come 2W 0*Xc con
Xc=fattore di scala(il 2 è dovuto al fatto che ci sono 2 nmos in
serie, quindi per Xc=1 si ha proprio 2W 0 e la W equivalente
della serie viene proprio W 0). Per l’invertitore finale si ha W0Xi
con Xi=fattore di scala per l’invertitore.
Valutiamo il logical effort rapportando la capacità degli ingressi
(per es A).
In questo caso è molto inefficiente poiché ci sono 4 dispositivi,
due dei quali sono PMOS. Per l’ingresso B è uguale, perché è
simmetrico.
Per l’ingresso C invece le cose sono diverse perché esso è
stato collegato ad un numero diverso di dispositivi. Si ha un g
pari a 2. L’ingresso C è privilegiato, lo sappiamo.
Cerchiamo di dimensionare la nostra cella. Per farlo, vediamo dove è inserita nell’addizionatore a
propagazione di riporto. Il cammino più lungo
sappiamo che è quello che prevede tante celle di
carry in cascata. Dobbiamo minimizzare il ritardo
della serie delle due porte logiche Xc e Xi.
Calcoliamo l’electrical effort complessivo (pari al
rapporto tra la capacità finale e la capacità
iniziale) e il logical effort complessivo che è il
prodotto dei due. Il fattore gh ottimale è la radice
quadrata di GH. Sfruttiamo questo risultato per
dimensionare Xi e Xc. Si noti che il ritardo minimo viene pari a 2*radicedi2 Tp0 (2 perché sono 2
porte in cascata di pari ritardo). Il nostro addizionatore a propagazione del riporto non potrà mai
andare più veloce di questo.
Imponendo il fattore trovato, si ha che le dimensioni dell’invertitore devono essere maggiori delle
dimensioni della cella carry di un fattore radicedi2. Si noti che non si ricava MAI il valore esatto
delle 2 porte, ma si ottiene un fattore dato dal rapporto tra le due dimensioni. Si noti che conviene
fare più grande l’invertitore piuttosto che la cella carry.
Ricordiamo che abbiamo
trascurato le capacità verso la
cella somma: posso farlo solo se
la Cs è molto più piccola della
capacità di ingresso
dell’invertitore. Da questa
condizione trovo una condizione
su Xi. In maniera analoga
ragiono per Xc. Dalle due
condizioni diciamo che: il ritardo minimo è 2radice2Tp0 e lo ottengo quando le dimensioni
dell’invertitore e della cella carry sono abbastanza grandi in modo da poter trascurare le capacità
della cella somma ed inoltre devono essere in rapporto radice2. Una scelta ragionevole è fare Xi 5
VOLTE più grande del rapporto Cs/Cgo.
Valutiamo infine il ritardo in cui non ci siano
invertitori dal cammino critico (per portarli in
serie agli ingressi, visto nella lezione di ieri).
Se facciamo questa operazione, nel cammino
critico c’è solo la cella carry. Se trascuriamo le
capacità della cella somma, l’electrical effort è
1 perché le 2 capacità sono uguali, quindi la Tp
viene 2Tp0. Xc lo dimensioniamo facendo in
modo che il contributo delle capacità della cella
somma siano trascurabili. In definitiva togliere l’invertitore è appagante, attenzione però perché le
dimensioni dei dispositivi della cella carry saranno più grandi. È vero che il circuito è più veloce ma
attenzione perché i dispositivi della cella carry saranno più grandi rispetto al caso in cui ci sono gli
invertitori in serie.
Trascuriamo le capacità della cella somma:
Tp=Tp0*h*g=2Tp0
Per poter trascurare le capacità della cella somma:
ALU
Discutiamo della struttura dell’unità logica aritmetica che realizzeremo nelle esercitazioni.
Questa ALU è un sistema combinatorio che dispone di due ingressi A e B a N bit (noi utilizziamo
un data path a 8 bit) dove arrivano i due operandi da trattare. L’altro ingresso (codice operativo)
espresso su m bit definisce l’operazione che si deve effettuare sui due operandi (somma,
differenza, ecc). Avendo m bit, possiamo codificare 2m operazioni possibili, anche se in realtà c’è
ridondanza e le operazioni veramente
possibili saranno di meno. Avremo due
tipi di operazioni:
Operazioni logiche: AND, XOR, …
TUTTI 0, TUTTI 1…Sono
operazioni molto semplici,
vengono fatte su coppie di bit!
Non sono nemmeno operazioni
critiche dal punto di vista del
ritardo
Operazioni aritmetiche: somma,
incremento, decremento, sottrazione. Non prevediamo la moltiplicazione o la divisione per
le quali si adottano dei blocchi a parte. In questo corso vedremo più avanti come vengono
realizzati i moltiplicatori. Con queste poche operazioni elementari realizzate in hardware
possiamo affidarci a cicli software per realizzare per es la moltiplicazione come
successione di somme. Le operazioni di incremento e decremento sono fondamentali per
accesso ad indici di matrici ecc.
Le operazioni aritmetiche sono più complicate delle logiche, saranno il collo di bottiglia della ALU in
termini di velocità.
Per le operazioni aritmetiche, è importante vedere quale sarà la rappresentazione utilizzata per i
numeri. Ne esistono diverse, ma noi utilizziamo quella in complementi alla base.
Noi dobbiamo trattare numeri con segno.
Per rappresentare un numero negativo si segue questo semplice algoritmo:
Nella rappresentazione in complementi alla
base le cifre hanno i pesi presentati in
figura. Si noti che il più significativo ha peso
-32, è l’unico ad avere un peso negativo. Si
capisce subito che se devo rappresentare
un numero negativo, il bit più significativo
deve essere per forza alto perché è l’unico
a darmi un contributo negativo. Il numero
più negativo è ovviamente 1000000 ovvero
-2n-1.
Vediamo la struttura interna della nostra ALU, particolarmente semplice. Dividiamo il nostro
sistema in due blocchi: uno effettua soltanto delle operazioni aritmetiche e un blocco che è
progettato per eseguire solo operazioni
logiche. Per le aritmetiche abbiamo 3
bit di codice operativo, mentre ne
abbiamo 4 per le operazioni logiche. Il
multiplexer sceglierà quale delle 2
uscite. Il bit di selezione farà parte
anch’esso del codice operativo.
Aritmetiche: con 3 bit di codice op. si
possono effettuare max 8 operazioni,
ne saranno di meno e lo vedremo.
Parte Aritmetica
Supponiamo di fare un circuito che sappia fare solo la somma o la differenza (addizionatore
sottrattore). Per fare la differenza, possiamo usare ancora un addizionatore realizzando
l’operazioni A+(-B). Quindi, prima di sommare, bisognerà cambiare segno all’operando B. Quindi,
dobbiamo complementare tutti i bit di B e aggiungere un LSB. Il circuito che realizza questa
operazione è a lato: si hanno un insieme di XOR
dove uno degli ingressi è l’iesimo bit di B e l’altro
ingresso è in comune e vale m (m ci dirà se
voglio fare la somma o la sottrazione). La Xor è
quindi un complementatore (vedi quad (a)). Se
m=1 faccio A-B, se m=0 faccio A+B.
Il blocco b-op realizza la tabella di verità sotto.
Se attivo l’invert e non 0, B sarà negato, se
attivo lo Zero e non l’invert tutte le uscite
saranno 0, se attivo sia invert che 1 tutte le
uscite saranno 1. Come possiamo realizzarlo? Usando un complementatore pilotato da Invert I
(ovvero un xor con I) ma non gli mando direttamente B, gli mando B and Zero negato.
Quali sono le operazioni aritmetiche realizzabili con
questo circuito?
Il nostro circuito di fatto somma A con B1 col riporto
c.La tabella a lato mostra i vari casi. Il secondo caso
non è molto utile, ma c’è e ce lo teniamo. Il terzo
caso è molto utile. Il quarto caso incrementa A. Il
quinto caso fa la sottrazione tra A e B e decrementa
(anche questa non è di grande interesse). Il sesto
caso fa effettivamente A – B. Il caso successivo
decrementa A. L’ultimo caso restituisce ancora A.
Parte logica
La parte logica è il blocco booleano ed ha 4 bit di codice op. Il cuore di questa parte logica è
realizzata da multiplexer 4 a 1. Saranno
8 mux 4a1. Gli ingressi saranno f0f1f2f3
mentre i bit i-esimi di A e B saranno gli
ingressi di selezione. Con dei mux
possiamo realizzare qualsiasi funzione
logica degli ingressi perché sono blocchi
universali. Per dimostrarlo, usiamo la
Formula di Espansione di Shannon.
Supponiamo di avere una funzione
booleana (o logica) di n variabili. Questa
funzione, può essere scritta come in
slide. La dimostrazione è ovvia perché
se X1=1 sopravvive solo il primo termine
(x1*f(1,x2,x3,…,xn) mentre se è pari a 0 sopravvive solo il secondo termine.
Questa OR la posso vedere come un multiplexer. Se ho quindi una funzione booleana di n variabili
booleane la posso realizzare con un multiplexer e con 2 funzioni di n-1 variabili. Ragionando in via
iterativa:
Algebricamente accade quello visto in figura. In
pratica, si ottiene una OR a 4 ingressi ognuno dei
quali è di n-2 variabili. Circuitalmente si realizza
come in slide. In pratica, posso realizzare un
multiplexer grande semplicemente mettendo in
cascata tanti multiplexer semplici.
Nel nostro caso abbiamo funzioni a due variabili. I
termini f sono costanti. Cambiando i quattro ingressi
f, riesco a fare una generica funzione di x1 e x2 che
in questo caso sono gli ingressi di selezione del
mux.
Vediamo le operazioni realizzabili.
Per es, se voglio fare la funzione “A”,
devo mettere 1100 ad f3f2f1f0.
Vediamo come possiamo
complessivamente organizzare il
nostro codice operativo.
Abbiamo in totale 4 bit per la
booleana, 3 per l’aritmetica e una per
il multiplexer. Si hanno quindi 8 bit. In
modalità aritmetica il bit f3 è non influente (guardando già la seconda organizzazione di bit).
Il sistema viene organizzato così:
Useremo un approccio bit slice come quello visto nel caso dell’addizionatore. I bit di controllo Zero
e Invert saranno comuni a tutto l’array, quindi viaggeranno in verticale. Stesso discorso per f0f1f2f3
e per il bit di selezione sel. L’ALU a n bit sarà realizzata sovrapponendo n istanze della bit-slice. I
dati viaggiano da sinistra a destra, i segnali di controllo dal basso verso l’alto.
L’uscita della alu verrà inviata ad un accumulatore, la cui uscita sarà la parte A dell’alu.
La cella “accumulatore” sfrutta l’uscita della ALU
ed il bus A.
Il bus B non è utilizzato dall’accumulatore.
Possiamo vedere a lato il layout della
cella accumulatore:
e il datapath complessivo:
Sistemi sequenziali:
temporizzazione
(cap.10)
In una logica sequenziale i registri sono comandati da un clock. Esistono due modi per realizzare
un sistema di memoria:
Con feedback positivo
basato su carica
Per quanto riguarda le convenzioni sulle
denominazioni:
un latch è un sistema sensibile al livello del
clock,
un registro è sensibile ai fronti di
commutazione del clock.
In varie letterature un circuito sensibile ai fronti di commutazione del clock è chiamato anche flipflop.
Un latch ha una fase di trasparenza e una fase di memorizzazione: nella trasparenza l’uscita
segue l’ingresso. In un registro o in un flip-flop invece, l’ingresso viene campionato in
corrispondenza del fronte e viene riportata in
uscita. L’uscita non segue più l’ingresso come
per il latch.
Esistono due tipi di latch:
positivo
negativo
quello che cambia il livello del clock su cui
sono in memorizzazione(e dualmente
trasparenti).
Noi ci riferiamo ai registri: elementi attivi sui fronti
del clock. Questo perché i latch servono per
realizzare i registri ma come elementi di
sincronizzazione si usano i registri. Parliamo ora
della dinamica di un registro, ovvero dei tempi
caratteristici.
Supponiamo un registro attivo sui fronti di salita.
Nessun sistema è ideale, ovvero in grado di
campionare in maniera ideale il dato di ingresso,
devono essere rispettati dei vincoli temporali.
Innanzitutto, il dato di ingresso deve essere
stabile sia per un certo tempo PRIMA del fronte
del clock sia per un certo tempo DOPO del fronte
del clock. In particolare, il tempo richiesto di
stabilità prima del fronte viene chiamato tempo di
setup mentre il tempo richiesto dopo il fronte
viene chiamato tempo di hold. L’uscita sarà
stabile dopo un certo tempo chiamato clock to q.
Quindi un registro è caratterizzato da questi 3 ritardi. Se non sono rispettati questi vincoli sul tempo
di setup e di hold, l’uscita sarà impredicibile! L’uscita diviene metastabile. Inoltre il clock to q
diviene imprecisato. Si ha un errore di sincronizzazione.
Un'altra applicazione tipica è quella in cui abbiamo un blocco combinatorio, un registro di ingresso
e un registro di uscita. In realtà i vincoli che ora
scriviamo sono validi in generale, sia per una
macchina a astati disegnata in alto sia per un
circuito aperto come quello in basso.
Quali sono questi vincoli da rispettare affinché il
circuito operi correttamente?
Nell’esempio, si ha un banco di registri a n bit, il
segnale X in uscita è ancora a n bit, viene
elaborato dal blocco combinatorio e poi l’uscita Y
viene memorizzata nel registro 2. I parametri
necessari sono quelli dei registri: il clock to q, il
setup e l’hold. Poi abbiamo bisogno dei parametri
del sistema combinatorio: ritardo combinatoriale
massimo e ritardo combinatoriale minimo. In figura
c’è una possibile evoluzione temporale. Il corrispondenza del primo pronte di discesa del clock il
dato X viene memorizzato
(osserviamo che X non cambia
subito dopo il clock, ma dopo
1pò). Quando X varia, dopo un po’
Y comincia a variare perché
lavora la logica combinatoria.
Dopo un po’ di tempo, la Y
smetterà di commutare e sarà
stabile, sarà a regime dopo un
ritardo massimo. A questo punto,
il nuovo valore di Y viene
memorizzato nel registro numero
2.
I vincoli sono sul:
tempo di setup: il nuovo valore deve assestarsi sufficientemente prima del fronte n+1 del
clock. Questo fronte lo abbiamo dopo un T
che deve essere sufficientemente grande
da consentire la commutazione del
registro, la commutazione di Y e deve
garantire il margine sul tempo di setup. Se
questa condizione non viene verificata, si
viola il tempo di setup. Si ha un errore di
sincronizzazione legato al tempo di setup.
Questo vincolo mi stabilisce la frequenza
massima del segnale di clock. Si osservi
che il periodo del clock è dettato dal ritardo
combinatoriale massimo. Per i registri, il
loro contributo in questo caso è dato dalla
somma di tq + ts. Questo parametro rappresenta la
velocità del registro! Quindi un registro veloce deve
avere un ritardo tq+ts il più piccolo possibile!
tempo di hold: vediamo cosa accade in corrispondenza del fronte n-esimo del clock e non
n+1 come prima. Quando avviene il fronte, contemporaneamente memorizzo il valore
precedente yn dell’uscita perché il clock agisce su entrambi i 2 registri. L’uscita, dopo il
fronte del clock, comincerà a commutare: dobbiamo fare in modo che ci sia un tempo
sufficiente in cui l’uscita rimane stabile anche dopo il fronte del clock altrimenti yn non verrà
memorizzato correttamente nel registro 2 di
uscita. Dopo quanto tempo l’uscita commuta?
Dopo il tq + il tcminimo. Affinché il circuito
funzioni bene allora, tq+tcmin deve essere
sufficientemente grande: l’uscita y deve
rimanere stabile per un tempo adeguato, pari al
tempo di hold. In questa osservazione non
entra il periodo del clock: può essere verificata
o meno indipendentemente dal periodo del
clock! Se il vincolo sul tempo di hold non viene
soddisfatto, non potrò mai fare in modo che il
circuito funzioni perché seppure abbassassi la
frequenza del clock, le cose non cambiano! Inoltre questo
vincolo è legato al ritardo minimo del sistema
combinatorio! Quanto maggiore è questo ritardo minimo,
meglio è. Inoltre, sono presenti due tempi caratteristici del registro: tq e th. Quanto vale il
ritardo minimo? Dipende dal sistema. Ci possono essere situazioni in cui il tcmin è nullo
(interconnessione): in questo caso il sistema funzionerà o meno soltanto se è verificata una
condizione che è legata soltanto i registri: tq>th.
Warning: quando vedremo la non idealità del clock queste relazioni dovranno essere
riviste.
Riepilogando avremo:
Vincolo sul tempo di setup:
Vincolo sul tempo di hold:
Questi vincoli impongono le seguenti condizioni:
Il vincolo sul tempo di setup determina la max frequenza di clock, che è limitata dal
massimo ritardo del sistema combinatorio;
La figura di merito del registro è la somma del tempo di setup+ritardo clock-to-q
Il vincolo sul tempo di hold dipende dal minimo ritardo del sistema combinatorio.
Condizione più critica per il tempo di hold: ritardo combinatoriale minimo
Il vincolo sul tempo di hold NON DIPENDE dal periodo del clock
Se per ogni registro: Tq > Th il vincolo sul tempo di hold sembra essere automaticamente
verificato.
Vediamo come valutare il ritardo minimo di un sistema combinatorio.
In altri capitoli abbiamo valutato il ritardo
massimo. Si procede in maniera simile. Per gli
ingressi associamo i tempi di arrivo minimi (in
genere diversi da quelli usati per il calcolo del
ritardo massimo), per le uscite si indicano i
tempi richiesti minimi (ancora una volta diversi
da quelli usati nel calcolo del ritardo max).
Si fa innanzitutto il grafo dei ritardi, poi
propaghiamo i tempi di arrivo e analogamente i
tempi richiesti.
I tempi di arrivo li propaghiamo da sinistra a destra. Al nodo
F ci sarà il tempo di arrivo minimo, in questo caso quindi
propaghiamo il minimo e non più il massimo dei ritardi!
Ricordiamo per tracciare il grafo dei ritardi:
Ad ogni nodo del circuito => un nodo del grafo
Un arco del grafo => corrisponde ad una coppia I/O
di una gate
Peso associato all’arco => delay
→
Vediamo cosa accade per i tempi richiesti: ci muoviamo da destra a sinistra e poi mettiamo il
massimo come valore su ogni nodo.
→
Per ogni nodo abbiamo il tempo richiesto, il tempo di arrivo e lo slack questa volta definito come il
tempo di arrivo meno il tempo richiesto. Infatti
il segnale deve arrivare dopo il tempo
richiesto. Si chiama Early slack. Osserviamo
che su Y1 il vincolo sul tempo non è
rispettato, infatti lo slack è negativo!! Abbiamo
quindi questo nodo con uno slack pari a -30.
Andando a ritroso, vediamo che ci sono altri
nodi con stesso slack e che costituiscono un
cammino tra ingresso e uscita. Questo
insieme di nodi mi definisce il cammino critico:
è in sostanza il cammino più veloce del
circuito!! Quando ci sono vincoli non rispettati,
bisognerà cambiare il circuito in modo da rispettare questi vincoli.
Bisognerà rendere più lento quel cammino in verde.
Se Early slack>0 allora i vincoli di timing sono
rispettati
L’insieme di nodi con Early slack minimo rappresenta
il CAMMINO CRITICO PER IL VINCOLO DI HOLD.
Nel nostro caso abbiamo la cascata di una nand e di un invertitore. È necessario aumentare il
cammino critico almeno di 30 Per rallentare, inserisco un
buffer! E ne aggiungo tanti in cascata fino a quando i
vincoli temporali vengono finalmente rispettati.
Con l'inserimento del buffer il vincolo di timing è
soddisfatto. Risolvere i problemi di timing sul ritardo
minimo è abbastanza semplice. Inserire questi buffer non
è a costo zero, poiché aumentano area e potenza
dissipata! Ovviamente un'altra strada è quella di fare un
down-sizing del circuito (faccio i dispositivi più piccoli). È ovvio che quando inseriamo dei buffer
inseriamo una logica ridondante. Bisognerà quindi segnalare che i due invertitori non devono
essere toccati perché stanno lì proprio per rallentare il cammino e non per fare logica.
Si noti che inserendo dei buffer aumenta la lunghezza dell’interconnessione, aumenta anche la
capacità e nascono delle interazioni tra tempo di setup e tempo di hold.
Quindi in generale:
Il vincolo sul tempo di hold può essere soddisfatto in maniera relativamente semplice,
inserendo dei buffer per aumentare il ritardo sui cammini più veloci.
L'inserimento dei buffers aumenta l'area e la dissipazione di potenza
L'aumento dell'area aumenta la lunghezza media delle interconnessioni si può avere un
certo peggioramento anche dei cammini più lenti (setup).
Vediamo una tecnica che permette di aumentare la frequenza operativa.
Consideriamo un circuito come quello in figura a lato.
Un circuito così fatto fornirà un uscita per ogni clock,
nell’ipotesi che diamo dati validi in ingresso. Il periodo
minimo sarà pari al clocktoq+setup+sommaritardi massimi.
Ogni T secondi, otterremo un dato valido.
La versione pipelined è fatta da datapath più
piccoli: il singolo percorso è più piccolo.
Se supponiamo uguali i registri, otteniamo il
minimo periodo del clock come in slide. Il periodo a
destra è minore perché abbiamo un solo termine
relativo al ritardo combinatorio. Il circuito di destra
è più veloce: ovviamente il circuito di destra deve
restituire un risultato valido.
Supponiamo di mettere A1 e B1 in ingresso: dopo
un clock, l’addizionatore avrà calcolato la somma e
il primo registro potrà memorizzare. In questo ciclo
di clock possiamo sia calcolare la somma sia
mettere nuovi dati in ingresso. Nel clock successivo mettiamo i dati calcolati nel secondo registro,
calcoliamo la somma dei secondi dati e forniamo in ingresso anche altri dati A3 e B3. Dopo un
altro clock, tutto scala in avanti. Il circuito non è che è più veloce, semplicemente elabora più dati
contemporaneamente. A parte i primi clock iniziali, per
ogni clock abbiamo dati validi in uscita!! Quindi
perdiamo una latenza iniziale ma abbiamo il tutto più
veloce nel caso in cui dobbiamo elaborare molto! Il
pipelining come tecnica introduce una latenza ma
permette di far lavorare il circuito più velocemente. È
una tecnica generale che si può utilizzare per parecchie
tipologie di circuiti. Tiriamo fuori la regola generale per
implementarlo. Quello che si fa è:
piazzare registri nel percorso critico e tagliare a metà il
circuito per evitare di lasciare qualcosa fuori.
Se voglio applicarlo all’addizionatore carry ripple, qui non è facile capire come spezzare a metà il
pipeline. Nella seconda figura, ogni puntino rappresenta un livello della pipe, ovvero un registro!
Ogni linea deve tagliare a metà! In sostanza bisogna tagliare proprio praticamente a metà ogni
linea!! Poiché il full adder lo supponiamo come blocco atomico (non tagliabile), il periodo minimo
del clock è pari a quello dato dall’espressione in figura.
Quindi in pratica con la pipelining aumento la Fclk ma introduco latenza.
Possiamo considerare un esempio di pipelining per un adder carry-ripple.
Ogni punto corrisponde ad un registro e tutti i
registri hanno il clock in comune.
Avremo per il Tmin:
Elementi di non-idealità del clock
Immaginiamo il clock come segnale ideale: frequenza fissa e attiva simultaneamente tutti i registri
del circuito.
Non è così ovviamente, ecco
perché devo portare in conto varie
non idealità:
Clock skew: non idealità
dovuta al ritardo sul sistema
di distribuzione del clock, ha
una componente
deterministica(predicibili in
fase di progetto) ed una
casuale;
Clock jitter: Variazione temporale fra due fronti consecutivi del clock (frequenza non
perfettamente costante): modulation + random noise. Si distinguono:
o Jitter cycle-to-cycle (short-term) tJS, massima differenza del periodo tra due cicli di
clock successivi
o Jitter assoluto
Se consideriamo due clock che si trovano nel mio circuito, essi saranno sfalsati tra loro, inoltre ci
sarà una componente aleatoria nell’istante di commutazione.
Il clock non è ideale per molti motivi: normalmente ho un generatore di clock unico e una rete di
distribuzione che consiste in buffer, linee di interconnessione ecc. Ogni linea finirà su flip flop più
grandi o minori. Le cause quindi sono: generatore, incertezze legate ai dispositivi che pilotano le
linee, linee stesse, alimentazione che causa rimbalzi, accoppiamento capacitivo, temperatura, flip
flop di carico.
Quando si progetta l’albero di clock vorremmo
ottenere che il clock arrivi in maniera
SINCRONA a tutto il circuito. Non ci interessa
molto che ci sia ritardo tra il generatore e il pin
vero e proprio!
Tra le cause dello skew troviamo:
interconnessioni e buffer delle linee potrebbero non essere bilanciati: i percorsi alcuni
saranno più veloci di altri. Capiamo che è un fattore deterministico che in fase di
progettazione si può risolvere;
variazioni dei parametri dei dispositivi che causeranno differenti ritardi (casuale);
delle wire saranno più lunghe di altre quindi le C e le R possono variare rispetto ai valori
attesi(casuale).
Il problema del jitter è che il clock lo vedo come una componente media e una aleatoria a media
nulla. Il jitter assoluto quindi è uno scostamento assoluto mentre il jitter ciclo a ciclo è la differenza
del periodo tra due clock consecutivi ed è quello più importante.
Il periodo del clock non è costante: ha un valore medio T cui si somma una componente aleatoria
a media nulla (jitter):
jitter assoluto: massimo scostamento del periodo rispetto al valore medio
jitter cycle-to-cycle: massima variazione fra due periodi consecutivi del clock.
Le cause del jitter sono:
generatore che non dà una forma perfettamente quadra;
Vdd che può variare nel tempo a causa di rimbalzi e produrre differente ritardo nei buffer;
temperatura; accoppiamento capacitivo tra le linee del clock e le altre linee. Questo dà
fastidio perché è una capacità NON costante!! Se ho una commutazione su un nodo che è
accoppiato ad un altro nodo, a seconda delle commutazioni c’è un effetto capacitivo
diverso! L’abbiamo visto nell’accoppiamento capacitivo tra linee.
Variazioni dei ritardi dovute a variazioni della temperatura;
Variazioni dei ritardi dovute a cross-coupling con linee adiacente (effetto Miller).
Come si gestiscono queste 2 non idealità?
Clock skew
Lo skew ha alcune cause deterministiche: supponiamo di aver ottenuto le due situazioni in figura.
Nella prima figura abbiamo un delay crescente man mano che mi sposto lungo il datapath del
circuito, avremo quindi il cosiddetto Positive skew:
Nella figura in basso il delay decresce man mano che mi sposto lungo il datapath. La direzione di
riferimento è quella lungo cui si propagano i dati, avremo quindi il cosiddetto Negative skew:
Per quanto riguarda il
Positive skew la situazione
che si presenta è
rappresentata in figura:
È come se il periodo del
clock si fosse allungato!
Perché il tempo che la rete
combinatoria ha a
disposizione è quello che
va da un fronte all’altro (in rosso), in pratica il periodo è determinato dai fronti di salita 1 e 4.
Caso duale:
negativo, è
periodo del
ridotto, come
figura:
se lo skew è
come se il
clock si fosse
vediamo in
Vediamo gli effetti del positive skew:
Per il vincolo sul tempo
di setup si ha un
beneficio con skew
positivo: la regola si
modifica infatti come in
slide. Al crescere del
ritardo delta il circuito
può andare più veloce o
comunque la
disuguaglianza è più
facile da verificare.
Per il tempo di hold, il delta deve essere minore di una certa quantità!
Se questa relazione non si verifica, il circuito non funziona
proprio!! Usare lo skew per andare più veloci quindi può
causare grossi problemi sul funzionamento del circuito
stesso!!
Ricapitolando:
Uno skew positivo (Δ>0) è benefico per le prestazioni (posso aumentare la frequenza di clock,
sebbene di poco) ma è MOLTO pericoloso per il funzionamento del sistema (vincolo di hold).
Uno skew negativo (Δ<0) peggiora di poco le prestazioni ma rende il sistema più immune a
problemi sul tempo di hold.
Rispetto ad un sistema senza clock skew, l'effetto del ritardo sul clock è equivalente ad una
variazione di tq.
Non sempre si può scegliere quale skew avere (sempre positivo o sempre negativo). Se ho dei
loop non posso fare nulla! Ecco perché consideriamo sempre che lo skew sia PEGGIORATIVO nei
casi. Consideriamo che:
peggiori sempre le prestazioni
renda il circuito meno robusto (renda più critico il vincolo di HOLD).
CLOCK JITTER
Non sapendo quando il periodo del clock sarà maggiore del valore nominale e quando sarà
minore, abbiamo entrambi i problemi evidenziati per lo skew:
peggiora le prestazioni
rende più critico il vincolo sul tempo di hold.
Le formule da usare quale saranno? Supponiamo di conoscere in linea di massima lo skew e jitter:
Devo ragionare sempre in via peggiorativa. Nella formula sottraggo 2 volte il jitter perché ho due
fronti del clock. Si vede che il periodo di clock peggiore.
Ci dobbiamo assicurare che il tempo combinatoriale
minimo sia abbastanza grande. Se non dovesse
esserlo, aggiungiamo dei buffer.
Immagineremo che la frequenza massima sia limitata anche da jitter e skew!
Spesso, per fare ciò, devo inserire della logica fittizia(buffer) per aumentare il ritardo
combinatoriale minimo:
Distribuzione del clock
Come distribuisco, quale strategia uso per distribuirlo in un circuito integrato con molti transistor e
molto estesi come superficie? La strategia deve ridurre lo skew nelle componenti note (non
aleatorie) e si può usare una: strategia con distribuzione ad albero in modo che il ritardo tra il
generatore e il flip flop sia sempre uguale. I flip flop sono le foglie. Per fare ciò, devo sapere dove
sono i flip flop sul silicio esattamente; una strategia con distribuzione a griglia: si cerca di fare i
ritardi quanto più piccoli è possibile. Si useranno dei buffer molto grossi in grado di erogare molta
corrente!
Immagino di avere 2 registri piazzati in due punti differenti. Dopo il buffer, ci saranno le 2 wire che
arrivano ai due registri. Avremo una C di carico dei registri diverse e quelle della linee diverse. Si
può schematizzare la linea con una rete a T.
→
Per calcolare lo skew tra le due foglie dell’albero, bisogna valutare il ritardo che il clock impiega per
arrivare nei due punti e farne la differenza.
Dal circuito di sinistra ricaviamo(Elmore delay):
Facendo la differenza tra le due espressioni, lo skew avrà l’espressione:
Quanto vale? Non si capisce, però il ritardo skew che si ottiene dipende dalle capacità di carico e
soprattutto dalle capacità e dalle resistenze delle LINEE di interconnessione!
Per avere una idea, mettiamo dei numeri e
vediamo cosa otteniamo: supponiamo di
avere dei flip flop realizzati con latch a porte
di trasmissione (quindi sono 8 pmos e
8nmos).
Calcolate le C, portiamo in conto anche la
resistenza per fare due conti. Ho linee in
metal1, supponiamo che la prima linea sia
anche più corta e supponiamo di ottenere
quelle resistenze. Lo skew è di 25.50 ps! Se
usassimo un registro da 64 lo skew diventa veramente grosso!! Se scambiamo però le 2 linee,
possiamo andare molto meglio, e otteniamo uno skew che è più piccolo del primo caso!
Si vorrebbe quindi bilanciare tutti i ritardi, tutte le foglie dell’albero. Una topologia realizzativa
dell’albero è quello dell’albero ad h: ho il clock che tramite un buffer è collegato alla parte centrale
dell’h, poi alla fine di ogni linea verticale ho delle h, se si va a
vedere, i percorsi dal centro alla foglia sono sempre gli stessi! Se
sulla singola foglia dell’albero ho registri diversi, dovrò compensare
usando dei buffer diversi. Se i nodi cui distribuire il clock non sono
perfettamente identici, si può agire sul sizing degli invertitori e sulle
interconnessioni per bilanciare i ritardi.
Supponiamo queste 2 situazioni: il clock ha una capacità piuttosto
elevata (in alto) e l’invertitore è 4x. Le capacità indicate in basso
sono quelle delle linee di trasmissione. Per questo esempio e la
maggior parte dei progetti così si comportano, si trascurano le
resistenze. Calcoliamo allora il ritardo con l’elettrical effort (il logical
dovrebbe essere sempre 1 perché sono invertitori).
La capacità di gate di un invertitore 1X sia 10fF
Il tempo caratteristico della tecnologia (ritardo di un
inverter che pilota un altro inverter identico):
t0=10ps
La figura riporta le sole capacità di
interconnessione, cui vanno aggiunte
la capacità di ingresso degli inverters e dei registri
Trascuriamo le resistenze delle interconnessioni,
per semplicità.
Valutiamo i ritardi:
Valutiamo la differenza:
Per migliorare questo skew, basta cambiare le dimensioni dell’invertitore in rosso. Lo porto da area
minima a 2x, così ottengo che il primo ritardo nella Ta
peggiora ma migliora di molto e complessivamente il
ritardo verso il punto a è diminuito quindi lo skew è
passato a 7.5ps! cambiando le dimensioni dei buffer
ottengo miglioramenti notevoli!
Abbiamo quindi un miglioramento:
Abbiamo detto che la seconda strategia per distribuire il clock
è quella in cui si vuole minimizzare il ritardo dal generatore di
clock verso tutte le foglie! Si fa una griglia con capacità molto
elevata perché copre tutto il chip: dissiperà molto. La
strategia dice che se minimizzo tutti i ritardi, questi saranno
uguali tra loro! Inoltre, poiché la griglia copre tutto, se in
ultima fase di progetto devo cambiare un mos o un qualcosa,
non devo toccare nulla perché alla fine la griglia sta ovunque
e sto coperto!
Si noti come in questo esempio la capacità è dell’ordine
dei nF e la potenza dissipata è il 40 % della totale!!! Si
usano due livelli di distribuzione: c’è un primo stadio di
buffer più piccoli che pilotano un secondo stadio di buffer
più grandi che pilotano tutto. Il driver misura 58mm
complessivamente!
Il driver centrale è quello che fa da carico al generatore del clock, e
poi ci sono le due SPINE (le due linee
fatte tutte di buffer).
Lo skew non è del tutto ottimizzato. Se
il ritardo massimo è basso, lo skew
complessivo è piccolo a piacere ma
ovviamente più abbasso l’immagine più
dissipo!
Esistono più strategie utilizzate: quella vista è la
centrale, si usa un solo driver centrale; nota i valori di
capacità diversi e i valori di potenza dissipata diversi.
Per capire quanto può essere grande lo skew in un
circuito integrato in funzione della frequenza del
processore, vediamo il grafico. Il valore percentuale
rientra SEMPRE nella fascia del 10% del periodo di
clock, ovviamente se aumenta la frequenza, in
valore assoluto questo skew diminuirà!
Con una distribuzione perfettamente bilanciata la
temperatura non è il fattore che incide di più, bensì
incide maggiormente in assoluto il mismatch dei
dispositivi!
Altro esempio reale
che mostra come il
clock nel P4 viene
distribuito: è un
misto tra albero e
piccole griglie.
Nella tecnologia a 90nm (sempre P4) ci si mantiene sotto i 3-4 ps!
Sempre nel p4, si usano tecniche specifiche: una delle cause era l’alimentazione. Si filtrano allora
le variazioni sulle tensioni di alimentazioni. Quello che si sosteneva, è che se si ha un rimbalzo del
10% sulla tensione di alim. Il buffer vede solo una variazione del 2%.
Generazione del clock
Vediamo ora come si genera il clock. I circuiti moderni funzionano con clock di alcuni GHz.
Questo crea 2 problemi:
1. generazione (generatori a ridotto jitter basati sull’oscillatore al quarzo non forniscono GHz
ma al max 100MHz);
2. se porto il clock on board a 3GHz, devo far commutare delle capacità enormi!! Quello che
si fa è generare un clock a frequenza più bassa e poi portarlo su in frequenza.
La prima strada per generare il segnale di clock è usare anelli ad aggancio di fase (PLL).
In pratica si utilizza un oscillatore a quarzo, per generare un segnale di riferimento a bassa
frequenza, poi degli anelli ad aggancio di fase (PLL) vengono utilizzati on-chip per moltiplicare il
segnale di riferimento esterno e generare il clock alla frequenza desiderata
Quindi il meccanismo degli anelli ad aggancio di fase permette di moltiplicare la frequenza di
un’onda quadra. Sono fatti così:
Sistema a ciclo chiuso. La frequenza prodotta dall’oscillatore controllato in tensione (VCO) viene
controllata in modo tale che, in condizioni di aggancio i segnali “reference clock” e “local clock”
sono identici (stessa frequenza e fase).
Poiché la frequenza del “local clock” è pari a quella del “system clock”/N, in condizioni di aggancio
la frequenza del “system clock” è N volte quella del “reference clock”.
I PLL sono sistemi misti Analogico-Digitali (la tensione di controllo del VCO è un segnale
analogico, il filtro di anello è un filtro RC ecc.).
Il filtro di anello deve essere progettato in modo da garantire la stabilità del sistema. Inoltre dal filtro
di anello, oltre che dal VCO, dipende il jitter del “system clock”.
I PLL:
1. vengono messi in ingresso ai circuiti digitali per elevare la frequenza del clock;
2. serve per distribuire il clock a due dispositivi digitali ed avere un sincronismo. Il pll fa da
buffer senza ritardo. I due clock in ingresso dei sistemi digitali sono esattamente in fase! Il
buffer ovviamente mi servirà sempre, per rendere uguali i ritardi però annullo i ritardi dei
buffer con i pll.
3. posso usare il pll per sincronizzare il trasferimento dati tra 2 circuiti.
I PLL operano come dei buffer a ritardo nullo. Il trasferimento dati fra chip1 e chip2 avviene a
frequenza inferiore rispetto al system clock. I dati
trasmessi sono sincroni con il reference clock
Nel chip 2 si utilizza un PLL per annullare gli
effetti del ritardo del clock buffer (de-skewing): il
segnale di clock al registro del chip2 è
perfettamente allineato con il reference clock,
nonostante la presenza del clock buffer.
Oltre ai PLL posso usare i DLL, circuiti simili che
hanno una struttura simile ai pll ma non c’è
divisione di frequenza e invece di avere un oscillatore controllato in tensione ho una delay line
controllata in tensione. Vediamo il confronto degli schemi a blocchi:
Riferendoci allo schema del DLL possiamo dire che:
Un DLL non ha un oscillatore controllato in tensione, ma una linea di ritardo controllata in
tensione.
In condizioni di aggancio, fo ed fREF sono
perfettamente allineati fra di loro (deskewing)
I DLL non consentono di moltiplicare la
frequenza di fREF
Sono sistemi incondizionatamente stabili ed
affetti da minore jitter.
Non posso usarli per moltiplicare il clock, ma
NEL circuito posso usare i DLL per la
temporizzazione/sincronizzazione!
Ecco un modo per avere un buffer a ritardo nullo (VCDL: voltage controlled delay line):
Progetto di Latch e Registri a
livello Transistor
Cap. 7
Ricordiamo la distinzione tra latch e registri:
un latch memorizza quando il clock è
basso (o dualmente alto)
un registro memorizza sul fronte del
clock, che sia di salita o di discesa.
Gli elementi di memoria saranno basati sulla
bistabilità. Non consideriamo elementi di
memoria dinamici.
Il latch lo vediamo riportato in questa figura sotto,
a porte di trasmissione. Le due porte di
trasmissione le possiamo schematizzare come due interruttori. Quando il clk è 1 la porta in alto è
spenta mentre quella in basso è accesa. Il segnale D si riporta in uscita. Siamo quindi in fase di
TRASPARENZA. Viceversa, quando il clock è 0, il sistema si riconfigura come due invertitori
collegati uno dietro
l’altro e siamo in fase
di hold. I due
invertitori
rappresentano
l’elemento di
memoria. Se ci serve
un latch che opera sui
livelli opposti, inverto
tra loro clock e clock negato. Nota che ci sono quattro dispositivi pilotati dal clock che danno una
certa capacità che comporta una Pdissipata e introduce delle problematiche per il clock skew
(maggiore è la capacità della linea, più difficile è controllare lo skew).
Come si può vedere vi è un elevato carico capacitivo sul clock (4 MOS), quindi:
Elevata Pd per pilotare il clock
Maggiori difficoltà per clock skew
Si osservi che queste due porte di trasmissione collegate in questo modo
realizzano un multiplexer. Il D-Latch lo possiamo vedere logicamente
come la struttura di destra.
Abbiamo visto che è presente la cascata di un
invertitore con una porta di trasmissione.
Questa può essere vista come tristate.
Esiste allora una configurazione migliore per
realizzare una porta tristate? Si, è quello di figura
sotto.
A livello layout, è più compatto perché non dovendo
mettere un contatto tra due pmos e due nmos (quei
contatti necessari per fare il collegamento che poi ho
eliminato). Si legge che ha un ritardo maggiore, quindi
una resistenza leggermente maggiore!
Come si vede dalla figura a lato il clocked
inverter presenta due contatti in meno nel
layout.
Con questo si può anche fare un multiplexer
con i clocked inverter(vedi figura sotto).
In basso metto un invertitore standard al posto del clock inverted. Si risparmia il carico sul clock,
non tanto l’area. Ottengo proprio un bistabile. In fase di memorizzazione non ci sono problemi.
Ora si alza il clock, siamo in fase di trasparenza. In questa fase c’è un problema di
DIMENSIONAMENTO!
Il W/L equivalente del clocked inverter (pilotato da D) deve essere più grande rispetto ai dispositivi
che stanno nell’invetitore di feedback. Nel conflitto al nodo P deve essere più forte il clocked
inverter!
Vediamo cosa deve accadere: questa situazione di errore
vista (che il livello resta a metà e abbiamo dissipazione di
potenza statica) si avrebbe solo se l’uscita dell’invrtitore in
alto fosse FISSATA A 0.
L’uscita dipende dal nodo P con un feedback.
Se il potenziale di P si abbassa sufficientemente da essere visto come livello BASSO, l’invertitore
in alto commuta e l’uscita va ad 1. In questo modo, si spegne il pmos in basso e si alza l’nmos e il
nodo P va a 0!
Tutto si basa su un opportuno dimensionamento a rapporto: la serie dei due nmos deve essere
tale da far abbassare il potenziale P sufficientemente!
Quindi il pmos deve essere piccolo, i due nmos in serie devono essere grande.
E’ una delle poche applicazioni un cui si usa una L maggiore della Lminima! Questa è una rara
eccezione!
Ora passiamo ai registri MasterSlave. Il sistema complessivo non è
mai trasparente, non c’è mai un
collegamento diretto tra D e Q.
L’uscita Q cambia quando lo slave
diventa trasparente. Dunque, un
registro master slave è realizzato
con due latch attivi sul fronte di
salita (per es) collegati così. Se
volessi farlo attivo sui fronti di
discesa, devo togliere l’invertitore
dal primo latch e metterlo al
secondo.
In basso possiamo vedere la
realizzazione di un registro MasterSlave con porte di trasmissione:
Si notino il numero di dispositivi pilotati!
Questa è la più semplice che possiamo realizzare. Cerchiamo di stimare in maniera
approssimativa i tempi caratteristici del registro: tsetup, thold, tcq. Quelli più influenti sono il tsetup
e il tcq.
Facciamo un stima del tempo di setup
tsetup: tempo prima del fronte del clock
nel quale il dato deve rimanere stabile.
Questo latch è attivo sul fronte alto del
clock (per capirlo, basta vedere quando
il secondo latch diventa trasparente,
ovvero quando la porta T3 è aperta!)
Inizialmente siamo nella condizione in
cui Clock=0. Se il clock è 0, il dato di ingresso fluisce attraverso T1 e I3 ed è disponibile a I4. Nota
che il dato di ingresso è disponibile anche a I2 ma T2 è spenta. Appena commuta il clock (diventa
1), la porta T2 si apre e se il dato è stabile da parecchio non ci sono problemi perché in ingresso e
in uscita alla T2 ho lo stesso livello logico!! Se invece il dato commuta in prossimità del clock, in
ingresso e in uscita di T2 posso avere segnali differenti e non so cosa succede! Il ritardo che si ha
sul cammino è pari a 3 volte il ritardo dell’invertitore più un ritardo della porta di trasmissione:
Ts=3Ti+Tm
Vediamo il ritardo clock to q. Questo
si stima come il ritardo di T3+il
ritardo di I6 (in prima
approssimazione).
Clock to Q: in corrispondenza del
fronte di salita del clock il dato deve
propagarsi attraverso T3 ed I6 per
raggiungere Q
Tq=Ti+Tm
Infine, vediamo il tempo di hold. Durante il fronte di salita, T2 si chiude e T1 si apre (disattiva). Se
ciò accadesse istantaneamente, non avrei problemi.
Possiamo trarre 2 conclusioni:
1) la frazione di periodo consumata dal registro è estremamente grande!
tsetup+tc=4ti+2tm ovvero si mangia 4 volte il ritardo di un invertitore e 2 volte il ritardo di
una porta di trasmissione. Il tempo minimo è proprio il tempo di hold che però non rientra
nella figura di merito velocità del nostro sistema in esame.
2) Posso realizzare un registro a scorrimento? Il ritardo combinatoriale è praticamente 0
(tcmin=0) e la condizione diventa quello di figura. Se però c’è un ritardo sul clock, la
condizione cambia!
In definitiva, sul master slave ho grande carico, il sistema è lento perché il tempo di setup è grande
(ma anche il tcq), è robusto!
Possiamo vedere il grafico del ritardo Tcq:
e come la variabilità del segnale di ingresso
possa inficiare il corretto funzionamento del circuito:
FUNZIONAMENTO CORRETTO
VIOLAZIONE DEL TEMPO DI
SETUP
C’è un'altra problematica che vediamo sul flip flop: Clock e clock
negato non sono esattamente uno l’inverso dell’altro, ci sono
degli istanti di tempo in cui si sovrappongono a causa proprio
dell’inserimento dell’invertitore sulla linea di clock!!
A causa di queste “finestre”, potrebbe accadere che:
sono trasparenti entrambi i latch e il dato di ingresso
potrebbe scappare verso l’uscita durante il fronte
sbagliato!
durante la fase di sovrapposizione 1-1, tutti gli nmos delle porte di trasmissione conducono!
Analogamente, se ci sono fasi in cui clock e clock negato sono entrambi 0, conducono tutti i
pmos! E cosa succede in questi casi?? Problema!!
L’unico modo che abbiamo per fare in modo che il circuito funzioni correttamente, è rendere
questa fasi brevissime: posiziono questo invertitore vicinissimo ai latch, le dimensioni vanno scelte
in maniera molto critica e soprattutto vanno fatte simulazioni da tutti i punti di vista!
Reset sincrono ed ascincrono
Il reset serve per inizializzare un registro, per portare tutte le uscite a 0. Non è sincrono.
Se il reset è alto, metto D a 0. Q non va a 0, andrà a 0 al successivo fronte del clock. Il reset
SINCRONO non ha problemi di sorta riguardo la realizzazione hardware. Il mux non è altro che
una and.
Il reset serve per portare il registro in uno stato predefinito (Q=0)
Reset sincrono: il comando di reset non è efficace
immediatamente, ma in corrispondenza del successivo fronte
attivo del clock
Reset asincrono: cambia lo stato del registro, portando Q=0, indipendentemente dal clock
Il reset asincrono deve funzionare anche
quando non c’è clock. Si deve modificare
quindi la struttura interna del registro.
Per effettuare il reset asincrono devo:
spezzare i loop di reazione
portare lo stato dei nodi interni ai valori
in figura
La soluzione al problema è riportata in figura a lato: al posto dell’altro invertitore che stava nel loop
di retroazione metto una NOR il cui ulteriore
ingresso è il reset. Se questo reset vale 0,
dobbiamo verificare che il sistema si comporti
normalmente: in questo caso,la NOR è a tutti gli
effetti un invertitore. Quando il reset è 1, i nodi
in uscita alle NOR si resettano e vanno a 0. Si
noti che rispetto a prima non ci sono invertitori
in serie, in questo modo ho fatto una struttura
NON invertente nel complesso data dalla
cascata di due blocchi invertenti.
Molto spesso è necessario introdurre un segnale di “enable” che consente, se attivo, di caricare il
registro.
La soluzione più intuitiva è il clock-gating che però:
RICHIEDE PARTICOLARE ATTENZIONE
Si introduce un clock skew rilevante
Il registro può acquisire i dati in corrispondenza delle commutazioni di
en, invece che del clock!
Il clock gating è utile per ridurre la dissipazione di potenza (lo
studieremo in quel contesto).
Caricamento condizionale di un registro: inserisco un nuovo segnale di
abilitazione che consente di caricare il registro o meno. Con la soluzione di figura, introduco un
ritardo sul clock e un problema relativo all’enable (leggi in rosso). Questa tecnica è però utile per
ridurre la dissipazione di potenza: sappiamo che il segnale di clock è uno dei più critici. In questo
modo, applicando per esempio l’enable ad un intero modulo, si riduce di molto la pd. Bisogna
comunque stare molto attenti quando si adotta tale soluzione.
Se voglio evitare di usare l’enable sulla linea di clock, uso un multiplexer
sul dato di ingresso!
In vhdl il caricamento condizionale segue proprio questo schema. Se ho un
processo, questo si attiva solo se cambia il clock. Avrò l’if prioritario che è
sul fronte attivo del clock e un if più interno che agisce sul dato iniziale.
Registri avanzati
Esistono altri tipi di registri:
SRAM-based
Sense-amplifier
Latch pulsate
SRAM-based
Abbiamo un bistabile fatto con 2 invertitori, i due rami del bistabile
possono essere portati a 0: un ramo tramite D e clk e l’altro tramite
Dnegato e clk.
Il principio di funzionamento di questo circuito è:
per clock=0, spengo i due nmos e il bistabile sta in
memorizzazione.
per clock=1, vogliamo che il sistema sia trasparente. Se per
esempio D=0, l’nmos di sinistra è spento, quello di destra è acceso! Ho
la serie di 2nmos accesi e cercano di portare l’uscita Q a 0. Il circuito
deve essere dimensionato a rapporto! La serie dei due nmos Dnegato e
clock deve essere più forte del PMOS dell’invertitore in alto (che è quello che cercherebbe
di tenerlo ALTO nel caso in cui Q era 1).
Si effettua un dimensionamento a rapporto, il PMOS dell’invertitore deve essere “debole” rispetto
alla serie dei due NMOS.
Faccio un miglioramento sul registro sram ottenendo il LATCH
SINGLE TRANSISTOR CLOCKED. L’idea è semplice: metto in
comune l’nmos del clock. Ho ridotto il numero di transistor e
soprattutto ho ridotto il carico sul clock! Si può avere un
problema: poiché ci sono proprio D e Dnegato sui rami, tra D e
Dnegato ci possono essere interlap in cui per es valgono
entrambi 1! E qui è critico! Allora devo rendere questi interlap
brevi!
Proviamo a fare un dispositivo DUALE che è trasparente quando il
clock è 0 e che non richiede l’inversiore del clock. Semplicemente
realizzo una struttura alimentata al contrario.
Trasparente per clk=0; memorizzazione per clk=1
In trasparenza, se D=1 si ha: Q=1; Q=0
Dimensionamento a rapporto: gli NMOS degli invertitori deboli rispetto
alla serie di due PMOS! (i PMOS devono avere W/L molto elevati).
Mettendo tutto in cascata, ottengo un registro A VERA SINGOLA
FASE DI CLOCK. Non si deve avere clock e clock negato e
DAVVERO non si ha
sovrapposizione.
Si noti che nel dispositivo DUALE ho più difficoltà a
realizzarlo, sarà più grande perché devo fare una serie
di PMOS più forte di un nmos!!
Si noti che QUI devo considerare tutti e 2 gli angoli di
processo opposti per simularlo e vedere se funziona
(slow n fast p e slow p fast n).
Ulteriore miglioramento dei registri SRAM: registri SRIS. Latch che
non richiedono un dimensionamento a rapporto. Sono più robusti.
Qui partiamo da un latch di tipo sram che avevo prima ma in più
aggiungo una rete verso l’alimentazione. Con questa rete, in fase di
trasparenza non ho problemi di rapporto tra dispositivi!
In realtà non è nient’altro che un latch SRAM con
l’aggiunta di una rete in serie all’alimentazione.
In fase di memorizzazione cosa accade? Bisogna stare attenti a fare
in modo che gli invertitori centrali siano sempre alimentati! Ebbene,
ciò accade. Quindi è una scelta molto intelligente.
Funzionamento per clk=1 (trasparenza) => Se D=0 anche Q viene portato a 0. In questa
fase il PMOS comandato da D è spento.Situazione analoga per D=1.
Funzionamento per clk=0 (memorizzazione). Il bistabile è correttamente alimentato. Il
PMOS comandato dal clock è in conduzione e conduce anche uno dei due PMOS
comandati da D e NotD.
Un registro si ottiene facilmente in configurazione master-slave, è necessario utilizzare un latch
SRIS duale (trasparente per clk=0).
I registri con logica embedded oltre a memorizzare, effettuano
anche operazioni logiche sugli ingressi.
Registro Sense-Amplifier based(SA)
Due stadi in cascata
Il primo stadio è il sense-amplifier
Il secondo stadio è un latch SR a porte
NAND
Funzionamento per clk=0 (precarica)
I due PMOS del sense-amplifier sono in conduzione e
portano ad 1 i due segnali NotS e NotR
Il latch SR a porte NAND è in fase di memorizzazione
Funzionamento per clk: 0 => 1
Il sense-amplifier ha inizialmente entrambe le uscite S ed
R ad 1.
Se D=1, S si porta a 0 mentre R resta ad 1 (valutazione)
Lo NMOS pilotato da S si spegne, ed ogni successiva
commutazione di D non altera lo stato del sense-amplifier
Il registro Sense-Amplifier based:
Non segue l’architettura costituita da due latch in cascata, ma è comunque edge-triggered
Circuito molto veloce: il tempo di setup è molto piccolo
Il Ritardo clock to Q può essere migliorato sostituendo al latch costituito delle due NAND un
circuito più efficace.
Pulse-Triggered Latch
Breve finestra di trasparenza dopo la
commurazione da 0 ad 1del clock, di durata
pari al ritardo di tre invertitori.
Tempo di hold pari alla finestra di trasparenza;
maggiore rispetto ad un registro standard
Circuiti Aritmetici
Addizionatori
Carry ripple (ritardo proporzionale ad N)
Carry select (ritardo proporzionale alla radice quadrata di N)
Carry skip (ritardo proporzionale alla radice quadrata di N)
Carry lookahead (ritardo proporzionale al logaritmo di N)
Multi-operando (carry-save)
Moltiplicatori
A matrice (array multipliers) carry-ripple e carry-save
Pipelined
Veloci ad albero (Wallace, Dadda)
<= Adder carry-ripple
Adder a selezione del riporto (carry select)
L’addizionatore ad N bit viene suddiviso in P blocchi,ognuno dei quali opera su M bit, con: N=P*M
Il primo blocco è un adder carry-ripple su M=4bit. I blocchi successivi includono due adder carry
ripple da M=4bit (unocon Cin=1 e l’altro con Cin=0) e dei multiplexer.
Indico con Ta e Tm i ritardi, rispettivamente, del full-adder e del multiplexer.
Il carry all’uscita del primo blocco è disponibile al tempo MTa
Le somme ed il carry all’uscita del secondo blocco sono disponibili al tempo: MTa + Tm
Le somme ed il carry all’uscita del terzo blocco sono disponibili al tempo: (MTa + Tm) + Tm
= MTa + 2Tm
Le somme ed il carry all’uscita dell’ultimo blocco: MTa + (P-1)Tm
Ottimizzazione ritardo dell’Adder carry select
T=MTa + (P-1)Tm
Come posso scegliere in modo ottimale M e P, dato N?
Sostituisco M=N/P e derivo rispetto a P:
quindi abbiamo ottenuto:
Il ritardo è proporzionale alla radice di N. Il miglioramento rispetto al carry ripple è sensibile quando
N è sufficientemente elevato
Esempio: tm=ta/2; n=32, m*=4, p*=8, da cui un ritardo pari a: t*=7.5 ta (carry-ripple: 32 ta
miglioramento di un fattore 4).
C’è però un prezzo da pagare: aumento dell’area (circa doppia rispetto ad un carry ripple)
E’ possibile ridurre ulteriormente il ritardo, eliminando il vincolo che tutti i blocchi siano della
stessa dimensione.
• Esempio. Supponiamo che Tm=Ta=1 e consideriamo la struttura iniziale
(non migliorata) in cui tutti i blocchi siano da 4 bit
Il segnale C8 e’ disponibile al tempo 5. Tutti i segnali giungono contemporaneamente al
multiplexer che fornisce C8.
Consideriamo il multiplexer che genera C12: Il segnale di selezione è disponibile al tempo 5,
mentre gli altri due ingressi (prodotti dai due adder carry-ripple) sono disponibili al tempo 4
E’ possibile portare il terzo blocco da 4 ad 5 bit senza peggiorare il ritardo.
Introduciamo adesso il concetto di generazione e propagazione del carry in un full-adder.
Cerchiamo di ricare un espressione in via ricorsiva per il calcolo dei carry di ogni bit.
Introduciamo poi il Block Generate e il Block Propagate.
Avevamo scritto:
Consideriamo i bit da 0 a 3 come un unico blocco:
Il riporto prodotto da questo blocco sarà 1 se:
Il carry si genera nel blocco (BG=1)
Oppure: il carry in ingresso è alto ed il carry si propaga attraverso il blocco (BP=1)
Nota Importante: il riporto prodotto dal blocco dipende dal riporto entrante se e solo se:
BP=1; in questo caso riporto uscente coincide con il riporto entrante
Se BP=0 il riporto del blocco potrà essere 0 oppure 1, ma non dipenderà dal valore di Cin.
Adder carry-skip
Abbiamo visto che il riporto prodotto da un blocco dipende dal riporto entrante se e solo se: BP=1;
in questo caso riporto uscente coincide con il riporto entrante.
Dunque, Se BP=1 non è necessario attendere che il riporto venga calcolato all’interno del blocco,
si può immediatamente riportare il riporto entrante all’uscita del blocco.
Questa osservazione è alla base dell’adder carry-skip.
Come per il carry-select, l’addizionatore ad N bit viene suddiviso in P blocchi, ognuno dei quali
opera su M bit, con: N=P*M.
Ogni blocco (anche il primo) è composto da un adder a propagazione del riporto e da un mux, ogni
blocco, inoltre, deve valutare il segnale di block propagate, BP.
In uscita viene fornito il riporto di ingresso (se BP=1) oppure il carry calcolato dall’adder a
propagazione del riporto (se BP=0).
Consideriamo la configurazione in figura. Dopo quanto tempo sarà disponibile il segnale C12?
Primo caso: BP2=0
Il riporto C12 non è funzione di C8 (dato che non c’è propagazione dal secondo al terzo stadio).
Il caso peggiore che può presentarsi è che il riporto si generi nel primo bit del terzo stadio e si
propaghi attraverso tutti gli altri full-adder del terzo stadio fino all’uscita.
Ritardo max: 4ta+tm,
(in generale m_ta+tm).
Secondo caso: BP2=1 e BP1=0
Il riporto C12 è uguale a C8, mentre C8 non dipende da C4. Il caso peggiore che può presentarsi è
che il riporto si generi nel primo bit del secondo stadio, si propaghi attraverso tutti i full-adder del
secondo stadio, attraversando due multiplexer fino a giungere a C12.
Ritardo max: 4ta+2tm,
(in generale m_ta+2tm).
Terzo caso: BP2=1, BP1=1 e BP0=0
Il riporto C12 è uguale a C8, C8 è uguale a C4, C4 non dipende da Cin
Il caso peggiore che può presentarsi è che il riporto si generi nel primo bit
del primo stadio, si propaghi attraverso tutti i full-adder del primo stadio,
attraversando tre multiplexer fino a giungere a C12
Ritardo max: 4ta+3tm
Quarto caso: BP2=1, BP1=1 e BP0=1
Il riporto C12 è uguale a C8, C8 è uguale a C4, C4 è uguale a Cin
Questa era la condizione peggiore per l’adder carry ripple. Nel caso del
carry skip, Cin attraversa tre multiplexer fino a giungere a C12
Ritardo max: 3tm
Tabellando i risultati ottenuti avremo:
Anche in questo caso, è possibile ridurre il ritardo, eliminando il vincolo che tutti i blocchi siano
della stessa dimensione.
Esempio. Supponiamo che Tm=Ta=1 e consideriamo la struttura iniziale con 4 blocchi da 4 bit,
allora il ritardo max è 11 per il bit S15 (S11 ha ritardo 10 ed S7 ha ritardo 9).
Nella tabella a lato possiamo vedere
di come scalino i ritardi e possiamo
capire dove possiamo aumentare di
un bit l’adder senza aggiungere
ulteriore ritardo al circuito.
Se ad esempio aumento le
dimensioni del primo blocco,
aumento i ritardi di tutte le uscite a
partire da S5, ed aumento pertanto
anche il cammino critico.
Stesso discorso Se aumento le
dimensioni dell’ultimo blocco, aumento il ritardo di S15 ed aumento pertanto anche il cammino
critico.
Supponiamo di aumentare di un bit le dimensioni del secondo blocco.
La nuova uscita sarà disponibile al tempo 10 (con un ritardo inferiore a quello massimo), il ritardo
del riporto all’uscita del secondo blocco, C8, non aumenta e quindi non vengono alterati i ritardi
delle uscite degli altri due blocchi.
In definitiva, la modifica proposta consente di aumentare il numero di bit dell’addizionatore,
senza peggiorare il ritardo.
Supponiamo invece di aumentare di due bit le dimensioni del secondo blocco.
In questo caso le nuove uscite saranno disponibile al tempo 10 ed 11 (con un ritardo inferiore a
quello massimo).
Il ritardo del riporto all’uscita del secondo blocco, C8, aumenta e quindi si incrementa il cammino
critico, in definitiva, questa modifica proposta non risulta vantaggiosa come prima.
Supponiamo di aumentare di un bit le dimensioni del terzo blocco.
La nuova uscita sarà disponibile al tempo 11 (con un ritardo pari a quello massimo), il ritardo del
riporto all’uscita del terzo blocco, C8, non aumenta e quindi non vengono alterati i ritardi delle
uscite degli altri due blocchi.
In definitiva, la modifica proposta consente di aumentare il numero di bit dell’addizionatore,
senza peggiorare il ritardo.
Supponiamo di aumentare di due bit le dimensioni del terzo blocco.
Le nuove uscite saranno disponibile al tempo 11 e 12 e quindi si incrementa il cammino critico
mentre il ritardo del riporto all’uscita del terzo blocco, C12, non aumenta.
In definitiva, la modifica proposta non risulta vantaggiosa.
In definitiva, è possibile aumentare di un bit le dimensioni del secondo e del terzo blocco, senza
aumentare il ritardo.
Si può dimostrare che, in generale, è possibile aumentare le dimensioni dei blocchi compresi fra il
secondo ed il penultimo. I blocchi di dimensione massima sono quelli al centro dell’addizionatore e
la distribuzione delle lunghezze dei blocchi è la seguente:
La pendenza delle due rette in figura dipende da Tm/Ta.
Adder Carry look-ahead
Ben si adatta su circuiti che devono sommare un numero significativo di bit. La struttura di base
include 3 blocchi :
1. calcola i segnali di generazione e propagazione di ogni bit
2. sfruttando questi segnali
, va a calcolare i riporti per ogni bit ( quelli entranti)
3. calcola le somma con il segnale C calcolato nel secondo blocco
Il primo e l’ultimo blocco non sono critici : entrambi operano solo con la cifra i-esima . (cifre che
stiamo sommando) . Il ritardo sarà concentrato nel secondo blocco che calcola i riporti e lo deve
fare nella maniera più veloce possibile .
Come possiamo calcolare i segnali di riporto?
Una prima opzione sarebbe di usare le equazioni di generazione e propagazione usate l’altra volta
e di espanderle.
C1 = primo bit
C2 = secondo bit : lo posso espandere mettendo al posto di c1 la prima formula.
Calcolo tutti i riporti in parallelo e con il ritardo di un'unica gate. Se proseguo ad espandere queste
funzioni per tutti i bit che dobbiamo sommare riusciamo a fare un circuito in cui il tempo per fare la
somma non dipende da N : ho N porte logiche , per ognuna , sfruttando g e p , è possibile
calcolare il carry e poi con altre XOR faccio la somma e potrebbe in teoria non dipendere da
N questa operazione.
Questo risultato è teorico perché si vede che le funzioni logiche che calcolano i riporti diventano
più complicate quando l’indice cresce. Pertanto , è vero che ci vuole un'unica porta logiche
per calcolare C4 , ma il ritardo di questa
porta diventa grande perchè il logical
effort diventa grande ( ovvero il numero
di transistori e aree crescono in maniera
incontrollata) . Posso adottare questo
approccio solo per pochi bit.
Se ho un addizionatore a 4 bit posso
realizzarlo come in slide ,i Blocchi
servono per calcolare segnali generazioni
e propagazione. Il CLA calcola i carry e
per ottenere le somma serve una porta
XOR . Potremmo fare qualcosa che ha ritardo che non dipende da N ma solo per 4 o 5 bit perché
le porte logiche altrimenti diventano troppo lente. Vogliamo estendere l’approccio utilizzando un
numero di bit grande perché i CLA hanno senso soltanto quando il numero di bit da sommare è
grande.
Possiamo vedere lo schema di un
adder CLA a 16 bit.
I blocchi CLA calcolano i carry, il
Block-generate ed il Blockpropagate.
BG e BP non
dipendono da Cin
Il cammino critico è quello
mostrato nella figura a lato.
Il cammino critico attraversa tre
blocchi CLA.
4bit: T=TGP + TCLA + TXOR
16bit: T=TGP + 3TCLA + TXOR
64bit: T=TGP + 5TCLA + TXOR
in generale:
T=TGP + (log2(N)-1)TCLA + TXOR
Stima dei ritardi; indico con:TGP il ritardo dei blocchi per il calcolo di gi e pi; TCLA il ritardo del
blocco CLA e TXOR il ritardo della xor per calcolare la somma finale.
Le limitazioni del CLA sono sicuramente:
rregolarità dei collegamenti
Lentezza del blocco CLA.
Adder parallel-prefix
Vediamo in generale qual è il
problema.
Supponiamo di avere un K ingressi :
. Supponiamo di avere un
operatore. Esso gode della properiteà
associativa ( non della commutativa
eventuialmente ) e lo indichiamo con +.
Il problema parallelo ( parallel prefix
problem )è: dati degli ingressi e un
operatore associativo, calcolare (
compute ) le K uscite come in figura
sotto .
La proprietà associativa significa non
ha importanza l’ordine con il quale
l’operatore è applicato ai vari operandi.
Cosa a che fare questo problema con il calcolo riporti?
Innanzitutto vediamo
quali sono questi
ingressi (
,
):
in pratica questi
ingressi saranno
costituiti da una
coppia di bit ( ovvero
un vettore di 2 bit. Es.
(g(0,0) , p(0,0) è un
ingresso ). Il primo
ingresso ad esempio
sarà la coppia
che costituiscono
generate e propagate
del bit meno
significativo nostri
operandi. Rispetto al
caso precedente
,quella che era X ora
è una coppia di valori.
Come definisco
questo operatore <> ? E’ realizzato come una porta logica che avrà due coppie di ingressi ( 4
segnali di ingresso) e fornisce una coppia di uscita ( 2 bit in uscita)
Quando il segnale
si alza , significa che il carry viene generato dal blocco che va da 0 a k1 . BG e BP li abbiamo introdotti nell’addizionatore a salto del riporto.
Definendo cosi ingresso e operatore , le uscite vengono a corrispondere ai segnali di BG e
BP. Riusciamo a calcolare applicando questa tecnica i segnali di BG e BP. Una volta che li
conosco, calcolare il riporto K-simo è banale perchè tale riporto k-esimo lo posso scrivere come :
Posso calcolare quindi tutti i carry , poi faccio le XOR e ho tutte le somme.
Se risolvo il problema “parallel prefix” con tempo di propagazione ridotto, riesco a fare anche la
somma nello stesso tempo Log di N . il nostro problema è cambiato ed è quello di capire come
calcolare tutte le uscite in un tempo proporzionale al numero di bit da sommare. Vediamo che
l’operatore non gode della proprietà commutativa. Se scambio di posto gli ingressi, l’uscita
cambia!
Prima di fare questo dobbiamo vedere se l’operatore gode di proprietà associativa. Facciamo
allora la verifica :
Considero questi due casi distinti :
Nel caso superiore applico l’operatore prima all’ingresso di indice 0 e 1 e poi il risultato
all’ingresso di indice 2 e ottengo un uscita.
Nella versione dopo, applico prima l’operatore agli ingressi 1 e 2 e il risultato all’ingresso 0 e
ottengo un'altra uscita. Se l’ operatore è associativo le uscite sono uguali perché non importa
l’ordine.
Dimostriamo l’associatività visto che della proprietà commutativa non mi interessa.
Applico prima gli ingressi in un modo e poi li applico al contrario. Sono identici. Le uscite sono i
segnali di BP e BG sempre sui 3 bit. Dobbiamo vedere come calcolare tutte le N uscite come ci
richiede il problema parallel prefix in un tempo rapido possibilmente .
Focalizziamoci sul calcolo dell’ultima uscita ( dove applico l’operatore a tutti gli ingressi ) . Questi
ingressi sono vettoriali. Una prima soluzione è mettere in cascata N-1 blocchi in questo modo
che vediamo a lato.
Questa prima soluzione è la più
immediata ma ha lo svantaggio di
essere la più lenta , il ritardo cresce
con N proporzionalmente.
Ha un vantaggio : l’ultima uscita y
che abbiamo è quella che si ottiene
applicando l’operatore a tutti gli
ingressi.
Questo metodo non ci fa calcolare
solo questa uscita ma ci consente
di calcolare tutte le N uscite. !
La prima uscita è il primo ingresso ,
l’altra uscita è la prima uscita , l’altra
è la seconda ecc , in un colpo
solo, con N-1 blocchi ottengo le uscite che mi servono! Questa purtroppo è anche la
soluzione più inefficace.
La seconda soluzione è la più rapida : consiste nel disporre gli operatori secondo una struttura ad
albero ovvero gli ingressi vengono elaborati in parallelo. Nella struttura ad albero se ho N ingressi ,
al secondo stadio ne ho N/2 , N/4 a quello successivo e cosi via. I segnali dopo ogni stadio si
dimezzano di volta in volta : il numero di stadi va come il log 2 di N.
Questo è vantaggio! In questo esempio non lo si vede perché abbiamo 4 bit => 2 stadi. 64 bit =>
numero stadi da attraversare è una frazione piccola rispetto alla struttura ripple.
Caso di 8 ingressi :
Dopo 3 stadi ho
calcolato i segnali di
BP e BG.
Effettivamente
disponendo ad albero i
blocchi logici , calcolo i
riporti con tempo log N.
Inconveniente : nella
struttura di slide calcolo
l’uscita da 0 a 7 ma a
noi servono tutte! Di
uscite valide abbiamo
la banale g0,p0 ,le due
uscite BP e BG di slide
e poi quella che va da
0,1 . Questa struttura
non è completa! Non
riesco a calcolare tutti i
riporti ma solo alcuni.
Per calcolare tutte le uscite , devo aggiungere altri blocchi che usano l’operatore <>.
Nell’aggiungere questi blocchi che servono a calcolare le altre uscite intermedie , devo fare
attenzione a non incrementare il ritardo rispetto a quello relativo all’ultima uscita . In questo caso il
ritardo massimo è 3 e non devo uscire fuori altrimenti perdo vantaggio.
Per calcolare i riporti intermedi uso un albero inverso :
Vediamo in grigio scuro i blocchi che avevamo prima.. Per calcolare altre uscite intermedie ,
aggiungo blocchetti in grigio chiaro . La particolarità è che questi blocchetti sono tali che ad ogni
livello ho sempre lo stesso numero di blocchi , il layout è regolare anche se le interconnessioni non
lo sono. L’uscita in rosso , rappresenta gli ingressi da 0 a 2. Per gli indici da 0 a 3 è quello in blu,.
Da 0 a 4 è quella in arancio.
Supponiamo vogliamo vedere l’uscita che rappresenta gli ingressi da 0 a 6 devo trattare tutti gli
ingressi con pedice che va da 0 a 6.
In realtà esistono differenti modi con i quali è possibile collegare questi blocchetti per risolvere il
problema parallel prefix. Queste tipologie si ottengono collegando in maniera diversa questi blocchi
:
Lo schema iniziale (in
alto a sinistra) viene
riportato in forma
semplificata con grafo in
verde. Non entriamo nel
dettaglio.
A lato vediamo lo schema dell’adder
parallel-prefix di Ladner-Fischer.
Tutte queste varie strutture hanno tutte lo stesso ritardo log 2 di N ma differiscono di qualcosa.
(slide 48).
La cella di coordinate 2,2 , ha fan out
elevato perché deve pilotare 4 celle
successive disposte in | : è più lenta
di quanto ci si aspetta. La struttura
seguente :
Ogni cella ha fan out solo di 2 .
Otteniamo lo stesso risultato , usando
più cellette , ma con fan out ridotto a
2. È la più veloce .
Confronto fra gli addizionatori
Carry ripple (ritardo proporzionale ad N). N full-adders. Layout semplice e regolare:
utilizzato quando non è necessaria elevata velocità.
Carry select (ritardo proporzionale alla radice quadrata di N). Ha un’area circa doppia
rispetto ad un carry-ripple.
Carry skip (ritardo proporzionale alla radice quadrata di N).Poco più lento di un carryselect. Occupa meno area di un carry select.
Carry lookahead (ritardo proporzionale al logaritmo di N).
Strutture adoperate in sistemi VLSI: parallel-prefix con celle base molto semplici e veloci. KoggeStone: fast CLA (fan-out minimo per ogni cella). Elevata occupazione di area. Scarsa regolarità del
layout.
I carry lookhead sono i più veloci ; c’è della logica semplice ( porta AND e porta ANDOR ). Alcune
come la kogge stone riducono il fan out per ogni cella.
Addizionatori multi-operando
Supponiamo di fare la
somma di 4 word. Come
faccio? Uso un certo
numero di addizionatori non
uno solo . L’approccio più
semplice è di usare un ADD
per calcolare A+B , un altro
per sommare al risultato C ,
l’altro per sommare D .
Altra soluzione è fare A+B
parallelamente alla somma
C+D per poi sommare.
Supponiamo che gli adder sono a propagazione del riporto. Usiamo la struttura più semplice
con l’adder più semplice :
Notiamo che la somma tra A e B mi
produce bit aggiuntivo : questo perché
bisogna tener presente che 2 termini
da 4 bit danno luogo ad un uscita su 5
bit. Quelli aggiuntivi li metto a massa.
Il ritardo massimo mi aspetto sia di
12. Nessun cammino individuabile
però passa attraverso tutti gli ADD .
Vediamo in slide diversi cammini
critici . Per quanto possiamo
cambiare le possibilità , il cammino
attraversa solo 8 full. Il ritardo
massimo è meno pesante! Per come
è realizzata la struttura quindi , non si
sommano i ritardi dei 3 full adder. Il
problema è che se vogliamo
rendere questo adder multi
operando più veloce , devo rendere più veloci tutti gli adder che lo compongono.
Ci viene allora in
soccorso la tecnica
carry-save che viene
usata per fare delle
somme di più operandi.
Questa tecnica segue
anch’essa l’algoritmo
come la scuola
elementare se devo
somare più numeri, ad
esempio 324 e 741,
come faccio?
Manualmente non
sommo i primi
due(324 e 741) , ma
comincio a sommare
tutte le cifre dello
stesso peso che si
trovano in verticale.
Ottengo una cifra di somma e un riporto che devo sommare sulla colonna a sinistra. Questa
tecnica viene adottata nelle strutture carry save. Comincio a sommare tutti i bit di peso 0. Sono 4 :
a0 – d0 . non esiste un full adder con 4 ingressi ecco perché ci vuole qualcosa di più complicato.
Ottengo un bit somma che ha lo stesso peso degli altri ( 0 visto che abbiamo iniziato con ingressi
a0-d0) e un bit di riporto che ha peso 1. Il risultato della somma , va sommato con d0 (bit a peso
0) che mi da y0 che è la cifra meno significativa.
Bit peso 1 : sono a1 b1 c1 a cui sommo il riporto precedente di peso 1 e l’altro bit d1. Il bit di
riporto non lo invio al full adder che si trova a sinistra, ma lo invio al full di sotto. È la stessa cosa
perché in quella colonna sommo bit di peso 1 ! quelli che vengono dagli stadi precedenti li sommo
più in basso in modo che arrivano segnali già ritardati.In questo caso mettendolo sotto ottengo
risultato con ritardo più piccolo. Ho 2 termini di peso 1 .
Bit peso 2 ,3 4 : i segnali di peso 2 3 e 4 si devono sommare tra di loro. Uso addizionatore VMA
(Vector Merging Adder) e serve per fare somma complessiva per ottenere uscita complessiva.
Il vantaggio di questa struttura è che ho un unico addizionatore dove il riporto effettivamente si
propaga da uno stadio all’addizionatore . L’addizionatore è l’elemento critico e lo posso fare con
tecnica veloce ( se devo andare veloce ) .
I full che stanno sopra danno luogo a propagazione verticale e il ritardo massimo in verticale è
pari al numero
di termini ( 10
parole da 64 bit
da sommare ,
ritardo
proporzionale a
10. ) il ritardo va
con log di
ognuna delle
parole da
sommare . Il
ritardo della
struttura.
Moltiplicatori
Vediamo qual è il metodo con il quale realizzare la moltiplicazione di 2 numeri binari :
Supponiamo che i numeri sono unsigned
positivi. L’algoritmo sarà modificato nel caso di
prodotto di numeri con segno. Seguiamo
l’algoritmo elementare : allineo e faccio prodotti.
Il risultato lo metto su prima riga. Procedo per
altre cifre. Il termine 1 in grigio chiaro da luogo
al termine grigio chiaro .
La moltiplicazione si realizza calcolando i
prodotti parziali che si hanno facendo i
prodotti tra le singole cifre del moltiplicatore
e poi sommando i prodotti parziali.
Il calcolo dei prodotti parziali lo posso realizzare come una AND:
Due operandi ad N-bit: risultato su 2N bit
Sono necessarie N2 porte AND a due ingressi per calcolare i prodotti parziali
I prodotti parziali devono poi essere sommati fra loro per ottenere il prodotto.
Vediamo la prima struttura semplice : moltiplicatore a matrice
Questo tipo di
circuito
realizza uno a
uno l’algoritmo
elementare
della
moltiplicazione
. Porto un
esempio di
due operandi
a 3 bit.
Il circuito che
viene fuori è
riportato sulla
destra.
Abbiamo un
insieme di
cellette. Ce ne
sono 3 su ogni
riga. Una ogni riga è sfalsata dalla superiore di una unità . gli ingressi a0 a1 a2 , viaggiano in
orizzontale su queste righe ma gli altri ingressi vanno in diagonale.
Cosa ci sarà in questa generica celletta? Nella cellette ci sarà una porta AND , che calcola il
prodotto parziale bj and ai .Se ho N^2 cellette ,avrò N^2 prodotti parziali che devono essere
sommati fra di loro.
Per sommarli introduco nella celletta un full adder. Questo , somma il prodotto parziale con altri
due segnali uno che viene alla destra della cella e uno che viene dalla parte superiore della cella
stessa.
Visivamente queste celle sono
posizionate cosi come erano
posizionati i termini prodotti parziali
di 4. Devo avere cura di sommare
termini dello stesso peso.
Qual’è il ritardo del moltiplicatore?
Questa analisi è semplificata :
Vediamo , come esempio far vedere che le celle non sono tra di loro uguali , un moltiplicatore su 4
bit :
Vediamo una struttura che realizza la somma dei prodotti parziali con tecnica carry save che
abbiamo visto prima :
Ottengo in uscita i bit significativi direttamente mentre , per le altre coppie di bit di peso omologo,
esse devono essere sommate nel VMA in maniera analoga nel caso dell’ addizionatore multi
operando carry save.
Le celle elementare sono le stesse ma abbiamo l’elemento in più ovvero il VMA addizionatore che
non c’era e che ora compare. Qual è il ritardo di questo sistema? Dobbiamo attraversare N
blocchi per avere gli ingressi del VMA quindi il ritardo è pari a N Tb + VMA ritardo.
Questo è un
esempio del
possibile cammino
critico. Le celle le
attraverso in
diagonale o in
verticale tanto
comunque sono
sempre N per
ottenere gli
operandi del VMA.
Il VMA opera su 2
ingressi che sono
da N bit. L’uscita
complessiva è 2n
bit. Se faccio
questo ADD a
propagazione del
riporto il ritardo è
proporzionale a N ,
quindi il ritardo di questo va con 2N. avremmo già un miglioramento rispetto alla struttura a matrice
di prima dove c’era 3n. il miglioramento massimo l abbiamo se anziché carry ripple mettiamo
addizionatore veloce.
Seconda formula , predomina il fattore NTB.
Con questo tipo di circuito riesco a realizzare contemporaneamente una modifica : un
moltiplicatore accumulatore. Un circuito che calcola al tempo stesso a per b e la somma. A*B +
C.
Cio è utile perché calcola somma e prodotto nello stesso tempo nel quale calcolerei solo il prodotto
: la somma ci viene gratis.
Se riprendo la struttura carry save di prima osservo che sulla prima riga e anche su due celle a
sinistra diagonale , ci sono ingressi posti a zero che non servono , inutilizzati. Nel caso del
moltiplicatore accumulatore , posso sfruttare questi ingressi per sommare la parola C come in
slide 12 :
In questo modo il mio sistema calcola prodotto e somma e la complessità è esattamente la stessa.
I moltiplicatori sono importanti nel calcolo di operazioni signal processing. Spesso devono operare
a frequenze di clock molto elevate. Abbiamo visto a suo tempo che per aumentare la f di clock di
un sistema si può usare la tecnica del pipelining : essa spezza il cammino critico quando si hanno
più blocchi combinatori in cascata introducendo 2 registri in grigio scuro dell’esempio :
Il ritardo si riduce perché il ritardo massimo combinatorio nel primo caso è la somma nel secondo
quello che gioca è il massimo di quei 3 ritardi. Si può avere un miglioramento che viene pagato in
latenza perché l’uscita non è disponibile immediatamente ma ci vogliono più cicli di clock per avere
l’uscita.
Questa techica è efficace se blocchi FGH hanno lo stesso ritardo. Per spezzare in maniera
uniforme il ritardo.
Vediamo se riesco ad applicare la tecnica al moltiplicatore carry save : devo ricostruire la struttura
iniziale ovvero tanti blocchi combinatori uno dietro l altro , inserisco tagli per spezzare il cammino
dei dati e dove ci sono i tagli inserisco i registri di pipelining.
Per realizzare correttamente e il pipelining del moltiplicatore dobbiamo riconduci a quella
struttura :
Nella struttura di partenza in 12 non è ovvio perchè alcuni dati piovono da sopra ( B e C) altri
arrivano a metà ( a1 , a2 ) apparentemente non seguono quella struttura in cascata vista prima.
Per ricondurci , dobbiamo fare operazioni su questo schema 12 altrimenti il risultato è scorretto.
Riporto tutti i segnali di ingresso da una stessa parte come in slide . Devo riportare sopra
perché e già ci stanno. Lo stesso per
. Una prima modifica è di riportare in 14 tutti i
segnali sopra. Posso pensare di inserire un registro di pipeline usando taglio in ---------- spezza in
due il flusso dei dati e ogni volta in cui linea orizzontale interseca segnale metto un registro di
pipeline , registri che sono segnati con dei pallini neri .
Quanti cicli per risultato? 5 cicli ( considerando anche ingresso).
Quale’è il ritardo del circuito? Vogliamo cioè sapere la F di clock al quale si può far operare
questo sistema. Bisogna vedere cosa c’è tra registro e registro successivo. Vediamo che in questi
primi tagli , tra un registro e l’altro c’è un singolo blocco dove c’è nd e full adder. Questo ritardo è lo
stesso in questi primi 3 tagli riportati. Nell’ultimo taglio trovo il VMA tra registro e suo successivo. Il
periodo di CK allora come lo stimo ?
Questa formula mi da il periodo del CK. Nel massimo normalmente vince Tvma perché il ritardo
del singolo blocco non compete con un ritardo di un addizionatore a N bit. Da questo punto di vista
, questo pipeline è stato fatto in maniera perfetta o migliorare? Nel caso migliore , tanti blocchi in
cascata sono in grado di spezzare in modo che ho ritardo fra i vari blocchi uguale. In questo caso
ho che il ritardo del blocco è una frazione del ritardo del VMA , non ha senso spezzare in
maniera cosi fine
Posso eliminare la seconda e la terza linea di taglio in modo da lasciare 3 registri : registro iniziale
, registro VMA e quello finale. Se levo queste due linee come cambia la formula di prima? Al posto
di tb avrei 3tb , magari dello stesso ordina di grandezza + Tvma , la freq di CK non la modifico ma
risparmio registri e riduco la latenza.
Se voglio salire ancora in fequenza posso pensare di introdurre pipelining nel VMA. VMA
pipelined. Dobbiamo allora mettere anche registri su uscite accanto a VMA per bilanciare le
latenza sull’uscita Y finale.
Già detto. Cambia il fattore che metto accanto a. TB.
Si debba effettuare la moltiplicazione di due numeri rappresentati in complementi alla base
Consideriamo un esempio con numeri rappresentati su tre soli bit.
L’algoritmo della moltiplicazione in questo caso è
diverso, perché i numeri non sono signed! Per la
somma non c’era differenza, qui invece si. Si devono
adottare architetture diverse a seconda se abbiamo
numeri signed o unsigned. Facciamo un esempio su 3
bit: sappiamo che i pesi dei 3 bit valgono -4 per il
MSB, 2 e poi 1 per l’LSB.
Quando facciamo i prodotti parziali tra due generici
numeri su 3 bit otteniamo i prodotti parziali in slide. Si
noti che alcuni di questi saranno negativi perché
compaiono b2 e a2. Per ottenere il risultato finale,
dovrò sommare le prime 2 righe e l’ultima e sottrarre la
terza e la quarta. Questo ricordiamo che è dovuto alla presenza dei due contributi con segno (-).
In pratica per sottrarre, sommiamo il numero cambiato di segno.
Osservazione importante: il risultato finale del nostro prodotto sarà su 6 bit, quindi nell’effettuare
questa operazione bisogna stare attenti a
rappresentare questi due termini negativi
sui 6 BIT complessivi!!!
Ricordiamo che il numero di bit del
prodotto finale è ovviamente la somma
del numero di bit dei due termini.
L’estensione in segno è necessaria.
Per i termini col segno negativo quindi,
complementiamo tutti i bit, aggiungiamo
1 e poi estendiamo in segno:
In pratica, prendiamo i due numeri che dobbiamo sottrarre.
Complementiamo tutto, estendiamo in segno (aggiungendo un nuovo bit MSB pari a quello che
c’era prima: in slide dopo aver complementato avevo “1 a1b2 a0b2 1 “, quindi devo mettere: “1 1
a1b2 a0b2 1”) e sommo 1.
In complementi alla base allora, per scrivere un numero su più bit, devo prendere la cifra più
significativa (l’MSB) e aggiungo tanti di questi bit.
Ora, dopo aver complementato i due termini negativi, non mi resta che sommare tutto.
Osservazione: la sottrazione di questi 2 termini la posso ottenere anche come in slide, in cui ho
messo da parte l’aggiunta degli 1 dell’estensione e l’1 che si deve sommare ogni volta che
complemento. Si noti che i termini sono costanti!! E allora, possiamo sommare a parte questo
fattore correttivo che sarà costante.
Fatto ciò:
in definitiva sommerò tutto e aggiungerò questa costante alla fine che tiene conto della
complementazione e dell’estensione in segno!!! In pratica il prodotto viene ottenuto semplicemente
sommando questi termini e aggiungendo quel fattore correttivo finale. Il vantaggio è che alcuni di
questi termini vengono realizzati con delle NAND e non AND, in più ovviamente devo sommare
una costante.
Posso ordinare i vari termini per vedere il tutto su 4 righe. Questa rappresenta la matrice dei
prodotti parziali, ovvero l’insieme dei termini per realizzare il prodotto di due numeri con segno.
Il circuito corrispondente è uguale a quello di prima, ma alcune celle INVECE DELLA AND hanno
la NAND! In più devo sommare il termine costante. Osservando il termine costante, si scoprirà che
questo avrà soltanto 2 cifre diverse da 0. Se avessi fatto il calcolo su 12 bit, avrei avuto sempre
solo 2 bit diversi da 0!!! Il peso di questi termini è: uno è la cifra più significativa del VMA, l’altro è il
riporto entrante. Si noti che il VMA aveva sia il MSB che il riporto entrante LIBERI (quando avevo
numeri unsigned infatti questi erano posti a massa). Quindi l’aggiunta di questa costante ulteriore
non comporta nessun aggravio!!
Il moltiplicatore signed è solo una VARIANTE dell’unsigned, ha allora la stessa complessità e non
richiede nessun aggravio particolare di hw.
Come esercizio, pensiamo a quale potrebbe essere la struttura di un moltiplicatore in cui uno dei
due operandi è
unsigned e l’altro è
signed! Sarà un’altra
variante. Si noti che
la struttura del
moltiplicatore non è
sempre la stessa, per
decidere quale
architettura
implementare devo
sapere a priori quali
numeri trattare!
La velocità del nostro circuito rimane vincolato alla velocità del VMA e a NTb, dove Tb è il ritardo
del singolo blocco e N c’è perché ho il riporto che si propaga in N blocchi. Nella struttura carrysave infatti il riporto si propaga in verticale e orizzontale. Il ritardo del VMA lo facciamo logaritmico
usando gli adder veloci studiati, il collo di bottiglia rimane allora la propagazione del riporto nei
blocchi. Rimane quindi una funzione lineare di N. è importante avere dei moltiplicatori veloci,
sono state sviluppate tecniche per avere moltiplicatori con ritardo funzione del log(N).
Moltiplicatori veloci, o ad albero.
Consideriamo di nuovo la moltiplicazione tra numeri unsigned. Le stesse tecniche possono essere
adoperate anche con i signed, le differenze sono minimali. Ovviamente il punto su cui agire è il
termine NTb. Consideriamo un esempio di
moltiplicatore 5x5. Rappresentiamo i
termini con puntini. L’insieme di puntini lo
chiamo matrice dei prodotti parziali.
L’altezza è il numero di righe della matrice,
pari proprio al numero di bit dei numeri.
Applico una serie di trasformazioni sulla
matrice ottenendo matrici equivalenti nel
senso che poi sommandole ottengo lo stesso risultato.
Moltiplicatore di Wallace
Riduco la matrice dei prodotti parziali, utilizzando full-adder ed
half-adder per sommare fra loro termini dello stesso peso. Il
termine a0b0 è l’unico con peso 0 e lo porto direttamente al
livello
successivo. I due termini di peso 1 vengono sommati da un
half-adder, producendo un bit somma,
ancora di peso 1, ed un bit carry di peso 2.
(Il rettangolo in figura rappresenta un half-adder)
Parto dal bit meno significativo. Questo mi dà proprio Y0,
quindi lo devo riportare pari pari in uscita. Passiamo ora ai
termini di peso 21. Uso un half-adder e sommo i due contributi evidenziati con un rettangolo, l’halfadder (lo rappresento col quadrato) restituirà 2 termini di peso diverso (somma e cout).
I tre termini di peso 2 vengono sommati da un full-adder,
producendo un bit somma, ancora di peso 2, ed un bit carry di
peso 3. (l’ellisse in figura rappresenta un full-adder)
Qualora sia possibile, è meglio utilizzare dei full-adder, che
riducono il numero dei prodotti
parziali (da 3 a 2): full-adder = compressore 3->2.
Procediamo allo stesso modo per i bit di peso maggiore. L’altezza
della matrice dei prodotti parziali è passata da 5 a
4.
Applico la tecnica di riduzione alla nuova matrice dei prodotti
parziali
L’altezza della matrice dei prodotti parziali è passata da 4 a 3.
Facendo un altro passaggio, ottengo una matrice di prodotti parziali
di altezza 2.
Abbiamo finito: i 4 termini fuori dal riquadro azzurro sono proprio i
primi 4 bit meno significativi del prodotto!
I termini nel riquadro azzurro sono gli ingressi del VMA che calcolerà
le altre uscite dell’addizionatore!
Il tempo di propagazione è il ritardo del VMA a cui devo aggiungere il
ritardo per ottenere i due operandi! Nel caso peggiore passo
attraverso 3 full adder per ottenere i bit che stanno in fondo!! Infatti,
per passare da una matrice all’altra uso dei full-adder!
Allora il ritardo è come in slide! Questo è il moltiplicatore di Wallace:
applica ricorsivamente un algoritmo che riduce l’altezza della matrice
dei prodotti parziali.
Il ritardo quindi va come 3 volte il ritardo di un full adder, ovvero:
Tp=3 Tfa + TVMA
È difficile fare i conti in generale: però, si vede che passando da un livello al succesivo, riduco
l’altezza della matrice di un fattore 3/2 perché il full-adder è un compressore 32! (considerazione
euristica!!) In generale allora il ritardo sarà come in slide. Nota ke K è funzione del numero di bit
secondo un logaritmo in base 3/2! Abbiamo allora un ritardo ke cresce secondo un log di N (in
base 3/2). Il moltiplicatore di Wallace è molto più veloce di quello a matrice, l’inconveniente è che
tende ad usare un numero eccessivo di half-adder!! Esistono delle tecniche più efficienti che
mantenendo lo stesso ritardo, riducono il numero di half-adder utilizzati per realizzare il
moltiplicatore.
In generale, il tempo di propagazione è:
Tp = k Tfa + TVMA, con: k _ log3/2(N)
Moltiplicatore Dadda
Sono moltiplicatori che si basano sulla successione di Dadda.
All’ultimo livello, l’altezza della matrice dei prodotti parziali è: A0=2
Al livello precedente, l’altezza deve essere: A1=A0×3/2=2×3/2=3.
Al livello ancora precedente, l’altezza deve essere: A2=A1×3/2=3×3/2=9/2=4.5, non potendo avere
un’altezza frazionaria: A2=4.
In generale: An+1= floor((3/2)An) con: A0=2 dove la funzione floor( ) rappresenta
l’arrotondamento per difetto all’intero più vicino.
Successione di Dadda 2, 3, 4, 6, 9, 13, .....
Se, ad esempio, ad un certo livello dell’albero, l’altezza della matrice dei prodotti parziali è 5, al
passo successivo l’altezza della matrice sarà 4.
Posso sfruttare questa informazione per evitare di inserire half-adder e full-adder dove non è
strettamente necessario.
Moltiplicatore di Dadda
Esempio: partiamo da un moltiplicatore
5x5. L’altezza è 5, compresa tra 4 e 6.
Allo step successivo dovrò portarmi ad
un’altezza pari a 4 (secondo Dadda). E
allora, i termini corrispondenti alle
colonne 20, 21, 22, 23, li posso portare
pari pari allo step successivo perché
sono alti 4. Nella colonna 2 4 inserisco
un full-adder per ottenere un’altezza di
4. Metto un altro full-adder a sinistra
corrispondente alla colonna 2 5 perché
ho il carry proveniente dalla colonna
precedente. Nel primo step inserisco
solo 2 full-adder. Questo mi garantisce
un’altezza pari a 4, quella richiesta.
Passo successivo: l’altezza ora è 4.
Il termine successivo della serie di
Dadda è 3 quindi inserisco 4 fulladder (solo quelli STRETTAMENTE
NECESSARI) come in figura per
ottenere un’altezza pari a 3. I
moltiplicatori di Dadda quindi
utilizzano poca logica, solo adder
strettamente necessari.
Qui per arrivare ad un’altezza
di 2, metto 3 half adder e 3
full adder. Ho finito. Nota: gli
half-adder li troviamo
tipicamente agli ultimi step
Osservazione: con questa
tecnica, c’è un solo termine
che calcoliamo in maniera
esplicita (che sarebbe l’unico
pallino nero fuori dal VMA).
Gli altri termini, li ottengo col
VMA. Il Vector Merging Adder
opera quindi su un numero di
bit maggiori rispetto ai
moltiplicatori di Wallace. È uno svantaggio. Il vantaggio è che usiamo un numero inferiore di porte
logiche nei primi step di elaborazione. Lo svantaggio è che il VMA deve essere più grande.
Confronto moltiplicatori ad albero
Wallace vs. Dadda
La velocità è la stessa: Tp=3 Tfa + TVMA
Area Wallace: 9 full-adder + 12 half-adders + VMA a 6 bit
Area Dadda: 9 full-adder + 3 half-adder + VMA a 8 bit (più carry)
Nel confronto si vede che la velocità è la stessa, l’area è diversa: il Dadda è più piccola. D’altra
parte, il VMA ha 8 bit nel Dadda ed è più complicato. Esistono tantissimi algoritmi che sono varianti
che cercano di ottenere il meglio dai circuiti!! In ogni caso comunque, il ritardo è funzione del
logaritmo di N.
Array carry-save vs. Dadda
Velocità array carry-save: Tp=3 Tfa + Tha + TVMA
Velocità Dadda: Tp=3 Tfa + TVMA
Area array carry-save: 12 full-adder + 4 half-adders + VMA a 4 bit
Area Dadda: 9 full-adder + 3 half-adder + VMA a 8 bit
Facendo un confronto con un moltiplicatore carry-save, quest’ultimo non richiede meno hardware
rispetto a quello ad albero, facendo i conti sulle aree il carry-save è in vantaggio rispetto al Dadda,
è più piccolo!
I moltiplicatori ad albero sono più veloci degli array carry-save, senza richiedere un particolare
aumento di hardware.
La differenza di velocità diviene sempre più grande al crescere del numero di bit da sommare
I moltiplicatori ad albero possono essere facilmente modificati in modo da realizzare moltiplicatoriaccumulatori o per moltiplicare numeri in complementi alla base.
L’unico vantaggio dei moltiplicatori array carry-save è la regolarità, che consente di realizzare
circuiti full-custom molto compatti.
Con metodologie basate su celle standard, conviene sempre adoperare strutture ad albero.
I moltiplicatori ad albero in generale non sono più grandi di quelli a matrice ma sono molto più
veloci. Quando un moltiplicatore viene sintetizzato e realizzato con celle standard, in pratica viene
SEMPRE REALIZZATO CON UNA STURTTURA AD ALBERO perché non ho vantaggi con una
struttura a matrice, l’area è sempre la stessa ma è molto più veloce!
Allora perché li abbiamo studiati? Perché se dobbiamo realizzare moltiplicatori in maniera custom,
proprio perché le strutture carry-save sono regolari, io mi progetto la cella e poi faccio l’array delle
celle! Nella struttura ad albero non ho regolarità, i full adder sono piazzati un po’ ovunque! Se li
devo progettare a mano ha quindi senso la struttura carry-save.
Se uso il vhdl, verrà realizzata una struttura ad albero perché più efficiente. I moltiplicatori ad
albero sono quindi vincenti. L’unico vantaggio delle carry-save è la regolarità dal punto di vista di
layout.
Che cambia se devo fare un moltiplicatore di numeri con segno o un moltiplicatore-addizionatore?
Per esempio se volessi fare: Y=A*B+C. Posso farlo con una struttura ad albero?
È semplice, basta aggiungere un’altra riga nella matrice dei prodotti parziali dove ci sommo proprio
il termine C. se devo fare Y=A*B+C+D aggiungo un’altra riga per D.
Se devo fare A*B con A e B in complementi alla base, signed, cosa cambia?
Alla fine comunque devo sommare dei termini, in pratica ci saranno dei termini con delle AND e
altri con delle NAND. I famosi 1 da sommare per il complemento, sono delle semplici costanti da
sommare.