Capitolo 1 RETI LOGICHE E ALGEBRA DELLA COMMUTAZIONE 1.1 - Introduzione Informazione è ciò che si conosce di una determinata realtà; per esprimere questa conoscenza occorre un criterio (codice) di rappresentazione, che sia correlato in maniera adeguata alla natura e alle proprietà della realtà in esame. Per esempio se si considera la geometria, l’informazione è costituita dalla conoscenza delle proprietà metriche delle figure ed è convenientemente rappresentata da numeri. Nel rispetto delle proprietà del codice, l’informazione può essere manipolata per ottenerne di nuova, accrescendo il livello di conoscenza sulla realtà di interesse: questo processo é detto elaborazione dell’informazione; tornando all’esempio della geometria, quando si addizionano due numeri che rappresentano la misura di due grandezze omogenee, si esegue un’elaborazione il cui risultato è un nuovo numero che viene interpretato come misura della grandezza somma delle due grandezze date. L’elaborazione può essere compiuta da sistemi naturali, primo tra tutti la mente umana, oppure da sistemi artificiali, dei quali il più noto e complesso è il calcolatore. I sistemi artificiali, a seconda della capacità di elaborazione che devono possedere, possono avere complessità strutturali e funzionali molto differenti, ma tutti sono riconducibili ad un unico modello denominato rete logica. Una rete logica può essere schematizzata esternamente come una scatola (in inglese black box) con n punti di ingresso ed m punti di uscita, attraverso i quali la rete scambia informazione con l’ambiente: l’informazione viene introdotta nella rete applicando ai punti di entrata n segnali di ingresso x0, x1, …, xn-1 e viene fatta uscire come risultato dell’elaborazione prelevando dai punti di uscita m segnali di uscita z0, z1, …, zm-1; in altri termini i segnali di -1- ingresso codificano l’informazione che deve essere elaborata dalla rete, quelli di uscita l’informazione prodotta dall’elaborazione (Fig. 1.1). Anche all’interno alla rete, durante il suo funzionamento, sono presenti segnali che codificano l’informazione nel suo fluire dall’ingresso verso l’uscita nel processo di elaborazione. Poiché con la tecnologia attuale le reti logiche sono realizzate convenientemente sotto forma di circuiti elettronici, tutti i segnali in gioco sono di natura elettrica e magnetica e si fa in modo che possano assumere solo valori discreti in numero finito e quindi possano codificare solo l’informazione istanziabile dall’insieme finito di combinazioni di quei valori. Per esempio un segnale a due valori può codificare l’informazione relativa allo stato (aperto o chiuso) di un interruttore, oppure allo stato (acceso o spento) di una lampada. Si tratta di segnali digitali, così detti in riferimento alle cifre (in inglese digits) di un sistema di numerazione, che sono appunto in numero finito. x0 x1 rete logica xn-1 z0 z1 zm-1 Fig. 1.1 I segnali digitali sono funzioni del tempo continue a tratti, assumendo valori costanti per certi intervalli di tempo e cambiando bruscamente alla fine di ogni intervallo, con un andamento formato da una successione di gradini, in generale di varia durata e variamente distanziati (Fig. 1.2a). Per questo comportamento i segnali digitali si differenziano dai segnali analogici, che matematicamente sono funzioni del tempo continue e derivabili (Fig. 1.2b) e si ritrovano nella maggior parte dei sistemi fisici, naturali o artificiali. f(t) f(t) t t0 t1 t t2 t3 t4 t5 t6 t7 a) segnale digitale b) segnale analogico Fig. 1.2 Per le reti logiche hanno pratico interesse solo i segnali digitali binari, ovvero quei segnali che possono assumere solo due valori. Questa limitazione dipende da due ragioni principali: una è di natura tecnologica, in quanto è molto più facile realizzare dispositivi che lavorano con segnali binari, che non costruire dispositivi in grado di operare su segnali a più di due valori. L’altra ragione è di carattere logico e su di essa torneremo ampiamente in seguito. Riguardo alla durata degli intervalli in cui un segnale binario si mantiene ad un valore -2- stabile, si distingue tra segnali a livelli e segnali ad impulsi. La differenza tra i due tipi non è peraltro assoluta, ma è in relazione al fatto che una rete logica risponde in uscita con un certo ritardo ∆R rispetto all’istante in cui si verifica una variazione di ingresso: se un segnale di ingresso mantiene il proprio valore stabile per un tempo più lungo di tale ritardo, è da considerare a livelli, altrimenti è trattato come un segnale ad impulsi (Fig. 1.3). ∆R segnale a livelli ∆R segnale a impulsi t Fig. 1.3 Quando l’andamento di un segnale digitale è costituito da una successione di impulsi della stessa durata che si ripetono con cadenza costante, il segnale è detto periodico (Fig. 1.4). f(t) t segnale digitale periodico Fig. 1.4 Quanto detto circa la ripidità dei fronti di salita e di discesa dei segnali digitali è puramente ideale, poiché nella realtà, a causa di fenomeni parassiti e inerziali, il valore dei segnali non può cambiare istantaneamente nè in un verso nè nell’altro, ma richiede un tempo non nullo sia in salita (tempo di salita, setup time, rise time) che in discesa (tempo di discesa, reset time, fall time). Volendo conservare l’aderenza al modello ideale (segnali con fronti ripidi) e al tempo stesso tenere conto dell’andamento reale, al posto dell’intervallo T in cui il livello del segnale rimane fisso consideriamo l’intervallo T’che include anche il tempo di salita e quello di discesa nel seguente modo. Se V1 e V2 sono rispettivamente il valore minimo e massimo del segnale, con tempo di salita si intende il tempo necessario perchè il segnale si porti da un valore che supera V1 del 10% del valore finale V2 ad un valore non inferiore al 90% di V2; analogamente il tempo di discesa è il tempo impiegato dal segnale per passare da un valore pari al 90% del livello V2 ad un valore che supera V1 del 10% di V2 (Fig. 1.5)). L’intervallo T’ in generale è più lungo di T e inizia in ritardo di ts. -3- segnale ideale T T V2 V1 0.9V2 0.1V2 ts segnale reale td segnale idealizzato T' Fig. 1.5 Torniamo a considerare le reti logiche dal punto di vista matematico, al fine di ricavare un modello funzionale che ne spieghi la capacità di elaborazione. Ci riferiamo ad una branca della matematica, la logica, che ha come oggetto di indagine le proposizioni logiche e le loro proprietà e costruisce regole (connettivi logici) per combinarle in nuove proposizioni; in questo senso si può affermare che essa realizza una semplice forma di elaborazione dell’informazione. Per la logica una proposizione è una frase della quale è possibile stabilire in modo non ambiguo e senza contraddizioni la verità o la falsità; per esempio le frasi: “il sole risplende” e “gli uomini hanno quattro mani” sono proposizioni nel senso della logica, dal momento che la prima può essere vera o falsa e la seconda è sempre falsa. La frase “tutti gli uomini sono alti” non è una proposizione in quanto è ambigua, mancando il riferimento rispetto al quale l’altezza è valutata, e neppure è una proposizione la frase “è falso che in questo momento io stia leggendo” in quanto contraddice se stessa. Astraendo dalla struttura sintattica delle proposizioni, ma considerandone solo la verità o la falsità, possiamo indicarle in modo sintetico con lettere dell’alfabeto, alle quali risultano associati i valori di verità delle proposizioni stesse; in questo senso le lettere assumono il ruolo di variabili e precisamente di variabili logiche i cui valori appartengono ad un insieme B di due soli elementi, indicati con la notazione inglese T (true) ed F (false), oppure più frequentemente con la notazione 1 e 0. Ne segue che un connettivo logico è una funzione f che ha per argomenti variabili logiche e definisce una variabile logica; si tratta di una funzione definita nel dominio B, a valori nel codominio B, ovvero f: B → B. Le funzioni logiche possono essere realizzate con i dispositivi che abbiamo chiamato reti logiche, associando variabili logiche e segnali: poichè le variabili logiche hanno solo due valori, è sufficiente che anche i segnali associati abbiano solo due valori e questa è l’altra ragione della quale si è parlato circa il fatto che si considerano solo segnali binari. Nel seguito faremo riferimento a segnali o a variabili logiche indifferentemente ed una rete fisica che manipola segnali potrà essere considerata in modo astratto come una funzione logica su -4- variabili logiche. Da qui discende che, ai fini del progetto logico delle reti, i valori effettivi dei segnali, da associare ai valori logici T ed F, non hanno importanza, purchè siano sufficientemente differenti per non creare ambiguità di riconoscimento da parte delle reti stesse. Per esempio se un segnale-tensione può variare nell’intervallo 0÷5 V, possiamo convenire di associare al valore logico F qualsiasi livello di tensione compreso nella fascia 0÷1V, al valore logico T qualsiasi livello nella fascia 4.5÷ 5.5V o viceversa, considerando invece logicamente ambigui, e quindi proibiti, i livelli tra 1 e 4.5 V (Fig. 1.6). V 5 4 3 2 1 0 T livelli proibiti F t Fig. 1.6 Le variabili logiche, oltre a rappresentare segnali, possono anche rappresentare la condizione o stato in cui si trovano elementi di commutazione (switch). Un commutatore S può essere chiuso, ossia può fare fluire corrente in un circuito, ed il suo stato è on, rappresentato dal valore T di una variabile logica s; oppure può essere aperto e non consentire il passaggio della corrente: il suo stato è allora off, rappresentato con il valore F della stessa variabile s. Per studiare le reti logiche si ricorre all’algebra booleana che, sviluppata intorno alla metà del XIX secolo dal matematico inglese George Boole per studi sulla logica, da poco più di mezzo secolo, fondamentalmente per opera di Shannon (1938), è applicata in una sua variante in questo contesto. Questa variante viene chiamata algebra della commutazione. -5- 1.2 - Algebra della commutazione 1.2.1 - Operatori fondamentali e porte logiche L’algebra della commutazione definisce due postulati fondamentali: il postulato dell’operatore di moltiplicazione logica e quello dell’operatore di addizione logica. La loro descrizione funzionale è fatta mediante tavole di verità, tabelle nelle quali ad ogni combinazione dei valori delle variabili-operando sono associati i valori delle variabili generate dall’applicazione degli operatori. Ricordando che una sequenza di cifre binarie costituisce la rappresentazione biunivoca in base 2 di un numero naturale, le combinazioni dei valori binari degli operandi possono essere interpretate come le rappresentazioni binarie degli interi nell’intervallo [0, 2n), essendo n il numero degli operandi, e quindi una tabella di verità può essere organizzata ordinando tali combinazioni secondo la successione naturale. In particolare dette x, y, z tre variabili logiche, le tavole di verità dei postulati fondamentali sono le seguenti: a) Postulato della moltiplicazione logica: z = x·y o semplicemente z = xy: x 0 0 1 1 y z = x·y 0 0 1 0 0 0 1 1 b) Postulato dell’addizione logica: z = x+y: x 0 0 y z = x+y 0 0 1 1 1 1 0 1 1 1 Esiste un terzo postulato, o della complementazione, definito nel seguente modo; data una variabile x, la variabile di valore opposto z = x, detta complemento o negazione di x, è descritta attraverso la tavola di verità: x z=x 0 1 1 0 Gli operatori di moltiplicazione e addizione corrispondono ai connettivi di congiunzione e -6- disgiunzione della logica delle proposizioni e alle operazioni di intersezione ed unione dell’algebra degli insiemi; analogamente il concetto di complemento di una variabile trova i suoi equivalenti nei concetti di proposizione negata e di complemento di un insieme. Passando all’ambito delle reti logiche, agli operatori moltiplicazione e addizione logici corrispondono due reti elementari che li realizzano e sono dette porta logica AND e porta logica OR, o semplicemente AND e OR (in inglese AND-gate e OR-gate). La porta AND possiede due segnali di ingresso x ed y ed uno di uscita z il quale assume valore 1 se e solo se entrambi i segnali di ingresso valgono 1, in accordo alla definizione di moltiplicazione logico. Analogamente la porta OR possiede due segnali di ingresso x ed y ed uno di uscita z il quale vale 0 se e solo se entrambi gli ingressi valgono 0, come è affermato dalla definizione di addizione logica. Il concetto di AND e di OR può essere esteso ad un numero di ingressi n > 2; in tal caso l’uscita della porta assumerà valore 1 o 0 se e solo se tutti gli n ingressi assumono contemporaneamente valore 1 o 0, rispettivamente per la porta AND e per la porta OR. Infine all’operatore di complementazione corrisponde una rete chiamata invertitore o porta NOT: essa possiede un solo ingresso x ed una uscita z, la quale assume valore 1 se l’ingresso ha valore 0 e viceversa. La figura seguente riporta i simboli usati per rappresentare le porte logiche. x y z = x·y AND x y z = x+y OR x z=x NOT Fig. 1.7 1.2.2 - Principio di dualità Osservando le tavole di verità della moltiplicazione logica e dell’addizione logica, è immediato verificare che, mentre la moltiplicazione dà risultato 1 solo se entrambi gli operandi valgono 1, l’addizione dà risultato 0 solo nel caso che gli operandi siano 0. La possibilità di trasferire un ragionamento fatto su uno dei due operatori all’altro operatore semplicemente scambiando i termini moltiplicazione e addizione e 0 e 1 non è casuale, bensì è un fatto proprio dell’algebra della commutazione, e più in generale di qualunque algebra di Boole, noto come principio di dualità, e può essere formulato come segue: Se una proposizione dell’algebra, il cui enunciato coinvolge solo gli operatori + e · , è vera, rimane tale se si scambiano i termini moltiplicazione e addizione tra di loro e le costanti 0 ed 1 tra di loro, ovunque nell’enunciato. È opportuno sottolineare che il principio di dualità non è un postulato nè un teorema, bensì una proprietà (o metateorema secondo McCluskey) di cui godono teoremi e postulati -7- dell’algebra e che può essere utilmente sfruttata per la loro definizione e dimostrazione; la dualità è una caratteristica intrinseca alla definizione degli operatori moltiplicazione logica e addizione logica ed esprime la simmetria esistente nelle strutture algebriche che possono essere costruite sull’insieme B. Un’immediata applicazione del principio di dualità si trova stabilendo le seguenti proposizioni, che costituiscono le proprietà fondamentali delle costanti logiche; tali proposizioni sono elencate a coppie, in quanto l’una è deducibile dall’altra per il principio di dualità: x = 0 se x = 1 x = 1 se x = 0 Le seguenti ulteriori proprietà delle costanti logiche, a coppie duali, possono essere stabilite da una diversa definizione della moltiplicazione, dell’addizione e della complementazione logici: 0·0 = 0 0+0 = 0 1·0 = 0·1 = 0 0=1 1+1 = 1 1·1 = 1 0+1 = 1+0 = 1 1=0 1.2.3 - Teoremi fondamentali dell’algebra della commutazione Introduciamo ora i teoremi e le proprietà fondamentali. Della maggior parte di essi esistono le due forme duali e in tale doppia formulazione saranno enunciati. Per quanto riguarda la dimostrazione, può essere seguito il metodo della induzione perfetta, ovvero per dimostrare un teorema se ne prova la validità per tutte le possibili combinazioni dei valori delle variabili, cosa possibile essendo l’insieme B finito. In alternativa è possibile una dimostrazione algebrica, ottenuta sfruttando i postulati, teoremi e proprietà precedentemente definiti e dimostrati, nonchè le proprietà delle costanti 0 e 1. Per la dimostrazione algebrica si rimanda all’Appendice. 1.2.3.1 - Teoremi di una variabile • Teorema dell’elemento indifferente e dell’elemento nullo x·1 = x x+1 = 1 x+0 = x x·0 = 0 •Teorema della complementazione x+x = 1 x·x = 0 x+x = x x·x = x • Teorema di idempotenza • Teorema di involuzione (x) = x -8- 1.2.3.2 - Teoremi di due o più variabili •Proprietà commutativa x+y = y+x x·y = y·x • Proprietà associativa x+(y+z) = (x+y)+z = x+y+z x·(y·z) = (x·y)·z = x·y·z • Proprietà distributiva x·(y+z) = (x·y)+(x·z ) x+(y·z) = (x+y)·(x+z ) • Proprietà di assorbimento x+x ·y = x x·(x+y) = x • Proprietà del consenso x·y+x·z+y·z = x·y+x·z (x+y)·(x+z)(y+z) = (x+y)·(x+z) Gli enunciati algebrici precedenti hanno una immediata interpretazione alla luce delle reti logiche; per esempio la proprietà associativa dell’addizione logica stabilisce l’equivalenza tra le tre reti illustrate nella parte superiore della Fig. 1.8; analogamente la proprietà distributiva esprime il fatto che le reti nella parte inferiore della stessa figura sono funzionalmente equivalenti: x y x y z x y z z a) Proprietà associativa x y x y z x z b) Proprietà distributiva Fig. 1.8 1.2.4 - Funzioni ed espressioni logiche Riprendendo i concetti introdotti nel paragrafo 1.1, siano date n variabili logiche x0, x1, ..., xn-1; una funzione logica (booleana) di tali variabili è una legge f che fa corrispondere ad ogni combinazione di valori di esse uno ed un solo valore di una variabile logica z e si indica con z = f(x0, x1, ..., xn-1) -9- Una funzione logica è rappresentata in modo implicito da una tavola di verità, in quanto questa specifica il valore della variabile dipendente z per ogni combinazione di valori binari delle variabili indipendenti, in modo simile a quanto visto per gli operatori fondamentali. In modo esplicito una funzione è data attraverso un’espressione algebrica, ovvero un’espressione nella quale variabili logiche e costanti sono legate tra loro dagli operatori logici; il valore di una funzione è ottenuto calcolandone l’espressione, ossia applicando agli operandi gli operatori logici secondo l’ordinamento naturale prioritario decrescente NOT, AND, OR. Tale ordinamento può essere alterato mediante l’uso delle parentesi, secondo le stesse regole dell’algebra dei reali. Ad una funzione logica f possono corrispondere più espressioni algebriche, formalmente diverse ma equivalenti tra loro; in particolare un’espressione algebrica può essere trasformata in un’altra più semplice, applicando opportunamente le proprietà dell’algebra. Per esempio consideriamo la seguente tavola di verità: a 0 0 0 0 1 1 1 1 b 0 0 1 1 0 0 1 1 c 0 1 0 1 0 1 0 1 z 0 0 1 0 1 1 1 0 essa rappresenta in forma implicita la funzione logica z = f(a,b,c) = (a+b+c)(a+b+c)(a+b+c)(a+b+c), come è possibile verificare per sostituzione diretta in essa dei valori 0 e 1. La rete di Fig. 1.9 è la sua realizzazione. a b c z Fig. 1.9 Nella figura i cerchietti su alcuni ingressi delle porte OR rappresentano in forma abbreviata il simbolo delle porte NOT richieste per complementare le variabili come richiesto dall’espressione; i pallini rappresentano punti in cui una linea si biforca, distribuendo in più - 10 - punti della rete lo stesso segnale (fan-out). 1.2.5 - Forme canoniche Tra tutte le espressioni algebriche equivalenti di una stessa funzione logica hanno particolare importanza due espressioni costruite a partire da due tipi di funzioni elementari, dette rispettivamente mintermini e maxtermini e definite come segue. Un mintermine o prodotto fondamentale pj è la funzione che vale 1 per la combinazione dei valori delle variabili x0, x1, ..., xn-1 che codifica in binario il numero naturale j, ovvero per * * * * x 0 x 1 …x n – 1 ≡ j , dove x i ∈ { 0, 1 }, i = 0, 1, …, n – 1 ; la sua espressione algebrica è costituita dalla moltiplicazione di n letterali derivati dalle n variabili con il criterio di scegliere la variabile xi affermata se vale 1 nella rappresentazione di j, negata se vale 0. Un maxtermine o somma fondamentale sk è la funzione che vale 0 per la combinazione dei valori delle variabili x0, x1, ..., xn-1 che codifica in binario il numero naturale k, ovvero per * * * * x 0 x 1 …x n – 1 ≡ k , con x i ∈ { 0, 1 }, i = 0, 1, …, n – 1 ; la sua espressione algebrica è costituita dall’addizione logica di n letterali derivati dalle n variabili con il criterio di scegliere la variabile xi negata se vale 1 nella rappresentazione di k, affermata se vale 0. Sia i mintermini che i maxtermini costruiti su n variabili sono 2n. Notare che i mintermini ed i maxtermini non hanno alcuna relazione diretta con una data funzione, ma sono esclusivamente definiti dal numero delle variabili . Le due espressioni costruite a partire dai mintermini o dai maxtermini prendono il nome di forme canoniche e sono definite nel modo seguente. La prima forma canonica o forma canonica SP (somma di prodotti) di una funzione f è la somma dei mintermini pj, corrispondenti alle combinazioni j per le quali f = 1. La seconda forma canonica o forma canonica PS (prodotto di somme) di una funzione f è il prodotto dei maxtermini sk, corrispondenti alle combinazioni k per le quali f = 0. Consideriamo per esempio la funzione logica definita dalla seguente tavola di verità. a 0 0 0 0 1 1 1 1 b 0 0 1 1 0 0 1 1 c 0 1 0 1 0 1 0 1 z 0 0 1 0 1 1 0 0 s0 s1 p2 s3 p4 p5 s6 s7 In corrispondenza di ogni riga in cui la funzione ha valore 1, scriviamo un termine ottenuto - 11 - come prodotto di tre letterali derivati dalle variabili a, b, c, prese in forma diretta (affermata) o complementata a seconda che figurino in quella riga con valore 1 o 0 rispettivamente; tale prodotto è uno dei mintermini della funzione. Analogamente per ogni riga per cui la funzione vale 0, si può scrivere un termine somma, ovvero un maxtermine, ottenuto come somma logica di tre letterali derivati dalle variabili a, b, c, complementate o affermate a seconda che figurino in quella riga rispettivamente con valore 1 o 0. Le due forme canoniche sono pertanto le seguenti: SP) PS) z = p2+p4+p5 = a·b·c+ a·b·c+a·b·c z = s0·s1·s3·s6·s7 = (a+b+c)·(a+b+c)·(a+b+c)·(a+b+c)·(a+b+c) Il procedimento descritto è un’applicazione del teorema di espansione di Shannon, la cui dimostrazione è facilmente condotta con il metodo della induzione perfetta: Una funzione logica di n variabili z = f(x0, x1 ..., xn-1) può essere decomposta nella somma di due funzioni di n-1 variabili, f(x0, x1 ..., xn-1) = xi·f(x0, x1, ..., xi-1, 0, xi+1, ..., xn-1)+xi·f(x0, x1, ..., xi-1, 1, xi+1, ..., xn-1), oppure nel prodotto di due funzioni di n-1 variabili, f(x0, x1, ..., xn-1) = (xi+f(x0, x1, ..., xi-1, 1, xi+1, ..., xn-1))·(xi+f(x0, x1, ..., xi-1, 0, xi+1, ..., xn-1)). Applicando iterativamente questo teorema, le forme canoniche SP e PS di una funzione z = f(x0, x1 ..., xn-1) sono esprimibili rispettivamente con le relazioni: fSP(x0, x1 ..., xn-1) = x0x1…xn-1f(1, 1, …, 1)+x0x1…xn-1f (1, 1, …, 0)+…+x0x1…xn-1f (0, 0, 2 –1 …, 1) +x0x1…xn-1f(0, 0, …, 0) = ∑ pi ⋅ f ( i ) ; i=0 fPS(x0, x1 ..., xn-1) = (x0+x1+…+xn-1+f(0, 0 ,…, 0))·(x0+x1+…+xn-1+f (0, 0, …, 1))·…· 2n – 1 (x0+x1+…xn-1+f(1, 1, …, 0))·...·(x0+x1+…+xn-1 +f(1, 1, …, 1)) = ∏ ( si + f ( i ) ) ; i=0 dove pi ed si sono rispettivamente i mintermini ed i maxtermini delle n variabili; le quantità * * * f ( i ) = f ( x 0, x 1, …, x n – 1 ) ∈ { 0, 1 } sono i valori che la funzione assume per le 2n possibili * * * * combinazioni binarie x 0 x 1 …x n – 1 delle variabili e x i ∈ { 0, 1 } . Ovviamente poichè alcuni di questi valori sono 0 ed altri 1, nella forma canonica SP figureranno, di tutti i mintermini possibili, solo quelli che garantiscono gli 1 della funzione; analogamente nella forma PS entreranno solo i maxtermini che garantiscono gli 0 della funzione. In generale, per una funzione di n variabili, supponendo di ordinarne le righe della tabella di verità da 0 a 2n-1, le forme canoniche si scrivono in forma abbreviata come segue: - 12 - fSP = Σn(m1, m2, ..., mk) fPS = Πn(M1, M2, ..., Mh) dove mi sono numeri naturali con 0 ≤ mi ≤ 2n-1, mi < mi+1, i = 1, ..., k, e k ≤ 2n-1 e Mj numeri naturali con 0 ≤ Mj ≤ 2n-1, Mj< Mj+1, j = 1, ..., h, e h ≤ 2n-1. Gli interi mi e Mj indicano le posizioni, riferite alle righe appropriate della tabella, rispettivamente dei mintermini e dei maxtermini di cui è costituita la funzione; l’indice n apposto ai simboli di sommatoria e di prodottoria specifica il numero delle variabili. Per esempio, per n = 3, la forma canonica espressa dalla notazione: Σ3(1, 3, 6) rappresenta la funzione logica z = abc + abc + abc E` facile rendersi conto che la forma canonica PS della stessa funzione è univocamente espressa, in modo implicito, come Π3(0, 2, 4, 5, 7), ovvero: z = (a + b + c)(a + b + c)(a + b + c )(a + b + c)(a + b + c) Ovviamente valgono le seguenti disuguaglianze: Σr(m1, m2, ..., mk) ≠ Σs(m1, m2, ..., mk) se r ≠ s Πr(M1, M2, ..., Mh) ≠ Πs(M1, M2, ..., Mh) se r ≠ s Vale la pena sottolineare anche che la fprma SP e la forma PS di una funzione f non sono l’una la duale dell’altra, come viceversa lo sono la somma ed il prodotto logico; tuttavia tra le due forme esiste una relazione che sarà illustrata nel seguito. Le forme canoniche, come del resto qualsiasi altra espressione, possono essere semplificate applicando le proprietà dell’algebra; per esempio consideriamo la funzione: z = abc + abc + abc Applicando successivamente la proprietà di idempotenza e la proprietà di assorbimento, essa può essere semplificata nel modo seguente: z = abc + abc + abc + abc = ac ( b + b ) + bc ( a + a ) = ac + bc 1.2.6 - Teoremi di De Morgan Nell’algebra della commutazione valgono due importanti teoremi, duali l’uno dell’altro, il cui enunciato è: Date n variabili logiche x0, x1, ..., xn-1, il complemento della loro addizione logica è uguale - 13 - alla moltiplicazione logica dei loro complementi; dualmente, il complemento della loro moltiplicazione logica è uguale alla addizione dei loro complementi: x0 + x1 + … + xn – 1 = x0 ⋅ x1 ⋅ … ⋅ xn – 1 x0 ⋅ x1 ⋅ … ⋅ xn – 1 = x0 + x1 + … + xn – 1 Dimostrazione La dimostrazione è condotta per induzione matematica, ovvero si dimostra la validità dei teoremi per n = 2, quindi, ammesso che valgano per un generico n, si dimostrano per n+1. Limitandoci alla prima delle due formulazioni, cominciamo a dimostrare la validità del teorema per due variabili x1, x2 e per questo, ricordando che la somma di due variabili è 1 se esse sono l’una il complemento dell’altra (teorema della complementazione x+x = 1), consideriamo la catena di uguaglianze x1+x2 +x1·x2 = (x1+x2+x1)·(x1+x2+x2) = (1+x2)·(1+x1) = 1·1= 1 la quale prova che x1+x2 è il complemento di x1·x2, ossia che si può scrivere x 1 + x 2 = x 1 ⋅ x 2 . Supponiamo ora che valga l’uguaglianza: x0 + x1 + … + xn – 1 = x0 ⋅ x1 ⋅ … ⋅ xn – 1 e indichiamo con y l’addizione logica delle prime n variabili: y = x0+x1+...+xn-1; in questo modo il complemento dell’addizione di n+1 variabili x0, ..., xn-1, xn può essere scritto nella forma: x 0 + x1 + … + xn – 1 + xn = y + xn Poiché il teorema di De Morgan vale nel caso di due variabili e per la precedente posizione si può scrivere: y + xn = y ⋅ xn = x0 + x1 + … + xn – 1 ⋅ xn = x0 ⋅ x1 ⋅ … ⋅ xn – 1 ⋅ xn che dimostra il teorema nel caso di n+1 variabili. La dimostrazione del teorema duale procede in modo analogo. La proprietà espressa dai teoremi di De Morgan non riguarda solo funzioni rappresentate come prodotto o come somma di variabili, ma può essere estesa al caso di funzioni qualsiasi attraverso una generalizzazione la quale consente di ottenere direttamente il complemento di una funzione assegnata: - 14 - Sia f(x0, x1, ..., xn-1, +, ·) una funzione logica di n variabili, la cui espressione algebrica contenga operatori moltiplicazione logica, addizione logica e complementazione; il complemento della funzione f si ottiene da questa complementandone le variabili e sostituendo l’operatore moltiplicazione logica con l’operatore addizione logica e viceversa: f(x0, x1, …, xn-1, +, ·) = f (x0, x1, …, xn-1, ·, +) Dimostrazione Una funzione f può essere sempre scritta in una delle due forme: f = A+B f = A·B dove A e B sono due espressioni logiche; il suo complemento, per i teoremi di De Morgan, si può scrivere in una delle due forme : f = A+B = A⋅B f = A⋅B = A+B A loro volta nelle espressioni A e B possono essere ulteriomente individuate sottoespressioni più semplici del tipo A'+B' o A'·B', a cui si possono applicare nuovamente i teoremi di De Morgan; ripetendo il procedimento più volte, si arriverà ad applicarlo alle singole variabili che risulteranno complementate, mentre gli operatori + e · saranno scambiati tra di loro. Per esempio data la funzione f = ab + ac + ( d + e ) se ne ricava immediatamente la funzione complemento che ha la seguente espressione: f = (a + b) ⋅ (a + c) ⋅ d ⋅ e si noti che il segno di complementazione esteso nell’espressione originaria non alle singole variabili ma a sottoepressioni rimane immutato. La verifica è facile, ricorrendo ai teoremi di De Morgan e alle proprietà dell’algebra: f = ab + ac + ( d + e ) = ab ⋅ ( ac + ( d + e ) ) = ( a + b ) ⋅ ac ⋅ ( d + e ) = (a + b) ⋅ (a + c) ⋅ d ⋅ e 1.2.7 - Dualità - Relazione tra funzione duale e funzione complemento Data un’espressione booleana E(x0, x1, ..., xn-1, + ,·), si dice duale di E l’espressione D[E] - 15 - = E(x0, x1, ..., xn-1, · , +), ottenuta da E scambiando il ruolo degli operatori + e ·. Per esempio la duale dell’espressione xy+z è (x+y)z. Vale il seguente teorema: Se E(x0, x1, ..., xn-1, +, ·) è un’espressione di una funzione f (x0, x1, ..., xn-1), allora la sua duale D[E] rappresenta la funzione f (x0, x1, ..., xn-1). Dimostrazione Data f (x0, x1, ..., xn-1 +, ·), si consideri la funzione f (x0, x1, ..., xn-1, +, ·) ed il suo complemento f (x0, x1, ..., xn-1, +, ·); per il teorema di De Morgan generalizzato quest’ultimo è uguale a f (x0, x1, ..., xn-1, ·, +) che, per la definizione di dualità, è la funzione duale di quella data. Da questo teorema discende che il complemento di una funzione f(x0, x1, ..., xn-1) si può ottenere calcolando la duale della funzione f (x0, x1, ..., xn-1); per esempio sia data la funzione f(x, y, z)= xy+z e consideriamo la duale della f (x, y, z) = x y+z, ossia (x+y)z: si vede immediatamente che essa coincide con il complemento della f, ottenuto in base al teorema di De Morgan generalizzato. L’introduzione del concetto di duale di un’espressione data permette di esprimere la relazione che lega le forme SP e PS di una funzione f(x0, x1, ..., xn-1, +, ·); precisamente, la forma PS è la duale della duale in forma SP dell’espressione data, la forma SP la duale della duale della forma PS data, ovvero: EPS(x0, x1, ..., xn-1, + ,·) = D[DSP[ESP(x0, x1, ..., xn-1, + ,·)]] ESP(x0, x1, ..., xn-1, + ,·) = D[DPS[EPS(x0, x1, ..., xn-1, + ,·)]] In pratica, per passare dalla forma SP (PS) alla PS (SP) basta applicare la proprietà distributiva dell’addizione rispetto alla moltiplicazione (della moltiplicazione rispetto all’addizione) e semplificare con le regole dell’algebra. Per esempio consideriamo l’espressione SP xy+yz; distribuendo, semplificando e applicando il consenso si ottiene: xy+yz = (xy+y)(xy+z) = (x+y)(x+z)(y+z) = (x+y)(y+z) Analogamente data l’espressione PS (x+y)(y+z), si ottiene: (x+y)(y+z) = xy+yy+xz+yz = xy+xz+yz = xy+yz - 16 - 1.2.8 - Insiemi funzionalmente completi - Gli operatori universali NAND e NOR Gli operatori booleani AND, OR, NOT formano un insieme funzionalmente completo, nel senso che qualunque funzione logica booleana può essere espressa in termini di essi. Tra gli operatori fondamentali è possibile definire anche altri insiemi funzionalmente completi, e precisamente la coppia (AND, NOT) e la coppia (OR, NOT). Infatti i teoremi di De Morgan garantiscono che l’addizione logica può essere espressa attraverso la moltiplicazione e la complementazione e che, dualmente, la moltiplicazione logica può essere espressa attraverso la addizione logica e la complementazione. Al riguardo è opportuno notare che le due coppie menzionate sono insiemi completi non ridondanti, in quanto non è possibile eliminare da esse uno degli operatori, senza perdere la completezza dell’insieme. Invece l’insieme di tutti gli operatori è ridondante, dal momento che l’eliminazione dell’operatore AND o OR lo trasforma in uno dei due insiemi completi irridondanti. Infine la coppia (AND, OR) non è un insieme funzionalmente completo, poichè non è possibile ottenere il complemento di una funzione solo attraverso tali operatori. Le implicazioni pratiche di quanto detto consistono nel fatto che per realizzare una qualunque funzione logica non è necessario disporre di porte AND, OR e NOT, ma sono sufficienti porte NOT insieme a porte AND oppure OR. In particolare, ad esempio, una porta AND (OR) ad n ingressi può essere realizzata con n+1 porte NOT ed una porta OR (AND), essendo: x1 ⋅ x2 ⋅ … ⋅ xn = x1 + x2 + … + xn x1 + x2 + … + xn = x1 ⋅ x2 ⋅ … ⋅ xn Definamo ora due nuovi operatori logici, denominati NAND e NOR e simboleggiati nelle espressioni con i simboli ⎮ e ↓ rispettivamente, attraverso le tavole di verità: x 0 0 1 1 y 0 1 0 1 x⎮y 1 1 1 0 x 0 0 1 1 y 0 1 0 1 x↓y 1 0 0 0 È immediato verificare che valgono le uguaglianze: x y = x⋅y x↓y = x + y le quali esprimono il fatto che eseguire l’operazione NAND o l’operazione NOR tra due variabili equivale ad eseguire rispettivamente le operazioni AND e NOT oppure le operazioni OR e NOT. Di fatto i nomi dei due nuovi operatori sono le contrazioni di NOT-AND e - 17 - NOT-OR. I due operatori sono commutativi, ma non associativi, come si può verificare immediatamente dalle rispettive tavole di verità: x⎮y = y⎮x x⎮(y⎮z) ≠ (x⎮y)⎮z x↓y = y↓x x↓(y↓z) ≠ (x↓y)↓z ad essi corrispondono due porte logiche che vengono rappresentate con i simboli seguenti: x y z=x⎮y x y z=x↓y NOR NAND Fig. 1.10 Gli operatori NAND e NOR sono detti operatori universali, in quanto è possibile definire qualunque altro operatore dell’algebra attraverso uno solo di essi; in questo senso quindi ciascuno costituisce un insieme funzionalmente completo. La verifica dell’universalità degli operatori NAND e NOR è immediata e consiste nell’esprimere gli operatori AND, OR, NOT solo mediante l’operatore NAND o l’operatore NOR: a) NAND x + y = x + y = xy = ( xx ) ( yy ) = ( x x ) ( y y ) xy = xy = ( xy ) ( xy ) = ( x y ) ( x y ) x = xx = x x b) NOR x + y = x + y = ( x + y ) + ( x + y ) = ( x↓y )↓ ( x↓y ) xy = xy = x + y = ( x + x ) + ( y + y ) = ( x↓x )↓ ( y↓y ) x = x + x = x↓x Nella Fig. 1.11 sono illustrate le reti funzionalmente equivalenti alle porte logiche AND, OR, NOT, costruite solo in termini di porte NAND e NOR. - 18 - x x x y x+y y y x y xy x y x+y x y x x xy y y x x x x x NAND x NOR Fig. 1.11 Mediante l’algebra qualunque espressione può essere trasformata in una espressione equivalente nella quale compaiono solo gli operatori NAND e NOR. In particolare le forme canoniche SP e PS si trasformano rispettivamente in due espressioni che prendono il nome di forma normale NAND e forma normale NOR. Per esempio consideriamo le seguenti espressioni canoniche: z = abc + abc + abc z = (a + b + c)(a + b + c)(a + b + c )(a + b + c)(a + b + c) Dalla prima, complementando due volte e applicando il teorema di De Morgan, si ottiene: z = abc + abc + abc = ( abc ) ( abc ) ( abc ) = ( ( |a )|b| ( |c ) )| ( a| ( |b )| ( |c ) )| ( a| ( |b )|c ) Analogamente dalla seconda si ricava: z = (a + b + c )(a + b + c)(a + b + c)(a + b + c )(a + b + c) = (a + b + c) + (a + b + c) + (a + b + c) + (a + b + c) + (a + b + c) = ( a↓b↓c )↓ ( a↓b↓ ( ↓c ) )↓ ( a↓ ( ↓b )↓ ( ↓c ) )↓ ( ( ↓a )↓ ( ↓b )↓c )↓ ( ( ↓a )↓ ( ↓b )↓ ( ↓c ) ) - 19 - 1.2.9 - Funzioni di n variabili Date n variabili logiche indipendenti, ci proponiamo di determinare il numero di funzioni booleane distinte di tali variabili. Poichè ogni variabile può assumere due valori 0 e 1, per n variabili esistono 2n combinazioni diverse di valori binari. D’altra parte per ciascuna di tali combinazioni una qualunque funzione delle n variabili assume uno dei due valori possibili 0 e 1. Il numero di funzioni possibili è allora pari al numero dei modi in cui possono essere disposti a gruppi di 2n n 2 con ripetizione i simboli 0 e 1, ovvero 2 2 . Per esempio se n = 2, si hanno 2 2 = 16 disposizioni distinte e quindi 16 tabelle di verità a cui corrispondono altrettante funzioni; la tabella seguente mostra le più comuni espressioni algebriche di tali funzioni: a b f0 =0 0 0 0 0 1 0 1 0 0 1 1 0 costante logica 0 (inconsistenza) f1 = ab 0 0 0 1 AND f2 = ab 0 0 1 0 mintermine di f6 f3 = a 0 0 1 1 variabile a f4 = ab 0 1 0 0 mintermine di f6 f5 = b 0 1 0 1 variabile b f6 = ab+ab 0 1 1 0 OR esclusivo: a⊕b f7 = a+b 0 1 1 1 OR f8 = a↓b 1 0 0 0 NOR f9 = (a+b)(a+b) 1 0 0 1 identità f10 = b 1 0 1 0 complemento di b f11 = a+b 1 0 1 1 maxtermine di f9 f12 = a 1 1 0 0 complemento di a f13 = a+b 1 1 0 1 implicazione (maxtermine di f9) f14 = a|b 1 1 1 0 NAND f15 = 1 1 1 1 1 costante logica 1 (tautologia) - 20 - ESERCIZI 1) Semplificare le seguenti espressioni logiche: xyz + xy + xyz bc + ac + ab + bcd ac + abd + bcd + abd + abcd ab + abd + abcd + bc y ( xz + x ) + xy abc + abc + abc + abc + abc (b + c)(a + c)(a + b )(b + c + d) (a + c + d)(a + c + d)(a + c + d)(a + b) abc + abc + ab abc + abcd + ac abc + bc + ac ( a + b + cd ) ( a + b ) ( a + b + c ) ( ab + acde + bcd ) ( abcd + bce + ae ) abcd + abcd + abcd + abd + bcd + abd (a + b + c)(a + b + c)(a + b + c)(a + b + c)(a + b) bc + ac + ab + bcd ( a + b )a + ( b + c ) + ab + ac ac + ace + ace + acd + ade (y + w)(x + z + w)(x + y + z + w )(x + y + z + w ) 2) Verificare se le seguenti uguaglianze sono vere: xy + xy + xyz = xyz + xy + yz xy ( xz + y ) + ( x + y ) ( xyz + xyz ) = yz + xz ab + cd + abcd + abcd = ( a + d ) ( b + c ) ab + abc = ( a + c ) ( b + c ) (a + b )(b + c)(a + c) = (a + b)(b + c)(a + c) bc + abd + ac = bc + ac ab + ab + bc = ab + ab + ac ab + bc + ac = ab + bc + ac a + bc = ab + ac + abc + abc 3) Ricordando che la duale D[f] di una funzione f è la funzione ottenuta da quella data scambiandone nell’espressione gli operatori di somma e prodotto logico, una funzione f si dice autoduale se vale l’uguaglianza f = D[f]. Verificare se le seguenti funzioni sono autoduali: - 21 - f f f f f = = = = = xy + xy y(x + z) + x(y + z) (x + y)(x + y) x ( y + z ) + xyz abc ( c + d ) + ab + ac + acd 4) Facendo uso del teorema di espansione di Shannon, trovare le forme canoniche delle seguenti funzioni: f = xy + x ( yz + yz ) f = ( a + bc ) ( ac + b ) f = ab ( c + d ) + ab ( c + d ) f = ( ab + cd ) ( ab + cd ) f = ab + c + abc f = a(b + c) f = (a + b)(b + c) f = 1 f = ( ab + c ) ( b + ac ) f = ( xy + z ) ( y + xz ) f = yz + wxy + wxz + wxz 5) Complementare le seguenti funzioni: f = a + bc + abc f = ( a + bc )a + b f = xyz + xy + yz f = ( bc + ad ) ( ab + cd ) f = a + cd ( b + ad ) 6) Utilizzando il principio di dualità, trovare la forma PS o SP delle seguenti funzioni: z = xy + x z = abc + ac + b z = a + bc + abc + ac z = (a + b)(a + b + c)(b + c) z = ( x + y + v ) ( x + y )v z = ( a + b )c ( b + d ) 7) Trovare le forme normali NAND e NOR delle seguenti funzioni: z = ∑ ( 0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 14 ) 4 z = ∑ ( 1, 2, 4, 6, 7 ) 3 z = ∏ ( 5, 7, 9, 11, 12, 17, 18, 22, 25, 29, 30 ) - 22 - 8) Verificare se gli operatori di seguito definiti sono operatori universali, utilizzando, ove necessario, anche le costanti logiche: y ⊥ x = xy x∇y = x + y x∆y = xy x y = (x + y)(x + y) x ⊕ y = xy + xy - 23 - - 24 - Capitolo 2 PROGETTO LOGICO DELLE RETI COMBINATORIE I Parte - Reti a due livelli di logica 2.1 - Introduzione Avendo definito nel primo capitolo le porte logiche elementari AND, OR, NOT e le porte NAND, NOR, XOR da esse derivate, siamo ora in grado di precisare più dettagliatamente il significato del termine rete logica. Una rete logica è un circuito che risulta dalla connessione dell’uscita di una o più porte logiche con l’ingresso di una o più altre porte logiche; a sua volta l’interconnessione di più reti logiche dà luogo ancora ad una rete logica nella quale ingressi e uscite esterni appartengono all’insieme degli ingressi e delle uscite delle reti componenti. Come esempio, in Fig. 2.1 è schematizzata una rete logica ottenuta collegando quattro reti logiche più semplici. Esistono due famiglie di reti logiche: le reti combinatorie e le reti sequenziali. Di entrambi i tipi può essere data sia una definizione funzionale che una definizione strutturale. Funzionalmente una rete logica è combinatoria se le sue uscite dipendono in ogni istante solo dal valore dei segnali applicati agli ingressi in quell’istante; strutturalmente una rete è combinatoria se non contiene cicli nè elementi di memoria: si dice anche che una rete combinatoria è aciclica o priva di memoria. Nell’ambito delle reti logiche, un ciclo è un cammino che riporta un segnale dall’uscita di una porta (o da una delle uscite di una sottorete) - 25 - al suo ingresso, direttamente o attraverso un numero qualsiasi di altre porte logiche (o di sottoreti). Per esempio nella Fig. 2.1 esistono due cicli marcati con 1 e 2 su tutti i rami che li compongono. rete logica n. 1 2 rete logica n. 2 1, 2 rete logica n. 4 1 rete logica n. 3 Fig. 2.1 Viceversa una rete sequenziale è una rete per la quale non è possibile predire il valore delle uscite in un certo istante solo dall’esame dei valori degli ingressi in quell’istante, ma occorre tenere conto anche dei valori che si sono succeduti agli ingressi in tutti gli istanti passati. Strutturalmente una rete sequenziale contiene cicli ed è dotata di memoria. Una rete combinatoria realizza una funzione logica e la sua struttura, intesa come topologia e numero di porte e di segnali interni tra le porte, dipende dall’espressione algebrica della funzione. Pertanto una stessa funzione può essere realizzata mediante più reti che differiscono tra di loro solo per numero di porte e di segnali (e quindi per complessità strutturale), ma non per la legge di trasferimento ingresso-uscita. 2.2 - Reti combinatorie a due livelli di logica Tra tutte le reti che possono realizzare una data funzione logica, consideriamo prima di tutto quelle che derivano dalla forme canoniche SP e PS della funzione ed il cui schema generale è illustrato nella Fig. 2.2. Si tratta di reti con struttura regolare, appartenenti al gruppo delle reti a due livelli di logica: il primo livello è costituto solo da porte AND o OR in numero pari ai mintermini o ai maxtermini della forma canonica ed ogni porta ha tanti ingressi quante sono le variabili della funzione. Il secondo livello comprende una sola porta OR o AND rispettivamente per la rete SP e PS, con un numero di ingressi pari al numero dei mintermini o dei maxtermini, collegati alle uscite delle porte del primo livello. Osserviamo che nel calcolo del numero dei livelli di logica normalmente non si considerano le porte NOT, poichè si suppone di disporre anche delle variabili complementate - 26 - direttamente all’ingresso della rete; ciò è realistico dal momento che molto spesso il complemento di una variabile è disponibile senza aumento di costo all’uscita della rete che genera la variabile stessa. porta 1 porta 1 n n porta 2 porta 2 n n k k porta k porta k n n livello 1 livello 2 livello 1 Rete canonica SP livello 2 Rete canonica PS Fig. 2.2 Reti a due livelli non si ottengono solo da espressioni canoniche, ma da qualsiasi espressione in somma di prodotti o in prodotto di somme. Di particolare interesse sono le reti derivanti da espressioni NAND o NOR, normali o no, poichè sono caratterizzate da una completa omogeneità strutturale che ne rende facile la realizzazione pratica. Per esempio se consideriamo l’espressione xy + z , la sua forma NOR, ottenuta dalla forma PS, è ( x↓y )↓ ( ( ↓y )↓z ) , a cui corrisponde la rete di Fig. 2.3; si noti che, come è stato detto sopra, la porta NOR utilizzata per generare la variabile y non rientra nel calcolo dei livelli di logica della rete. x y y z Fig. 2.3 L’interesse verso le reti a due livelli di logica deriva dal fatto che sono le più veloci che è possibile progettare per una data funzione. Infatti il ritardo, che dipende dal percorso interno più lungo e quindi dal numero massimo di porte che vengono attraversate su tutti i cammini, in queste reti è pari soltanto al doppio del ritardo di una singola porta. - 27 - 2.3 - Il problema della sintesi delle reti combinatorie La sintesi di una rete combinatoria consiste nel ricavarne la struttura, conoscendone la funzione ingresso-uscita sotto forma di tavola di verità o di espressione algebrica. In generale il processo non porta ad una soluzione unica, poichè la stessa tavola di verità può dare luogo ad una molteplicità di reti, differenti per numero e tipo di porte e per collegamenti interni, essendo possibile operare riduzioni algebriche sull’espressione data o ricavata (in forma canonica) dalla tavola di verità; tutte queste reti, tuttavia, sono tra loro equivalenti agli effetti esterni. La scelta di una rete piuttosto che un’altra viene operata sulla base di criteri di ottimo, che tendono a minimizzare parametri di costo ritenuti significativi. Per esempio si può ricorrere a metodi che portano a realizzare, per una data tavola di verità, la rete con il minimo numero di porte e di segnali e quindi più economica: per questo approccio, limitatamente alle reti a due livelli di logica, si conoscono metodi sistematici per la sintesi ottima. Un altro approccio è determinato dalla tecnologia di fabbricazione dei circuiti integrati, in particolare di quelli a larga e larghissima scala di integrazione (LSI e VLSI). Infatti in tale tecnologia si assume come parametro di costo non tanto il numero delle porte, ma piuttosto l’estensione della superficie di silicio richiesta per realizzare su un singolo micrologico o “chip” sia gli elementi attivi, sia le piste di comunicazione, le quali hanno dimensione di complessità paragonabile a quella dei primi. Prima di occuparci del problema della sintesi ottima, verifichiamo come dalla descrizione tabellare di una funzione sia possibile effettivamente sintetizzare più reti funzionalmente equivalenti. Consideriamo a questo scopo la funzione definita dalla seguente tavola di verità: a 0 0 0 0 1 1 1 1 b 0 0 1 1 0 0 1 1 c 0 1 0 1 0 1 0 1 z 0 0 1 1 0 0 0 1 da questa possiamo derivare l’espressione canonica SP, la quale può essere ridotta, producendo una nuova espressione equivalente; inoltre dalla forma canonica si può ricavare la forma normale NAND, oppure si può trasformare l’espressione ridotta in una forma NOR, generando così altre rappresentazioni ancora della medesima funzione. A queste espressioni corrispondono altrettante reti topologicamente differenti, ma equivalenti dal punto di vista funzionale. Avremo così: - 28 - a) forma canonica SP z = abc + abc + abc b) espressione ridotta z = b(a + c) c) forma normale NAND z = ( ( |a )|b ( |c ) )| ( ( |a )|b|c )| ( a|b|c ) d) forma NOR z = ( ↓b )↓ ( ( ↓a )↓c ) 2.4 - Criteri di minimizzazione delle funzioni combinatorie SP e PS Come è stato detto nel paragrafo precedente, oltre alle reti che derivano dalle espressioni canoniche SP e PS, è possibile realizzare altre reti a due livelli di logica. La loro struttura deriva sempre da espressioni algebriche che sono nella forma di somma di prodotti o prodotto di somme e quindi è sempre del tipo schematizzato in Fig. 3.2, con le seguenti, peraltro ovvie, osservazioni: a) non tutte le porte AND (OR) del primo livello hanno lo stesso numero di ingressi, ovvero non tutte generano mintermini (maxtermini) della funzione; b) il loro numero non è direttamente in relazione con il numero di 1 (di 0) presenti nella tavola di verità della funzione. Per esempio consideriamo la seguente espressione canonica z = abc + abc + abc mediante l’algebra essa può essere semplificata, come è noto, nel modo seguente: abc + abc + abc = bc ( a + a ) + abc = bc + abc = c ( b + ab ) = bc + ac ottenendo ancora una forma SP, quindi a due livelli di logica ma non canonica, più semplice, per numero di porte e di segnali, di quella canonica da cui è derivata. Questo esempio mette in evidenza il problema di come progettare reti minime a due livelli di logica. Tra le varie scelte che possono essere fatte per individuare un criterio di minimo, alcune delle quali sono state accennate nel paragrafo precedente, esamineremo quella (tradizionale) che mira alla minimizzazione di due parametri che influenzano la complessità, e quindi il costo, di una rete: 1) il numero dei porte logiche o gate Ng; 2) il numero dei segnali Nd presenti nella rete. Nel caso di reti derivate da espressioni SP, questi parametri dipendono dal numero dei termini prodotto Np e dal numero di letterali Nv presenti nelle espressioni stesse secondo le relazioni: - 29 - Ng = Np + 1 Nd = Nv + Np Analogamente per reti combinatorie costruite su espressioni PS valgono le seguenti relazioni: Ng = Ns +1 Nd = Nv + Ns nelle quali Ns è il numero totale di termini somma ed Nv il numero di tutti i letterali presenti in esse. In generale esiste un metodo algebrico per ottenere una somma minima, basato sull’uso ripetuto della proprietà associativa, del teorema della complementazione e del teorema del consenso. Per esempio data la funzione: f = xyz + xyz + xyz + xyz e considerato che valgono le uguaglianze: xyz + xyz = xy xyz + xyz = xy si ottiene la somma minima: f = xy + xz Ragionamenti duali possono essere fatti relativamente a realizzazioni in prodotto di somme. Tuttavia il procedimento algebrico è poco adatto per la riduzione a forma minima di espressioni con molti termini e con molte variabili, perchè tedioso, non sistematico e incline a errori. Una notevole semplificazione si ha con i metodi che saranno illustrati di seguito. Osserviamo prima di tutto che una n-upla di variabili logiche, x0, x1,..., xn-1, può essere interpretata come l’insieme delle coordinate dei vertici di un cubo di spigolo unitario nello spazio ad n dimensioni (ipercubo di grado n): infatti le coordinate dei vertici dell’ipercubo assumono in essi tutte le 2n possibili combinazioni di 0 e 1, esattamente come possono fare n variabili logiche. Inoltre ricordiamo che un prodotto logico di n variabili affermate o complementate (prodotto completo o mintermine) è una funzione che vale 1 solo per una tra le 2n possibili combinazioni dei valori 0 e 1 delle variabili. Poichè questa combinazione costituisce il valore delle coordinate di un vertice dell’ipercubo di grado n, possiamo dire che un vertice è rappresentato da un prodotto completo. Un prodotto logico che non comprenda tutte le n variabili rappresenta più vertici - 30 - dell’ipercubo associato, e precisamente un suo sottocubo. Infatti sia P un prodotto di n-1 variabili e xi la variabile mancante; poiché possiamo scrivere: P = P ⋅ ( xi + xi ) = P ⋅ xi + P ⋅ xi può essere espresso come somma di due prodotti completi, che differiscono solo per la variabile xi, che compare affermata in uno e complementata nell’altro e conseguentemente può P assumere due volte valore 1, una volta quando il prodotto P⋅xi = 1 ed una quando il prodotto P⋅xi = 1. Esso rappresenta quindi due vertici adiacenti dell’ipercubo, ovvero un sottocubo di grado 1; si dice che P copre due vertici, di coordinate XX...1...X e XX...0...X rispettivamente, con X ∈ {0,1}, o che rappresenta un sottocubo di 1 di grado 1. Per esempio nel caso di tre variabili a, b, c il termine ac copre i punti 001 e 011. In generale un prodotto di k variabili (k ≤ n) copre 2n-k vertici che formano un ipercubo di 1 di grado n-k. Con ragionamenti analoghi, ricordando che una somma di tutte le variabili (somma completa o maxtermine) è una funzione che vale 0 solo per una delle 2n possibili combinazioni binarie delle variabili e poiché tale combinazione rappresenta il valore delle coordinate di un vertice dell’ipercubo associato, si può affermare che un vertice di un ipercubo è rappresentabile da una somma completa. Una somma di n-1 variabili rappresenta un sottocubo di grado 1, ossia nell’ipercubo copre due vertici di coordinate XX...0...X e XX...1...X rispettivamente, con X ∈ {0,1}, potendosi esprimere nella forma S = ( S + xi ) ⋅ ( S + xi ) che vale 0 due volte, una quando S+xi = 0 ed una quando S+xi = 0. In generale una somma di k variabili (k ≤ n) copre 2n-k vertici che formano un sottocubo di 0 di grado n-k. 2.4.1 - Implicanti Sia f(x0, x1, ..., xn-1) una funzione di n variabili; diremo che un termine prodotto P è un implicante di f e scriveremo P → f se P copre almeno un vertice dell’ipercubo di grado n, nel quale f vale 1, e non copre alcun vertice in cui f vale 0. Poichè in generale f vale 1 anche in altri vertici non coperti da P, si può affermare che essa include o copre il suo implicante P. Dalla definizione discende che una funzione è esprimibile come somma dei suoi implicanti: m f = ∑ Pi i=1 - 31 - e che ogni forma SP è una somma di implicanti di f. In particolare lo è la prima forma canonica, nella quale ogni mintermine è implicante di f. Tra tutti gli implicanti di una funzione hanno particolare importanza gli implicanti primi, definiti nel modo seguente: Un implicante P si dice primo se non esiste alcun altro implicante P' → f tale che P → P'. Questa definizione significa che P è un implicante primo se, per qualunque altro implicante P', esiste almeno un vertice, in cui la funzione vale 1, coperto da P ma non da P', ossia se accade che un qualunque altro implicante P' non copre P. In pratica un implicante primo è l’implicante che copre il maggior numero di vertici adiacenti in cui la funzione vale 1 e che non è coperto da alcun altro implicante. Come esempio consideriamo la funzione definita dalla seguente tavola di verità: a 0 0 0 0 1 1 1 1 b 0 0 1 1 0 0 1 1 c 0 1 0 1 0 1 0 1 z 1 1 0 1 1 1 0 0 I termini abc , abc , abc , abc , abc sono implicanti della funzione, coincidendo con i mintermini dell’espressione canonica SP. Analogamente sono implicanti i termini: ab, ab , ac , bc , bc ciascuno dei quali copre due vertici dell’ipercubo delle tre variabili, in cui la funzione vale 1, come pure il termine b che copre quattro vertici in cui f vale 1. Questo termine è anche implicante primo in quanto è l’unico implicante che copre quattro vertici e non è coperto da alcun altro implicante. L’implicante ac è a sua volta primo poichè è l’unico che copre il vertice di coordinate 011 in cui la funzione vale 1. Si può dimostrare il seguente teorema: Per ogni funzione f esiste almeno un sottoinsieme di implicanti primi P = {P1, P2,..., Pp} tale che la funzione può essere espressa nella forma f = ∑ Pi ∈ P - 32 - Pi . il quale asserisce che una funzione può essere espressa mediante la somma di tutti i suoi implicanti primi. Tuttavia non tutti gli implicanti primi sono sempre indispensabili per l’intera copertura, ma alcuni possono essere sostituiti dall’unione di altri implicanti primi; in particolare possono essere sostituiti da quelli che sono assolutamente necessari per coprire anche altri vertici in cui la funzione vale 1. Per esempio se ab, bc, ac sono tre implicanti primi di una funzione di tre variabili, l’implicante ac può essere sostituito dall’unione degli altri due i quali, oltre ad altri vertici, coprono tutti quelli coperti da ac. Ciò risulta evidente anche algebricamente, ricordando il teorema del consenso. Da queste considerazioni sull’indispensabilità o meno degli implicanti primi, possiamo introdurre il concetto di insieme non ridondante di implicanti primi: Un insieme R = {P1, P2, ..., Pr} è un insieme non ridondante di implicanti primi se una funzione f può essere espressa come somma di suoi implicanti primi, mentre non può essere espressa come somma di implicanti primi di un qualunque sottoinsieme di R. In modo informale possiamo dire che un insieme non ridondante è un insieme di implicanti primi avente la minima cardinalità sufficiente per coprire tutti i vertici dell’ipercubo in cui la funzione è 1, relativamente ad una particolare scelta di implicanti primi. Una funzione espressa attraverso un insieme non ridondante dei suoi implicanti primi si dice in forma SP prima non ridondante. Tale forma può essere sempre trovata con una procedura che consiste nell’eliminare dall’insieme R degli implicanti primi ogni implicante che possa essere sostituito dall’insieme di altri due e ripetendo tale operazione finchè è possibile. Come già accennato può accadere che alcuni implicanti primi non possano essere assolutamente eliminati, perchè sono gli unici che coprono vertici in cui la funzione vale 1. Tali implicanti sono detti primi essenziali; più precisamente si può enunciare la seguente definizione: Un implicante P è primo essenziale se esiste almeno un punto dove P = 1 e f = 1, e non esiste alcun altro implicante primo P' tale che sia P' = 1 in quel punto. Tutti gli implicanti primi essenziali devono figurare nella forma SP prima non ridondante di una funzione. Ad esempio per la funzione definita dalla tavola di verità della pagina precedente, l’implicante primo ac è essenziale poichè è l’unico a garantire la copertura del vertice 011. 2.4.2 - Implicati Data una funzione di n variabili f (x0, x1,..., xn-1) ed un termine S, somma di un sottoinsieme di quelle variabili, diremo che - 33 - S è implicato di f, e scriveremo S ← f, se S copre almeno un vertice dell’ipercubo di grado n in cui f vale 0 e non copre alcun vertice in cui f vale 1. Analogamente a quanto visto per gli implicanti, la definizione precedente equivale a dire che la funzione f copre l’implicato S; discende inoltre da essa che una funzione è esprimibile r come prodotto dei suoi implicati f = ∏ Sj . Questa espressione è di tipo PS e si può perciò j=1 affermare che ogni forma PS è un prodotto di implicati di f. In particolare lo è la seconda forma canonica, nella quale ogni maxtermine è implicato di f. In modo del tutto analogo a quanto detto nel paragrafo precedente si definiscono i concetti di implicato primo e di insieme non ridondante di implicati primi, come pure quello di forma PS prima non ridondante e infine il concetto di implicato primo essenziale. Riprendiamo la funzione definita nell’esempio del paragrafo precedente; essa ammette come maxtermini le somme a + b + c, a + b + c , a + b + c le quali sono perciò implicati. Sono inoltre implicati i termini b+c e a+b che coprono rispettivamente i vertici (010, 110) e (110, 111). Tali implicati sono anche primi ed essenziali perchè ciascuno copre il massimo numero di vertici in cui la funzione vale 0 e non è coperto da alcun altro implicato, ed inoltre ciascuno copre un vertice (010 e 111 rispettivamente) che non può essere coperto in alcun altro modo. Pertanto questi due implicati fanno parte della forma PS prima non ridondante che risulta: f = (b + c)(a + b) 2.4.3 - Sintesi ottima di reti combinatorie a due livelli di logica Avendo introdotto i concetti di forma SP e di forma PS prima non ridondante, possiamo dimostrare il seguente teorema: Una forma SP o PS minima di una funzione è una forma SP o PS prima non ridondante Consideriamo una funzione f di n variabili, espressa in una forma SP o PS a cui corrisponde una rete per la quale siano minimi i valori dei parametri Ng e Nd. Questa espressione è certamente una somma di implicanti o di implicati primi. Infatti se un implicante Pj (o un implicato Sj) in f non fosse primo, esisterebbe un implicante primo Pj' → f (o un implicato primo Sj' ← f ) tale che Pj → Pj' (oppure Sj ← Sj'), il quale potrebbe essere sostituito a Pj o a Sj nell’espressione minima di f. Poichè Pj' o Sj' comprenderebbe un minore numero di variabili rispetto a Pj o Sj, ne deriverebbe una riduzione del valore di Nd, contro l’ipotesi che la forma data sia minima. Inoltre se la forma non fosse non ridondante, si potrebbe eliminare da essa - 34 - almeno un termine, riducendo così il valore di Ng, nuovamente contro l’ipotesi che la forma sia minima. Come conseguenza di questo teorema, la sintesi ottima di reti a due livelli di logica si riduce alla ricerca delle forme SP o PS prime non ridondanti delle funzioni logiche. La ricerca procede attraverso i seguenti passi: a) determinazione dell’insieme P degli implicanti o dell’insieme S degli implicati primi della funzione; b) selezione da P o da S di un insieme non ridondante di implicanti o di implicati primi, la cui somma o il cui prodotto copra la funzione ed il cui costo sia minimo. È possibile definire metodi sistematici per trovare la forma minime di una funzione. Questi metodi sono il metodo delle mappe di Karnaugh e il metodo di Quine-McCluskey o metodo tabellare. 2.5 - Mappe di Karnaugh Un ipercubo di grado n può essere rappresentato sotto forma di una tabella di 2n caselle, ciascuna delle quali corrisponde ad un vertice dell’ipercubo ed è identificata di conseguenza dalle sue n coordinate binarie. Tabelle di questo genere sono chiamate mappe di Karnaugh e sono utilizzate per descrivere funzioni logiche, secondo il procedimento di seguito illustrato. Date n variabili x0, x1, ..., xn-1, la mappa di Karnaugh dell’ipercubo associato ad esse si costruisce facendo in modo che l’adiacenza geometrica tra due caselle, ovvero la comunanza di un lato, corrisponda alla loro adiacenza logica e viceversa, intendendo che due caselle sono logicamente adiacenti quando i loro identificatori differiscono per il valore di una sola coordinata. Le mappe per n = 2, 3, 4 sono illustrate nella Fig. 2.4, nella quale la numerazione decimale delle caselle è ottenuta dalle rispettive coordinate binarie: 0 0 0 x1 1 2 x2 1 1 3 n=2 x2 x3 00 01 11 10 0 0 1 3 2 x1 1 4 5 7 n=3 6 x3 x4 00 01 11 10 00 0 1 3 2 01 4 5 7 6 x1 x2 11 12 13 15 14 10 8 9 11 10 n=4 Fig. 2.4 Affinchè l’adiacenza logica sia completa, la mappa deve essere pensata non distesa su un piano, come per convenienza viene disegnata e come è in effetti per n = 2, bensì su una superficie cilindrica per n = 3, toroidale per n = 4, su superfici più complesse per n ≥ 5, in modo - 35 - che i lati opposti coincidano. Consideriamo ora una funzione f delle n variabili x0, x1, ..., xn-1; essa può essere rappresentata sulla mappa di Karnaugh delle variabili, contrassegnando con 1 tutte le caselle le cui coordinate costituiscono un numero binario che corrisponde ad uno dei prodotti fondamentali (mintermini) inclusi nella funzione; con 0 (o lasciandole vuote) le rimanenti caselle. In questo modo si stabilisce una corrispondenza biunivoca tra le caselle della mappa contrassegnate con 1 e i mintermini dell’espressione canonica SP di f. Per esempio la seguente funzione di tre variabili in forma canonica SP: f = abc + abc + abc è descritta dalla mappa della Fig. 2.5: a bc 00 01 11 10 0 1 1 1 1 Fig. 2.5 Anche funzioni in prodotto di somme possono essere rappresentate mediante mappe di Karnaugh, salvo contrassegnare con 0 le caselle di coordinate corrispondenti ad una delle somme complete (maxtermini) incluse nella funzione e con 1 (o lasciandole vuote) le altre. Così la stessa funzione dell’esempio precedente, espressa in forma canonica PS: = (a + b + c )(a + b + c)(a + b + c)(a + b + c)(a + b + c) è rappresentata dalla mappa: a bc 00 01 11 10 0 0 0 1 0 0 0 Fig. 2.6 nella quale le cinque caselle contrassegnate con 0 sono in corrispondenza biunivoca con i maxtermini dell’espressione canonica. Le mappe di Karnaugh trovano pratica applicazione fino ad un massimo di 5 o 6 variabili; tuttavia per questi valori conviene disegnare due e quattro mappe da quattro variabili rispettivamente, al fine di facilitare la ricerca delle adiacenze. Nel caso di cinque variabili una delle due mappe corrisponde a tutte le righe della tavola di verità per le quali la quinta variabile vale 0, l’altra a tutte le righe della tavola per le quali la quinta variabile vale 1; pertanto risultano - 36 - adiacenti anche le caselle sull’una e l’altra mappa che si trovano nelle posizioni corrispondenti, ossia hanno identiche le altre quattro coordinate; per esempio sono adiacenti le caselle {1, 17}, {13, 29} e così via tutte le coppie i cui equivalenti decimali differiscono di 16: x4 x5 00 01 11 10 00 0 1 3 2 x4 x5 00 01 11 10 00 16 17 19 18 01 4 5 7 6 x2 x3 11 12 13 15 14 10 8 01 20 21 23 22 x2 x3 11 28 29 31 30 9 11 10 x1 = 0 10 24 25 27 26 x1 = 1 Fig. 2.7 Ritorniamo all’esempio precedente e alle rappresentazioni sulle mappe delle forme canoniche della funzione data; per quanto detto a proposito di implicanti ed implicati, gli 1 e gli 0 delle due mappe corrispondono ad altrettanti mintermini e maxtermini della funzione. Consideriamo allora le seguenti forme ridotte SP e PS della funzione: f PS = ( a + b )c f SP = ac + bc Nella prima il termine ac copre i punti 001 e 011 che corrispondono sulla mappa all’insieme delle due caselle della prima riga contrassegnate con 1; poichè ac è un implicante di f, si conclude che tale implicante è rappresentato da quelle due caselle. Analogamente il termine bc è un altro implicante della funzione e sulla mappa corrisponde al gruppo di due caselle di coordinate 011 e 111. Questi implicanti sono primi ed essenziali. Analogamente nell’espressione PS il termine somma a+b è un implicato ed è rappresentato dall’insieme delle caselle di coordinate 100 e 101. Infine il termine c è pure un implicato e corrisponde alle caselle di coordinate 000, 100, 010, 110. Anche questi implicati sono primi ed essenziali, per cui le due espressioni fSP e fPS sono forme prime non ridondanti. In generale un implicante che contiene k variabili, 1 ≤ k ≤ n è rappresentato su una mappa di Karnaugh di 2n caselle dall’insieme di 2n-k caselle adiacenti contenenti 1 della funzione: esso è dunque un ipercubo di 1 di grado n-k e la sua espressione è data dal prodotto delle variabili il cui valore rimane costante nel passare da una casella a quella adiacente, prese affermate o complementate a seconda che tale valore costante sia 1 oppure 0. Un implicato di k variabili è rappresentato dall’insieme di 2n-k caselle adiacenti contenenti 0 della funzione ed è un ipercubo di 0 di grado n-k, avente come espressione la somma delle variabili i cui valori rimangono costanti da una casella a quella adiacente, prese affermate o complementate a seconda che tale valore costante sia 0 oppure 1. Per esempio la funzione di quattro variabili rappresentata dalla mappa di Fig. 2.8 possiede sei implicanti primi, indicati sulla mappa con un rettangolo ed elencati a lato, dei quali ac è essenziale, mentre degli altri un - 37 - sottoinsieme non ridondante è formato da {bcd, abd}, che dà luogo all’espressione minima: cd 00 01 11 10 1 1 00 ab 01 1 11 1 10 1 1 1 ac, abd, bcd, acd, abd, bcd 1 Fig. 2.8 f = ac + bcd + abd Nella Fig. 2.9 è mostrata la mappa di una funzione che possiede tre implicanti primi, di cui due sono essenziali ( ab e ac), mentre il terzo bc è coperto dall’unione degli altri due e può essere eliminato nella ricerca dell’espressione non ridondante; ciò è verificabile anche algebricamente, per il teorema del consenso; in altri termini si dice che bc implica la somma di ab e di ac: bc → ab + ac a bc 00 01 11 10 0 1 1 1 1 1 Fig. 2.9 Pertanto l’espressione ab + ac costituisce la forma SP prima non ridondante, formata solo da implicanti essenziali. Un altro esempio di funzione la cui mappa è coperta da implicanti essenziali è il seguente: cd 00 01 11 10 00 1 1 1 ab 01 1 1 11 1 1 10 1 Fig. 2.10 Una stessa funzione può avere più forme prime non ridondanti, nelle quali figurano lo - 38 - stesso numero di implicanti (o implicati) dello stesso ordine: pertanto la scelta di quale forma realizzare è una questione che dipende da considerazioni diverse da quelle finora esaminate. Un esempio mette in luce questo fatto: la mappa della Fig. 2.11 può essere coperta con le due espressioni: f 1 = ab + bc + bc f 2 = ac + bc + bc Si tratta di due forme prime non ridondanti, in ciascuna delle quali compaiono gli implicanti essenziali bc e bc, mentre la casella di 1 di coordinate 010 può essere coperta dagli implicanti primi ab o ac indifferentemente. a bc 00 01 11 10 0 1 1 1 1 1 1 Fig. 2.11 Infine le due mappe seguenti rappresentano funzioni prive di implicanti e di implicati essenziali: bc 00 01 11 10 0 0 0 0 a 0 0 0 1 cd 00 01 11 10 00 1 1 ab 01 1 1 11 1 10 1 1 1 Fig. 2.12 Riassumendo, con le mappe di Karnaugh la sintesi ottima delle reti a due livelli avviene secondo il seguente procedimento: a) si individuano dapprima gli implicanti (o gli implicati) primi essenziali che, come è stato detto, devono figurare nella forma minima. b) Si effettua una ulteriore scelta in modo da coprire tutti gli 1 (o gli 0) rimasti scoperti dalla prima selezione. In questa seconda fase sono possibili più scelte, tutte plausibili almeno in base al criterio di ottimizzazione che è stato suggerito. - 39 - 2.6 - Metodo tabellare di Quine-McCluskey In alternativa al metodo delle mappe, che tra l’altro perde molta della sua utilità quando il numero di variabili è superiore a 6, ne è stato sviluppato un altro il quale, pur complesso, ha il vantaggio di poter trattare un numero qualunque di variabili; esso è noto come metodo tabellare o di Quine-McCluskey ed è articolato in due fasi: a) determinazione di tutti gli implicanti (o implicati) primi mediante l’uso della tabella degli implicanti (o degli implicati); b) scelta della forma minima utilizzando la tabella di copertura. 2.6.1 - Fase a) Consideriamo per semplicità solo il caso della forma minima SP per una funzione logica di n variabili. Questa funzione vale 1 per un certo numero di combinazioni binarie dei valori delle sue variabili, siano h1, h2, ..., hα. A ciascuna di esse attribuiamo un peso espresso dal numero di 1 presenti nella combinazione; per esempio la combinazione 01011 ha peso tre in quanto contiene tre 1. Le combinazioni hi, 1 ≤ i ≤ α, vengono disposte in una tabella, raggruppate in sezioni ordinate secondo il peso crescente; all’interno di una sezione le combinazioni sono in ordine numerico crescente. In tal modo coppie di combinazioni che si trovano in sezioni adiacenti differiscono esattamente per il valore di un bit nella stessa posizione e corrispondono a espressioni del tipo: P·xi, P·xi nelle quali P è un prodotto di n-1 variabili esclusa la variabile xi che vale 0 nella combinazione di una sezione e 1 in quella della sezione adiacente. Fra queste combinazioni viene eseguita un’operazione, detta prodotto di fusione, che consiste nel sostituire ad esse una nuova combinazione avente gli stessi bit in tutte le posizioni, tranne in quella relativa ai bit che differiscono nelle combinazioni di partenza, dove non viene specificato alcun valore. Questo processo equivale ad applicare la proprietà associativa e quella della complementazione: P·xi + P·xi = P ovvero a sostituire ai due termini prodotto un unico prodotto P che possiede la xi variabile in meno. Il procedimento è applicato sistematicamente tra ogni combinazione di una sezione e tutte quelle della sezione successiva, arrivando a costruire una seconda tabella che possiede una sezione in meno rispetto alla tabella di partenza e nella quale, sezione per sezione, il risultato delle fusioni è costituito da combinazioni con un bit in meno rispetto alle combinazioni che - 40 - hanno fuso, nella posizione in cui è avvenuta la fusione. Tale assenza è contrassegnata con “–”. Vengono inoltre contrassegnate nella tabella originaria tutte le coppie di combinazioni che hanno fuso. Ripetendo il procedimento sulla seconda tabella, se ne genera una terza e così via fino ad arrivare ad una situazione nella quale non sono più possibili prodotti di fusione. I prodotti che corrispondono a tutte le combinazioni che nelle varie tabelle non hanno fuso, ovvero quelle che non sono state contrassegnate, più il prodotto relativo all’ultima fusione effettuata costituiscono l’insieme degli implicanti primi. Sia data per esempio la funzione di quattro variabili f = ∑ ( 0, 1, 5, 6, 7, 8, 10, 12, 13, 15 ) . 4 In base ad essa costruiamo la tabella degli implicanti, che ha un numero di righe pari al numero di 1 della funzione, ovvero otto; ogni riga è contrassegnata con l’equivalente decimale della combinazione binaria delle variabili per la quale la funzione vale 1 e le dieci combinazioni sono ripartite in sezioni secondo il peso e all’interno della sezione sono in ordine crescente (tabella a): a 11 00 1 1 0 00 01 1 10 01 13 11 15 1 00 11 8 8 5 56 6 10 10 12 7 12 13 7 15 b 00 00 0 0 1 11 10 01 1 1 a)1 11 1 c 00 00 0 0 0 01 11 10 01 10 01 1 a) d 00 11 0 0 1 10 00 0 01 11 11 1 √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ 0,1 0,8 1,5 8,10 8,12 5,7 5,13 6,7 12,13 7,15 13,15 a 0 – 0 1 1 0 – 0 1 – 1 b 0 0 – 0 – 1 1 1 1 1 1 c 0 0 0 – 0 – 0 1 0 1 – d – 0 1 0 0 1 1 – – 1 1 a b c d 5,7,13,15 – 1 – 1 c) √ √ √ √ b) Eseguiti tutti i possibili prodotti di fusione, la tabella si trasforma in quella indicata in b) e da questa con un ulteriore passo si ottiene la tabella finale c). A questo punto non sono più possibili fusioni e le combinazioni che nelle tre tabelle non hanno fuso corrispondono ad altrettanti implicanti primi, che pertanto sono: abc, bcd, acd, abd, acd, abc, abc, bd Prima di proseguire osserviamo un fenomeno che si presenta molto frequentemente nel procedimento descritto. Esso consiste nel fatto che ogni combinazione contenente due o più posizioni vuote può essere generata dalla fusione di più coppie di righe. Questo è il caso della combinazione –1–1 ottenuta al secondo passo dalla fusione della riga (5,7) con (13,15) e della - 41 - riga (5,13) con (7,15). Un modo di evitare questa ripetizione è quello di considerare solo quelle coppie di combinazioni in sezioni adiacenti i cui equivalenti decimali formano una successione crescente: così la coppia ((5,7)–(13,15)) è da considerare, mentre non lo è la coppia ((5,13)–(7,15)). Tuttavia bisogna ricordarsi di contrassegnare come partecipanti a fusione tutte quelle righe i cui equivalenti decimali figurano in qualche riga prodotta dalla fusione di altre coppie; così le righe (5,13) e (7,15), pur non essendo prese in considerazione, devono essere contrassegnate perchè i loro equivalenti figurano nella riga (5,7,13,15) della terza tabella. L’altra possibilità consiste nell’effettuare comunque la fusione, ma non scriverla se già presente in qualche riga di una tabella. 2.6.2 - Fase b) In questa fase viene costruita un’espressione SP prima non ridondante per la forma minima della funzione, esaminando le relazioni tra gli implicanti primi ed i mintermini della funzione stessa. In questo processo si fa uso di una tabella, detta tabella di copertura, in cui ogni riga corrisponde ad un implicante ed ogni colonna ad un mintermine ossia ad un 1. L’incrocio della riga i con la colonna j viene contrassegnato con ×, se l’implicante relativo a quella riga copre l’1 relativo alla colonna. Una forma SP minima viene ricavata dalla tabella di copertura come somma degli implicanti corrispondenti ad un insieme R di righe della tabella tale che: • R copre la tabella, ovvero per ogni colonna della tabella esiste almeno una riga che presenta un contrassegno in quella colonna; • fra tutti i possibili insiemi che possono essere scelti in accordo al punto precedente, R è quello di minima cardinalità. Per poter determinare l’insieme R si applicano due criteri detti essenzialità e dominanza. Una riga è detta essenziale se esiste almeno una colonna che ha un contrassegno solo in corrispospondenza di essa; l’implicante corrispondente è essenziale e deve figurare nella forma minima SP della funzione. Una riga i domina una riga j se oltre agli stessi contrassegni della riga j presenta almeno un contrassegno in più. Illustriamo il procedimento attraverso l’esempio fatto per la fase a). La tabella di copertura si presenta come mostrato di seguito, avendo indicato, per comodità, con le lettere maiuscole dalla A alla H nell’ordine gli implicanti elencati al termine della fase a). Il primo passo consiste nel determinare, se ve ne sono, tutte le colonne che hanno una sola ×: per esse esiste un solo implicante che copre l’1 corrispondente; tale implicante, come detto, è essenziale e la riga associata prende il nome di riga essenziale, mentre la colonna è detta distinta. Nella tabella dell’esempio le colonne 6, 10 e 15 sono distinte e le righe D, F ed H sono essenziali; i rispettivi implicanti devono figurare perciò in qualunque forma SP minima. - 42 - 0 1 5 6 7 A × × B × C × × D E F × × G H × × 8 10 12 13 15 × × × × × × × × × Tutte le colonne distinte e le righe essenziali vengono cancellate dalla tabella. La cancellazione di una riga essenziale comporta la cancellazione anche delle colonne che, pur non essendo distinte, hanno una × in quella riga: infatti l’1 di ciascuna di quelle colonne è coperto almeno dall’implicante della riga essenziale e non occorre ricercare per esso altre coperture. Nella tabella data la cancellazione della riga D comporta la cancellazione anche delle colonne 8 e 10 (distinta); la cancellazione della riga F determina la cancellazione anche delle colonne 6 (distinta) e 7; infine la cancellazione della riga H fa sparire le colonne 5, 7, 13 e 15 (distinta). Al termine di questo passo, per la forma minima possiamo scrivere: f = D + F + H + … = abd + abc + bd + … mentre la tabella di copertura si riduce alla seguente: 0 1 12 A × × B × C × E × G × In essa si osserva che le righe B e C sono dominate dalla riga A e possono essere eliminate, lasciando inalterate le colonne 0 ed 1 dove hanno rispettivamente un contrassegno; la tabella si riduce ulteriormente alla seguente: - 43 - 0 1 12 A × × E × G × In questo modo la riga A diventa essenziale (secondaria) per le colonne distinte 0 ed 1, pertanto l’implicante associato dovrà fare parte della forma minima; la cancellazione di A comporta la cancellazione anche delle colonne 0 ed 1 e la tabella si riduce alla colonna 12 e alle righe E ed H. Queste sono uguali, avendo gli stessi contrassegni, per cui una delle due è superflua e può essere rimossa; quella rimasta diventa allora essenziale e l’implicante associato dovrà entrare a far parte della forma minima: se si cancella la riga E, rimane la H come essenziale secondaria, viceversa se si cancella la riga H, rimane come essenziale la E e in definitiva il procedimento porta ad individuare due forme minime: ⎧ ⎪ E ⎪ ⎩ G f = D+F+H+A+⎨ ⎧ ⎪ acd ⎪ ⎩ abc = abd + abc + bd + abc + ⎨ 2.6.3 - Tabelle cicliche Può accadere che nella tabella di copertura esistano o rimangano righe e colonne non vuote che non possono essere cancellate nè invocando l’essenzialità nè la dominanza: una tabella di questo genere è detta ciclica e può presentarsi quando esistono più forme prime non ridondanti. Il procedimento più comunemente seguito per risolvere una tabella ciclica è noto come metodo dell’albero binario ed è articolato in più passi, in corrispondenza di ciascuno dei quali sono eseguite due fasi applicate alla riga della tabella di copertura incompleta che ha più contrassegni, fino a completare una di due forme non ridondanti possibili. fase a) Si considera la riga selezionata come essenziale e si semplifica la tabella cancellando quella riga e le colonne coperte da essa; quindi si procede alla ulteriore riduzione applicando iterativamente i passi illustrati nel paragrafo precedente. fase b) Si considera la riga selezionata come eliminabile, quindi la si rimuove lasciando inalterate le colonne coperte da essa; dopo la sua rimozione si semplifica la tabella secondo il consueto procedimento. E` ovvio che durante l’esecuzione di ogni fase può risultare un’ulteriore tabella ciclica, per cui la procedura è di fatto ricorsiva e può portare ad una molteplicità di forma minime, tra le quali verrà scelta quella di costo minimo, per minimo numero di termini prodotto e/o di letterali distinti. - 44 - 2.7 - Funzioni non completamente specificate Accade di frequente che il valore di una funzione logica non debba essere specificato per tutte le combinazioni di valori delle sue variabili ma solo per alcune, e ciò per vari motivi: a) in relazione ad un dato problema, certe combinazioni di valori non si presentano mai, in quanto codificano informazione non richiesta; b) il valore dell’uscita non ha interesse per certe combinazioni, in rapporto allo specifico problema, quindi è inutile generarle. c) alcune combinazioni sono proibite perchè corrispondono a valori dei segnali di ingresso alla rete che realizza la funzione i quali, per ragioni tecnologiche, non devono essere mai applicati. Supponiamo per esempio che una funzione di quattro variabili debba riconoscere le cifre decimali pari e quelle dispari, assumendo valore 0 per le prime e valore 1 per le seconde. È chiaro che in questo problema non è significativo il valore assunto dalla funzione per le combinazioni di valori delle sue variabili corrispondenti agli interi da 10 a 15, che pure con quattro variabili binarie sono rappresentabili. In tutti questi casi si dice, sia pure impropriamente, che siamo in presenza di funzioni incomplete o non completamente specificate; le combinazioni di valori delle variabili per le quali il valore della funzione non è specificato si dicono condizioni di indifferenza (don’t care) e ad esse corrispondono nel metodo delle mappe di Karnaugh caselle contrassegnate in qualche modo, ad esempio con ×. Ai fini della sintesi ottima di una rete che realizzi una funzione incompleta f, siano h le condizioni di indifferenza della funzione; esistono allora 2h modi distinti di specificare tali valori come 1 o come 0 e quindi 2h distinte funzioni complete f ' che coprono la funzione f. Tra esse si sceglie, per la sintesi, quella che consente di realizzare la rete di costo minimo. In pratica sulla mappa di Karnaugh della funzione f tutti i valori × vengono specificati come 1 o come 0, a seconda che ci si riferisca ad una mappa di 1 o di 0. Quindi si cerca una forma prima non ridondante, tenendo conto che in essa non devono essere presenti implicanti o implicati primi che non coprono 1 o 0 appartenenti anche alla funzione f. Per esempio per il problema del rilevatore della parità di una cifra decimale avremo la seguente mappa: cd 00 01 11 10 ab β 00 1 1 01 1 1 11 × × × × 10 1 × × Fig. 2.13 - 45 - α γ Specificando le × come 1 si ottiene una nuova mappa, relativa ad una delle funzioni complete f ', che ammette la forma prima non ridondante {α, β, γ} e che copre la funzione f. Poichè gli implicanti β e γ coprono punti di f ' ma non di f, la forma prima non ridondante di questa sarà costituita solo dall’implicante α, per cui avremo f = d, come peraltro era da aspettarsi. La presenza di condizioni di indifferenza viene simbolicamente indicata, nella forma SP, con la notazione ∆n(l1, l2, ..., lγ), dove gli interi li per i = 1, ..., γ-1, γ ∈ {1, 2, ..., 2n} indicano le caselle della mappa di Karnaugh o equivalentemente le righe della tabella di verità per le quali non è significativo il valore della funzione ed n è il numero delle variabili. 2.8 - Reti a più uscite 2.8.1 - Definizione del problema Spesso le reti combinatorie hanno molteplici uscite ed esistono perciò più funzioni, ciascuna delle quali controlla una delle uscite della rete, correlandone i valori a quelli presenti in ogni istante sugli ingressi ed espressi dai valori di n variabili x0, x1, ..., xn-1. In linea di principio la sintesi di una rete a più uscite potrebbe consistere nella sintesi separata delle reti per le singole funzioni, con gli ingressi a comune: sarebbe una soluzione molto semplice ma certamente non sempre ottima. Per rendercene conto basta esaminare due semplici casi. Sia data una rete a due uscite, definite dalle funzioni: f1 = ∑ ( 1, 3, 7 ) f2 = 3 ∑ ( 3, 6, 7 ) 3 la sintesi separata di esse porta alle seguenti espressioni minime derivabili dalle mappe di Fig. 2.14: yz yz 00 01 11 10 00 01 11 10 0 1 1 0 1 x x 1 1 1 1 1 f1 = xz+yz f2 = yz+xy Fig. 2.14 cui corrisponde la seguente rete (Fig. 2.15): - 46 - x f1 z y f2 x Fig. 2.15 È ovvio che questa non è la soluzione ottimale, dal momento che l’implicante primo yz è comune alle forme minime di entrambe le funzioni e può quindi essere sintetizzato una sola volta, mediante una sola porta AND la cui uscita è collegata all’ingresso delle porte OR di uscita di f1 ed f2. Si passa in questo modo alla rete di Fig. 2.16, che è ottima: x f1 z y f2 x Fig. 2.16 Tuttavia il procedimento che è stato seguito in questo esempio non è sempre così chiaramente intuibile, come risulta da un altro caso. Le due funzioni siano infatti: f 1 = ∑ ( 1, 3, 7 ) f 2 = ∑ ( 2, 6, 7 ) 3 3 alle quali corrispondono due reti minime ottenute dalle mappe della figura seguente: yz yz 00 01 11 10 00 01 11 10 0 1 1 0 1 x x 1 1 1 1 1 f2 = xy+yz f1 = xz+yz Fig. 2.17 Esse non hanno implicanti primi in comune per cui sembrerebbe che l’unica realizzazione possibile fosse la rete di Fig. 2.18: - 47 - x f1 z y z f2 x Fig. 2.18 Invece si può osservare che in entrambe le funzioni esiste un 1 nella stessa posizione 111 ≡ 7, per cui se esso viene coperto con il mintermine xyz, le due funzioni acquistano l’espressione: f 1 = xz + xyz f 2 = yz + xyz alle quali corrisponde la rete di Fig. 2.19 che, pur non essendo minima, è più economica della precedente avendo meno porte: x f1 z x y f2 z Fig. 2.19 Questi esempi mettono in luce che nella sintesi di reti a più uscite occorre tenere conto di due fatti importanti, sui quali deve essere basata una tecnica di progetto specifica: 1) non è pensabile di sintetizzare le singole funzioni separatamente; 2) non sempre la definizione di un insieme non ridondante di implicanti (o di implicati) primi porta ad una soluzione globale migliore, anzi non è sufficiente considerare solo implicanti (o implicati) primi. Per risolvere il problema osserviamo che la forma più generale di una rete combinatoria in forma SP ad m uscite è quella nella quale vi sono porte AND collegate ad una sola porta OR di uscita, porte AND collegate a due porte OR di uscita, ecc., ed infine porte AND collegate ad m porte OR di uscita. Inoltre possono esservi ingressi della rete collegati direttamente alle porte OR di uscita: essi possono essere considerati equivalenti a porte AND con gli ingressi uguali (Fig. 2.20). - 48 - fj fj implicante di fj f1 fj f2 fk implicante di fj·fk implicante di f1·f2·…·fm fm Fig. 2.20 Se una porta AND è collegata ad una sola porta di uscita j della rete, esiste una ed una sola combinazione di valori dei suoi ingressi per la quale la sua uscita vale 1 e di conseguenza vale 1 anche l’uscita della rete e la funzione fj associata. Questa porta realizza pertanto un implicante della funzione fj e se la rete è minima si tratta certamente di un implicante primo. Consideriamo ora una porta AND che alimenta due porte OR di uscita j e k. Per una ed una sola combinazione di valori degli ingressi la sua uscita è 1 e di conseguenza sono 1 le uscite delle porte OR ad essa collegate e in definitiva le funzioni fj ed fk associate. Viceversa se l’uscita della porta AND è 0, può darsi che fj ed fk continuino ad essere 1, oppure può darsi che una o l’altra (o eventualmente entrambe) siano 0: se ciò accade sicuramente è 0 la funzione prodotto fj·fk, pur non essendo necessario che siano 0 tanto fj quanto fk. Pertanto il prodotto delle variabili che sono di ingresso a quella porta AND implica la funzione prodotto fj·fk, che vale 1 se e solo se fj ed fk valgono 1. Se la rete è globalmente minima, la rimozione di un ingresso dalla porta AND che alimenta fj ed fk può alterare il valore di fj o di fk (o di entrambe), ma sicuramente altera la funzione fj·fk: il prodotto generato dalla porta AND è un implicante primo di fj·fk, mentre non è detto che lo sia anche delle funzioni componenti. Questa situazione si presenta nel secondo esempio, nel quale il prodotto xyz è implicante primo di f1·f2, in quanto si ha: f 1 ⋅ f 2 = ∑ ( 7 ) = ( xz + yz ) ( yz + xy ) = xyz 3 ma non di f1 nè di f2, dal momento che nelle loro espressioni è possibile eliminare rispettivamente x o z dal prodotto xyz senza alterare il loro valore: - 49 - f 1 = xyz + xz = z ( xy + x ) = z ( y + x ) = yz + xz f 2 = xyz + yz = y ( xz + z ) = y ( x + z ) = xy + yz Estendendo queste considerazioni ad una porta AND collegata ad r uscite, f1, f2, ..., fr, si può affermare che essa corrisponde ad un implicante primo della funzione f1·f2·...·fr e, in generale, possiamo concludere che l’insieme di tutte le porte di ingresso della rete corrisponde all’insieme degli implicanti primi di f1, f2, ..., fm, f1·f2, …, f1·fm, …, fm-1·fm, …, f1·f2·...·fm. Per il progetto ottimo di una rete a più uscite è dunque necessario generare gli implicanti primi delle singole funzioni di uscita e di tutte le funzioni prodotto a 2 a 2, a 3 a 3, ..., ad m ad m delle funzioni date. Questi implicanti si dicono implicanti primi multipli; più precisamente un implicante multiplo risponde alla seguente definizione: Un implicante primo multiplo di un insieme di m funzioni f1, f2, ..., fm è un prodotto di variabili di ingresso che costituisce 1) un implicante primo di una delle funzioni date fj, oppure 2) un implicante primo di una delle funzioni prodotto f j ⋅ f j ⋅ … ⋅ f j , 1 2 k jk = 1, …, m, k ≤ m. La scelta di quali implicanti primi multipli siano da selezionare per la forma minima viene effettuata con i metodi già visti per le reti ad una uscita, adattati al caso specifico; considerazioni analoghe valgono per le reti a più uscite in forma PS, cioè aventi porte AND come porte di uscita. 2.8.2 - Sintesi delle reti a più uscite con le mappe di Karnaugh La sintesi viene effettuata in due passi. Il primo passo consiste nel determinare gli implicanti primi multipli, utilizzando le mappe di Karnaugh per le funzioni date e per le funzioni prodotto di esse a 2 a 2, a 3 a 3, ..., ad m ad m. Il secondo passo consiste nel ricavare una scelta opportuna di implicanti primi multipli, ricordando che in essa devono figurare necessariamente gli implicanti essenziali, la cui definizione è estesa rispetto a quella data a suo tempo nel seguente modo: Siano f1, f2, ..., fm m funzioni delle medesime variabili x0, x1, …, xn-1 e {P1, P2, ..., Pr} il corrispondente insieme di implicanti primi multipli. Un implicante primo multiplo della funzione fi o di qualunque prodotto di funzioni comprendente fi, è detto essenziale per la funzione fi se e solo se è l’unico che include un prodotto fondamentale di fi; quel prodotto fondamentale è detto distinto e quell’implicante deve figurare nell’espressione di fi. - 50 - Per esempio, date le seguenti funzioni ed il loro prodotto : f 1 = ∑ ( 0, 1, 5, 8, 11 ) f 2 = ∑ ( 1, 5, 9, 10, 11, 13, 15 ) 4 4 f 1 f 2 = ∑ ( 1, 5, 11 ) 4 è immediato determinarne sulle relative mappe (Fig. 2.21) gli implicanti primi multipli, elencati di seguito: f1: {A ≡ a b c, B ≡ a c d, C ≡ a c d, D ≡ a b d}; f2: {E ≡ c d, F ≡ a d, F ≡ a b c}; f1f2: {B ≡ a c d, H ≡ a b c d}. B cd 00 01 11 10 00 1 1 01 1 ab 11 1 10 1 A C f1 E B cd cd 00 01 11 10 00 01 11 10 F 00 1 00 1 01 1 1 01 ab ab 11 1 1 11 1 1 1 1 10 10 H G f1 f2 f2 D Fig. 2.21 Per la funzione f1, l’implicante primo multiplo B è essenziale, in quanto copre l’1 in posizione 5 e come tale deve essere selezionato per la forma minima. B è implicante primo multiplo anche della funzione f1f2, ma non della funzione f2, per la quale gli 1 in posizione 1 e 5 sono coperti dall’implicante E; quindi per f2 si dovrebbe selezionare E e non B. D’altra parte però l’implicante F è essenziale per f2, mentre non lo è per f1 e tanto meno per f1f2; la selezione di F per f2 garantisce la copertura degli 1 di questa funzione in posizione 9, 11, 13 e pertanto conviene rinunciare ad E e coprire gli altri due 1 in posizione 1 e 5 con B, con un risparmio complessivo di un implicante. L’1 in posizione 10 dovrebbe essere coperto dagli implicanti primi multipli essenziali D e G per f1 ed f2 rispettivamente; tuttavia al loro posto conviene selezionare l’implicante primo multiplo essenziale H della funzione f1f2, essendo già stato coperto per f2 l’1 in posizione 11con la scelta di F e potendo coprire l’1 in posizione 8 per f1 con l’implicante primo multiplo C in alternativa ad A. La scelta di C rende superfluo l’implicante A di f1. Pertanto le espressioni di f1 ed f2 sono: f1 = B+C+H ≡ a c d+b c d+a b c d f2 = B+F+H ≡ a c d+ad+a b c d - 51 - ESERCIZI 1) Delle seguenti funzioni trovare: a) gli implicanti o gli implicati primi; b) gli implicanti o gli implicati primi essenziali; c) tutte le espressioni minime SP o PS; d) le forme NAND e NOR: f = ∑ ( 0, 1, 2, 5, 6, 7 ) 3 f = ∑ ( 1, 3, 4, 6, 7, 9, 12, 13 ) 4 f = ∑ ( 0, 1, 2, 3, 5, 7, 8, 9, 10, 16, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31 ) 5 f = ∏ ( 0, 1, 2, 5, 7, 10, 11, 14, 15, 16, 17, 18, 21, 23, 26, 27, 30, 31 ) 5 f = ∏ ( 0, 1, 2, 4, 5, 7, 9, 10, 11, 13, 15 ) 4 2) Minimizzare le seguenti funzioni con il metodo tabellare di Quine-McCluskey: f = Σ4(1, 2, 4, 5, 7, 8, 10, 13, 14, 15) f = Σ4(1, 2, 7, 8, 9, 10, 13, 15) 3) Minimizzare le seguenti funzioni, specificando in modo appropriato le condizioni di indifferenza: f = Σ 4( 1, 2, 7, 8, 10, 13, 15 ) + ∆ ( 0, 5, 11, 12 ) f = Π 4( 1, 9, 14, 15 ) ⋅ ∆ ( 4, 5, 6, 7 ) f = Σ 4( 1, 4, 9, 14, 15 ) + ∆ ( 2, 5, 6, 11, 12 ) 4) Sintetizzare in forma minima le seguenti reti a più uscite: f 1 = Σ 3 ( 0, 1, 3, 5, 7 ) f 2 = Σ 3 ( 1, 2, 3, 4, 6 ) f 3 = Σ 3 ( 5, 6, 7 ) f 1 = Σ 4 ( 0, 2, 4, 5, 7, 10, 15 ) f 2 = Σ 4 ( 0, 1, 3, 4, 5, 6, 14 ) f 3 = Σ 4 ( 1, 3, 5, 7, 8, 12, 15 ) f 1 = Σ 4 ( 0, 2, 3, 4, 8, 12, 13 ) f 2 = Σ 4 ( 2, 3, 5, 6, 7, 8, 13, 14, 15 ) f 1 = Π 4 ( 2, 3, 8, 12, 13 ) f 2 = Π 4 ( 2, 3, 5, 6, 7, 8, 12, 13, 14, 15 ) - 52 - f1 = Σ4 (1, 3, 5, 8, 9, 11, 13) f2 = Σ4 (3, 5, 7, 8, 13, 14, 15) f 1 = ∑ ( 0, 4, 5, 6, 7, 8, 11, 15 ) 4 f 2 = ∑ ( 4, 5, 7, 14, 15 ) 4 f 3 = ∑ ( 1, 6, 7, 9, 13, 14, 15 ) 5) Trovare la rete NAND ottima per le funzioni: f1 = Π4(2, 3, 8, 12, 13) f2 = Π4(2, 3, 5, 6, 7, 8, 12, 13, 14, 15) 6) Realizzare un circuito combinatorio che riceve in ingresso un numero intero di cinque bit e riconosce se si tratta di un numero primo; il circuito deve essere in forma minima SP e in forma NOR. 7) Data la funzione descritta dalla seguente mappa, si realizzi la relativa rete logica: d,e b,c d,e 00 01 11 10 00 01 11 10 00 1 0 1 1 1 1 0 1 01 × 1 1 1 1 0 × 1 11 × 1 × 0 × 0 × × 10 × × × 1 1 × 0 × a=0 a=1 8) Una rete combinatoria ha quattro ingressi a, b, c, d ed una uscita z, la quale dipende dagli ingressi secondo la funzione: f 1 = ac + ab + bcd + ac Si vuole trasformare la rete in un’altra con gli stessi ingressi e funzione di uscita f 2 = bc + bd + bcd , mediante una seconda rete avente funzione di uscita F(a, b, c, d). Trovare l’espressione minima di F e specificare quale operazione logica deve essere realizzata tra f1 ed F per ottenere il risultato voluto. - 53 - 9) Data la funzione f1 = Σ4(0, 1, 3, 4, 5, 7, 8, 9, 11, 15), realizzare la funzione f = Σ(0, 1, 2, 3, 4, 5, 7, 10, 11, 14, 15), combinandola con un’opportuna funzione f2. 10) Da un gruppo di quattro soldati devono essere selezionati 2 o 3 volontari per una missione pericolosa. Interrogati dal comandante circa le condizioni per la loro disponibilità, i quattro danno le seguenti risposte: soldato A: è disposto ad andare con B e D, con B e C, con C e D oppure con B da solo, ma non con C né con D da soli; soldato B: può andare con C o con D, ma non con entrambi, a meno che non sia presente anche A; soldato C: non va d’accordo con D, tranne quando è presente anche A, mentre va sempre d’accordo con B; soldato D: non vuole né A né C da soli, ma è disposto a fare gruppo con entrambi; con B va d’accordo e accetta anche di far parte di un gruppo di tre soldati in cui oltre a B ci sia A. Studiare una rete logica NOR di minimo costo per aiutare il povero comandante a capire quali gruppi potrebbe formare. 11) Un circuito combinatorio ha due ingressi di due bit ciascuno a(a0, a1) e b(b0, b1), un ingresso o di un bit ed una uscita z, pure di un bit. a b a0 a1 b0 z b1 o Se o vale 1, l’uscita assume valore 1 se a > b, altrimenti vale 0. Se o vale 0, l’uscita vale 1 se a < b. Si definisca il circuito attraverso la tavola di verità della funzione z = f(o, a0, a1, b0, b1) e se ne dia una realizzazione in forma minima PS. 12) Progettare una rete logica che simula il comportamento di un visitatore in un labirinto come quello illustrato in figura, nel quale I indica il punto di ingresso ed i numeri 1, 2 e 3 indicano le uscite possibili: - 54 - 1 2 I 3 Nota: indicare con variabili logiche le alternative di fronte alle quali si trova il visitatore in corrispondenza dei bivi. 13) Realizzare un circuito “maggioritario”, ossia un circuito che rileva se tra n ingressi, con n dispari, almeno (n+1)/2 sono uguali; fare il caso di n = 5. 14) Realizzare la funzione f = acd + bcd + abd + abc come combinanzione di tre funzioni f1, f2, f3 secondo l’espressione f = f1f2+f3, sapendo che f 1 = a ⊕ b . 15) Data la funzione f = Σ4(0, 1 ,2, 3, 9, 11, 13, 15), si realizzi una rete per la funzione F = Π4(1, 3, 4, 6, 8, 10, 11, 12) secondo la forma F = f•f1, essendo f1 una funzione da definirsi ed il simbolo • un opportuno operatore logico da individuarsi come una delle 16 funzioni di 2 variabili. 16) Realizzare un comparatore per coppie di numeri di due bit in complemento a due, il quale dà in uscita l’informazione se i due numeri sono uguali, oppure qual è il più grande. 17) Un dispositivo di acquisizione dati possiede due ingressi di controllo p ed s per la selezione del modo di funzionamento; purtroppo il costruttore non ha tenuto conto del fatto che quando entrambi i controlli sono 1, il dispositivo non può funzionare correttamente, mentre se entrambi sono 0 nessuna operazione ha luogo. Si realizzi una rete impedisce il verificarsi della situazione di errore, per qualunque coppia di valori - 55 - assegnata ai due segnali di controllo (v. figura). Proporre più di una soluzione. p p’ s’ ? s dispositivo di acquisizione 18) Realizzare un circuito combinatorio che converte una cifra decimale dal codice 8, 4, 2, 1 al codice 8, 4, -2, -1, sapendo che le cifre con le quali si caratterizza un codice posizionale sono i pesi da attribuire ai singoli bit della rappresentazione in tale codice, a seconda della loro posizione. Esempio: il numero 6 è rappresentato dalla consueta stringa 0110 nel codice 8, 4, 2, 1 e dalla stringa 1010 nel codice 8, 4, -2, -1 19) Realizzare un circuito che converte una cifra decimale dal codice BCD (Binary Coded Decimal, ovvero decimale codificato in binario) al codice Gray; questo può essere costruito dal corrispondente codice BCD secondo le relazioni: gi = bi ⊕ bi + 1 , i = 0, …, 3 e b 4 = 0 20) Realizzare un circuito incrementatore modulo 10, ossia un circuito con quattro ingressi e quattro uscite che funziona nel modo seguente. Quando all’ingresso si presenta una delle configurazioni binarie corrispondenti ai numeri decimali tra 0 e 8 compresi, le uscite assumono la configurazione binaria che corrisponde all’intero successivo di quello in ingresso, mentre se all’ingresso si presenta una delle configurazioni che rappresentano uno degli interi tra 9 e 15, le uscite assumono la configurazione degli interi tra 0 e 6. 21) Ripetere l’esercizio 20), considerando come condizioni di indifferenza tutti gli ingressi tra 9 e 15. 22) Realizzare un circuito che calcola il numero X mod m, per interi X di 5 bit e per una scelta arbitraria di m ≥ 2. - 56 - 23) Un circuito combinatorio implementa la funzione f = a + bc + acd , ma durante il collaudo si scopre che per gli stati di ingresso 0011, 0111 e 0010 si verificano anomalie di funzionamento; realizzare un circuito da applicare agli ingressi del circuito difettoso, in modo da evitarne il malfunzionamento. 24) Una stringa binaria di 4 bit può contenere una cifra decimale codificata secondo la seguente tabella;Nessun’altra configurazione è significativa. Si progetti un circuito in forma minima NOR che riceve in ingresso la stringa binaria e dà in uscita 01 se essa contiene 0, 2, 6, 7, oppure 8; 10 se contiene un’altra configurazione legittima; 11 altrimenti. 0 1 2 3 4 5 6 7 8 9 0011 0100 0101 0111 1000 1001 1011 1100 1101 1111 25) Un impianto idraulico è costituito da un pozzo P, una pompa M, un serbatoio S ed un utilizzatore U. La pompa è usata sia per prelevare l’acqua dal pozzo e mandarla nel serbatoio o all’utilizzatore, sia per mandare l’acqua dal serbatoio all’utilizzatore. Per questo nell’impianto si trovano le elettrovalvole V1 e V2, che scelgono l’afflusso all’entrata della pompa (V1 aperta, V2 chiusa: acqua dal pozzo; V1 chiusa, V2 aperta: acqua dal serbatoio), e le elettrovalvole V3 e V4 all’uscita della pompa (V3 aperta, V4 chiusa: acqua al serbatoio; V3 chiusa, V4 aperta: acqua all’utilizzatore). Inoltre quattro sensori rilevano la condizione dell’impianto e precisamente s1 avverte se nel pozzo c’è acqua, s2 avverte se il serbatoio è pieno, s3 se è vuoto ed infine s4 rileva se l’utilizzatore richiede acqua. - 57 - s2 V3 V2 V4 S M V1 U s3 s4 P Rete Logica s1 Se il serbatoio non è pieno, nel pozzo c’è acqua e l’utilizzatore non la richiede, la pompa è in funzione e le valvole sono orientate in modo da fare affluire l’acqua al serbatoio. Invece se l’utilizzatore richiede acqua ed il serbatoio ne contiene, la pompa è in funzione con le valvole disposte in modo da alimentare U dal serbatoio; se questo è vuoto, l’utilizzatore riceve l’acqua dal pozzo. In ogni altro caso la pompa è ferma e le valvole si trovano in qualsiasi posizione che eviti il pericolo di riversare acqua dal serbatoio al pozzo. Si progetti una rete logica in forma minima che ha come ingressi i segnali binari generati dai sensori e come uscite cinque segnali binari per il controllo delle valvole e del motore della pompa. 26) Sintetizzare mediante porte NOR la rete combinatoria di figura in modo che l’uscita q abbia il valore indicato in tabella per le varie combinazioni degli ingressi di controllo a e b, e l’uscita e assuma valore 1 in caso di errore per traboccamento, operazione impossibile, ecc. x q y e a b - 58 - a b q 0 0 1 1 0 1 0 1 (x+y) mod 2 (x-y) mod 2 xy mod 2 x/y mod 2 Capitolo 3 PROGETTO LOGICO DELLE RETI COMBINATORIE II Parte - Reti a più di due livelli di logica e Reti modulari 3.1 - Introduzione Le reti a due livelli di logica, pur essendo particolarmente apprezzabili per le doti di velocità, non si prestano ad essere utilizzate in qualunque situazione per due ragioni principali: a) non sempre queste reti presentano valori minimi dei parametri Ng ed Nd rispetto a reti con più di due livelli di logica; b) esistono vincoli di natura tecnologica sul numero massimo di segnali di ingresso e di uscita che limitano la pratica realizzabilità delle reti a due livelli per qualsiasi applicazione. Esaminiamo brevemente queste due categorie di problemi. a) Per il primo punto, un semplice esempio risulta significativo per dimostrare come reti a due livelli possano essere più costose di quelle a più livelli, in termini di valori di Ng ed Nd. Consideriamo la funzione “generatore di parità”, ossia una funzione di n variabili che assume valore 1 se il numero di variabili con valore 1 è dispari e 0 altrimenti. Tale funzione è descritta da una mappa di Karnaugh configurata a scacchiera, nella quale una casella di 1 è circondata da n caselle di 0 e viceversa, come viene mostrato nella Fig. 3.1 per n = 4. - 59 - x3 x4 00 01 11 10 00 1 1 x1 x2 01 1 11 1 1 10 1 1 1 Fig. 3.1 E’ facile verificare che l’espressione che si ricava da questa mappa è l’OR esclusivo delle n variabili, ovvero: f(x0, x1, ..., xn-1) = x0⊕ x1⊕ ...⊕ xn-1 Nella realizzazione a due livelli di logica, poichè non esistono adiacenze tra le caselle di 1, tutti gli implicanti primi (che sono anche essenziali) hanno n letterali ed il loro numero è pari a metà delle caselle, ovvero 2n-1. La realizzazione richiede quindi 2n-1 porte AND ciascuna con n ingressi, seguite da una porta OR con 2n-1 ingressi; i parametri Ng ed Nd pertanto valgono: Ng = 2n-1+1 Nd = n·2n-1+2n-1 = (n+1)·2n-1 Nel caso di n = 8 risulta Ng = 129 e Nd = 1152, ossia valori chiaramente non realistici. Tuttavia la funzione in esame può essere realizzata anche collegando tra loro n-1 blocchi XOR a due ingressi secondo una struttura ad albero, come illustrato nella figura seguente: x0 x1 x2 x3 + x0⊕ x1 ⊕ ⊕ x0⊕ x1 ⊕ x2⊕ x3 x2⊕ x3 ⊕ xn-2 xn-1 x0⊕ x1 ⊕ ... ⊕ xn-1 ⊕ ⊕ xn-2⊕ xn-1 Fig. 3.2 Poichè ogni blocco XOR richiede tre porte (due AND ed un OR) con due ingressi ciascuna, avremo Ng = 3·(n-1) ed Nd = 3·2·(n-1), con una dipendenza lineare da n, anzichè esponenziale. Nel caso di n = 8 i valori di Ng ed Nd scendono rispettivamente a 21 e 42. - 60 - b) Per quanto riguarda il secondo tipo di problema, in una rete combinatoria con n ingressi, m uscite e p porte chiamiamo fan-out di un ingresso della rete xi , 0 ≤ i ≤ n-1 , o di un’uscita zj di una porta, 0 ≤ j ≤ p-1, il numero di porte alimentate da xi o da zj. Chiamiamo quindi fan-out della rete il massimo tra i fan-out dei suoi ingressi e delle uscite delle sue porte. Si dice invece fan-in di una porta il numero dei suoi ingressi; fan-in di una rete è il massimo fan-in delle sue porte (Fig. 3.3). l1 l2 lp fan-in = max{l1, l2, ..., lp} Fig. 3.3 Per questioni di natura tecnologica il fan-in ed il fan-out di una porta logica non possono superare determinati limiti. Poichè nelle reti a due livelli di logica il fan-in (ed anche il fan-out) possono assumere valori anche molto elevati, come nell’esempio di Fig. 3.1, tali reti non possono essere sempre realizzate, ma occorre ripiegare su strutture a più livelli di logica, derivate da quelle a due livelli attraverso l’uso della proprietà distributiva dell’algebra e in grado di mantenere il fan-in ed il fan-out dei singoli blocchi a livelli accettabili; ad esempio possono essere utilizzate strutture ad albero, come quella indicata nella Fig. 3.4a, detta libera da fan-in o quella della Fig. 3.4b, detta libera da fan-out. x0 x1 x2 x3 xn-2 xn-1 xi xi a) b) xi Fig. 3.4 Si osservi che in Fig. 3.4b i vari blocchi dell’albero non svolgono alcuna funzione logica, tranne riportare in uscita il segnale di ingresso convenientemente amplificato in modo da eliminare il problema del fan out. Essi prendono il nome di buffer. Purtroppo per le reti a più di due livelli di logica non si conoscono metodi sistematici di sintesi ottima e di conseguenza, nella ricerca della soluzione praticabile, si devono seguire vari approcci, più o meno basati su criteri euristici. - 61 - 3.2 - Partizionamento Nel caso di reti complesse un utile approccio alla sintesi può essere quello di cercare di suddividere l’intera rete richiesta per un dato problema in più sottoreti da collegare opportunamente tra loro; nella scomposizione si cerca di trovare un compromesso accettabile tra fan-in e/o fan-out e velocità di risposta. In pratica si tenta di individuare nella formulazione del problema combinatorio una serie di funzioni logiche abbastanza semplici, le quali concorrono a definire l’intera funzione richiesta per la soluzione. Per ciascuna funzione si progetta, possibilmente in forma minima, la rete corrispondente e infine tutte le reti vengono interconnesse secondo la logica definita dal problema. Vedremo nel prossimo paragrafo che molto spesso, accanto a funzioni generiche, è possibile riconoscere un numero - abbastanza ridotto - di funzioni tipiche ricorrenti frequentemente, alle quali corrispondono altrettante reti logiche utilizzabili come blocchi standard secondo un criterio modulare. E’ chiaro che più è fine il grado di partizionamento e più semplici e con bassi valori di fan-in e fan-out risultano le reti componenti, ma spesso a scapito della velocità. Per esempio si consideri il seguente problema: Progettare una rete combinatoria la quale, dati tre numeri interi di n bit, A, B, C, con A > B, produce in uscita C se risulta min {B, A-B} < C < max{B, A-B}; altrimenti produce in uscita 0. Per risolvere il problema, isoliamo le funzioni: a) calcolo della differenza tra A e B; b) calcolo del minimo tra B e la differenza A-B; c) calcolo del massimo tra B e la differenza A-B; d) confronto tra il minimo e C; e) confronto tra C ed il massimo; f) calcolo del valore logico che indica se entrambe le condizioni sono vere o almeno una delle due è falsa; g) scelta tra il numero C ed il numero 0 da far uscire dalla rete a seconda di quel valore. Associando un blocco logico a ciascuna funzione individuata e collegando i vari blocchi secondo l’ordine appropriato, si arriva al seguente schema a blocchi della rete (Fig. 3.5). 0 min ≤ B A B scelta min A-B max B ≤ max C Fig. 3.5 - 62 - Z Nella figura i vari blocchi sono identificati con la funzione che svolgono; le linee marcate indicano segnali di n bit, quelle sottili segnali di un solo bit. Per completare la realizzazione della rete logica rimane soltanto da sintetizzare a livello porte i vari blocchi, cercando, se possibile, di progettarli come reti a due livelli, esprimendone la funzione in forma SP o PS; così il blocco denominato “scelta” può essere realizzato sulla base della tavola di verità della sua funzione: detta x la variabile di uscita della porta AND e Ci il bit i-esimo del numero C e Zi il corrispondente bit dell’uscita Z, si ha: x 0 1 Zn-1 0 Cn-1 ... ... ... Z0 0 C0 Vale la pena notare che se il tempo di risposta è un parametro progettuale importante, si può migliorare la soluzione eliminando la porta AND e integrando nel blocco “scelta” la funzione f), per cui dette x0 e x1 le uscite dei due blocchi comparatori, la tavola di verità di “scelta” si modifica nel seguente modo: x1 0 0 1 1 x0 0 1 0 1 Zn-1 0 0 0 Cn-1 ... ... ... ... ... Z0 0 0 0 C0 Ovviamente questo va ad aumentare la complessità strutturale del blocco “scelta” ed in particolare il suo fan-in. Una particolare tecnica di partizionamento, frequentemente utilizzata, è la fattorizzazione. Essa consiste nel porre a fattore comune sottoespressioni che sono presenti in più termini prodotto o somma di espressioni booleane SP o PS , sfruttando la proprietà associativa del prodotto rispetto alla somma o della somma rispetto al prodotto. In questo modo una rete a due livelli viene spezzata in una cascata di sottoreti più semplici. Per esempio nell’espressione f = x 1 x 2 x 3 x 4 + x 1 x 2 x 3 x 4 entrambi i prodotti hanno in comune il termine x1x2; perciò l’espressione può essere riscritta come f = x 1 x 2 ( x 3 x 4 + x 3 x 4 ) la quale, pur avendo valori maggiori di Ng ed Nd, consente di realizzare una rete con un fan-in inferiore. La fattorizzazione può essere applicata iterativamente ad una stessa espressione, ottenendo ad ogni passo un aumento del numero dei livelli di logica, insieme alla riduzione della complessità del fan-in o del fan-out. - 63 - 3.3 - Reti combinatorie modulari In una rete logica di una certa complessità, accade spesso che accanto a porzioni che realizzano funzioni particolari, specifiche del problema e che prendono genericamente il nome di logica sparsa, ve ne siano altre per funzioni più generali, indipendenti dal problema specifico. Data la loro caratteristica, per queste funzioni non è necessario progettare reti ad hoc per ogni loro occorrenza, ma si ricorre a blocchi logici generali, identificati con un nome legato alla funzione svolta e di volta in volta è necessario solo definire alcuni parametri, come numero di ingressi e di uscite. Questi blocchi possono essere costruiti con tecnologia a media e larga scala di integrazione (MSI e LSI) sotto forma di circuiti integrati (chip) da montare su piastre a circuito stampato, per la realizzazione a componenti discreti di una rete logica, oppure possono essere integrati su silicio insieme all’intera rete, sotto forma di chip custom o di circuiti ASIC. In ogni caso il loro utilizzo consente di dare alla rete una notevole regolarità strutturale che facilita la costruzione e la testabilità, diminuisce i costi di progettazione e di fabbricazione, aumenta l’affidabilità. Un’altra caratteristica interessante di questi blocchi funzionali è la modularità, ovvero la possibilità di realizzare la loro funzione specifica per un determinato numero di ingressi ricorrendo a blocchi della stessa funzionalità, ma per un numero di ingressi inferiore, con tecnica ricorsiva. In questo caso il parametro che ha più interesse minimizzare è il numero totale dei moduli elementari, piuttosto che i parametri Ng o Nd, in quanto questo porta a minimizzare il numero dei circuiti integrati necessari. Nel seguito esamineremo alcune classi di funzionalità combinatorie di frequente uso nelle tecniche digitali, realizzabili mediante reti a due o più livelli di logica, seguendo l’approccio modulare descritto. 3.4 - Convertitori di codice A questa classe di funzionalità appartengono tutte le funzioni combinatorie che operano una trasformazione da un codice di rappresentazione di ingresso ad un diverso codice di uscita; con il nome di codificatori e decodificatori sono chiamate le reti che realizzano tali funzioni. 3.4.1 - Codificatori Un codificatore 2n×n è un circuito con 2n ingressi, x ,x 2n – 1 2n – 1 – 1 , …, x 0 , ed n uscite, zn-1, zn-2, ..., z0, nel quale le combinazioni possibili dei valori degli ingressi sono quelle che contengono un solo 1, ovvero quelle per le quali è: - 64 - xi = 1 0 ≤ i ≤ 2n-1 xj = 0 j ≠ i In corrispondenza a ciascuna di tali combinazioni di ingresso, in uscita si presenta la sequenza binaria: zn-1, zn-2, ..., z0 ≡ i ovvero le variabili zh, 0 ≤ h ≤ n-1, assumono una combinazione che rappresenta in binario l’intero i, 0 ≤ i ≤ 2n-1. In altri termini se si considerano le linee di ingresso ordinate da 0 a 2n-1, il valore dell’uscita indica il numero della linea di ingresso (contando a partire da 0)sulla quale è presente il valore logico 1. Per esempio un codificatore 22×2 è definito dalla seguente tavola di verità: x3 0 0 0 1 x2 0 0 1 0 x1 0 1 0 0 x0 1 0 0 0 z1 0 0 1 1 z0 0 1 0 1 Per tutte le rimanenti combinazioni di ingresso le uscite non sono specificate. E` facile verificare con l’ausilio delle mappe di Karnaugh che le espressioni delle uscite sono: z0 = x1+x3 z1 = x2+x3 Espressioni di questo tipo valgono in generale, ovvero ogni variabile di uscita è la somma logica di opportuni sottoinsiemi delle variabili di ingresso. Da tali espressioni deriva direttamente la struttura del codificatore, di cui la figura seguente mostra un esempio riferito al caso esaminato, insieme alla rappresentazione di un codificatore di dimensioni generiche 2n×n come blocco funzionale: x0 x1 x2 x3 x0 x1 2n×n z1 z0 z1 zn-1 x2n-1 z0 Fig. 3.6 Una applicazione dei codificatori è la seguente. In un sistema di elaborazione, affinché un - 65 - dispositivo di ingresso/uscita (periferica) possa comunicare con il processore, è necessario che ne richiami l’attenzione e si identifichi. Queste due azioni possono essere svolte insieme predisponendo per ogni periferica una linea di richiesta connessa al sistema attraverso un codificatore. In tal modo la periferica è individuata da un indirizzo, definito implicitamente dalla posizione della sua linea di richiesta all’ingresso del codificatore; l’attivazione di una di queste linee fornisce pertanto anche l’informazione necessaria per identificare la periferica (Fig. 3.7). P0 P1 P2 0 0 1 2n×n Processore Pn-1 0 Fig. 3.7 3.4.2 - Decodificatori I decodificatori sono reti molto importanti nelle applicazioni digitali, prime fra tutte quelle riguardanti la realizzazione di dispositivi di memoria. Limitandoci per semplicità ai decodificatori binari, si tratta di circuiti con n ingressi e 2n uscite tali che per ciascuna delle 2n combinazioni binarie degli ingressi solo una assume valore 1, mentre le altre sono 0. In altre parole un decodificatore interpreta ogni combinazione di ingresso come un numero naturale i nell’intervallo [0, 2n-1] e corrispondentemente attiva la linea di uscita che si trova nella posizione i. Poichè per ogni combinazione di ingresso solo uno dei possibili mintermini delle n variabili vale 1, le funzioni di uscita di un decodificatore sono semplicemente zi = x0*·x1*·...·xn-1*, xh* ∈ {xh, xh} e possono essere realizzate con una rete costituita da un unico livello di porte AND, almeno finchè il loro fan-in lo consente. Per esempio un decodificatore 2 a 4 (4 out of 2) è descritto dalla seguente tavola di verità: x1 0 0 1 1 x0 0 1 0 1 z3 z2 z1 z0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 - 66 - dalla quale si ricavano direttamente le espressioni delle uscite: z0 = x1x0 z1 = x1x0 z2 = x1x0 z3 = x1x0 La Fig. 3.8 riporta la struttura del decodificatore esemplificato ed il diagramma a blocchi generale: x0 z0 z1 x1 x0 x1 xn-1 e n×2n z2n -1 e z3 z2 a) z1 z0 b) Fig. 3.8 La figura inoltre mostra che, se oltre agli ingressi xi, i = 0, ..., n-1, si applica a tutte le porte AND uno stesso segnale binario e, si ottiene un decodificatore il cui funzionamento dipende proprio da e, nel senso che quando e = 0, le uscite sono tutte 0, indipendentemente dal valore attuale degli ingressi xi, mentre per e = 1, si realizza il normale funzionamento. L’ingresso e agisce come controllo, e viene indicato con il termine enable o select (linea tratteggiata in Fig. 3.8); invece gli ingressi xi costituiscono i dati. Quando il numero di ingressi è grande al punto che non è possibile realizzare un circuito di decodifica con un solo livello di porte, si ricorre a varie soluzioni le quali realizzano la rete sulla base di decodificatori di dimensioni più piccole. Per esempio un decodificatore 3×8 può essere realizzato con due decodificatori 2×4 ciascuno dei quali sia provvisto dell’ ingresso di enable, che viene alimentato dal bit più significativo per un decodificatore e dal suo complemento per l’altro, secondo lo schema a blocchi di Fig. 3.9: - 67 - z0 e z3 z4 x0 x1 x2 e z7 Fig. 3.9 Un metodo alternativo a quello ora illustrato consiste nel realizzare ricorsivamente un decodificatore n×2n mediante due decodificatori n/2×2n/2 ed una matrice di porte AND n×n; per esempio un decodificatore 4×16 può essere realizzato con due decodificatori 2×4 ed una matrice 4×4 di AND, come nella Fig. 3.10: matrice di AND 4×4 x0 x1 2×4 x2 x3 2×4 z15 z14 z13 z12 z11 z10 z9 z8 z7 z6 z5 z4 z3 z2 z1 z0 Fig. 3.10 A sua volta con due decodificatori 4×16 come quelli di Fig. 3.10 ed una matrice di porte AND 16×16 si può realizzare un decodificatore 8×256 e così via. Poichè tuttavia sono disponibili matrici generalizzate di porte, ovvero matrici h×h×...×h (k volte) aventi k·h ingressi riuniti in k gruppi di h ingressi ciascuno e hk uscite e nelle quali ogni porta AND ha k ingressi, uno per ognuno dei k gruppi di ingressi della matrice, un decodificatore 8×256 può essere realizzato anche partendo da 4 decodificatori 2×4 ed una matrice 4×4×4×4, com’è illustrato nella Fig. 3.11. La scelta della tecnica realizzativa dipende come sempre da - 68 - considerazioni tecnologiche e di costo: se ad esempio il criterio è la minimizzazione di Ng, è da preferire la seconda soluzione che richiede meno porte. x0 x1 z0 2×4 Matrice 4×4×4×4 x2 x3 (256 porte AND a 4 ingressi) 2×4 z255 2×4 2×4 x4 x5 x6 x7 Fig. 3.11 3.5 - Selettori Due funzionalità molto vicine alla decodifica sono quelle che effettuano la selezione di un segnale tra più, sia in ingresso (multiplexing) sia in uscita (demultiplexing). Le reti combinatorie che realizzano queste funzioni sono dette rispettivamente multiplexer o selettore di ingresso e demultiplexer o selettore di uscita. 3.5.1 - Multiplexer Un multiplexer è un circuito che seleziona uno tra n segnali in ingresso e lo instrada su un’unica linea di uscita z, mediante l’uso di k segnali di controllo y0, y1, ..., yk-1, k = log2n (Fig. 3.12). x0 x1 z xn-1 y0 y1 yk-1 Fig. 3.12 - 69 - La funzione di uscita z(x0, x1, ..., xn-1, y0, y1, ..., yk-1) si ottiene tenendo conto che per ogni combinazione dei segnali di controllo solo un segnale di ingresso deve essere selezionato; pertanto essa deve essere la somma logica dei prodotti di ciascun segnale xi per uno dei 2k ≥ n mintermini delle k variabili di controllo, ossia: z = p0 x0 + p1 x1 + … + pn – 1 xn – 1 = y 0 y 1 …y k – 1 x 0 + y 0 y 1 …y k – 1 x 1 + … + y 0 y 1 …y k – 1 x n – 1 Per esempio nel caso di n = 2, k = 1, si ottiene la semplice rete di Fig. 3.13, governata dalla funzione z = yx0+yx1: x0 z x1 y Fig. 3.13 Un multiplexer è una rete a due livelli di logica che, per quanto riguarda le varibili di controllo, è in forma canonica e come tale può essere sempre realizzata con n porte AND a k+1 ingressi ed una porta OR ad n ingressi. Tuttavia dall’espressione dell’uscita si deduce facilmente che il multiplexer è realizzabile mediante un decodificatore k×2k le cui uscite sono inviate ad una matrice n×n di porte AND a due ingressi insieme agli n ingressi xi; infine le uscite della matrice sono sommate in un OR ad n ingressi (o in una rete libera da fan-in equivalente) (Fig. 3.14). x0 x1 xn-1 y0 y1 yk-1 k×2k z Fig. 3.14 Il multiplexer trova una interessante applicazione, oltre quella propria per la quale è - 70 - progettato, anche come generatore universale di funzioni combinatorie di k variabili, o meglio come dispositivo per la lettura di tavole di verità di funzioni. Infatti se confrontiamo l’espressione della sua uscita con la formulazione del teorema di espansione di una funzione in forma SP si vede che esse coincidono, se interpretiamo y0, y1, ..., yk-1 come argomenti di una funzione f e le variabili x0, x1, ..., xk-1 come le uscite di tale funzione corrispondenti alle n combinazioni degli argomenti, quando ogni xi sia fissato ad un valore 0 o 1 in accordo alla tavola di verità della f. Per esempio la funzione di tre variabili definita dalla seguente tavola di verità: a 0 0 0 0 1 1 1 1 b 0 0 1 1 0 0 1 1 c 0 1 0 1 0 1 0 1 f 0 1 1 0 1 0 1 0 può essere realizzata con un multiplexer ad 8 ingressi-dati, fissati ai valori x0 = 0, x1 = 1, x2 = 1, x3 = 0, x4 = 1, x5 = 0, x6 = 1, x7 = 0, e 3 ingressi di controllo ai quali sono applicati gli argomenti della funzione a, b, c della funzione, come in Fig. 3.15: 0 1 1 0 1 0 1 0 MUX 8×1 f(a,b,c) a b c Fig. 3.15 Questa tecnica può essere estesa per generare funzioni di k variabili mediante un unico multiplexer con i ≤ k ingressi di selezione, più logica booleana sparsa. Si divide idealmente la tavola di verità della funzione in 2k-i parti di 2i righe ciascuna e si osserva che per ogni gruppo di 2k-i righe, una per ogni parte della tavola di verità, che si corrispondono distando una dall’altra di 2i, le prime i variabili meno significative x0, ..., xi-1 hanno sempre valore costante, mentre le variabili da xi a xk-1 assumono tutte le possibili 2k-i combinazioni di valori; dunque per ognuno di quei gruppi di righe la funzione dipende solo dalle variabili che cambiano. Si - 71 - definiscono allora i funzioni g0, ..., gi-1 di tali variabili, deducendone i valori dalla funzione f(x0, ..., xi-1, xi, ..., xk-1), come mostra la seguente tabella, e se ne costruiscono le rispettive reti; quindi le uscite delle reti sono collegate ordinatamente agli ingressi-dati del multiplexer e le variabili x0, ..., xi-1 sono applicate agli ingressi di selezione (Fig. 3.15): xk-1 ... xi 0 ... 0 ... g0 f(0,0,...,0) ... g1 f(1,0,...,0) ... 1 ... 1 f(0,1,...,1) f(1,1,...,1) ... ... gi-1 f(i-1,0,...,0) ... f(i-1,1,...,1) Nota: la notazione f(r,b,b,...,b), con 0 ≤ r ≤ i-1 e b ∈ {0,1}, indica il valore della funzione quando le variabili x0, ..., xi-1 codificano in binario l’intero r e le altre assumono una qualunque delle combinazioni da 0...0 a 1...1. xi xi+1 g0 xk-1 xi xi+1 0 g1 1 MUX xk-1 f(x0, ..., xk-1) 2i-1 xi xi+1 gi-1 xi-1 x0 xk-1 Fig. 3.16 In alternativa, si può leggere la tavola di verità della funzione mediante un albero di multiplexer identici, con i variabili di selezione, connessi nel seguente modo. Si immagina ancora la tavola di verità della funzione divisa in 2k-i parti di 2i righe ciascuna e si applicano i 2i elementi di ciascuna parte agli ingressi di 2k-i multiplexer controllati dalle variabili x0, ..., xi-1. Le uscite dei multiplexer sono applicate a gruppi di i agli ingressi di 2k-2i ulteriori multiplexer controllati dalle variabili xi, ..., x2i-1 e così via fino ad un unico multiplexer finale controllato dalle variabili xk-i, ..., xk-1 (Fig. 3.17). Può accadere che non tutti gli ingressi del multiplexer finale siano utilizzati, ma soltanto 2l, con l < i: in questo caso le variabili di controllo xk-i+l, ..., xk-1 saranno fissate a 0. - 72 - f(2k-1) f(2k-2i) 2i-1 1 0 2i-1 f(22i-1) 2i-1 = 1 0 f(2i) 1 0 2i-1 0 0 2i-1 = 2i-1 = f(2i-1) f(0) 1 0 x0 xi-1 1 0 xi x2i-1 xk-i xk-1 f Fig. 3.17 3.5.2 - Demultiplexer Un demultiplexer è una rete combinatoria che realizza la funzione opposta a quella del multiplexer, in quanto trasferisce un unico segnale di ingresso su una di n uscite z0, z1, ..., zn-1 selezionata mediante k = log2n segnali di controllo. Ogni uscita sarà perciò governata da una funzione del tipo: zi = pi·x, pi = y*0·y*1·...·y*k-1, y*j ∈ {yj, yj} nella quale è riconoscibile uno dei mintermini di k variabili moltiplicato per x; ciò conduce ad una immediata realizzazione con un decodificatore k×2k le cui uscite sono applicate ad una matrice 1×n di AND a due ingressi; le uscite della matrice sono le uscite del demultiplexer (Fig. 3.18). Sia nei multiplexer che nei demultiplexer i segnali-dati in ingresso ed in uscita in generale sono di b bit, in quanto è frequente la necessità di smistare byte o parole: la struttura delle due reti non cambia, salvo che la porzione relativa alla matrice di AND deve essere replicata b volte, mentre rimane unica la parte di decodifica. - 73 - x y0 y1 yk-1 k×2k z0 z1 zn-1 Fig. 3.18 Esistono infine reti in grado di effetture la selezione di segnali di b bit tra n in ingresso e di trasferirli su uno tra m segnali, pure di b bit, in uscita: esse sono perciò provviste di k = log2n segnali di controllo per la selezione di ingresso e di h = log2m segnali di controllo per la selezione di uscita, come illustrato in Fig. 3.19. x0 x1 b y0 y1 yk-1 w0 w1 wh-1 b xn-1 b MUX-DEMUX b b z0 z1 b zm-1 Fig. 3.19 3.6 - Generazione di funzioni combinatorie generiche 3.6.1 - ROM Il concetto che abbiamo visto applicato nei multiplexer per realizzare funzioni combinatorie è basato in sostanza sulla generazione dei mintermini di n variabili, sul prodotto di ciascuno per 1 o per 0 secondo che la funzione abbia 1 o 0 in uscita per ogni data combinazione binaria e sulla somma logica di questi prodotti: la struttura che ne deriva è un caso particolare di una più generale comunemente conosciuta con il nome di ROM (Read Only - 74 - Memory) o memoria di sola lettura. In effetti dal punto di vista concettuale il più semplice metodo di progetto di reti combinatorie ad n uscite per generare n funzioni di k variabili consiste nel produrre gli m = 2k mintermini di quelle variabili mediante un decodificatore e nel sommare funzione per funzione i mintermini corrispondenti alle righe di 1 nella tabella di verità di ciascuna funzione. La denominazione di memoria di sola lettura data ad una rete di questo tipo si giustifica con le seguenti considerazioni. Logicamente una ROM è un dispositivo in grado di conservare indefinitamente l’informazione memorizzata al momento della fabbricazione e di renderla disponibile in uscita su richiesta. L’informazione è codificata sotto forma di m stringhe binarie di n bit (n ≥ 1) che sono dette parole e sono riferite attraverso un indirizzo numerico variabile tra 0 ed m-1. L’indirizzo è codificato mediante k = log2m segnali binari da 1 bit in modo che per ogni combinazione di valori 0 ed 1 ad essi assegnati viene selezionata una delle m parole. In realtà alle parole di una ROM non corrisponde alcuna realtà fisica, ma esse hanno solo un significato logico derivante dal fatto che viene stabilita una corrispondenza biunivoca tra ogni valore dell’indirizzo ed il valore dei bit della parola indirizzata: se interpretiamo ognuno di tali bit come l’uscita di una funzione i cui argomenti sono le variabili associate ai segnali indirizzo, una ROM può essere realizzata mediante una rete a più uscite come quella sopra descritta ed il cui schema a blocchi è indicato nella Fig. 3.20: array di OR programmabile indirizzo 0 x0 x1 xk-1 k×2k m-1 fn-1 f1 f0 Fig. 3.20 In esso compare un array di OR detto programmabile: con questo termine si intende una schiera lineare di n porte OR ad m ingressi, nella quale è possibile interrompere selettivamente determinati percorsi di ingresso, facendo bruciare con un impulso di corrente dei fusibili presenti su di essi, in modo da fare arrivare all’entrata della porta i-esima (0 ≤ i ≤ n-1) solo il sottoinsieme di mintermini richiesto per realizzare la funzione che governa il bit associato. Il processo di distruzione è permanente nelle ROM propriamente dette e viene compiuto in fabbrica secondo le indicazioni del cliente; esso rappresenta la fase di scrittura dell’informazione e in pratica consiste nel realizzare la rete combinatoria che genera n funzioni in forma canonica degli stessi argomenti: il contenuto di una ROM è dunque cablato in - 75 - hardware all’atto della costruzione del dispositivo. Esistono anche ROM dette riprogrammabili, nelle quali la bruciatura dei collegamenti di ingresso alle porte OR non è permanente, ma essi possono essere ripristinati per mezzo di luce ultravioletta (PROM) o per via elettrica (EPROM): tale operazione determina la distruzione della configurazione circuitale (layout) precedente e quindi la perdita dell’informazione in essa cablata; riprogrammando la memoria si stabilisce una nuova configurazione di connessioni interne e quindi la memorizzazione di un nuovo contenuto informativo. Per esempio sia richiesta una ROM di otto parole da quattro bit, configurate secondo la tabella seguente: parola/bit 0 1 2 3 4 5 6 7 3 0 0 0 0 1 1 0 1 2 0 1 0 0 1 0 0 1 1 1 1 1 0 1 1 0 1 0 1 0 0 0 0 1 1 1 La struttura che si ottiene è costituita da un decodificatore 3×8 e da quattro porte OR le cui uscite sono le funzioni f0, f1, f2, f3 associate ai bit 0, 1, 2 e 3 di ogni parola; gli ingressi di ogni porta OR sono le uscite del decodificatore che nella numerazione da 0 a 7 corrispondono alla presenza di 1 nella colonna relativa della tabella (Fig. 3.21): a0 a1 a2 3×8 0 1 2 3 4 5 6 7 f3 f2 f1 f0 Fig. 3.21 In questo modo specificando ad esempio l’indirizzo 5, si ottiene in uscita la parola corrispondente, ovvero 1011. Le ROM sono dispositivi molto versatili per realizzare in hardware funzioni matematiche, conversioni di codici, programmi di controllo di sistemi di elaborazione (microprogrammi), - 76 - generatori di caratteri, parti combinatorie di reti sequenziali. Tuttavia presentano alcuni inconvenienti. Prima di tutto l’ingombro, che cresce come 2n, se n è il numero delle variabili di ingresso (indirizzo): aggiungere una variabile significa raddoppiare le dimensioni della ROM; questo dipende dal fatto che le ROM, generando funzioni in forma canonica, richiedono un decodificatore completo. Pertanto, come orientamento generale, per funzioni semplici è sempre molto più conveniente progettare reti minime specifiche. Anche la velocità non gioca a favore delle ROM, rispetto a reti progettate avendo come scopo l’ottimizzazione di questo parametro, pur essendo dispositivi più veloci di altri tipi di memorie, quali le RAM: valori tipici del tempo di risposta sono dell’ordine di qualche decina di ns (1 ns = 10-9 s). 3.6.2 - PLA Con questa sigla (Programmable Logic Arrays) si indicano componenti funzionalmente simili alle ROM, spesso accomunati a queste sotto l’unica sigla PLD (Programmable Logic Devices). Tuttavia le funzioni generate dalle PLA non sono in forma canonica ma in forma minima, ossia per ciascuna funzione vengono prodotti solo i termini che costituiscono un insieme non ridondante di implicanti (o di implicati) primi. Le PLA sono dispositivi molto utilizzati per la realizzazione di reti combinatorie qualsiasiin modo regolare e semplice, in particolare per realizzare la logica sparsa. Si tratta di strutture a due livelli di logica, divise in due sezioni: una matrice o piano di AND, dove vengono generati i prodotti necessari per le funzioni, secondo i criteri di sintesi ottima delle reti a più uscite; una matrice o piano di OR per la generazione delle funzioni di uscita. Le uscite della matrice di AND prendono il nome di linee prodotto o linee delle parole, mentre gli ingressi sono dette linee dei bit. Gli ingressi delle porte OR sono linee delle parole e le uscite sono dette linee di uscita. Gli incroci delle linee delle parole con le linee dei bit o con le linee di uscita prendono il nome di crosspoint e in corrispondenza di ciascuno di essi esiste un ingresso ad una porta logica (Fig. 3.22). In pratica, dal punto di vista tecnologico è più conveniente realizzare i due piani con porte di un unico tipo e ciò è reso possibile grazie all’esistenza degli operatori logici universali e delle corrispondenti porte NAND e NOR. linee dei bit y linee di uscita x matrice AND x0 x0 x1 x1 xk-1 xk-1 matrice OR f0 f1 fn-1 Fig. 3.22 - 77 - linee delle parole ↓ x ·/+ y Le variabili di ingresso sono presentate al piano AND insieme ai loro complementi attraverso circuti detti phase splitter, che costituiscono la forma più semplice di decodificatore e che sono provvisti di buffer per il pilotaggio delle porte AND (Fig. 3.23). , x x x x → x x Fig. 3.23 Ovviamente non tutti i crosspoint devono essere attivi, nel senso che non deve esistere un ingresso ad una porta AND o OR per ogni coppia di linee (bit, parola) o (parola, uscita) che si incrociano, ma nel piano AND sono attivi solo quelli che servono a collegare elettricamente le linee delle parole con quelle dei bit richieste per formare i vari prodotti e nel piano OR quelli che devono collegare alle linee di uscita gli insiemi opportuni di linee delle parole. In corrispondenza dei crosspoint inutilizzati gli ingressi alle porte sono distrutti, con un sistema analogo a quello delle ROM, durante la fase di programmazione della PLA. Esistono anche varianti più semplici delle PLA propriamente dette, nelle quali si cerca di ridurre l’ingombro ed il costo: si tratta delle PAL o Programmable Array Logic, nelle quali non esiste la possibilità di programmare il piano OR, in quanto i crosspoint presenti in esso sono collegamenti fissi e la programmabilità è limitata al solo piano AND (Fig. 3.24). I tempi di propagazione tipici delle PAL variano da circa 15 ns a circa 25 ns. Una versione ancora più semplice è costituita dalle HAL (Hard Array Logic) nelle quali non esistono crosspoint fusibili, ma le connessioni sono realizzate in fabbrica con un processo di mascheratura per deposizione metallica, secondo le specifiche fornite dal cliente. matrice AND x0x0x1x1 matrice OR xk-1 xk-1 f0 f1 fn-1 Fig. 3.24 Un’altra famiglia di componenti modulari studiati per la realizzazione di circuiti logici è costituita dai Gate Arrays o più in generale dai Programmable Gate Arrays (PGA); si tratta di - 78 - dispositivi formati da un gran numero di celle elementari identiche che possono essere variamente interconnesse a formare una rete più complessa. Le interconnessioni sono realizzate dal costruttore sulla base di maschere fornite dall’utente deponendo nella fase finale di integrazione uno strato di metallo (antifusing) fra le celle per costruire porte logiche standard, tra le porte per formare circuiti più o meno complessi e tra i circuiti ed i piedini di ingresso/uscita per le connessioni con l’esterno. Vediamo ora un esempio di progetto logico di una PLA e per questo consideriamo le stesse funzioni definite dalle tabelle relative alla ROM di Fig. 3.21, ossia f0 = ∑3(0,5,6,7), f1 = ∑3(0,1,2,4,5,7), f2 = ∑3(1,4,7), f3 = ∑3(4,5,7). Le rispettive forme minime si possono ricavare con il metodo delle mappe di Karnaugh e sono le seguenti: f 0 = abc + ac + ab = b + ac + ac f1 f 2 = abc + abc + abc f 3 = ab + ac Pertanto il piano AND della PLA deve generare gli implicanti primi abc, abc, abc, abc, ab, ab, ac, ac, b, mentre il piano OR è costituito da quattro porte OR: a·b·c a·b·c a·b·c a·b·c a·b a·b a·c a·c b a b c f3 f2 f1 f0 Fig. 3.25 La minimizzazione logica di una PLA, sia al fine di ridurre l’area di silicio necessaria per integrare una data struttura o di distribuirla sul minor numero possibile di chip, è sicuramente un’operazione vantaggiosa, ma presenta una complessità molto elevata (si tratta infatti di un problema NP-completo) a causa del grande numero di ingressi e di uscite di solito coinvolti e comporterebbe tempi di elaborazione proibitivi per l’esecuzione dei programmi di sintesi ottima basata sui metodi a suo tempo esaminati. Per questi motivi, in pratica si accettano soluzioni sub-ottime, di tipo euristico, nelle quali viene tollerata una certa ridondanza interna alle matrici AND e OR. - 79 - 3.7 - Circuiti aritmetici 3.7.1 - Addizionatori 3.7.1.1 - Richiami di aritmetica in campo finito Sia dato un campo numerico di capacità βn, dove β è la base del sistema di rappresentazione ed n il numero di cifre; tutti i risultati di operazioni aritmetiche per essere significativi devono poter essere rappresentati all’interno di quel campo. D’altra parte per qualunque numero naturale X, nel campo è rappresentabile, come stringa di n cifre, il numero |X|βn (si legga X modulo βn), resto della divisione intera di X per βn, ossia |X|βn = X- X/βn×βn. Pertanto se è X < βn, la sequenza di cifre contenuta nel campo è effettivamente la rappresentazione di X, altrimenti è la rappresentazione di un numero minore di X; in questo caso il numero X non può essere rappresentato in maniera corretta e se è il risultato di un’operazione aritmetica, si dice che essa ha determinato un traboccamento (overflow). Siano X ≡ xn-1xn-2...x0 e Y ≡ yn-1yn-2...y0 le rappresentazioni in base β di due numeri naturali; il valore della cifra i-esima della somma e quello del riporto dalla posizione i-esima alla (i+1)-esima sono date dalle seguenti relazioni, valide per ogni i, 0 ≤ i ≤ n-1: si = xi + yi + ci β ci + 1 = xi + yi + ci ------------------------β Poichè valgono le disuguaglianze 0 ≤ X, Y ≤ βn-1 la somma S = X+Y soddisfa le relazioni 0 ≤ S ≤ 2(βn-1) e pertanto la sua rappresentazione può richiedere n+1 cifre; infatti il massimo numero rappresentabile con n cifre è βn-1, quello rappresentabile con n+1 cifre è βn+1-1 e valgono le disuguaglianze β n-1 < 2(β n-1) < β n+1-1. Se questa è la situazione e non è possibile espandere il campo, nell’addizione si verifica un traboccamento ed il numero S non può essere correttamente rappresentato: il campo contiene il numero |S|β n, mentre il riporto cn è uguale ad 1. Consideriamo ora il problema dell’addizione di numeri relativi, limitandoci al caso della base 2. Delle due rappresentazioni più utilizzate per i numeri relativi, quella in modulo e - 80 - segno comporta artificiose complicazioni in quanto l’addizione algebrica si trasforma in un’addizione aritmetica delle grandezze dei numeri se essi sono concordi, in una sottrazione se sono discordi; per questo facciamo riferimento alla rappresentazione in complemento a 2 in un campo di lunghezza pari a quella degli addendi e dell’addizionatore, una metà del quale è utilizzato per rappresentare i numeri positivi e lo 0, l’altra metà per quelli negativi. La notazione in complemento consente di ricondurre ogni operazione di tipo additivo tra numeri relativi ad un’addizione tra i numeri naturali che ne costituiscono le rappresentazioni, dal momento che la sottrazione tra due numeri equivale a sommare all’uno il complemento dell’altro. Per questa ragione non considereremo la sottrazione come operazione a sè. Tuttavia, mentre nel caso dei numeri naturali tutto il campo è disponibile per rappresentare il valore dei numeri, che pertanto coprono l’intervallo da 0 a βn-1 estremi compresi, in questo caso il campo a disposizione per il valore è metà. Siano X ed Y due numeri relativi, rappresentati in complemento a 2 su n bit; affinchè l’addizione possa essere effettuata correttamente, è necessario che il campo abbia ampiezza sufficiente per rappresentare il risultato; in caso contrario si ha traboccamento dal semicampo dei numeri positivi a quello dei numeri negativi o viceversa. La rilevazione del traboccamento implica il confronto fra i bit più significativi degli addendi xn-1 e yn-1 e quello della somma sn-1: se gli addendi sono dello stesso segno (xn-1= yn-1), concordanza di valore di sn-1 con xn-1 (o con yn-1) significa risultato corretto, discordanza significa che traboccamento; se gli addendi sono invece di segno discorde, non c’è bisogno di ulteriori controlli, perchè il risultato è sicuramente sempre corretto in valore e segno (non c’è mai traboccamento). Una possibile rete per rilevare il traboccamento è la seguente: ov sn-1 yn-1 xn-1 Fig. 3.26 Il riconoscimento del traboccamento però può essere effettuato anche in base alle considerazioni seguenti. I - Se X ed Y sono entrambi non negativi, la somma S = X+Y è pure un numero non negativo e poiché xn-1 = yn-1 = 0, anche sn-1 deve essere 0; d’altra parte le seguenti relazioni: sn – 1 = xn – 1 + yn – 1 + cn – 1 = cn – 1 2 = 2 cn = xn – 1 + yn – 1 + cn – 1 --------------------------------------------------2 = cn – 1 -----------2 = mostrano che se cn-1 è 1, il bit più significativo della somma è pure 1 e c’è traboccamento; se - 81 - cn-1 è 0, la somma è correttamente rappresentata. Il riporto cn è in ogni caso uguale a 0. II - Se X ed Y sono negativi, anche la loro somma S = X+Y è negativa; dal momento che i bit più significativi delle rappresentazioni di X e di Y sono 1, ovvero x'n-1 = y'n-1 = 1, per avere il risultato corretto deve essere 0 anche il bit più significativo della rappresentazione della somma, s'n-1; d’altra parte le uguagliamze: s' n – 1 = x' n – 1 + y' n – 1 + c n – 1 2 = 2 + c n – 1 2 = c n – 1 cn = x' n – 1 + y' n – 1 + c n – 1 ---------------------------------------------------2 = 2 + cn – 1 ---------------------2 = 1 mostrano che se cn-1 è uguale a 0, s'n-1 è pure 0 e la somma S è rappresentata erroneamente come numero positivo e c’è traboccamento; viceversa se cn-1 è 1, anche s'n-1 è 1 ed S è rappresentata da S' correttamente. Il riporto cn è in ogni caso 1. III - I due numeri siano discordi con X ≥ 0, Y < 0, situazione alla quale possiamo sempre riportarci senza perdere in generalità; possono darsi due casi: a) X ≥ |Y |; allora 0 ≤ S < X ed è sempre rappresentata correttamente, e si ha s'n-1 = 0. Inoltre xn-1 = 0 e y'n-1 = 1 e dalla relazione: s' n – 1 = x n – 1 + y' n – 1 + c n – 1 2 = 1 + c n – 1 2 = 0 si deduce che deve essere cn-1 = 1 e quindi cn = (1+cn-1)/2 = 1. b) X-|Y| < 0; allora Y < S < 0 , ovvero s'n-1 = 1. Dalla relazione s' n – 1 = x n – 1 + y' n – 1 + c n – 1 2 = 1 + c n – 1 2 = 1 si ricava cn-1 = 0 e conseguentemente cn = (1+cn-1)/2 = 0. La tabella seguente riassume le situazioni descritte: xn-1 yn-1 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 sn-1 cn-1 cn esito 0 1 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 1 1 somma positiva (corretta) traboccamento somma negativa (corretta) somma positiva (corretta) somma negativa (corretta) somma positiva (corretta) traboccamento somma negativa (corretta) - 82 - Essa mostra che la rilevazione del traboccamento può essere condotta sulla base del confronto tra il bit di riporto verso la posizione più significativa del risultato cn-1 e quello di riporto nella posizione (n+1)-esima, cn: infatti solo in presenza di overflow tali bit sono diversi, per cui una singola porta XOR avente come ingressi tali riporti è sufficiente per generare il bit di overflow. 3.7.1.2 - Addizionatore ripple-carry In binario, dovendo effettuare l’addizione di due numeri naturali X = xn-1xn-2…x1x0 e Y = yn-1yn-2…y1y0, in linea di principio si può pensare ad una funzione combinatoria a due livelli di logica con n+1 uscite la quale produca in funzione dei 2n ingressi attuali n+1 variabili binarie che rappresentano gli n+1 bit del numero S, risultato dell’addizione: S = cnsn-1sn-2…s1s0 Una tale funzione è in grado di produrre il risultato in due unità di tempo, una per un gruppo di porte AND che agiscono non appena si sono formati i dati di ingresso, una per un gruppo di porte OR che operano quando le porte AND hanno prodotto le loro uscite. In pratica il numero di porte ed il loro fan-in diventano proibitivi non appena n è superiore a 2÷3, rendendo impossibile realizzare la funzione in questo modo ed è obbligatorio trovare altri metodi che usano logica a più di due livelli, anche se a prezzo di un maggiore tempo di calcolo. Infatti, mentre l’uscita s0 della funzione S dipende solo dalla coppia (x0, y0), l’uscita s1 dipende dalle due coppie (x1, y1) e (x0, y0) e così via; in generale l’uscita si dipende da 2(i+1) variabili, 0 ≤ i ≤ n-1 e le uscite sn-1 e cn dipendono da tutte le 2n variabili. La complessità delle sottoreti che calcolano le singole cifre della somma aumenta quindi in maniera inammissibile. Al fine di individuare una soluzione praticabile, cominciamo a considerare la somma di due numeri binari di 1 bit, x ed y; dal momento che quando i due numeri valgono 1 il risultato dell’addizione è 10, ossia un bit s di somma pari a 0 e un bit c di riporto pari ad 1, occorre definire due funzioni logiche s = f(x, y), c = g(x, y), attraverso le tavole di verità: x 0 0 1 1 y 0 1 0 1 s 0 1 1 0 c 0 0 0 1 Come si può vedere, s vale 1 quando x ed y sono diversi e vale 0 quando sono uguali, mentre c vale sempre 0, tranne nel caso x = y = 1, per cui si ha: s = xy+xy = x⊕y c = xy - 83 - La rete che realizza queste funzioni è detta semiaddizionatore o half adder (HA) ed è mostrata nella Fig. 3.27: x s y c Fig. 3.27 Il termine semiaddizionatore deriva dal fatto che questa rete non è in grado di produrre correttamente la somma quando i due bit non sono una coppia isolata, ma ciascuno fa parte di una stringa di n bit rappresentante un numero binario; infatti il bit di somma e quello di riporto in posizione i-esima in tal caso dipendono non solo dalla coppia di bit addendi xi e yi, ma anche dal bit di riporto ci proveniente dalla somma della coppia (xi-1, yi-1). Occorre allora ridefinire le tabelle di verità della somma e del riporto, facendovi figurare anche ci: xi 0 0 0 0 1 1 1 1 yi 0 0 1 1 0 0 1 1 ci 0 1 0 1 0 1 0 1 si 0 1 1 0 1 0 0 1 ci+1 0 0 0 1 0 1 1 1 Il loro esame mostra ancora che si è 1 solo se il numero di 1 nella terna (xi, yi, ci) è dispari, quindi è ancora espresso dall’OR esclusivo delle tre variabili, mentre il riporto verso la posizione (i+1)-esima è 1 solo se almeno una coppia delle tre variabili è 1, per cui si ha: si = xi⊕yi⊕ci = (xi⊕yi)⊕ci ci+1 = xiyi+xici+yici D’altra parte con l’algebra si può scrivere: ci+1 = xiyi+xici+yici = xiyi+xiciyi+yicixi = (xiyi+yixi)ci+xiyi = (xi⊕yi)ci+xiyi Ne risulta la rete di Fig. 3.28, nella quale sono riconoscibili due semiaddizionatori HA ed una porta OR e che è detta addizionatore completo o full adder (FA): - 84 - ci xi yi si ci+1 ⇓ ci si HA xi ci+1 HA yi Fig. 3.28 Torniamo ora al problema iniziale di sommare due numeri binari di n bit; ciò può essere fatto mediante n-1 addizionatori completi ed un semiaddizionatore per la coppia di bit meno significativi, collegati in modo che l’uscita di riporto dello stadio i-esimo sia collegata all’ingresso di riporto dello stadio (i+1)-esimo e applicando le coppie di bit (xi, yi), i = 0, …, n-1, agli ingressi corrispondenti (Fig. 3.29). In questo schema le singole cifre della somma non sono generate contemporaneamente, con lo stesso ritardo dal momento di applicazione degli operandi in ingresso, ma ognuna con un ritardo variabile che dipende strettamente dalle coppie di cifre o gruppi di coppie di cifre precedenti: prima che sia noto il valore del riporto che concorre a formare il bit di somma dello stadio i-esimo occorre, nel caso peggiore, che tutti gli stadi da 0 a i-1 abbiano prodotto il loro risultato; quando la situazione del caso peggiore si verifica per la cifra più significativa, l’addizione è effettuata con un ritardo massimo TA pari a: TA = (n-1)∆c+ max(∆s, ∆c) xn-1 yn-1 xi yi x0 y0 ci+1 FAn-1 cn sn-1 c1 FAi cn-1 si Fig. 3.29 - 85 - HA0 ci s0 essendo ∆c il tempo di propagazione dall’ingresso all’uscita del riporto c in un full adder e ∆s il tempo di propagazione dall’ingresso all’uscita della somma s. All’estremo opposto si verifica la situazione per cui i dati hanno valori tali che nessun riporto 1 viene generato e quindi il tempo di risposta dell’addizionatore ha il valore minimo ∆s. Questa variabilità di comportamento dell’addizionatore per quanto riguarda il tempo di risposta e la sua forte dipendenza dal valore e dalla lunghezza degli addendi è dovuta alla natura essenzialmente sequenziale del riporto, il cui fronte si propaga serialmente da uno stadio all’altro: da questa caratteristica deriva il nome di addizionatore ripple carry attribuito a questa rete. Per sottrarre l’addizione all’influenza negativa del riporto e aumentarne la velocità sono state studiate varie tecniche, le più comuni delle quali sono le seguenti: 1) Si può prevedere un circuito che evita la propagazione del riporto attraverso i vari stadi, calcolandone in anticipo il valore per tutti in modo che, almeno in teoria, l’addizione possa avvenire simultaneamente su tutti i bit (tecnica di carry look-ahead). 2) Quando si deve eseguire un flusso continuo di addizioni, si può ripartire in uguale misura su ogni operazione il ritardo dovuto al riporto rimandandone la propagazione a dopo che è entrato nell’addizionatore l’ultimo operando (tecniche di carry save e di pipelining). 3.7.1.3 - Addizionatore carry look ahead (CLA) Riprendiamo l’espressione del riporto generato dallo stadio i-esimo dell’addizionatore: ci+1 = (xi⊕yi)ci+xiyi e osserviamo che un valore 1 di esso può essere dovuto a due fatti, mutuamente esclusivi: a) il riporto si genera localmente allo stadio i-esimo perchè i due bit xi e yi sono entrambi 1; questo è espresso dal termine prodotto xiyi che viene detto termine di generazione; notare che quando ciò accade l’altro termine (xi⊕yi)ci è nullo; b) il riporto si genera nello stadio precedente i-1 e lo stadio i-esimo semplicemente lo propaga al successivo, essendo xi o yi (ma non entrambi) 1: di ciò è responsabile il termine (xi⊕yi) che prende perciò il nome di termine di propagazione; notare anche che quando il termine di propagazione vale 1, è nullo il termine di generazione, per cui essi sono mutuamente esclusivi nel determinare ci+1. Detti g e p i due termini sopra introdotti, possiamo scrivere il riporto ci+1 nella forma: ci+1 = gi+pici e iterando questa equazione per i = 0, 1, …, n-1, otteniamo: c1 = g0 c2 = g1+p1c1 - 86 - c3 = g2+p2c2 . . . cn-1 = gn-2+pn-2cn-2 cn = gn-1+pn-1cn-1 Infine sostituendo ricorsivamente nell’equazione i-esima l’espressione di ci-1 data dall’equazione precedente, si arriva alle seguenti equazioni: c1 = g0 c2 = g1+p1g0 c3 = g2+p2g1+p2p1g0 . . ci = gi-1+pi-1gi-2+pi-1pi-2gi-3+ …+pi-1pi-2…p2g1+pi-1pi-2…p2p1g0 . . cn = gn-1+pn-1gn-2+pn-1pn-2gn-3+ …+pn-1pn-2…p2g1+pn-1pn-2…p2p1g0 le quali mostrano che il riporto ci in uscita allo stadio (i-1)-esimo è dovuto al termine di generazione di quello stadio, oppure al termine di propagazione di quello stadio e al termine di generazione dello stadio (i-2)-esimo, oppure al termine di propagazione di quello stadio, al termine di propagazione dello stadio (i-2)-esimo e al termine di generazione dello stadio (i-3)-esimo e così via. I termini di generazione e di propagazione sono facilmente ottenibili come uscite del full adder, modificandone la struttura come indicato nella Fig. 3.30: ci xi si yi pi gi Fig. 3.30 Per ciascuna equazione possiamo allora costruire una rete combinatoria a due livelli di logica in forma SP che riceve in ingresso il termine di generazione e quello di propagazione prodotti nello stadio dell’addizionatore ad essa relativo e genera il riporto per lo stadio successivo. L’insieme di tali reti costituisce un modulo detto carry look-ahead generator (CLAG); poichè ogni riporto è generato in base alla conoscenza simultanea di tutti i termini di generazione e di propagazione degli stadi dal primo a quello corrente, e in definitiva di tutte le coppie di bit dalla meno significativa a quella corrente, i vari stadi dell’addizionatore con carry - 87 - look-ahead generator possono operare effettivamente in parallelo, producendo il risultato con un ritardo costante pari a ∆s+ 2∆g, essendo ∆g il ritardo di una porta. La Fig. 3.31 mostra un addizionatore a quattro bit con carry look-ahead generator. x3 y3 FA c4 g3 s3 p3 c3 x2 y2 x1 y1 g2 s2 p2 y0 c1 c2 FA x0 FA g1 s1 p1 HA g0 s0 Fig. 3.31 Purtroppo i benefici dell’uso del carry look-ahead generator sono rapidamente vanificati al crescere di n perchè, come si vede già dall’esempio, il numero di porte e soprattutto il numero dei segnali in ingresso ad esse cresce a livelli inaccettabili: questa tecnica può essere applicata fino a valori di n non superiori a 5÷6. Per addizionatori di lunghezza maggiore è necessario trovare un compromesso tra complessità realizzativa e velocità di risposta. Una soluzione consiste nel dividere gli operandi in k gruppi di q bit, in modo che sia n = k×q e q ≤ 6, applicando la tecnica di carry look-ahead all’interno di ogni gruppo, mentre tra un gruppo e l’altro viene applicata quella di ripple carry. In alternativa si può propagare serialmente il riporto tra gli stadi all’interno di ogni gruppo, riservando l’uso del carry look-ahead alla propagazione da un gruppo all’altro. Per questa soluzione occorre naturalmente dimensionare i gruppi in modo che sia k ≤ 6, aumentando corrispondentemente il valore di q. Una terza soluzione consiste nel propagare i riporti con tecnica carry look-ahead sia all’interno di ogni gruppo che tra i gruppi. In questa soluzione occorre disporre di almeno due livelli di carry look-ahead generator: al primo livello si trovano generatori dei riporti anticipati che lavorano sui singoli gruppi; al secondo livello quelli che lavorano tra i gruppi, ricevendo termini di generazione e di propagazione dai generatori del primo livello. La Fig. 3.32 mostra un addizionatore per numeri di 16 bit realizzato secondo la tecnica descritta e avendo scelto per - 88 - q un valore pari a 4. y15 x15 y12 x12 y11 x11 s11 s10 c16 s15 s14 s13 s12 I livello y8 x8 s9 s8 y7 x7 s7 s6 y4 x4 s5 s4 4 stadi di FA c15 c14 c13 c12 4 stadi di FA c11 c10 c9 c8 4 stadi di FA c7 c6 c5 c4 CLAG a 4 stadi CLAG a 4 stadi CLAG a 4 stadi c8 c12 II livello c4 y3 x3 s3 s2 y0 x0 s1 s0 4 stadi di FA c3 c2 c1 c0 CLAG a 4 stadi c0 CLAG a 4 stadi Fig. 3.32 Nel caso in cui la ripartizione dei bit degli operandi in gruppi produca un valore k > 6, i generatori del secondo livello devono essere ulteriormante divisi in più livelli, ottenendo complessivamente una struttura ad albero nella quale, per ragioni di modularità e di regolarità, si tende ad utilizzare in tutti i nodi generatori di carry look-ahead della stessa lunghezza q. Con questo schema, poichè la profondità dell’albero è logqn, TA è espresso dalla relazione: T = (4·logqn+2)·∆g nella quale il fattore moltiplicativo 4 è dovuto al fatto che per ogni livello devono essere generati in parallelo (vedi Fig. 3.30) un termine di propagazione (2∆g) ed uno di generazione (∆g) e quindi il riporto (2∆g); la base del logaritmo si spiega con il fatto che l’albero è q-ario; infine il termine aggiuntivo 2 è dovuto al ritardo per la generazione del bit di somma. Da questa relazione risulta una complessità O(logqn) che, pur essendo superiore a O(1), quale avrebbe un addizionatore con carry look-ahead ad un unico livello e stadi a due livelli di logica, è decisamente inferiore alla complessità O(n) del semplice addizionatore ripple carry. Se si assume, come nell’esempio e come avviene spesso in pratica, che ogni generatore di carry look-ahead abbia quattro stadi, la relazione precedente dà per il tempo di risposta T di un CLA in funzione della lunghezza n degli addendi un andamento come riportato dalla seguente tabella: n TA 4 16 64 256 6∆g 10∆g 14∆g 18∆g - 89 - 3.7.1.4 - Addizionatore carry save Un’altra tecnica per l’addizione, di pratica utilità soprattutto in presenza di addizioni ripetute, è quella detta di carry save (CSA) o di acquisizione ritardata dei riporti. L’idea di base consiste nel considerare l’addizione come una procedura ricorsiva nella quale al passo i-esimo si formano due vettori di n bit Si e Ci, denominati vettore delle somme parziali e vettore dei riporti parziali, a partire dal vettore delle somme parziali Si-1 e dal vettore dei riporti parziali Ci-1, traslato a sinistra di una posizione rispetto al passo precedente, per tenere conto del corretto allineamento, e proseguendo fino ad avere un vettore dei riporti parziali nullo, oppure finchè un bit di valore 1 nella posizione più significativa del vettore dei riporti indica la presenza di traboccamento. Le componenti di tali vettori sono date dalle relazioni: S ji = S ji – 1 ⊕ C ji –– 11 C ji = S ji – 1 ⋅ C ji –– 11 per i = 2, 3, …, j = 0, ..., n-1 e C –i 1 = 0, mentre al primo passo si ha: S j1 = x j ⊕ y j C j1 = x j ⋅ y j Per esempio siano X = 0101101 e Y = 0110101; avremo: 0101101 0110101 0011000 0100101 1001010 1010010 0001000 0010000 1000010 0010000 0100000 1100010 0000000 S1 C1 2C1 S2 C2 2C2 S3 C3 2C3 S4 C4 = 0: fine della procedura da cui il risultato S = 1100010. Il procedimento potrebbe essere eseguito, in linea di principio, con una rete logica che - 90 - utilizza n(n-1)/2 semiaddizionatori disposti su n file, nell’i-esima delle quali vengono addizionati il vettore delle somme e quello dei riporti traslato, ottenuti come uscita della fila (i-1)-esima (Fig. 3.33). I semiaddizionatori della fila (n-1)-esima producono in uscita i bit da S0 ad Sn-1 ed il bit Cn del risultato. In pratica però, in dipendenza dei valori attuali degli addendi, il vettore dei riporti parziali può annullarsi prima del passo finale, determinando la fine del calcolo, mentre i vettori parziali devono continuare ad essere trasferiti attraverso le file rimanenti dell’addizionatore, con inutile spreco di tempo; inoltre la complessità strutturale è molto più elevata rispetto a quella dell’addizionatore ripple carry e, nel caso peggiore, il tempo di risposta ha complessità O(n); per queste ragioni la rete di Fig. 3.33 ha solo valore di principio. La complessità della struttura può essere riportata da O(n2) a O(n) utilizzando una sola fila di n semiaddizionatori e due dispositivi (registri) capaci di memorizzare ciascuno n bit. Inizialmente essi memorizzano gli addendi X ed Y e nei vari passi del calcolo i vettori Si e Ci; le loro n uscite sono connesse ordinatamente agli ingressi dei semiaddizionatori come mostra la Fig. 3.34. xn-1 yn-1 x2 HA x1 HA 1 1 Cn-1 y2 1 Sn-1 1 Cn-2 S2 HA 2 1 C1 2 Sn-1 C2 n-3 HA 1 1 S1 C0 1 S0 HA HA 2 Cn-1 x0 y0 HA 1 C2 y1 2 S2 2 C1 2 S1 n-3 Sn-1 Cn-1 HA n-2 n-2 Cn-1 n-2 Sn-1 Cn-2 HA Cn n-1 Cn-1 Sn-1 S1 S0 Fig. 3.33 Si noti che la traslazione verso sinistra del vettore dei riporti parziali è ottenuta semplicemente presentando agli ingressi del registro R1 la stringa di bit cn-2…c10 e - 91 - trascurando il bit cn-1. 0 X n cn-1 n Y n MUX MUX R1 R2 n array di n HA vettore dei riporti vettore delle somme Fig. 3.34 Questo schema, pur di complessità ridotta rispetto a quello originario, presenta l’inconveniente di un tempo di risposta ancora più lungo, perchè ad un ritardo pari a quello della rete di Fig. 3.33 si aggiunge quello dei multiplexer e quello necessario per memorizzare i vettori parziali nei registri; quindi è di scarsa utilità quando si devono sommare solo due operandi. Introducendo però un terzo registro e sostituendo i semiaddizionatori con n addizionatori completi, la struttura diventa adatta per effettuare addizioni su un flusso continuo di dati (Fig. 3.35). Ad ogni passo vengono sommati con tecnica carry save i contenuti dei tre registri che consistono in un nuovo dato di ingresso (R2), nel vettore delle somme parziali (R3) e in quello dei riporti parziali traslato (R1), questi ultimi derivanti dal passo precedente; in altri termini i nuovi contenuti dei registri R1 ed R3 al passo i-esimo sono rispettivamente: R3(i) = R1(i-1)⊕R2(i-1)⊕R3(i-1) R1(i) = 2(R1(i-1)·R2(i-1)+R1(i-1)·R3(i-1)+R2(i-1)·R3(i-1)) 0 R1 dati di ingresso n R2 R3 array di FA vettore delle somme vettore dei riporti Fig. 3.35 - 92 - Quando tutti gli addendi sono stati sommati, il registro R2 non partecipa più alle operazioni, mentre R1 ed R3 contengono i valori finali rispettivamente del vettore dei riporti e di quello delle somme. Per ottenere la somma corretta è necessario un ulteriore passo di addizione nel quale i due vettori sono sommati insieme con tecnica ripple carry (o carry look-ahead) ed il risultato viene memorizzato ad esempio nel registro R3: il tempo richiesto per quest’ultima addizione si ripercuote sulla durata di ciascuna somma per una frazione tanto più piccola quanto più numerosi sono i dati in ingresso. Pertanto il tempo necessario per calcolare ciascuna addizione, nel caso di N addendi, è circa uguale a TFA+TR+TA/(N-1), dove TFA rappresenta il tempo di risposta di un full adder, TR il tempo di memorizzazione in un registro e TA il tempo dell’addizione finale. Per effettuare l’ultima somma si possono seguire due strade: 1) far lavorare l’addizionatore come quello di Fig. 3.34, mantenendo costantemente a 0 il registro R2 ed eseguendo con tecnica CS tra il contenuto di R1 e di R3 un numero di addizioni pari alla lunghezza dei vettori dei riporti e delle somme, a meno che non si arrivi prima alla situazione in cui il vettore dei riporti diventa 0; 2) riorganizzare l’array dei full adder già esistenti in modo da ottenere un addizionatore ripple-carry, come indicato in Fig. 3.36 per il bit k-esimo: R1k R2k R3k MUX Array di full adder FAk FAk-1 al FAk+1 Ck Sk Ck-1 Sk-1 Fig. 3.36 Come ultima osservazione, è chiaro che i registri, il numero di addizionatori completi e la capacità delle linee di connessione devono essere dimensionati sulla lunghezza del risultato finale oppure, in alternativa, la loro dimensione condiziona il numero massimo di dati che possono essere sommati insieme. Per esempio supponiamo di dover sommare quattro numeri X1 = 15 = 1111, X2 = 12 = 1100, X3 = 7 = 111, X4 = 17 = 10001; il risultato è S = 51 = 110011 e quindi occorre che i registri e l’addizionatore abbiano una lunghezza di almeno 6 bit. Il seguente schema riproduce i contenuti dei registri ai vari passi del calcolo. Inizialmente R1 ed R3 sono azzerati, mentre R2 contiene il primo addendo X1; alla fine R3 contiene il risultato. - 93 - R1 R2 R3 operazione 000000 001111 000000 000000 001111 001111 000000 001100 001111 inizializza i registri calcola S1 e C1 trasla C1 e carica X2 001100 001100 000011 011000 000111 000011 calcola S2 e C2 trasla C2 e carica X3 000011 000111 011100 000110 010001 011100 calcola S3 e C3 trasla C3 e carica X4 010100 010001 001011 101000 001011 110011 calcola S4 e C4 trasla C4 addiziona S4 e C : risultato 3.7.1.5 - Addizionatore pipeline registri delle somme e dei riporti parziali n-2 semiaddizionatori xn-1 registri delle somme e dei riporti parziali n semiaddizionatori y0 n-1 semiaddizionatori x0 registri delle somme e dei riporti parziali Quando si tratta di calcolare una quantità di somme tra coppie di numeri, l’addizionatore CSA di Fig. 3.32 ritrova la sua utilità se tra una fila e l’altra di semiaddizionatori viene intercalata una coppia di registri con funzione di memoria temporanea per mantenere i vettori delle somme e dei riporti parziali (Fig. 3.37): yn-1 Fig. 3.37 Si ottiene un addizionatore che è detto pipeline e costituisce un’applicazione particolare di una tecnica di elaborazione molto diffusa, chiamata pipelining; si tratta di organizzare in cascata k elementi di calcolo ognuno dei quali fornisce come uscita l’ingresso al successivo. E’ un modello simile a quello di una catena di montaggio nella quale esistono varie stazioni di servizio dove vengono effettuate le stesse operazioni su tutti gli esemplari che si muovono lungo la catena. - 94 - Nel caso dell’addizionatore, una coppia di addendi viene presentata all’ingresso del primo livello e l’uscita è memorizzata nella prima coppia di registri; nel momento in cui l’uscita di quei registri è presentata in ingresso ai semiaddizionatori del secondo livello, una seconda coppia di addendi può essere applicata all’ingresso del primo livello, e così via finchè dopo k passi tutti i livelli di addizionatori stanno lavorando, il k-esimo sulla prima coppia di dati, il (k-1)-esimo sulla seconda, il primo sulla k-esima. Da questo momento all’uscita del sistema cominciano a presentarsi i risultati che si susseguono con ritmo costante, uno ogni passo di pipelining, ossia uno ogni intervallo di tempo necessario perchè una stazione di servizio esplichi il proprio compito. Si distingue così un periodo transitorio di k passi all’inizio, durante il quale la pipeline si riempie, uno di pari durata che ha inizio quando l’ultima coppia di dati viene ricevuta in ingresso e durante il quale la pipeline si svuota, ed un periodo di regime durante il quale la risorsa di calcolo è totalmente occupata. Se il numero m di coppie di addendi da sommare è considerevolmente più grande di k, l’incidenza del transitorio su ogni addizione diventa trascurabile e si può dimostrare che il tempo di risposta dell’addizionatore è costante; precisamente se k sono gli stadi di pipeline e Te il tempo elementare di operazione, il numero di operazioni effettuate nell’unità di tempo è: k ν = --------------------------------k–1 T e 1 + ----------- m Per m → ∞, ν tende al valore massimo k/Te. 3.7.2 - Moltiplicatori La moltiplicazione è un’operazione che ricorre molto frequentemente in svariate applicazioni, spesso con vincoli stringenti di tempo di risposta, e per questo sono stati studiati molti algoritmi e molte strutture allo scopo di aumentare la velocità rispetto a quella dell’algoritmo base. Questo, noto come algoritmo di moltiplicazione per somme e traslazioni, deriva direttamente dall’espressione del prodotto di due numeri X = xn-1…x1x0 e Y = yn-1…y1y0, nella quale uno dei due fattori figura in forma polinomiale con base 2: n–1 P = X⋅Y = Y⋅ ∑ xj ⋅ 2 j j=0 n–1 = ∑ Y ⋅ xj ⋅ 2j j=0 Poiché le cifre xj valgono 0 o 1, l’espressione mette in evidenza che il prodotto si calcola come somma di al più n termini, ottenuti da uno dei due fattori traslato verso sinistra di 0, 1, ..., n-1 posizioni binarie; pertanto, nel caso peggiore, la complessità in tempo è O(n2) o, nella migliore delle ipotesi se le somme sono effettuate con tecnica CLA, O(nlogn). - 95 - 3.7.2.1 - Moltiplicatore a schiera Per valori moderati di n, tipicamente per n ≤ 16, è possibile effettuare la moltiplicazione usando una struttura combinatoria che deriva dalle seguenti considerazioni. Il prodotto di X ed Y può essere riscritto nella forma: n–1 n–1 n – 1 P = ∑ Yx j 2 j = ∑ 2 j ∑ x j y i 2 i i = 0 j=0 j=0 la quale mostra che è necessario prima di tutto generare n2 prodotti da 1 bit del tipo xjyi. Poichè nel caso di numeri di un solo bit il prodotto aritmetico e quello logico coincidono, questi prodotti possono essere ottenuti semplicemente con una matrice di porte AND n×n, come illustrato nella Fig. 3.38. xn-1 x1 x0 y0 y1 xn-1y0 x1y0 x0y0 xn-1y1 x1y1 x0y1 xn-1yn-1 x1yn-1 x0yn-1 yn-1 Fig. 3.38 Per calcolare la loro somma, poi, si usa una struttura formata da n semiaddizionatori ed n2-2n addizionatori organizzati secondo un array bidimensionale di n righe e 2n-1 colonne; il bit k-esimo del prodotto, di peso 2k, 0 ≤ k ≤ 2(n-1), viene generato dalla colonna corrispondente dell’array, secondo lo schema della Fig. 3.39, che per semplicità è disegnato per n = 4. - 96 - x3y3 x2 y3 x1 y3 x0y3 x3y0 x0y2 x2y0 x0y1 x1y0 HA HA HA x3y1 FA x3y2 FA p 7 p6 FA x2y2 FA FA FA HA p5 x2 y1 p4 x0y0 x1 y1 FA x1 y2 FA p3 p2 p1 p0 Fig. 3.39 Per spiegare la struttura di Fig. 3.39 scriviamo per esteso la doppia sommatoria della espressione del prodotto, ancora nel caso di n = 4: P = x0y0+x0y12+x0y222+x0y323+x1y02+x1y122+x1y223+x1y324+x2y022+x2y123+x2y224+ +x2y325+x3y023++x3y124+x3y225+x3y326 = =x0y0+(x0y1+x1y0)2+(x0y2+x1y1+x2y0)22+(x0y3+x1y2+x2y1+x3y0)23+ +(x1y3+x2y2+x3y1)24+(x2y3+x3y2)25+x3y326 Poichè sommando 4 bit si possono avere fino a 2 bit di riporto di valore 1 che vanno ad aggiungersi ai bit degli addendi di peso immediatamente superiore (in generale con k bit si possono avere k/2 bit di riporto uguali ad 1), questa espressione mostra che dalla somma x0y1+x1y0 può nascere un riporto che si propaga dalla posizione di peso 2 a quella di peso 22; da questa possono aversi due riporti che devono essere aggiunti ai termini di peso 23; a loro volta possono generarsi tre riporti dalla posizione di peso 23 a quella di peso 24, ancora tre riporti di 1 dalla posizione di peso 24 a quella di peso 25 e infine da questa somma possono aversi due riporti di valore 1 da aggiungere al termine di peso 26. Di qui nasce la struttura di Fig. 3.38, la quale prende il nome di moltiplicatore a schiera - 97 - ed è in sostanza un addizionatore ripple carry a due dimensioni; pertanto il tempo della moltiplicazione è dato dal ritardo di una porta AND della matrice più il doppio del ritardo di un addizionatore ripple carry ad n stadi, ovvero: TM = 2((n-1)∆c+max(∆c, ∆s))+∆g La complessità in tempo è dunque O(n), mentre quella in numero di componenti è O(n2). Le prestazioni in tempo possono essere migliorate nel caso in cui siano da moltiplicare flussi continui di dati, facendo operare la struttura in pipeline, purchè siano intercalati tra le righe dell’array dei registri buffer. 3.7.2.2 - Moltiplicatore di Wallace Come abbiamo visto, l’addizionatore CS ad n bit consiste di n addizionatori completi disgiunti ed ha come ingressi tre numeri e l’uscita è costituita da un vettore S (somma parziale) e da un vettore C (riporto parziale). La caratteristica importante è l’assenza di riporto all’interno dell’addizionatore, dal momento che solo dopo aver sommato tutti i dati di ingresso è richiesto un passo di acquisizione dei riporti, effettuato sommando i vettori S e C ad esempio con tecnica ripple carry sugli stessi addizionatori allo scopo opportunamente riorganizzati. A loro volta i vettori S e C possono essere ingressi di un secondo addizionatore carry save ad n bit insieme ad un quarto numero W e così via, dando luogo ad una struttura di tipo pipeline, come illustrato in Fig. 3.40 per la somma di quattro numeri X, Y, Z e W di quattro bit: X Y Z X3 Y3 Z3 X2 Y2 Z2 X1 Y1 Z1 X0 Y0 Z0 FA13 FA12 FA11 FA10 CS adder W C S ⇒ W3 W2 W0 W1 CS adder FA23 FA22 FA21 HA20 C' S' C'3 S'3 C'2 S'2 C'1 S'1 C'0 S'0 Fig. 3.40 Un addizionatore carry save a più stadi come quello sopra illustrato può essere utilizzato per eseguire la moltiplicazione secondo una struttura detta moltiplicatore di Wallace, esemplificato in Fig. 3.41 per numeri di 8 bit. - 98 - x6Y26 Y27 x7 x4Y24 Y25 x5 x2Y22 Y23 x3 x1Y2 CS adder C CS adder S C S CS adder CS adder C x0Y S C S CS adder C S CS adder C S ripple carry adder P Fig. 3.41 Il suo funzionamento è definito dalle seguenti considerazioni. Il prodotto di due numeri X ed Y di n bit si può scrivere nella forma: n–1 P = ∑ Mi i=0 nella quale vengono sommati insieme n termini di 2n bit ciascuno del tipo: Mi = xiY2i con 0 ≤ i ≤ n-1, ottenuti moltiplicando Y per il bit i-esimo del moltiplicatore X, pesato con la potenza di 2 corrispondente. Per effettuare la sommatoria può essere utilizzato un albero di addizionatori carry save che operano ciascuno su gruppi di tre ingressi, il quale produce due vettori C ed S di 2n bit; infine questi vettori sono addizionati insieme attraverso uno stadio finale di addizionatore ripple carry, come mostrato dalla Fig. 3.41. Notare che per ottenere i termini Mi basta presentare su ciascuno degli n ingressi il valore - 99 - 0 oppure il moltiplicando Y traslato verso sinistra di 2i, a seconda del valore del bit xi del moltiplicatore. Il numero k di livelli dell’albero è legato alla dimensione n dei fattori dalla relazione: k = log 2n – 1 ---------------------log 23 – 1 mentre il numero totale di addizionatori completi e semiaddizionatori è dell’ordine di n2, come mostra la seguente tabella per diversi valori di n: n 6 8 12 16 24 numero di numero di addizionatori semiaddizionatori 16 12 38 15 102 29 192 56 488 87 totale numero di livelli 28 53 131 248 575 3 4 5 6 7 Pertanto questa struttura è pratica solo se n è abbastanza piccolo. Per grandi valori di n il numero di addizionatori può diventare eccessivo ed in tal caso si ricorre alla tecnica di partizionare i dati in s segmenti di q bit in modo che sia n = s×q e di generare solo q prodotti Mi che vengono addizionati con un addizionatore del tipo descritto. Il procedimento viene ripetuto s volte ed ogni prodotto parziale viene accumulato insieme al risultato ottenuto dai passi precedenti. - 100 - ESERCIZI 1) Realizzare una rete combinatoria per la funzione Σ4(0,1,3,5,6,8,9,10,12,14) con multiplexer a 16, 8, 4 e 2 ingressi, utilizzando in tutti i casi il minor numero possibile di componenti e nell’ipotesi che si debba memorizzare l’intera tavola di verità della funzione. Si calcoli il ritardo delle varie reti costruite, esprimendolo in unità ∆g. 2) Realizzare una rete per la funzione dell’esercizio 1, ammettendo di avere a disposizione solo multiplexer a 8 o a 4 ingressi e porte logiche AND e OR e rinunciando a memorizzare la tavola di verità completa. 3) Utilizzando esclusivamente multiplexer, si disegnino almeno due realizzazioni differenti della seguente funzione, escludendo la soluzione con un solo multiplexer: f = Π4(0, 1, 3, 4, 6, 9, 11, 12, 15) 4) Supponendo di disporre solo di porte XOR e di porte NOR a due ingressi, progettare una rete che accetta in ingresso numeri con segno di 6 bit e calcola sui bit 0÷4 la parità pari degli 1, se il numero è positivo; la parità pari degli 0, calcolata sempre sugli stessi 5 bit, se il numero è negativo. 5) Progettare con ROM un circuito che ha in ingresso valori di temperatura in gradi Celsius nell’intervallo da 0 °C a 20 °C di grado in grado e fornisce in uscita i corrispondenti valori in gradi Farenheit; si ricordi che tra le due scale termometriche esiste la relazione: tF = 32+1.8tC 6) Ripetere l’esercizio 4 supponendo che i valori di ingresso siano specificati di due gradi in due gradi; qual è l’inconveniente ad utilizzare la stessa ROM dell’esercizio 4? Supponendo che, per qualche ragione, una ROM sia un circuito il cui costo cresce esponenzialmente con la capacità, come si potrebbe risolvere l’eventuale problema di costo derivante dal quesito precedente? 7) Progettare con ROM un circuito che accetta in ingresso valori di temperatura da 0 °C a 20 °C oppure da 32 °F a 68 °F e produce in uscita valori di temperatura nell’altra scala; realizzare la struttura in modo che ogni parola della ROM contenga sia un valore in °C, sia in °F. 8) Progettare una ROM per tabulare con la precisione di 2-8 la funzione sinx, data di seguito per valori dell’argomento tra 0 e 90°, con passo 10°: x 0 10° 20° 30° 40° 50° 60° 70° 80° 90° sinx 0 0.1736 0.3420 0.5 0.6427 0.766 0.866 0.9397 0.9848 1 Supponendo di disporre di chip di memoria da 8 parole×4 bit, stabilire quanti chip sono necessari e come devono essere interconnessi. - 101 - 9) Progettare un circuito che calcola il valore troncato all’intero della radice quadrata dei interi tra 0 e 100. 10)Un tizio molto freddoloso decide di installare nella sua casa, qui riprodotta in pianta, un sistema di allarme che faccia suonare un campanello quando porte e finestre sono aperte in modo tale da provocare correnti d’aria. Progettare il sistema di allarme. F1 P1 F2 P3 P2 11) Realizzare con multiplexer a quattro ingressi la seguente funzione: d,e 00 00 b,c 01 0 01 11 10 00 0 0 0 0 01 11 0 × 0 0 × 0 11 0 0 × 0 0 10 × 0 × 0 × a=0 10 × 0 a=1 12) Disegnare lo schema a blocchi di un circuito con due ingressi a e b di n bit ed una uscita z, pure di n bit, il quale elabora nel seguente modo coppie di interi positivi applicati agli ingressi: 1) se a è dispari e b pari, calcola z = a----------– b- ; 2 2) se a è pari e b dispari, calcola z = a----------+ b- ; 2 3) altrimenti z = 0. 13) Riconoscere che la rete di figura implementa un modulo FA: a b f1 c f2 - 102 - 14) Realizzare un circuito che calcola la somma modulo m di due numeri naturali A e B minori di m. Si osservi che nel caso peggiore la somma può valere 2m-2 e quindi può traboccare dal campo al più una volta. 15) Progettare un circuito con due ingressi interi di 12 bit X ed Y che funziona nel seguente modo: se X-Y è maggiore o uguale a X/2 il circuito dà in uscita X, altrimenti Y. 16) Progettare un circuito che riceve in ingresso su 8 bit un caratttere del codice ASCII (o Unicode) e se il carattere è una cifra (codici decimali da 48 a 57) produce in uscita il codice BCD di quella cifra; se il carattere è una lettera minuscola (codici decimali da 97 a 122) la trasforma in maiuscola (codici decimali da 65 a 90) e viceversa. Negli altri casi trasferisce in uscita il carattere entrante senza modifiche. 17) Realizzare un circuito con tre ingressi interi di 10 bit A, B, C, che produce 1 in uscita quando risulta min {A, B} < C < max{A, B} 18) Realizzare un circuito con un ingresso intero di n bit X ed una uscita che assume valore X/2, quando X è pari, (X+1)/2 quando X è dispari. 19) Supponendo di disporre di circuiti per la generazione anticipata dei riporti della capacità di 5 bit, progettare un CLA per numeri di 28 bit e se ne valuti il tempo di risposta. 20) Calcolare la complessità, espressa come numero di HA/FA necessari, ed il tempo di risposta di un moltiplicatore di Wallace per numeri di 10 bit (o più in generale per numeri di n bit). 21) Disegnare lo schema a blocchi di un circuito sottrattore per numeri interi senza segno di n bit, definendo anche la struttura a livello porte di un modulo FS (Full Subtractor) che considera tre bit: minuendo, sottraendo e prestito. 22) Analizzare la funzione della rete logica di figura, nella quale i blocchi D sono memorie da 1 bit, i blocchi FA sono addizionatori completi xi, yi e pi bit di tre numeri naturali X, Y e P. yn-1 yn-2 y1 y0 xn-1, ..., x1, x0 D D F.A. cn-2 - 103 - F.A. c1 D D D F.A. pn ,..., p0 c0 D 23) E’ richiesto un multiplexer a sette ingressi facendo uso di uno a 16 ingressi, ma poiché non si ha la sicurezza che gli ingressi dall’ottavo in poi non vengano mai selezionati, si decide di fare in modo che la selezione sia effettuata con la legge Y = X mod 7, essendo X l’equivalente decimale del codice di controllo applicato al multriplexer ed Y quello effettivamente operante (v. figura). Progettare il multiplexer e la logica di controllo. 0 MUX 6 X 24) Progettare una ROM la quale, dati due numeri a e b rispettivamente di tre e due bit, fornisce in uscita il valore x = ab. Calcolare inoltre il numero totale di porte AND e OR necessarie per la ROM, supponendo che il fan-in sia 6. 25)Si disegni lo schema a blocchi di un circuito combinatorio che esegue il calcolo x+y, con y = abs(2x+3), se x > 0. Per il calcolo di y si usi di una ROM. 26) Si sintetizzi mediante PLA in forma omogenea NAND la rete a quattro uscite: f1 = Σ3(0,1,5,6) f2 = Σ3(0,3,4,5,6) f3 = Σ3(1,4,5,6) f4 = Σ3(1,3,4,5) Inoltre si sintetizzi la rete utilizzando un unico multiplexer a quattro ingressi, con 4 bit per ingresso. 27) Si disegni lo schema a blocchi di un circuito logico combinatorio che riceve in ingresso due numeri interi X ed Y di 12 bit e ne calcola rispettivamente la radice quadrata approssimata all’intero superiore ed il logaritmo in base due troncato all’intero inferiore; quindi produce come uscita un bit di valore: 1 se il numero degli 1 in X1/2 è pari, 0 se è dispari, quando X1/2 ≥ log2Y; 1 se il numero degli 1 in log2Y è dispari, 0 se è pari, quando X1/2 < log2Y. Per il calcolo di X1/2 e di log2Y si faccia riferimento a memorie di sola lettura, specificandone soltanto numero di parole e lunghezza di parola. 28) Progettare un decodificatore binario-BCD, che converte numeri interi rappresentati in binario su quattro bit nella rappresentazione 8-4-2-1 e segnala in uscita una situazione di errore per numeri maggiori di 9. - 104 - Capitolo 4 AUTOMI A STATI FINITI 4.1 - Introduzione L’addizione di due numeri binari X e Y di n bit può essere eseguita, oltre che con gli addizionatori esaminati nel cap. 3, anche disponendo di un solo full adder, se si procede nel seguente modo. Si comincia a sommare la coppia di bit meno significativi degli addendi ad un istante scelto come iniziale t0, ottenendo dopo il ritardo δ del full adder il bit meno significativo della somma ed un bit di riporto; ad un istante successivo t1 = t0+ δ si addizionano i bit della coppia successiva ed il bit di riporto generato al primo passo e ritardato nella propagazione dall’uscita all’ingresso del full adder di δ unità di tempo, e ancora dopo un tempo δ si ottiene il secondo bit della somma ed il nuovo riporto. Il processo si ripete fino all’esaurimento degli addendi (Fig. 4.1). Questo modello di addizione presenta alcune importanti caratteristiche: xi yi ci full adder δ ci+1 si Fig. 4.1 1) la somma è calcolata in n passi, un bit dopo l’altro, con cadenza uguale a δ. 2) Al passo i-esimo si sommano insieme i bit i-esimi degli addendi e il riporto del passo (i-1)-esimo reso disponibile in ingresso al tempo ti ritardandolo da ti-1 di δ unità di tempo mediante un elemento di ritardo. 3) Il riporto del passo (i-1)-esimo dipende oltre che dal valore degli addendi a quel passo anche dal riporto del passo (i-2)-esimo il quale dipende dagli addendi del passo (i-2)-esimo e dal riporto del passo (i-3)-esimo e così via. Questo significa che per poter - 105 - conoscere il valore della somma all’istante ti è necessaria la conoscenza del valore degli addendi su cui si opera in quell’istante e di tutti i valori precedenti, ovvero della “storia” temporale dei valori degli addendi. Il riporto riassume questa storia. In generale per situazioni come quella dell’addizione seriale è necessario ricorrere ad un modello in grado di descrivere funzioni logiche che definiscono non corrispondenze tra valori degli argomenti e valori del risultato, ma tra sequenze dei valori degli argomenti e valori del risultato, ossia deve essere in grado di descrivere funzioni sequenziali. Tale modello, che non può essere una semplice tavola di verità come quella delle funzioni combinatorie, prende il nome di macchina sequenziale o automa. Ritornando all’esempio, osserviamo che la storia dei valori degli addendi può essere divisa in due classi: quella che porta a generare un riporto 0 all’istante ti e quella che dà luogo ad un riporto 1. Chiamiamo queste classi stati interni o semplicemente stati dell’addizione seriale. Memorizzando il valore attuale del riporto nello stato appropriato, è possibile tenere una traccia sintetica della storia degli addendi dall’istante iniziale fino all’istante ti. Indichiamo con A lo stato dell’addizione all’istante ti se un riporto uguale a 0 si è generato all’istante ti-1, e con B lo stato se un riporto uguale a 1 si è generato all’istante ti-1. Chiamiamo inoltre stato attuale lo stato dell’addizione nell’istante in cui una nuova coppia di bit viene presentata all’ingresso e stato successivo lo stato in cui l’addizione viene a trovarsi dopo che una coppia di bit è stata elaborata. L’addizione seriale può essere allora descritta mediante la seguente tabella, nella quale viene specificato, per ogni combinazione di valori degli argomenti e per ogni stato attuale, lo stato successivo ed il valore della somma: xi, yi 00 01 11 10 A A, 0 A, 1 B, 0 A, 1 B A, 1 B, 0 B, 1 B, 0 Fig. 4.2 Ad esempio se lo stato attuale è A (riporto uguale a 0) e la coppia di bit da sommare è (1,1), lo stato successivo diventa B e la somma assume valore 0 e così via. Gli automi che considereremo hanno tutti un numero finito di stati (automi a stati finiti). - 106 - 4.2 - Modelli di automi a stati finiti Sia dato un automa A a stati finiti che descrive una funzione sequenziale e siano X = {X(ti)} l’insieme degli stati di ingresso, ovvero l’insieme di tutte le possibili combinazioni di valori che possono essere assunte dagli argomenti negli istanti {ti = t0+ i∆, i = 0, 1, 2, ...}, essendo t0 l’istante iniziale e ∆ l’incremento (supposto costante) di tempo tra un istante ed il successivo; S = {S(ti)} l’insieme degli stati interni; Z = {Z(ti)} l’insieme degli stati di uscita, ossia l’insieme di tutte le possibili combinazioni di valori prodotti dalla funzione negli istanti {ti}. Il comportamento nel tempo di A può essere descritto nel seguente modo. Se all’istante attuale ti A si trova nello stato S(ti ) ∈ S e viene applicato lo stato di ingresso X(ti) ∈ X, si produce in conseguenza lo stato di uscita Z(ti) ∈ Z e l’automa si porta nello stato successivo S(ti+1 ) ∈ S. Sia Z(ti) che S(ti+1) dipendono univocamente da S(ti) e da X(ti) e tale dipendenza è espressa attraverso le seguenti equazioni, che sono dette equazioni caratteristiche o rispettivamente funzione di transizione degli stati e funzione di uscita di A: S(ti+1) = f(S(ti), X(ti)) Z(ti) = g(S(ti), X(ti)) Il modello descritto è noto come modello di Mealy ed è caratterizzato dal fatto che in esso sia lo stato successivo sia lo stato di uscita sono definiti in funzione dello stato di ingresso e dello stato interno attuale. Esiste un altro modello, detto modello di Moore, secondo il quale l’uscita dipende solo dallo stato attuale, e per il quale le equazioni caratteristiche hanno la seguente forma: S'(ti+1) = f'(S'(ti), X(ti)) Z'(ti) = g'(S'(ti)) Il comportamento del modello di Moore, riassunto dalle sue equazioni caratteristiche, è descrivibile nel seguente modo. Se all’istante ti l’automa A' si trova nello stato attuale S'(ti) con uno stato di uscita qualsiasi e viene applicato lo stato di ingresso X(ti), essa si porta nello stato S'(ti+1), e in dipendenza di questo nuovo stato interno lo stato di uscita viene aggiornato a Z'(ti). La funzione di transizione degli stati, comune ai due modelli, può essere riscritta per qualunque istante tra t0 (istante iniziale) e ti (istante attuale) nella seguente forma, iterando la prima delle equazioni caratteristiche per ogni i, fino a i = 0: S(ti+1) = f(X(ti), S(ti)) = f(X(ti), X(ti-1), S(ti-1)) = … = f(X(ti), X(ti-1), …, X(t0), S(t0)) - 107 - Sostituendo questa espressione nelle funzioni di uscita dei modelli di Mealy e di Moore otteniamo rispettivamente: Z(ti) = g(X(ti), X(ti-1), ..., X(t0), S(t0)) Z'(ti) = g'(X(ti-1), X(ti-2), ..., X(t0), S'(t0)) Queste stabiliscono che lo stato di uscita all’istante attuale dipende dalla successione degli stati di ingresso a partire dallo stato iniziale e dallo stato interno iniziale. È da notare inoltre che mentre nel modello di Mealy la sequenza degli stati di ingresso da cui dipende lo stato di uscita all’istante attuale ti termina all’istante attuale, nel modello di Moore questa sequenza termina all’istante precedente ti-1. In altre parole nel modello di Mealy una sequenza di stati di ingresso genera una sequenza simultanea di stati di uscita; viceversa nel modello di Moore la sequenza di uscita è ritardata di un passo temporale rispetto a quella di ingresso che la genera, come è schematizzato nella seguente tabella, nella quale si è posto per semplicità S(tj) = Sj, Z(tj) = Zj e si è ammesso che S'(ti) ≡ S(ti) e Z'(ti) ≡ Z(ti): t0 Mealy t1 t2 t3 t0 S0 S1 S2 S3 Moore t1 t2 t3 t4 S0 S1 S2 S3 Z0 Z1 Z2 Z3 Z0 Z1 Z2 Z3 I modelli di Mealy e di Moore possono essere interpretati secondo gli schemi a blocchi funzionali descritti dalla Fig. 4.3: modello di Mealy X(ti) f S(ti+1) ∆ S(ti) g Z(ti) g' Z(ti) S(ti) modello di Moore X(ti) f' S'(ti+1) ∆ S'(ti) S'(ti) Fig. 4.3 I blocchi f e g ( o f' e g') sono realizzazioni delle funzioni f e g (f' e g') rispettivamente. Sia f che f' hanno per argomenti X(ti) e lo stato attuale S(ti) e generano lo stato successivo S(ti+1) o S'(ti+1), il quale, dopo il ritardo ∆, diventa stato attuale e come tale si ripresenta all’ingresso del - 108 - blocco f o f', nonché all’ingresso del blocco g o g', insieme allo stato di ingresso X(ti) per il modello di Mealy, da solo per il modello di Moore. 4.3 - Rappresentazione degli automi Rappresentare un automa significa specificarne le equazioni caratteristiche, rendendo esplicite le relazioni funzionali che esse esprimono e definendo in qualche modo i simboli che rappresentano gli stati di ingresso, interni e di uscita, per esempio attraverso un codice alfabetico o numerico; un modo di rappresentazione è attraverso un grafo di stato, ossia un grafo orientato nel quale i nodi corrispondono agli stati interni e gli archi alle transizioni da uno stato all’altro. Come vedremo successivamente il grafo di stato è uno strumento molto utile nel procedimento di sintesi, costituendone il primo passo che parte dalla descrizione a parole del comportamento di una funzione sequenziale e ne ricava una descrizione formale. Aderendo alla convenzione, d’ora in poi costantemente seguita, di indicare con Xj, Sj e Zj rispettivamente X(tj), S(tj) e Z(tj), nel modello di Mealy ogni nodo del grafo è etichettato con la specifica di uno stato Sj, mentre gli archi sono contrassegnati con la coppia di stati esterni (Xh, Zk); quindi per esempio la porzione di grafo indicato nella seguente figura: Xh/Zk Si Sj Fig. 4.4 si interpreta dicendo che se lo stato attuale è Si e si presenta lo stato di ingresso Xh, l’automa si porta nello stato Sj e lo stato di uscita diventa Zk. Nel modello di Moore i nodi sono contrassegnati con la coppia (Sj, Zk )e gli archi con Xh; pertanto il grafo precedente assume la forma mostrata in Fig. 4.5: Xh Si,Zl Sj,Zk Fig. 4.5 intendendo che se l’automa è nello stato Si, a cui corrisponde uno stato di uscita Zl, lo stato di ingresso Xh provoca la transizione allo stato Sj, raggiunto il quale l’uscita assume lo stato corrispondente Zk. Il grafo di stato può essere rappresentato sotto forma di una tabella, detta tabella di flusso, - 109 - le cui righe corrispondono agli stati interni e le colonne agli stati di ingresso; nel modello di Mealy ciascuna casella contiene lo stato successivo e l’uscita attuale corrispondenti alla coppia di coordinate (Sj, Xh) che costituiscono lo stato totale. Per esempio consideriamo un automa di Mealy avente due stati di ingresso, quattro stati interni e due stati di uscita, che indichiamo rispettivamente con X1, X2, S1, S2, S3, S4, Z1, Z2. Esso può essere definito dalla sua tabella di flusso costruita specificando per ogni coppia (stato attuale, stato di ingresso) la corrispondente coppia (stato successivo, stato di uscita): X1 X2 S1 S2, Z1 α S2, Z1 S2 S3, Z2 β S3 S1, Z1 S4 S4, Z1 S1, Z2 S4, Z2 γ S3, Z1 Fig. 4.6 La tabella di flusso permette anche di descrivere il comportamento dell’automa nel tempo, seguendo in essa gli spostamenti del punto di operazione. Per esempio supponiamo che partendo dallo stato interno iniziale S1, sia applicata all’ingresso la sequenza di stati X1 X1 X2. All’istante iniziale t0 l’automa si trova ad operare con lo stato totale (S1, X1) in corrispondenza del quale lo stato di uscita è Z1 e lo stato successivo è S2 (punto di operazione α). All’istante t1 lo stato totale diventa (S2, X1), a cui corrisponde uscita Z2 e stato successivo S3 (punto di operazione β). Infine al terzo istante t2, si deve considerare la riga della tabella (S3, X2), cui corrisponde uscita Z2 e stato successivo S4 (punto di operazione γ). L’evoluzione degli stati è indicata sulla tabella dalla successione delle frecce ed è riassunta come mostra il seguente quadro: t0 t1 t2 X(ti) X1 X1 X2 S(ti) S1 S2 S3 Z(ti) Z1 Z2 Z2 S(ti+1) S2 S3 S4 Fig. 4.7 Nel modello di Moore le caselle della tabella di flusso contengono solo lo stato successivo, mentre lo stato di uscita è riportato in una colonna separata; infatti dal momento che lo stato di - 110 - uscita dipende solo dallo stato attuale e non dallo stato di ingresso, tutte le caselle di una stessa riga avrebbero lo stesso simbolo per lo stato di uscita, e si può risparmiare scrivendolo una sola volta (Fig. 4.8). X1 X2 S1 S2 S2 Z1 S2 S3 S1 Z1 S3 S1 S4 Z2 S4 S4 S3 Z2 Fig. 4.8 4.4 - Similitudine tra modello di Mealy e modello di Moore Un automa può essere modellato indifferentemente secondo Mealy o secondo Moore, in quanto si può dimostrare la validità del seguente asserto: Dato un automa di Mealy A1 ed un automa di Moore A2, uno stato Si,1 di A1 ed uno stato Si,2 di A2 sono simili, e si scrive Si,1 ~ Si,2, se sono soddisfatte le seguenti condizioni, per qualunque stato di ingresso Xh: f (Xh, Si,1) ~ f '(Xh, Si,2) g(Xh, Si,1) = g'(f '(Xh, Si,2)) dove per l’automa di Moore g'(f'(Xh, Si,2)) è lo stato di uscita associato allo stato interno successivo di Si,2. Ovviamente la sequenza di uscita di A2 è ritardata di un passo rispetto alla corrispondente sequenza di ingresso. Gli automi A1 ed A2 sono simili se per una stessa sequenza di stati di ingresso, partendo da due qualunque stati iniziali simili Si,1 ed Si,2 generano la stessa sequenza di stati di uscita. Per esempio se consideriamo gli automi definiti dalle tabelle di flusso della Fig. 4.9: - 111 - X1 X2 X3 1 2, Z1 2, Z1 3, Z2 2 3, Z3 1, Z4 3, Z1 3 1, Z4 2, Z5 2, Z5 Mealy X1 X2 X3 a c d f Z1 b d e e Z2 c d e e Z3 d a a b Z4 e c d f Z5 f d e e Z1 Moore Fig. 4.9 si può facilmente verificare in base alla definizione che 1 ~ d; 2 ~ a, e; 3 ~ b, c, f. Perciò i due automi sono simili. Dato un automa A1 (di Mealy o di Moore), è possibile convertirlo in un automa A2 simile (di Moore o di Mealy) utilizzando i seguenti procedimenti. 1) Trasformazione Mealy-Moore • Ad ogni stato interno Sj di A1 (di Mealy) corrispondono nj stati simili Sj,i di A2 (di Moore), dove nj è uguale al numero di coppie distinte stato successivo-stato di uscita (Sj, Zi) presenti nella tabella di flusso di A1. Se Sj è uno stato singolare di A1, cioè se nella tabella di A1 non compare anche come stato successivo, ad esso corrisponde in A2 uno stato simile pure singolare S'j. • Lo stato successivo corrispondente ad ogni stato Sj,i viene determinato in modo che siano rispettate le relazioni: f(Xh, Sj) ~ f '(Xh, Sj,i) g(Xh, Sj) = g'(f '(Xh, Sj,i)) ovvero se f (Xh, Sj) = Sp e g(Xh, Sj) = Zm, allora f'(Xh, Sj,i) = Sp,m. • Lo stato di uscita è determinato dalla relazione g'(Sj,i) = Zi; lo stato di uscita corrispondente allo stato S'j è lasciato non specificato. La ragione di questo assegnamento sta nel fatto che, coerentemente con lo sfasamento di un passo temporale tra A1 ed A2, l’uscita associata allo stato Sj,i in A2 deve essere la stessa generata dall’automa A1 in corrispondenza di un proprio stato interno attuale Sk avente come successore lo stato Sj, per ogni stato di ingresso Xh. • Alle eventuali righe della tabella di A2 per le quali non siano stati definiti stati successivi potranno essere assegnati valori identici. - 112 - La procedura di conversione sopra descritta si giustifica facilmente in merito alla individuazione degli stati successivi e degli stati uscita mediante i grafi di stato delle due macchine, come illustrato in Fig. 4.10. Xi Xi/Zr Sp,r/Zr Xk Xh Xk/Zn ⇒ Sp Xh/Zm Sp,n/Zn Sp,m/Zm Mealy Moore Fig. 4.10 Come esempio consideriamo la tabella di Mealy di Fig. 4.11a. Allo stato S1 corrisponde nella tabella di Moore lo stato simile S1,1; allo stato S2 corrisponde lo stato S2,1. Allo stesso modo allo stato S3 corrispondono come simili gli stati S3,1 e S3,2, allo stato S4 gli stati simili S4,1 e S4,2. Infine allo stato S5 singolare corrisponde lo stato S'5, pure singolare. Nella tabella di Moore così definita gli stati successivi di S1,1 sono S3,1e S1,1; i successori di S2,1 sono S2,1 e S1,1; gli stati S3,1 e S3,2 hanno entrambi come successori gli stati S4,2 e S3,2, mentre gli stati S4,1 e S4,2 hanno entrambi per successori gli stati S4,1 e S2,1. Infine allo stato S'5 corrispondono gli stati successivi S3,2 e S1,1. Per quanto riguarda lo stato di uscita, si ha g'(S1,1) = Z1, ossia l’uscita associata allo stato S1,1 è la stessa relativa allo stato 1 dell’automa di Mealy e così via per le altre righe, tranne che per la riga S'5, dove l’uscita non è specificata. X1 X2 11 31 11 Z1 1 3, Z1 1, Z1 21 21 11 Z1 2 2, Z1 1, Z1 31 42 32 Z1 3 4, Z2 3, Z2 32 42 32 Z2 4 4, Z1 2, Z1 41 41 21 Z1 5 3, Z2 1, Z1 42 41 21 Z2 5' 32 11 - X1 X2 a b Fig. 4.11 2) Trasformazione Moore-Mealy • Ad ogni stato interno Sj dell’automa di Moore corrisponde una stato interno simile S'j - 113 - dell’automa di Mealy, dal momento che la riga corrispondente a S'j della tabella di A2 può essere completamente definita tramite le relazioni f(Xh, Sj) ~ f '(Xh, S’j), g(f(Xh, Sj)) = g'(Xh, S'j). • Lo stato successivo corrispondente allo stato S'j viene determinato dalla relazione f'(Xh, S’j) ~ f(Xh, Sj), ovvero se f(Xh, Sj) = Sk allora f'(Xh, S’j) = S'k ~ Sk. • Lo stato di uscita è determinato dalla relazione g'(Xh, S'j) = g(f(Xh, Sj)), vale a dire se f(Xh, Sj) = Sk, e g(Sk) = Zm allora g'(Xh, S'j) = Zm. La giustificazione di questa regola è data nella Fig. 4.12. Xh Xh/Zm Sj, - ⇒ Sk, Zm S’j S’k Moore Mealy Fig. 4.12 Per esempio consideriamo la tabella di Moore di Fig. 4.13a; la tabella di Mealy simile ha lo stesso numero di stati interni 1', 2', 3', 4' e gli stati successivi si trovano rispetto agli stati attuali nella stessa corrispondenza che si riscontra nell’automa di Moore. Per lo stato di uscita consideriamo che allo stato attuale 1 corrisponde lo stato successivo 2 per lo stato di ingresso X1 e che lo stato di uscita corrispondente a 2 è Z2: tale stato viene indicato come uscita nella casella (1', X1) di A2; analogamente si procede per tutti gli altri stati totali di A1. X1 X2 1 2 3 Z1 1' 2', Z2 3', Z1 2 1 4 Z2 2' 1', Z1 4', Z2 3 2 2 Z1 3' 2', Z2 2', Z2 4 1 4 Z2 4' 1', Z1 4', Z2 b X1 a X2 Fig. 4.13 La trasformazione dal modello di Mealy a quello di Moore o viceversa conduce ad un nuovo automa simile che, almeno per il primo tipo di trasformazione, ha il minimo numero di stati interni, se minimo è il numero di stati dell’automa originario. Nel secondo caso può essere necessario minimizzare il numero di stati dell’automa ottenuto, secondo un procedimento che sarà visto più avanti. E` conveniente usare queste conversioni quando, disponendo di un automa di un certo tipo, se ne vuole ottenere uno dell’altro tipo senza bisogno di ripercorrere tutto il processo di definizione. In taluni casi tuttavia è desiderabile che, dato un automa A1 di un tipo, si possa ottenere un automa simile A2 dell’altro tipo che conservi il più possibile la struttura interna di A1. - 114 - a) Consideriamo il modello di automa di Mealy e ricordiamo che la sequenza degli stati di uscita di un automa di Moore è ritardata di un passo rispetto alla sequenza degli stati di ingresso da cui ha origine e quindi anche rispetto alla sequenza degli stati di uscita di un automa di Mealy simile, al quale sia applicata la stessa sequenza di ingresso. Pertanto la struttura di un automa di Moore A2 simile ad uno di Mealy dato si può ottenere dalla struttura di questo semplicemente aggiungendo all’uscita un elemento di ritardo identico a quello presente sull’anello di reazione. L’automa che ne risulta è chiamato automa di Mealy ritardato (Fig. 4.14b). automa di Mealy S(ti+1) X(ti) f Z(ti) g ∆ a) S(ti) automa di Moore (di Mealy ritardato) S(ti+1) X(ti) ∆ g ∆ f Z(ti) b) S(ti) Fig. 4.14 b) Si consideri ora la struttura di un automa di Moore; la struttura di un automa di Mealy simile si può ottenere da questo se si riesce ad anticipare di un passo l’uscita. Ciò può essere fatto se si sconnette l’ingresso della rete g dall’uscita dell’elemento di ritardo e la si collega all’uscita del blocco f, come è mostrato in Fig. 4.15b. L’automa che ne risulta è detto automa di Moore anticipato. X(ti) f automa di Moore S(ti+1) S(ti) ∆ g Z(ti) a) automa di Mealy (di Moore anticipato) X(ti) ∆ f S(ti+1) g Z(ti) b) S(ti) Fig. 4.15 Le trasformazioni sopra descritte possono portare ad un aumento considerevole di stati - 115 - interni, dal momento che i blocchi f e g della macchina trasformata rimangono inalterati. In particolare nella trasformazione Mealy → Moore ad uno stato della macchina di Mealy può corrispondere un numero di stati della macchina di Moore simile che al massimo è pari al numero degli stati di uscita; se indichiamo con n è il numero di stati interni, con l quello degli stati di ingresso e con m quello degli stati di uscita e tenendo conto del fatto che la tabella di flusso possiede n×l caselle, il numero complessivo di stati della macchina di Moore può arrivare a n×min(m,l). Pur essendo possibile realizzare un automa secondo un modello o l’altro indifferentemente, nei casi concreti la scelta deve essere fatta secondo opportuni criteri. Se il criterio è unicamente quello di una minore complessità logica, il modello di Mealy è da preferire perchè in generale presenta un numero di stati interni inferiore a quello di Moore. Tuttavia esiste un altro parametro in base al quale si può procedere. In un automa di Moore lo stato di uscita è sempre significativo, in quanto dipende solo dallo stato interno e quindi può essere fatto variare, come vedremo, in corrispondenza di istanti ben precisi, in sincronismo con un riferimento temporale esterno (clock); invece nell’automa di Mealy lo stato di uscita può cambiare in risposta a transizioni spurie dello stato di ingresso e durante l’intervallo tra il segnale di sincronismo ed il cambiamento dello stato di ingresso, assumendo eventualmente valori non significativi. Come conclusione, in tutti i casi in cui lo stato di uscita deve essere sempre significativo deve essere preferito l’automa di Moore, anche se questo porta ad una maggiore complessità logica della realizzazione. 4.5 - Riduzione delle tabelle di flusso 4.5.1 - Tabelle di flusso completamente specificate Data la tabella di flusso completa di un automa A, talvolta è possibile trovare un altro automa A' il cui comportamento è sostanzialmente identico a quello di A, tanto che l’uno può essere sostituito all’altro. Se A' ha meno stati di A, si dice che A può essere ridotto. La riduzione del numero di stati di un automa può condurre ad una minore complessità della rete che lo realizza e quindi è un procedimento che merita attenzione. Consideriamo per esempio i due automi di Fig. 4.16: X1 X2 X1 S1 S1, Z1 S2, Z1 X2 S1 S1, Z1 S2, Z1 S2 S1, Z1 S3, Z1 S2 S1, Z1 S3, Z1 S3 S1, Z1 S4, Z1 S3 S1, Z1 S4, Z1 S4 S1, Z1 S5, Z2 S4 S1, Z1 S4, Z2 S5 S1, Z1 S5, Z2 A' A Fig. 4.16 - 116 - Per l’automa A è immediato rendersi conto che la sequenza di stati di uscita per una qualunque sequenza di stati di ingresso è la stessa sia che l’automa parta dallo stato S4, sia che parta dallo stato S5. Possiamo cambiare quindi S5 in S4 in tutte le caselle della tabella di flusso in cui tale stato compare, in modo che esso non figuri più come stato successivo; così facendo tanto S4 quanto S5 vengono ad avere gli stessi stati successivi e gli stessi stati di uscita. Si dice che S4 ed S5 sono stati indistinguibili; S5 può essere rimosso dalla tabella che pertanto si trasforma in A'. In generale diremo che uno stato S di un automa A è indistinguibile da uno stato S' di un automa A' se i due automi, partendo rispettivamente da S e da S', generano la stessa sequenza di stati di uscita per qualunque sequenza di stati di ingresso. Se due stati S ed S' sono indistinguibili, si scrive S ≡ S. Il concetto di indistinguibilità tra stati può essere esteso agli automi, dicendo che un automa A ed uno A' sono indistinguibili (e pertanto possono essere scambiati tra di loro senza alcuna conseguenza) se per ogni stato Si di A esiste uno stato Sj' di A', con Si ≡ Sj', tale che per qualunque sequenza di stati di ingresso i due automi, partendo rispettivamente dagli stati iniziali Si ed Sj', generano la stessa sequenza di stati di uscita; in maniera alternativa diremo che A e A' sono indistinguibili se per ogni stato Si di A esiste uno stato Sj' di A' tale che sia Si ≡ Sj' e viceversa. La relazione di indistinguibilità è riflessiva (infatti ogni automa è indistinguibile da se stesso), è simmetrica (se Ai ≡ Aj, allora Aj ≡ Ai ), è transitiva ( ovvero se Ai ≡ Aj e Aj ≡ Ak, allora è anche Ai ≡ Ak) e pertanto è una relazione di equivalenza. Essa, applicata all’insieme degli stati di un automa A, individua una partizione completa Π che divide gli stati in sottoinsiemi disgiunti, tali che tutti gli elementi di uno stesso sottoinsieme sono stati tra loro indistinguibili ed elementi appartenenti a sottoinsiemi diversi sono stati distinguibili. I sottoinsiemi di Π sono detti classi di indistinguibilità di A. Consideriamo ora un automa A e tutti quelli A' indistinguibili da A ed aventi un numero di stati inferiore. Tra gli automi A' ce ne sarà uno, Amin, che possiede il minimo numero di stati, e precisamente, per quanto detto, pari al numero delle classi di indistinguibilità di A e questo sarà l’automa da sostituire ad A. Per il problema della minimizzazione degli stati di A è dunque essenziale determinarne le classi di indistinguibilità. Secondo la definizione, un insieme di stati {S1, S2, …, Sr} di un automa A costituisce una classe di indistinguibilità se essi generano, per qualunque sequenza di stati di ingresso, la stessa sequenza di stati di uscita, quando siano assunti come stati iniziali di A: si tratta di una definizione non utilizzabile direttamente a causa della sua impraticità; tuttavia per risolvere il problema è sufficiente considerare sequenze di ingresso di lunghezza uno e di lunghezza due, verificando che: 1) per ogni stato di ingresso Xk, sia verificate le uguaglianze g(Xk, S1) = g(Xk, S2) = … = g(Xk, Sr), ovvero gli stati dell’insieme {S1, S2, …, Sr} siano indistinguibili sotto una - 117 - sequenza di ingresso di lunghezza unitaria; 2) gli stati successivi, per ogni stato di ingresso Xk, siano pure indistinguibili, ovvero f(Xk, S1) ≡ f(Xk, S2) ≡ … ≡ f(Xk, Sr). Segue che due stati Si ed Sj sono distinguibili se e solo se a) sono distinguibili sotto una sequenza di ingresso unitaria oppure b) esiste almeno uno stato di ingresso Xk per il quale i loro successori f(Xk, Si), f(Xk, Sj) sono distinguibili. Inoltre, poichè la relazione di indistinguibilità è transitiva, nella ricerca ci si può limitare a determinare solo le coppie di stati indistinguibili, seguendo una procedura che si avvale di una tabella, detta tabella a scala o di Unger, la quale, per una tabella di flusso con n stati, possiede n-1 righe, numerate da S2 ad Sn ed n-1 colonne, numerate da S1 ad Sn-1 (Fig. 4.17). S2 S3 Sn-1 Sn S1 S2 Sn-2 Sn-1 Fig. 4.17 a) Ricerca delle coppie di stati indistinguibili La casella (Si, Sj), i < j viene contrassegnata con × se Si ed Sj sono distinguibili; altrimenti è riempita con tutte le coppie implicate da Si ed Sj per tutti gli stati di ingresso. Se Si ed Sj non implicano alcuna coppia, ossia sono tali che per essi valgono le uguaglianze f(Xk, Si) = f(Xk, Sj) e g(Xk, Si) = g(Xk, Sj), per ogni Xk, la casella è lasciata vuota. Dopo aver riempito tutte le caselle con questo procedimento, si sostituisce ulteriormente con × il contenuto di ogni casella contenente almeno una coppia (Sm, Sn) tale che la casella di coordinate (Sm, Sn) contenga × e si procede in questo modo finchè è possibile. Quando nessun contrassegno può più essere inserito, tutte le coppie di stati distinguibili hanno × nelle rispettive caselle. Viceversa tutte le coppie rimaste indicate nelle caselle sono indistinguibili, come lo sono a maggior ragione tutte quelle che costituiscono le coordinate di caselle rimaste vuote. b) Ricerca delle classi di indistinguibilità. 1) Partendo dallo stato Si, i = 1, 2, ..., si costruisce un insieme Bi comprendente Si e tutti gli stati da esso indistinguibili, tenendo conto che se gli stati Si, Sj, ..., Sk sono indistinguibili da uno stesso stato Sh, per la proprietà transitiva, l’insieme {Si, Sj, ..., Sk, Sh} è una classe di - 118 - indistinguibilità. 2) Per uno stato Sl non contenuto in alcuno degli insiemi Bk costruiti in questo modo e tale che per qualunque altro stato Sm, sia l < m, si costruisce un ulteriore insieme Bl contenente Sl e tutti gli stati da esso indistinguibili. 3) Si ripete il passo 2 finchè tutti gli stati figurano in qualche insieme Bi. Gli insiemi così generati sono disgiunti e definiscono la partizione Π che viene utilizzata per generare la tabella minima. c)Ricerca della tabella minima. 1) Gli stati dell’automa ridotto corrispondono alle classi di indistinguibilità definite dalla partizione Π. 2) Gli stati successivi e gli stati di uscita sono definiti come segue. Se lo stato attuale è Bi = {Si1, Si2, ..., Sik} e lo stato di ingresso è Xj, sia Bij = {f(Xj, Si1), f(Xj, Si2), ..., f(Xj, Sik)}. Poichè tutti gli stati in Bij sono indistinguibili, ci deve essere in Π uno ed un solo insieme Bh tale che Bij ⊆ Bh; definiamo tale insieme come stato successivo, corrispondente allo stato totale (Xj, Bi) e come stato di uscita assumiamo g(Xj, Bi) = g(Xj, Si1) = g(Xj, Si2) = ... = g(Xj, Sik). Vediamo come esempio la riduzione della tabella di flusso di Fig. 4.18: X1 X2 S1 S3, Z1 S2, Z1 S2 S3, Z1 S4, Z1 S3 S5, Z1 S6, Z1 S4 S5, Z2 S1, Z2 S5 S1, Z1 S2, Z1 S6 S5, Z1 S4, Z1 Fig. 4.18 a) Si costruisce la tabella di Unger, osservando che sono coppie di stati distinguibili le coppie (S1, S4), (S2, S4), (S3, S4), (S4, S5), (S4, S6), per cui inizialmente essa si presenta come in Fig. 4.19a: - 119 - × S2 S2 S4 S2 S S S3 S3 S5 SS3 SS5 2 6 4 6 S S S3 S3 S5 2 6 S4 × × × S5 S1 S3 SS1 SS3 SS1 SS5 2 4 2 6 × S6 SS3 SS5 S3 S5 S4 S6 2 4 × S1 S2 S3 S4 × × × S1 S5 S2 S6 × × S3 S5 × × × S1 S2 S3 S4 S5 × S4 S5 S1 S3 S1 S5 S2 S4 S6 S5 × a) b) Fig. 4.19 Quindi, poichè la casella (2, 4), corrispondente alla coppia di stati distinguibili (S2, S4), contiene una ×, anche la casella (1, 2), contenente all’inizio la coppia suddetta, viene contrassegnata con ×; lo stesso procedimento è ripetuto per tutte le altre caselle non contrassegnate inizialmente e si arriva così alla tabella di Fig. 4.19b. A questo punto una ripetizione del procedimento non porta ad inserire ulteriori ×, per cui le coppie rimaste non sostituite nella tabella sono tutte le coppie di stati indistinguibili: (S1, S3), (S3, S5), (S1, S5), (S2, S6). b) Poichè gli stati S3 ed S5 sono indistinguibili da S1, formano l’insieme B1 = {S1, S3, S5}. Lo stato S2, non appartenente a B1, è indistinguibile da S6 con cui forma l’insieme B2. Infine lo stato S4 costituisce da solo un terzo insieme B3, e quindi si ha la partizione Π = [{S1, S3, S5}, {S2, S6}, S4]. c) L’automa ridotto ha quindi tre stati definiti da Π, B1, B2, B3. Poichè B1 = {S1, S3, S5}, l’insieme B11 = {f(X1, S1), f(X1, S3), f(X1, S5)}, desumibile dalla tabella di flusso dell’automa, è {S1, S3, S5} = B1; l’insieme B12 = {f(X2, S1), f(X2, S3), f(X2, S5)} è {S2, S6} = B2. Pertanto i successori dello stato B1 per i due stati di ingresso sono rispettivamente B1 stesso e B2. Analogamente si trova che i successori di B2 sono B1e B3 e quello di B3 è B1 per entrambi gli stati di ingresso. Per quanto riguarda lo stato di uscita, si ha g(X1, B1) = g(X1, S1) = f(X1, S3) = f(X1, S5) = Z1 e così via per tutti gli altri stati totali. Si arriva così alla tabella di flusso ridotta di Fig. 4.20: X1 X2 {S1, S3, S5} B1 B1, Z1 B2, Z1 {S2, S6} B2 B1, Z1 B3, Z1 {S4} B3 B1, Z2 B1, Z2 Fig. 4.20 - 120 - Come secondo esempio consideriamo la tabella di flusso dell’automa di Fig. 4.21: 0 1 A H, 0 G, 1 B C, 0 E, 0 C B, 0 A, 0 D E, 1 H, 0 E H, 0 D, 1 F E, 1 H, 0 G A, 1 H, 0 H D, 0 F, 1 Fig. 4.21 alla quale corrispondono le tabelle di Unger di Fig. 4.22a e 4.22b. La figura 4.22b mostra che gli stati indistinguibili sono: A ≡ E; B ≡ C; D ≡ F ≡ G; pertanto a = {A, E}; b = {B, C}; c = {D, F, G}; d = {H} sono gli stati dell’automa ridotto; inoltre gli stati successivi sono: a1 = {H} = d; a2 = {G, D} ⊆ c; b1 = {C, B} = b; b2 = {E, A} = a; c1 = {E, A} = a; c2 = {H} = d; d1 = {D} ⊆ c; d2 = {F}⊆ c e le uscite: g(0, a) = g(0, A) = g(0, E) = 0; g(1, a) = g(1, A) = g(1, E) = 1; g(0, b) = g(0, C) = g(0, B) = 0; g(1, b) = g(1, C) = g(1, B) = 0; g(0, c) = g(0, D) = g(0, F) = g(0, G) = 1; g(1, c) = g(1, D) = g(1, F) = g(1, G) = 0; g (0, d) = g(0, H) = 0; g(1, d) = g(1, H) = 1. B × B C × BC AE × × × D E DG × × × × F × G × × × H DH FG A B C D × × × × BC AE × × × E DG × × × F × × × × AE G × × × AE × AE × C H × A × B × C × AE × DH × × DF D E F G Fig. 4.22 Pertanto la nuova tabella è la seguente: - 121 - × × × × × D E F G 0 1 a d, 0 c, 1 b b, 0 a, 0 c a, 1 d, 0 d c, 0 c, 1 Fig. 4.23 4.5.2 - Tabelle di flusso incomplete Consideriamo ora il caso di tabelle di flusso nelle quali vi siano condizioni di indifferenza sugli stati interni oppure sugli stati di uscita o su entrambi, dovute a sequenze “proibite” di stati di ingresso per la presenza di vincoli su transizioni simultanee di due o più variabili di ingresso, oppure più in generale contenute nelle specifiche del comportamento dell’automa. Tali tabelle sono dette incomplete o non completamente specificate e si prestano molto spesso, proprio per questa loro caratteristica, ad essere ridotte. Ci proponiamo perciò di trovare un metodo semplice per questo scopo. Esaminiamo dapprima tabelle nelle quali le condizioni di indifferenza riguardano solo gli stati di uscita e definiamo una relazione, detta di compatibilità, nel seguente modo: due stati Si ed Sj si dicono compatibili, e si scrive Si ≈ Sj , se per ogni stato di ingresso Xk, gli stati successivi f(Xk, Si) e f(Xk, Sj) sono pure compatibili, mentre gli stati di uscita g(Xk, Si) e g(Xk, Sj) sono uguali laddove sono specificati, sono qualsiasi se non specificati. Si tratta di una relazione più lasca di quella di indistinguibilità e precisamente di una relazione che è riflessiva e simmetrica, ma non necessariamente transitiva, e pertanto non è una relazione di equivalenza. E’ evidente che la relazione di indistinguibilità per le tabelle complete è un caso particolare della relazione di compatibilità. Definiamo inoltre classe di compatibilità un insieme di stati interni {S1, S2, …, Sr} tali che ogni elemento sia compatibile con tutti gli altri; una classe di compatibilità è massima se non è contenuta in alcun’altra classe di compatibilità. Il concetto di classe di compatibilità è importante perchè la procedura per la riduzione di una tabella di flusso incompleta porta a generare una nuova tabella di flusso i cui stati sono classi di compatibilità della tabella data. Tuttavia, a differenza del caso delle tabelle complete, la ricerca non può essere condotta sistematicamente, ma attraverso tentativi, a causa della non transitività della relazione di compatibilità. Di fatto, con l’aiuto della tabella di Unger si individuano tutte le coppie di stati compatibili, come nel caso delle tabelle complete; quindi si procede come segue: 1) muovendo da destra verso sinistra sulla tabella di Unger finale, si considera la prima colonna che contiene una o più coppie di stati compatibili e si costruisce una classe di - 122 - compatibilità costituita da tutte le coppie di stati che sono coordinate di caselle contenenti coppie di stati compatibili; 2) si considera la colonna precedente che contiene almeno una coppia di stati compatibili. Se lo stato che la identifica è compatibile con tutti gli stati di una classe di compatibilità già definita, si aggiunge a tale classe a formarne una più grande; altrimenti si aggiungono a quelle già esistenti una o più nuove classi di compatibilità comprendenti il nuovo stato e quelli con esso compatibili; notare che questi possono eventualmente essere presenti anche in altre classi già definite; 3) si ripetono i passi 1) e 2) fino ad esaurire le colonne della tabella. Questo procedimento genera, per il modo come vengono costruite, tutte classi di compatibilità massime. Per esempio consideriamo la seguente tabella di flusso e la tabella di Unger corrispondente (Fig. 4.24). Applicando la procedura descritta si ottiene: colonna S4: viene generata la prima classe di compatibilità {S4, S5}; colonna S3: S3 è compatibile con S4, ma non con S5 , per cui entra a far parte di una nuova classe insieme ad S4 e si ottiene {S4, S5}, {S3, S4}); colonna S2: anche in questo caso lo stato S2 definisce una nuova classe insieme allo stato S3 con cui è compatibile e che si trova già in una classe precedentemente definita, ottenendo le classi {S4, S5}, {S3, S4}, {S2, S3}). 0 1 S1 S4, Z1 S2, Z1 S2 S5, Z1 S1, Z1 S2 S4S5 S3 S4, - S3, Z1 S3 S2S3 SS1SS3 4 5 S S S3 S2S3 S1S3 S4 S3, Z2 S3, Z1 S4 × × S4 × × S5 S2, Z2 S2, Z1 S5 × × × × × S2S3 S1 S2 S3 S1 S2 S4S5 S2 4 5 S2S4 S S S2S3 2 3 S3 S4 S5 S4 Fig. 4.24 colonna S1: S1 è compatibile con la classe {S2, S3} preesistente, per cui entra a fare parte di essa, trasformandola in una più ampia; alla fine si ottengono le classi di compatibilità massime {S4, S5}, {S3, S4}, {S1, S2, S3}. Per concludere introduciamo i concetti di relazione di copertura e di insieme chiuso di classi di compatibilità: 1) una classe di compatibilità ne copre un’altra se ogni suo stato è anche stato dell’altra; per esempio la classe {S1, S2, S3} copre {S2, S3}, ovvero è più grande di questa (in particolare è massima); una tabella di flusso T1 copre una tabella T 2 se e solo se per ogni stato Si,2 di T 2 - 123 - esiste uno stato Sj,1 di T1 tale che le due tabelle, partendo rispettivamente da Sj,1 e da Si,2, danno luogo alla stessa sequenza di stati di uscita, per la stessa sequenza di stati di ingresso, in tutti i punti in cui la tabella T1 è specificata. 2) un insieme di classi di compatibilità è chiuso se, per ogni sua classe, tutte le classi di compatibilità implicate dall’applicazione di una qualunque sequenza di stati di ingresso sono contenute nell’insieme. La ricerca della tabella minima mira ad individuare un insieme di classi di compatibilità che copra la tabella data, che sia chiuso e che abbia la minima cardinalità. Al riguardo occorre osservare che la tabella di flusso, che ha come stati le classi di compatibilità massime ottenute con la procedura descritta sopra, è certamente una soluzione, ma non è detto che sia necessariamente quella minima, non valendo sempre la proprietà transitiva per la relazione di compatibilità; pertanto il numero di classi di compatibilità massima costituisce un limite superiore al numero di stati di una tabella ridotta. Riguardo al modo come sono determinati gli stati successivi nella tabella ridotta, per ogni sua riga (ossia per ogni data classe di compatibilità) e per ogni stato di ingresso si considerano i successori di tutti gli stati della tabella data, i quali faranno parte di una stessa classe di compatibilità implicata da quella data: la classe implicata definisce lo stato successivo cercato. Per gli stati di uscita infine, se in almeno uno degli stati appartenenti ad una classe di compatibilità implicata da una data classe lo stato di uscita è definito, esso viene assunto come stato di uscita da associare a quella data classe, altrimenti lo stato di uscita rimane non specificato. Ritornando all’esempio, indichiamo con a, b e c gli stati della tabella ridotta, coincidenti rispettivamente con le classi di compatibilità {S1, S2, S3}, {S3, S4}, {S4, S5} determinate in precedenza e osserviamo che risulta f(0, S1) = S4, f(0, S2) = S5, f(0, S3) = S4 per cui f(0, a) = c; f(1, S1) = S2, f(1, S2) = S1, f(1, S3) = S3 per cui f(1, a) = a; f(0, S3) = S4, f(0, S4) = S3 per cui f(0, b) = b; f(1, S3) = S3, f(1, S4) = S3 per cui f(1, b) = b, oppure f(1, b) = a; f(0, S4) = S3, f(0, S5) = S2 per cui f(0, c) = a; f(1, S4) = S3, f(1, S5) = S2 per cui f(1, c) = a. In definitiva si ottiene la seguente tabella ridotta: a c, Z1 a, Z1 b b, Z2 b, Z1 c a,Z2 a, Z1 Fig. 4.25 Nella costruzione della tabella ridotta si può presentare una situazione di incertezza circa la classe di compatibilità da scegliere come stato successivo, a causa del fatto che uno stesso stato della tabella originaria può figurare in più classi di compatibilità; quando le condizioni di indifferenza nella tabella di flusso originaria riguardano solo le uscite, si può risolvere il problema seguendo un criterio analogo a quello visto a proposito del metodo di - 124 - Quine-McCluskey per le funzioni combinatorie, relativamente alla determinazione dell’insieme non ridondante di implicanti primi condotta con l’aiuto della tabella di copertura e con i criteri di essenzialità e di dominanza: qui le classi di compatibilità giocano il ruolo degli implicanti e gli stati della tabella originaria quello degli “1” della funzione. Procedendo in questo modo si può arrivare anche ad escludere una o più classi di compatibilità dalla tabella ridotta. Per esempio nel caso della tabella di Fig. 4.24, osserviamo che le classi di compatibilità a e c sono essenziali per la sua copertura, mentre la b è inclusa in esse, come mostra la Fig. 4.26a, e pertanto può essere eliminata dalla tabella ridotta, che risulta composta da due soli stati (Fig. 4.26b): essenziale essenziale S1 S2 S3 S4 S5 a × × × b × × c × × a a c, Z1 a, Z1 c a, Z2 a, Z1 b Fig. 4.26 Consideriamo ora le tabelle di flusso che presentano condizioni di indifferenza anche sugli stati interni. In queste situazioni è possibile riportarci facilmente al caso trattato finora. Consideriamo infatti uno stato fittizio s stabile, ossia tale che f(Xh, s) = s, ∀Xh, e con uscite non specificate: se nella tabella originaria si specifica s come stato successivo in ogni casella in cui lo stato successivo non è specificato, non si altera la tabella di flusso, in quanto lo stato s, essendo stabile, è compatibile con tutti gli stati della tabella data e non introduce in essa alcun vincolo. Con questo artificio si può procedere alla riduzione della tabella trasformata, individuando le classi di compatibilità massime, dalle quali poi avremo cura di eliminare lo stato fittizio s. Come esempio, consideriamo la situazione descritta nella Fig. 4.27a. La procedura per la determinazione delle classi di compatibilità sopra descritta porta a individuare solo le classi di compatibilità massime 1 = {A, C, s} e 2 = {B, D, s}, ovvero le classi 1 = {A, C} e 2 = {B, D} che costituiscono un insieme chiuso che copre la tabella modificata, senza condizioni di indifferenza sugli stati interni; pertanto la tabella ridotta finale è quella mostrata in Fig. 4.27d. - 125 - 0 1 A A, - B, 0 B -, - C, 1 C A, 1 D, D B, 0 A, a) 0 1 A A, - B, 0 B × B s, - C, 1 C BD × ⇒ C A, 1 D, - D × Bs D B, 0 A, - s Bs A s s, - s, b) Fig. 4.27 - 126 - 0 1 1 1, 1 2, 0 AC Cs B 2 2, 0 1, 1 × As Ds C c) As Bs D d) 1 = {A, C} 2 = {B, D} ESERCIZI 1) Convertire la seguente tabella di flusso di Mealy in quella di Moore simile: A B C D E F G X0 A,0 C,2 C,1 A,0 E,0 F,0 A,1 X1 B,1 E,0 D,1 A,1 F,1 F,2 B,2 X2 D,2 F,1 A,2 C,1 B,2 C,0 D,0 2) Convertire la seguente tabella di flusso di Moore in quella di Mealy simile: A B C D E F G X0 A C C A E F A X1 B E D A F F B X2 D F A C B C D 0 0 1 2 1 0 - 3) Minimizzare la seguente tabella di flusso, quindi convertire la tabella ridotta in quella di Moore simile: a b c d e f g X1 X2 X3 X4 a,0 b,2 e,1 d,2 e,1 a,1 b,2 b,2 f,0 d,1 d,1 g,2 d,1 c,0 e,0 g,1 f,0 f,0 e,0 f,0 g,1 d,2 c,3 c,2 d,1 f,3 c,2 f,3 4) Disegnare il grafo degli stati dell’automa di Moore simile a quello dato in figura, senza passare attraverso la trsformazione per similitudine delletabelle di flusso: - 127 - X1/0 X0/0 X1/0 A B X0/0 X0/0 D C X1/1 X1/1 X0/0 5) Si minimizzi il seguente automa di Mealy, quindi si converta l’automa ridotto in quello simile di Moore: A B C D E F X1 -, -, F, 0 -, A, D, 0 X2 E, 1 B, -, -, E, 0 F, - X3 A,E, 1 -, C, 0 F, -, - X4 C, 1 F, 1 B, 1 -, -, -, - 6) Convertire la seguente tabella di flusso in quella simile di Moore: 1 2 3 4 5 6 x1 x2 1,0 2,0 2,0 6,0 1,0 6,0 3,1 4,1 3,1 4,1 5,0 5,0 7) Ridurre il seguente automa, quindi si effettui la conversione Me → Mo dell’automa ridotto: - 128 - x1 x2 x3 1 2 3 4 5 6 7 8 4,1 8,0 1,0 5,1 5,1 1,1 4,1 2,0 5,0 2,1 3,1 1,0 6,0 4,0 7,0 2,1 6,1 8,1 7,0 4,1 4,1 5,1 3,1 8,1 8) Trasformare il seguente automa di Moore in quello di Mealy simile, quindi ridurre la tabella di flusso ottenuta: x1 x2 x3 A B C D E F G H A A E B F H B A C F E C F A E B B G H E G B A F 0 1 1 0 0 0 1 9) Ridurre la seguente tabella di flusso: A B C D E F G H x1 x2 C,1 D,0 C,1 D,0 H,1 F,1 F,0 H,1 A,0 B,0 B,0 E,0 E,0 A,0 G,0 G,0 - 129 - 10) Ridurre la seguente tabella di flusso: a b c X1 X2 X3 X4 a,1 a,0 c,0 b,1 b,0 b,0 -,b,1 c,0 c,0 c,0 c,0 11) Ridurre la seguente tabella di flusso, quindi trasformare la tabella ridotta in quella di Moore simile: a b c d e f X1 X2 X3 X4 a,0 -,d,0 d,1 -,-,- -,c,0 c,1 -,e,0 c,1 b,0 b,0 b,1 f,0 f,1 f,0 a,1 d,1 -,d,1 e,1 e,0 12) Trasformare il seguente grafo degli stati di Moore in quello di Mealy simile, senza passare attraverso la procedura di conversione delle tabelle di flusso: 1 A,- C,0 0 0 B,0 0 1 1 1 1 0 E,0 1 D,1 0 Quindi ridurre la tabella di Mealy ottenuta. - 130 - 0 F,1 Capitolo 5 RETI SEQUENZIALI 5.1 - Modelli di reti sequenziali Una rete sequenziale è la realizzazione fisica di un automa a stati finiti. All’esterno un rete sequenziale è rappresentata, come qualunque rete logica, con n ingressi ed m uscite, a cui sono associate altrettante variabili logiche. All’interno, per poter realizzare gli stati dell’automa, la rete deve possedere elementi di memoria. Poichè come si è visto qualunque rete si ottiene esclusivamente collegando tra loro blocchi logici, gli elementi di memoria in una rete sequenziale devono poter essere ottenuti mediante opportune connessioni tra blocchi logici. Precisamente le connessioni richieste sono realizzate in modo che si formino uno o più cicli diretti o indiretti tra l’uscita di uno (o più) blocchi logici e l’ingresso dello stesso (o degli stessi). Consideriamo una rete R contenente uno o più cicli. In R è sempre possibile trovare dei blocchi tali che, sconnettendone le uscite dal resto delle rete, si interrompono tutti i cicli. Siano Y0, Y1,..., Yk-1 le variabili associate alle uscite di tali blocchi e y0, y1,..., yk-1 le variabili associate ai loro ingressi. In questo modo si individua nella rete una porzione priva di cicli, quindi combinatoria, ed una, esterna alla precedente, costituita dai percorsi che portano le variabili Yi ai punti di entrata delle variabili yi, 0 ≤ i ≤ k-1. La Fig. 5.1 esemplifica la scomposizione. y2 Y2 y1 Y 1 y1 Fig. 5.1 - 131 - y2 Y2 Y1 Le connessioni esterne alla parte combinatoria si chiamano anelli di reazione e l’insieme {Y} o {y} costituisce l’insieme delle variabili di anello. Esse sono gli elementi logici mediante i quali viene codificata l’informazione relativa agli stati interni dell’automa e vengono quindi dette correntemente variabili di stato. Una rete con k anelli possiede k variabili di anello che permettono di codificare 2k stati interni. Per esempio nell’addizionatore seriale, nel quale esistono due stati, c’è un solo anello (la richiusura del segnale di riporto dall’uscita all’ingresso) ed una sola variabile di anello. In particolare una rete combinatoria ha un solo stato e nessuna variabile di anello, in quanto priva di anelli di reazione. È da notare che il numero e la disposizione dei tagli per eliminare i cicli possono essere diversi in una stessa rete e ciò porta a diverse realizzazioni di uno stesso automa. Generalizzando queste considerazioni, una rete sequenziale può essere strutturata secondo la Fig. 5.2 (modello di Huffman). In questo schema la rete combinatoria genera l’insieme {Z} delle variabili che codificano lo stato di uscita e l’insieme {Y} delle variabili che codificano lo stato successivo e ha come ingressi l’insieme {x} delle variabili che codificano lo stato di ingresso e l’insieme {y} delle variabili che codificano lo stato attuale. Tra le variabili degli insiemi {Y} e {y} esiste la correlazione temporale Yi → yi, 0 ≤ i ≤ k-1, per cui lo stato successivo diventa stato attuale e questo concorre con gli ingressi a generare il nuovo stato successivo e così via in una sequenza temporale t0, ..., ti-1, ti, ti+1, ... . x0 z0 xn-1 y0 zm-1 Y0 RETE COMBINATORIA yk-1 Yk-1 Fig. 5.2 Il modello di Huffman, dal momento che assume implicitamente la parte combinatoria priva di ritardi, è in grado di descrivere il funzionamento della rete sequenziale solo considerando la variabile tempo discretizzata. In altre parole il tempo viene fatto avanzare a passi unitari e si ammette che le transizioni di stato siano possibili solo tra la fine di un passo e l’inizio del successivo e che la risposta dell’intera rete sia definita in corrispondenza di essi: si tratta di un modello puramente ideale che opera in modo sincrono. In realtà, come sappiamo, internamente alla parte combinatoria esistono ritardi, diversi sui vari percorsi, dei quali occorre tenere conto nel modo di specificare le variabili di uscita e le variabili dello stato successivo in funzione delle variabili di ingresso e delle variabili dello stato attuale. Ai fini del modello possiamo pensare che questi ritardi siano concentrati sugli anelli di reazione e sulle linee di uscita e che la parte combinatoria ne sia priva; in tal modo i valori delle variabili {Y} sono generati istantaneamente, mentre l’aggiornamento delle variabili {y} e delle - 132 - variabili di uscita avviene con i ritardi propri delle rispettive linee. Con questa ipotesi lo schema della rete sequenziale si modifica in quello della Fig. 5.3, nella quale è immediato fare rientrare i modelli strutturali secondo Moore e secondo Mealy, definendo in modo opportuno il comportamento della rete combinatoria per quello che riguarda gli insiemi {Y} e {Z} in funzione degli insiemi {x} ed {y}: x0 xn-1 z0 ∆0 RETE COMBINATORIA y0 yk-1 zm-1 ∆m-1 Yk-1 Y0 ∆k-1 ∆0 Fig. 5.3 corrispondentemente le equazioni caratteristiche assumono la forma: Yi(t+∆i) = fi(x1(t),..., xn(t), y1(t),..., yk(t)), 0 ≤ i ≤ k-1 zj(t+∆j) = gj(x1(t),..., xn(t), y1(t),..., yk(t)), 0 ≤ j ≤ m-1 per il modello di Mealy e la forma Yi(t+∆i) = f'i(x1(t),..., xn(t), y1(t),..., yk(t)), 0 ≤ i ≤ k-1 zj(t+∆j) = g'j(y1(t),..., yk(t)), 0 ≤ j ≤ m-1 per il modello di Moore. Poichè i ritardi {∆i} e {∆j} sono differenti e in generale sconosciuti, le variabili di stato si propagano sui rispettivi cammini con rapporti di velocità diversi e sconosciuti. Reti che rispondono a questo modello sono dette asincrone. Si tratta di reti soggette ad una serie di vincoli che ne limitano il pratico impiego. Infatti, di norma, a) solo una variabile di ingresso xi per volta può cambiare valore e b) non è consentito alcun cambiamento in ingresso prima che lo stato conseguente l’ultimo cambiamento si sia stabilizzato (proprietà delle transizioni di ingresso a stati stabili). La ragione di queste limitazioni sta nel fatto che le reti asincrone sono soggette per loro natura a transizioni multiple, ovvero sono in grado di tenere traccia di tutti i cambiamenti delle variabili di stato che si verificano in conseguenza di un cambiamento dello stato di ingresso. Infatti per una data combinazione di ingresso {x0, x1,..., xn-1, y0, y1,..., yk-1}, viene generata una combinazione di valori delle variabili dello stato successivo {Y’0, Y’1,..., Y’k-1} la quale è riportata in ingresso con velocità diverse sui vari percorsi di reazione determinandone un nuovo assetto, diverso tuttavia da quello finale; in conseguenza viene generata una nuova combinazione {Y"0, Y"1,..., Y"k-1}, pur essendo rimaste le variabili {xi} costanti, e così via fino - 133 - al raggiungimento dello stato finale previsto. La rete passa attraverso una sequenza di stati interni instabili, prima di arrivare a quello finale stabile (il quale peraltro potrebbe anche non essere mai raggiunto, potendosi innescare un comportamento oscillatorio oppure potendo diventare stabile uno stato diverso da quello previsto), in conseguenza di un’unica variazione dell’ingresso. Se dunque qualche variabile di ingresso xi cambiasse durante la fase di stabilizzazione, il comportamento della rete diventerebbe del tutto imprevedibile, non essendo possibile conoscere lo stato interno in cui si trova la rete al momento di tale variazione. Una conseguenza di quanto detto è il fatto che le reti asincrone possono funzionare correttamente solo con segnali a livelli, ossia con segnali nei quali l’intervallo minimo tra due transizioni di livello consecutive non è inferiore al massimo ritardo di stabilizzazione degli stati interni: si dice anche che le reti asincrone lavorano in modo fondamentale. Reti asincrone, reti con segnali a livelli, reti in modo fondamentale sono quindi sinonimi, anche se esistono reti in modo fondamentale che possiedono uno o più ingressi che accettano segnali ad impulsi, come sarà visto nel seguito. Al fine di eliminare l’incertezza sulla durata del tempo di stabilizzazione di una rete asincrona, che può essere difficile da valutare e che comunque può essere diverso da un esemplare all’altro della stessa rete sequenziale, è necessario modificare il modello, sottraendolo all’influenza dei ritardi interni. La soluzione consiste nel creare una separazione tra lo stato successivo e lo stato attuale, inserendo sui percorsi di reazione elementi di memoria (elementi di registro) non temporanei, come lo sono i ritardi dello schema di Fig. 5.3, bensì in grado di conservare per un tempo arbitrariamente lungo i valori delle variabili {Y} e di presentarli agli ingressi {y} solo in istanti ben precisi e controllabili, sincronizzati da un segnale ad impulsi C. Il nuovo modello che ne deriva è quello di una rete sequenziale sincronizzata, schematizzato nella Fig. 5.4. x0 xn-1 y0 yk-1 z0 RETE COMBINATORIA Mk-1 zm-1 Yk-1 Y0 M0 C Fig. 5.4 Il modo di funzionamento del modello è il seguente, nell’ipotesi di una rete di Mealy. Supponiamo che gli elementi di registro contengano ad un istante t0, assunto come iniziale, lo stato Sh e che in quell’istante sia applicato agli ingressi principali lo stato di ingresso Xi. Sia - 134 - ∆R il massimo ritardo con cui l’informazione si propaga attraverso la parte combinatoria. Dopo tale intervallo lo stato di uscita Zp e lo stato successivo Sk saranno stabilizzati all’uscita principale della rete e all’ingresso dei registri ed il punto di operazione si troverà nella casella di coordinate (Sh, Xi) della tabella di flusso, contrassegnata con α (Fig. 5.5). Xi Xj α α' α t0 Sh Sk, Zp α' ∆Z ∆M ∆R β Sk Sm, Zr t1 Sl, Zq α ∆Z+∆M t2 β ∆R ∆R β Fig. 5.5 Sia ∆Z ≥ 0 l’intervallo di tempo durante il quale le uscite della rete combinatoria rimangono stabili e supponiamo di applicare un impulso all’ingresso C dei registri dopo questo intervallo. Ciò determina la memorizzazione dello stato successivo Sk presente agli ingressi a livelli dei registri e, dopo il ritardo di propagazione interno ∆M di questi, Sk diventa stato attuale e si presenta agli ingressi secondari {y} della parte combinatoria. Se all’istante t1 in cui cessa l’impulso si applica un nuovo stato di ingresso Xj, con un ritardo ∆R il punto di operazione si sposterà sulla tabella di flusso nella posizione β a cui corrisponde il nuovo stato interno successivo Sl ed il nuovo stato di uscita Zq. A questo punto il ciclo può ricominciare. Se invece il nuovo stato di ingresso Xj viene applicato ad un istante t2 successivo a t1, all’istante t1+∆R l’uscita diventa Zr e tale rimane fino all’istante t2+∆R in cui acquista il valore definitivo Zq, mentre viene previsto lo stato successivo Sm, che a sua volta sarà sostituito dallo stato successivo definitivo Sl all’istante t2+∆R: sulla tabella di flusso questa situazione si manifesta con lo spostamento del punto di operazione prima in α' e successivamente in β. Per una rete di Moore, la situazione è rispecchiata nella Fig. 5.6 e mostra che dopo ∆R unità di tempo a partire dall’istante t1, in cui cessa l’impulso di sincronizzazione, compare l’uscita Zp associata al nuovo stato Sk, mentre gli effetti del nuovo stato di ingresso Xj, indipendentemente dal fatto che sia applicato all’istante t1 o ad un istante successivo t2, si faranno sentire dopo l’ulteriore impulso di sincronizzazione, che al più presto può essere applicato all’stante t1+∆R+∆Z. A seconda dell’istante in cui lo stato di ingresso Xj viene applicato, il punto di operazione potrà spostarsi direttamente da α a β, oppure transitare prima da α', ma in ogni caso l’uscita non ne risente. In ogni caso il comportamento del modello corrisponde esattamente a quello ideale sincrono e quindi può essere sostituito ad esso. - 135 - Sul funzionamento di una rete sequenziale che rispecchia questo modello fisico si possono fare alcune osservazioni rispetto alla rete sincrona ideale. Xi Xj α α' α Sh Sk Zs α' Sm Sl ∆Z ∆M ∆R β Sk t1 t0 Zp α ∆Z+∆M t2 β ∆R ∆R β Fig. 5.6 a) Nel modello ideale, se lo stato di ingresso e quello interno cambiano insieme, lo spostamento del punto operativo sulla tabella di flusso avviene secondo tale doppia transizione (linea obliqua). Nel modello fisico la presenza del registro consente la sequenzializzazione del cambiamento dello stato interno e di quello di ingresso. b) L’intervallo di operazione nel modello ideale è rigidamente fissato dall’intervallo della sequenza temporale. Invece nel modello reale l’intervallo ∆Z+∆M+∆R tra due punti operativi successivi può variare da un minimo pari a ∆M+∆R, potendo far durare per un tempo nullo la disponibilità dello stato di uscita, ad un massimo qualsiasi. c) Il modo di operare della rete fisica, al contrario di quella asincrona, è di tipo ad impulsi per la presenza del segnale C. La durata dell’impulso di questo segnale non deve superare il ritardo interno degli elementi di registro. Infatti se ∆M fosse arbitrariamente lungo, si verificherebbe una variazione delle variabili {y} determinata dalla propagazione delle variabili {Y} attraverso gli elementi di memoria, ed una eventuale risposta della parte combinatoria con conseguente variazione indesiderata delle variabili {Y} prima del termine dell’impulso. Per garantire il rispetto della stabilità degli ingressi agli elementi di memoria durante l’impulso, occorre modificare il modello inserendo in cascata ad essi opportuni ritardi aggiuntivi; tuttavia vedremo nel seguito che, utilizzando particolari elementi di memoria, questo vincolo può essere rimosso senza danno per il corretto funzionamento della rete. Le reti reali rispondono oltre che al modello di Fig. 5.4, in cui tutti gli elementi di memoria hanno un unico ingresso di sincronizzazione ad impulsi e costituiscono un unico registro di lunghezza pari al numero delle variabili di stato presenti nella rete, anche ad un modello in cui l’impulso di sincronismo viene inviato separatamente a ciascun elemento di memoria. Esistono inoltre due categorie principali di reti sincronizzate: a) quelle nelle quali ai terminali di ingresso e di uscita della parte combinatoria sono applicati solo segnali a livelli e b) quelle in cui esiste almeno un ingresso su cui si trova un segnale ad impulsi. - 136 - a) Lo schema generale delle reti di questa categoria è mostrato in Fig. 5.7; rispetto allo schema di Fig. 5.4, ogni elemento di memoria ha uno o più ingressi (variabili di eccitazione) che sono in relazione ad una variabile di stato successivo, nel senso che sono argomenti delle funzioni di stato realizzate dall’elemento di memoria stesso. Il modo di funzionamento tuttavia non differisce da quello del modello generale e queste reti possono essere realizzate sia secondo il modello di Mealy che secondo quello di Moore. x0 xn-1 y0 yk-1 z0 RETE COMBINATORIA zm-1 }ti, i = 0, ..., r0 }tj, j = 0, ..., rk-1 Mk-1 M0 C Fig. 5.7 b) Alla seconda categoria appartengono le reti nelle quali il segnale ad impulsi è applicato, oltre che agli elementi di memoria, anche ad almeno un ingresso primario della rete combinatoria, o meglio della parte di essa che genera i segnali di uscita; la temporizzazione delle uscite principali è quindi modificata rispetto al modello generale, in quanto la loro disponibilità è condizionata alla presenza del segnale di sincronismo; si tratta di reti modellate secondo Mealy ritardato. Anche in questo schema gli elementi di memoria possiedono uno o più ingressi a cui sono applicate le variabili di eccitazione generate dalla parte combinatoria (Fig. 5.8). x0 xn-1 C y0 yk-1 z0 RETE COMBINATORIA zm-1 }ti, i = 0, ..., r0 }tj, j = 0, ..., rk-1 Mk-1 M0 Fig. 5.8 - 137 - 5.2 - Elementi di memoria I più semplici elementi di memoria sono reti sequenziali asincrone o sincronizzate, dette latch e flip-flop, le quali possiedono due stati interni, codificati come stato 0 e stato 1. 5.2.1 - Latch 5.2.1.1 - Latch SR Il più noto componente della famiglia, anche per ragioni storiche, è il latch SR. Si tratta di una rete, facilmente modellabile come macchina di Moore, con due ingressi denominati S (set) ed R (reset) ed una uscita Q la quale coincide con l’unica variabile di stato y, come è indicato nel seguente schema a blocchi (Fig. 5.9). S R Q y Y ∆ Fig. 5.9 Per questa rete le equazioni caratteristiche hanno la seguente forma: Y(t+∆) = f(S(t), R(t), y(t)) Q(t) = g(y(t)) = y(t) L’espressione esplicita della funzione f può essere determinata a partire dalla descrizione a parole del funzionamento del latch attraverso le seguenti frasi, dove × sta per “non specificato”: S = 1 e R = 0⇒ S = 0 e R = 1⇒ S = 0 e R = 0⇒ S = 1 e R = 1⇒ Y=1 Y=0 Y=y Y=× (operazione di set) (operazione di reset) (operazione di latch) (configurazione proibita) Nell’operazione di latch lo stato successivo è uguale allo stato attuale, sia esso lo stato stabile 1 oppure lo stato stabile 0; lo stato 1 è raggiunto con una operazione di set, lo stato 0 con una operazione di reset; infine la combinazione di ingresso S = R = 1 non è consentita poichè, come vedremo, può non essere determinato lo stato assunto dalla rete quando tale configurazione cambia. Dalla descrizione a parole si ricava la seguente mappa di Karnaugh e quindi l’espressione di f, ad esempio in forma PS (Fig. 5.10). La rete corrispondente è illustrata nella figura in due forme alternative, di cui la seconda evidenzia anche il segnale di uscita della prima porta NOR; questo segnale Q' in genere, ma non sempre, è il complemento dell’uscita Q. - 138 - y S, R 00 01 11 0 0 0 × 1 S Y = R ( S + y ) = R ( S + y ) = R + ( S + y ) = R↓ ( S↓y ) × 0 y 10 S Q' R Q ∆1 ∆2 R Y Q Fig. 5.10 La mappa di Karnaugh sulla quale viene effettuata la sintesi altro non è che la tabella di flusso del latch e da essa deriva l’equazione caratteristica, imponendo per Y la condizione sotto la quale il latch assume o rimane nello stato stabile 0 (o stato di reset). Vale la pena notare che, rispetto alla forma della tabella di flusso degli automi a stati finiti esaminati nel capitolo 4, nella quale gli stati venivano espressi con un nome simbolico, in una rete sequenziale gli stati sono codificati dalle variabili di stato e quindi sono indicati con le combinazioni di valori binari che esse possono assumere. Imponendo la condizione sotto la quale il latch assume o rimane nello stato stabile 1 (o stato di set), si ottiene la seguente espressione NAND: Y = S + Ry = S| ( R|y ) nella quale i segni di complementazione attribuiti alle variabili S ed R indicano che il funzionamento risponde ancora alla definizione a parole, purchè si intenda invertito il valore da assegnare alle variabili di ingresso per ogni operazione del latch. In altri termini l’operazione di set, ad esempio, avrà luogo quando S = 0 ed R = 1. La figura 8.10 mostra il circuito corrispondente: R S S y Y Q R Q Q' Fig. 5.11 L’informazione contenuta nella tabella di flusso può essere rappresentata anche in un’altra forma detta tabella di eccitazione (trigger table), la quale specifica quali devono essere i valori di ingresso per ogni possibile transizione dallo stato presente allo stato successivo: - 139 - y 0 0 1 1 Y 0 1 0 1 S 0 1 0 X R X 0 1 0 L’interpretazione della tabella è la seguente. Se il latch deve rimanere nello stato 0 è necessario che l’ingresso di set S sia 0, indipendentemente dal valore dell’ingresso di reset R. Infatti se R = 0, viene effettuata un’operazione di latch e lo stato rimane inalterato, nella fattispecie 0; se R = 1, il latch compie una operazione di reset e lo stato successivo sarà certamente 0. Analogamente si interpretano le altre righe della tabella. Il latch SR, come ogni rete asincrona, funziona a livelli, ovvero i segnali di ingresso devono mantenere il proprio valore costante per un periodo di tempo pari almeno al ritardo dell’intera rete; tale intervallo è chiamato tempo di eccitazione o trigger time. Più precisamente, se indichiamo con TS e TR i tempi di eccitazione dell’ingresso S e dell’ingresso R e con ∆ = ∆1+∆2 il ritardo del latch, espresso dalla somma dei ritardi delle due porte NOR, deve essere: TS,TR ≥ ∆ = ∆1+∆2 come è visualizzato nel seguente diagramma temporale: S Q' R Q' Q Q ∆2 ∆1 TS ∆1 ∆2 TR Fig. 5.12 Se viceversa i segnali di ingresso S od R rimangono al valore 1 per un intervallo di tempo inferiore al periodo di eccitazione, il latch non riesce a seguire la variazione dello stato di ingresso e può effettuare un’operazione scorretta i cui effetti si manifestano con un impulso spurio (spike) in uscita (Fig. 5.13). Vediamo ora il motivo per il quale non è consentita la configurazione di ingresso S = R = 1, riferendoci allo schema di Fig. 5.11, e tenendo presente che ragionamenti duali valgono anche per lo schema di Fig. 5.12. Se entrambi gli ingressi S ed R hanno valore 1, sia Q che Q' diventano 0, poichè entrambe le porte NOR hanno un ingresso che vale 1. Se a questo punto simultaneamente S ed R assumono valore 0, non è possibile sapere con certezza quale stato assume il latch, in quanto ciò dipende dalla velocità relativa con cui rispondono le porte NOR - 140 - e dal ritardo con cui i nuovi valori di Q e di Q' si propagano ciascuno all’ingresso dell’altra porta NOR. S Q' Q Fig. 5.13 Infatti dall’esame del circuito è possibile vedere che se il ritardo ∆1 è minore del ritardo ∆2, l’uscita Q conserva valore 0 e Q' diventa 1, ossia il latch assume lo stato 0. Viceversa se ∆1 è maggiore di ∆2, l’uscita Q assume valore 1 e Q' il valore 0, corrispondenti allo stato 1. Questa incertezza viene risolta quando uno dei due ingressi assume di nuovo valore 1 (Fig. 5.14). S R Q Q' Fig. 5.14 È da osservare che, come è stato accennato in precedenza e come indica la Fig. 5.14, non sempre i segnali di uscita delle porte NOR hanno valori opposti e ciò accade quando S ed R hanno lo stesso valore 1. Il latch SR può essere dotato di un ingresso ad impulsi C con funzione di ingresso di controllo e prende allora il nome di gated latch o anche, seppure impropriamente, di latch sincronizzato (Fig. 5.15). In questa versione le operazioni del latch sono possibili solo quando C è attivo, ossia i segnali S ed R sono di fatto sostituiti dai segnali CS e CR rispettivamente, per cui gli ingressi S ed R non hanno effetto finchè C non diventa 1. S Q' C Q R Fig. 5.15 Gli ingressi condizionati dal segnale di controllo si dicono ingressi sincroni, a significare che essi hanno effetto quando il latch è controllato dall’attività dell’ingresso C, mentre quelli - 141 - dei latch delle figure 5.10 e 5.11 sono detti asincroni; esistono latch con ingressi sia sincroni che asincroni, questi ultimi indicati con termini quali preset e clear e utilizzati per effettuare operazioni di set e di reset in modo asincrono rispetto al segnale C e quindi rispetto all’operazione corrente. Le forme d’onda dei segnali sono mostrate nella Fig. 5.16, la quale indica in corrispondenza degli istanti ta e tb che il dispositivo trasmette direttamente in uscita, a meno del ritardo di propagazione proprio, gli effetti di una variazione sugli ingressi S o R, in presenza del segnale C attivo. Questo comportamento è una caratteristica dei latch che viene indicata con il termine di trasparenza e i circuiti sequenziali con due stati vengono distinti in latch se hanno la caratteristica della trasparenza e in flip-flop altrimenti. S R C Q ta tb Fig. 5.16 Il fatto che il segnale C debba essere attivo affinchè le variazioni di ingresso abbiano effetto sull’uscita indica che il latch SR è sensibile al livello di C. Questo può determinare il fenomeno, indesiderato in una rete sincronizzata dalla quale ci si aspetta che le variazioni di stato e di uscita si verifichino a istanti ben definiti, di avere transizioni dell’uscita anche dopo che l’ingresso C è passato da 0 ad l (istante ta), o che addirittura l’uscita possa cambiare più volte durante uno stesso impulso di sincronizzazione (intervallo a partire da tb). La soluzione del problema richiede che la durata dell’impulso di sincronizzazione (control pulse width) sia ridotta al minimo, compatibilmente con la necessità di assicurare che i segnali di ingresso rimangano invariati per un tempo sufficiente per il raggiungimento del nuovo stato; ma questo rende comunque impossibile definire con certezza l’istante della sincronizzazione e per questo motivo i latch sincronizzati tendono ad essere sostituiti nelle applicazioni da altri elementi di memoria sincronizzabili effettivamente sul fronte di un segnale di controllo. Un altro punto da sottolineare è che l’indeterminatezza di funzionamento del latch SR quando gli ingressi passano dal valore 11 al valore 00 contemporaneamente, più teorica che pratica in un latch asincrono a causa della scarsa probabilità che due ingressi possano realmente cambiare nello stesso istante, diventa invece reale in un latch sincronizzato, se S ed R sono 1 quando C passa da 1 a 0. 5.2.1.2 - Latch D Se in un latch SR, sia del tipo asincrono, sia del tipo sincronizzato, si fa in modo che agli ingressi a livelli S ed R siano applicati segnali di valore opposto l’uno rispetto all’altro, si - 142 - ottiene un nuovo tipo di latch denominato latch D, il cui schema è illustrato nella Fig. 5.17. Questo latch possiede solo un ingresso a livelli D e internamente si differenzia da un SR unicamente per la presenza di un invertitore che complementa tale segnale all’ingresso di reset R. Il vantaggio di questa struttura è duplice: 1) il segnale Q' è sempre il complemento di Q e 2) non esiste il rischio di una combinazione di ingresso proibita. L’equazione caratteristica si ottiene semplicemente considerando che è R = S = D, ossia: Y = D·(D+y) = D S D R latch C SR Q Q Fig. 5.17 valida per la versione asincrona; essa indica che l’uscita è uguale all’ingresso, ovviamente ritardata rispetto ad esso del tempo di propagazione. La tabella di eccitazione specifica tale fatto nella seguente forma: y 0 0 1 1 Y 0 1 0 1 D 0 1 0 1 ovvero affinché lo stato successivo sia nullo, l’ingresso deve essere 0, mentre un valore dell’ingresso uguale ad 1 provoca l’aggiornamento dello stato pure al valore 1. Per la versione sincronizzata, l’equazione caratteristica assume la seguente espressione, ottenuta applicando i teoremi di De Morgan ed il teorema del consenso e ricordando ancora che R = D: Y = CD· ( CD + y ) = ( C + D )· ( CD + y ) = CD + yC + yD = CD + yC Si noti che se C = 0, risulta Y = y, ossia il latch è in grado di conservare stabilmente lo stato, cosa non possibile nella versione asincrona. La Fig. 5.18 illustra le forme d’onda tipiche del latch D, evidenziando in ta, tb, tc la trasparenza del dispositivo che è ancora del tipo sensibile al livello di C. - 143 - D C Q ta tb tc Fig. 5.18 5.2.2 - Flip-flop Un flip-flop è un elemento di memoria a due stati con un ingresso di controllo, il quale non ha la proprietà della trasparenza, ossia nel quale i cambiamenti dell’uscita non sono mai una risposta diretta di cambiamenti degli ingressi sincroni. Viceversa un flip-flop risponde solo a transizioni dell’ingresso di controllo o degli ingressi asincroni, se presenti. La differenza di comportamento di un flip-flop rispetto ad un latch è messa in evidenza dal seguente grafico che mostra le forme d’onda del segnale di uscita Qff di un flip-flop D, che esamineremo tra breve, e del segnale di uscita Ql del latch omonimo: D C Ql Qff ta tb tc Fig. 5.19 Come si vede il comportamento dei due dispositivi è lo stesso finchè il segnale D cambia mentre C è 0; invece all’istante ta, in cui si verifica la transizione 1 → 0 di D essendo C = 1, l’uscita Ql del latch cambia con il proprio ritardo interno dal valore 1, che aveva assunto in conseguenza della transizione 0 → 1 di C, al valore 0, mentre quella del flip-flop Qff rimane insensibile a tale transizione di ingresso, conservando il valore 1 assunto allo stesso modo di Ql; l’uscita Qff subisce la transizione 1 → 0 in conseguenza della successiva transizione 0 → 1 di C con D = 0. In maniera analoga, all’istante tb si verifica la transizione 0 → 1 dell’ingresso sincrono D, con C = 1; ad essa il latch risponde con la transizione 0 → 1 dell’uscita, mentre l’uscita del flip-flop rimane a 0. Infine all’istante tc la caduta di D con C = 1 provoca la caduta di Ql, ma non ha effetto su Qff. La non trasparenza dei flip-flop viene ottenuta attraverso una configurazione di tipo master-slave: due dispositivi trasparenti sono collegati in cascata, in modo che l’uscita del primo (master) sia ingresso del secondo (slave), e sono controllati con i segnali C e C - 144 - rispettivamente (Fig. 5.20), cosicchè la transizione 1 → 0 di C determina l’aggiornamento dello stato del master, lasciando immutato lo stato dello slave e la transizione 0 → 1 provoca l’aggiornamento dello stato dello slave, concordemente all’uscita del master, mentre lo stato di questo non è influenzato dal valore degli ingressi sincroni. In sostanza il latch master ha il compito di elaborare l’informazione modificando il prorio stato in risposta a variazioni di ingresso, mentre il latch slave serve per ritardare la propagazione del risultato in uscita. Q ingressi sincroni C latch slave latch master Fig. 5.20 5.2.2.1 - Flip-flop D Utilizzando nella Fig. 5.20 latch D come master e slave, si ottiene un flip-flop D master-slave, il cui schema è mostrato in Fig. 5.21; con la notazione della figura è immediato anche ricavarne le equazioni caratteristiche: Y 1 = CD + Cy 1 C,D 00 01 11 10 α β 00 00 10 00 00 ϑ y1,y2 01 01 11 00 00 Q 0 1 η 11 01 11 ε 11 11ζ 1 γ δ 10 00 10 11 11 D Y 2 = Cy 1 + Cy 2 Y1 D master D slave C Q = y2 Y2 Q D Q C > FF D Q Q 0 a) b) c) Fig. 5.21 Da esse, come pure dalla tabella di flusso mostrata in Fig. 5.21a, si vede che quando il segnale C è 0, lo stato Y1 del master segue le variazioni dell’ingresso D, ma lo stato dello slave e di conseguenza l’uscita Q si mantengono stabili; viceversa quando C è 1, il master non può modificare il proprio stato comunque vari l’ingresso D, mentre lo stato Y2 e l’uscita Q diventano uguali all’ ingresso Y1. Pertanto l’uscita Q cambia diventando uguale a D a causa della transizione 0 → 1 di C; per renderci meglio conto di questo fatto, supponiamo che il flip-flop si trovi nello stato stabile 00 e che C e D siano 0 (casella α della tabella di flusso); se a questo punto cambia l’ingresso D da 0 a 1, lo stato diventa 10, pure stabile: il punto di operazione si sposta sulla tabella da α in β e - 145 - quindi in γ: come si vede la variazione di D non si risente in uscita, che continua ad essere 0. Se ora si verifica la transizione 0 → 1 di C, lo stato diventa 11 ed il punto di operazione si sposta in δ e quindi in ε, che rappresenta una condizione di stato stabile, caratterizzata dal fatto che l’uscita Q vale 1, ossia è diventata uguale all’ingresso; se D cambia di nuovo da 1 a 0 con C ancora ad 1, lo stato rimane immutato (casella ζ) e l’uscita pure. Una transizione 1 → 0 di C con D stabile a 0 porta il flip-flop nello stato 01 (caselle η e ϑ) e l’uscita rimane stabile ad 1. Dunque qualsiasi variazione di D con C uguale a 0 viene memorizzata nel master, mentre qualunque sua variazione con C = 1 non ha alcun effetto sul circuito. Viceversa una transizione 0 → 1 di C provoca l’aggiornamento dello stato di uscita e una transizione opposta è senza influenza. La tabella di eccitazione del flip-flop D è la seguente: Il flip-flop descritto, per il fatto di possedere un ingresso C di controllo dinamico, nel senso che l’ingresso D viene acquisito sul fronte in salita di tale controllo e l’uscita varia seguendo immediatamente tale fronte, viene qualificato come flip-flop D positive edge triggered (eccitato sul fronte in salita). Le sue forme d’onda tipiche sono quelle già mostrate nella Fig. 5.19. L’ingresso dinamico viene riconosciuto sullo schema a blocchi della Fig. 5.21c con il simbolo “>”. Cambiando l’ordine con cui il segnale C ed il suo complemento sono applicati al latch master e allo slave, si ottiene un flip-flop D eccitato sul fronte in discesa (negative edge triggered). 5.2.2.2 - Flip-flop JK Anche il latch SR può essere trasformato in un flip-flop non trasparente di tipo master slave, allo stesso modo con cui è stato realizzato il flip-flop D; tuttavia, a causa del non determinismo del funzionamento quando S ed R sono 1, si preferisce al suo posto un flip-flop, detto flip-flop JK, che si ottiene riportando le uscite Q e Q' rispettivamente sull’ingresso R e sull’ingresso S del latch master attraverso due porte AND insieme a due ingressi esterni denominati J e K rispettivamente (Fig. 5.22). J C K master S1 R1 slave S2 Q' = Q R2 Q Fig. 5.22 Il flip-flop JK ha il vantaggio di consentire tutte e quattro le combinazioni di J e di K ed il suo funzionamento rispecchia quello del flip-flop SR (o del latch SR), con gli ingressi J e K che corrispondono agli ingressi S ed R rispettivamente: quando C = 0, qualsiasi variazione degli ingressi J e K non viene avvertita all’uscita, che rimane stabile. Se J = 0 e K = 0 quando C cambia da 0 ad 1, l’uscita rimane inalterata; se J = 0 e K = 1 quando avviene la transizione di C, viene effettuata un’operazione di reset e l’uscita assume valore 0; se J = 1 e K = 1 al - 146 - momento della transizione di C, l’uscita assume il valore complementare di quello originario. Infine se J = 1 e K = 0, avviene un’operazione di set e l’uscita assume valore 1. La transizione 1 → 0 di C non ha alcun effetto sull’uscita. Nella Fig. 5.23a il funzionamento del flip-flop JK è riassunto attraverso la sua tabella di flusso mentre la Fig. 5.23b riporta la tabella di eccitazione, la cui interpretazione è la seguente. Se lo stato attuale (y) e quello successivo (Y) sono uguali a 0, ciò può essere dovuto a due motivi: 1) il flip flop sta effettuando un’operazione di latch (J=0 e K=0), oppure un’operazione di reset di uno stato che è già 0 (J=0 e K=1). Se lo stato attuale è 0 ed il successivo 1, si può essere in presenza di un’operazione di set (J=1, K=0), oppure di un’operazione di complementazione dello stato (J=1, K=1). Nel caso opposto si può avere un’operazione di reset (J=0 e K=1) oppure di complementazione dello stato (J=1 e K=1). Infine se lo stato attuale e quello successivo sono entrambi 1, si può avere un’operazione di latch (J=0 e K=0) oppure di set (J=1 e K=0). C=1 C=0 J, K 00 01 11 10 Q 00 00 00 10 10 00 0 y1,y2 y 0 0 1 1 01 11 01 01 11 00 1 11 11 01 01 11 11 1 10 00 00 10 10 11 0 Y 0 1 0 1 a) J 0 1 X X C 0 ↑ ↑ ↑ ↑ K X X 1 0 b) J X 0 0 1 1 K X 0 1 1 0 Q Q Q 0 Q 1 c) Fig. 5.23 La Fig. 5.23c infine riporta una tabella correntemente fornita dai costruttori di componenti digitali al posto della tabella di flusso per riassumere il funzionamento del flip-flop, in quanto esprime l’uscita in funzione dell’ingresso di sincronizzazione C e degli ingressi sincroni. il simbolo ↑ indica la transizione positiva del segnale C. Oltre alla versione di Fig. 5.22, per il flip-flop JK si usa anche lo schema di Fig.5.24 che fa uso di un flip-flop D master-slave e realizza un dispositivo del tipo positive edge-triggered. J K D D Q Q J C K > FF Q JK Q C Fig. 5.24 Le forme d’onda tipiche di un flip-flop JK sono mostrate in Fig. 5.25: - 147 - J K C Q Fig. 5.25 5.2.2.3 - Flip-flop T Un terzo tipo di flip-flop edge-triggered è il flip-flop T, detto talvolta toggle, schematizzato nella Fig. 5.25a. Il modo di operazione è il seguente; se T è 0, lo stato rimane stabile; se T è 1, lo stato cambia quando si verifica la transizione 0 → 1 di C. Questo flip flop si può derivare dal flip-flop JK edge triggered collegando tra di loro gli ingressi J e K (Fig. 5.25b), oppure si può realizzare con un flip-flop D ed una porta XOR, secondo lo schema di Fig. 5.26c. T C FF > T Q Q J T C > K Q a) Q b) T C XOR c) D > Q Q Fig. 5.26 Nella Fig. 5.27a è riportata la tabella analoga a quella di Fig. 5.23c per il flip-flop JK e la tabella di eccitazione; inoltre è mostrato anche il diagramma temporale. C 0 ↑ ↑ T X 0 1 Q Q Q Q y 0 0 1 1 Y 0 1 0 1 a) T 0 1 1 0 T C Q b) c) Fig. 5.27 5.2.2.4 - Flip-flop asincroni Esistono infine due tipi di flip-flop master-slave asincroni: essi sono un flip-flop SR ed un flip-flop T, entrambi caratterizzati dal fatto che rispondono ad impulsi sui loro ingressi e sono in genere utilizzati non come singoli componenti, ma nel progetto di strutture più complesse. In particolare il flip-flop SR master-slave asincrono trova applicazione quando in ingresso vi possono essere più impulsi dei quali solo il primo deve essere avvertito. Infatti questo - 148 - flip-flop effettua un’operazione di set sul fronte in discesa di un impulso sull’ingresso S, mentre impulsi successivi su S sono ignorati; analogamente viene effettuata un’operazione di reset sul fronte in discesa del primo impulso sull’ingresso R. Lo schema logico è mostrato in Fig. 5.28 insieme alle forme d’onda: S R S S latch SR latch SR R Q R Q Q Fig. 5.28 Il flip-flop T master-slave asincrono ha un solo ingresso T e cambia stato ogni volta che un impulso si presenta sull’ingresso, per cui è particolarmente adatto a realizzare una funzione di conteggio binario. Si può derivare da un flip-flop JK master-slave mantenendone gli ingressi J e K ad 1 e applicando il segnale T all’ingresso di sincronizzazione (Fig. 5.29a) oppure da un flip-flop D richiudendone l’uscita Q all’ingresso D e applicando il segnale T come nel caso precedente (Fig. 5.29b). Le forme d’onda sono mostrate in Fig. 5.29c. 1 a) Q T J T > Q K > Q Q Q D b) T > Q T c) Q Fig. 5.29 5.3 - Sintesi delle reti sequenziali sincronizzate Il procedimento per la sintesi delle reti sequenziali sincronizzate può essere suddiviso in due passi. a) Costruzione della tabella di flusso dell’automa che descrive il comportamento, definito a parole, della rete che soddisfa certe relazioni ingresso-uscita prefissate, che realizza determinate operazioni o che risolve un dato problema. - 149 - b) Costruzione della rete a partire dalla tabella di flusso secondo un prefissato modello strutturale. a) La costruzione della tabella di flusso rappresenta l’operazione più laboriosa e difficile, specialmente quando il numero degli stati interni, di ingresso e di uscita è elevato. Per questo è utile avvalersi, ad uno stadio intermedio tra la descrizione a parole originaria e la tabella di flusso, di un grafo di stato che tenga conto del modello di Mealy o di Moore che si intende assumere. Quindi la tabella viene costruita inserendo una riga per ogni nodo del grafo ed una colonna per ogni arco uscente da un nodo, ossia per ogni stato di ingresso. Ciascuna casella viene contrassegnata con lo stato successivo, ricavato dal nodo a cui è diretto un arco uscente e con lo stato di uscita corrispondente per la macchina di Mealy, oppure aggiungendo a margine una colonna con lo stato di uscita per la macchina di Moore. Per esempio si voglia costruire una rete sequenziale la quale è in grado di riconoscere, in una sequenza arbitraria di caratteri alfanumerici in ingresso, una sottosequenza particolare, quale aba, segnalando il riconoscimento con uno stato di uscita z2; lo stato z1 segnala invece ogni altra condizione. Indicando con x qualunque carattere diverso da a e da b, i grafi di stato secondo Mealy e secondo Moore sono i seguenti: b,x/z1 a/z1 a/z1 1 b, x 1/z1 2 x/z1 x/z1 b/z1 x b/z1 a/z2 a a 2/z1 x b, x a b b 4/z2 3 a 3/z1 Fig. 5.30 Per il grafo secondo Mealy, supponendo di essere nello stato 1, finchè nella sequenza di ingresso non si incontra il carattere a, lo stato non cambia e l’uscita rimane z1; quando si presenta a, poichè questo può essere l’inizio di una sottosequenza da riconoscere, lo stato cambia in 2 e l’uscita rimane z1. Nello stato 2, finchè vengono riconosciuti caratteri a, si rimane nello stesso stato, mentre qualunque carattere x fa ritornare l’automa nello stato 1; invece il riconoscimento di b fa passare nello stato 3 ancora con uscita z1. Infine dallo stato 3 il presentarsi in ingresso di un secondo carattere a provoca il cambiamento dell’uscita a z2, perchè la sottosequenza è stata riconosciuta, mentre lo stato successivo è nuovamente 2 e non 1, come ci si potrebbe aspettare, dal momento che il carattere a che termina la sottosequenza riconosciuta può essere l’inizio di una nuova sottosequenza aba; al contrario qualunque altro - 150 - carattere riporta l’automa nello stato 1 e lo stato di uscita torna ad essere z1. Per l’automa di Moore con stato iniziale 1 e stato di uscita corrispondente z1, il presentarsi dello stato di ingresso a provoca ancora il passaggio in 2 con uscita z1, mentre qualunque altro stato di ingresso lascia immutato lo stato. L’automa rimane nello stato 2 finchè in ingresso è presente lo stato a, raggiungendo lo stato 3 se in ingresso si presenta b; invece qualunque altro stato di ingresso x riporta in 1. L’uscita associata allo stato 3 è ancora z1 e il riconoscimento di un ulteriore carattere a fa passare nello stato 4, dove l’uscita diventa z2, per l’avvenuto riconoscimento di aba; si noti che in questo caso il presentarsi di una seconda a dopo b non riporta lo stato in 2, perchè l’uscita deve assumere il valore che indica l’esito positivo della ricerca, mentre allo stato 2 è associato il valore di uscita che indica esito negativo. Dallo stato 4 l’arrivo di b riporta l’automa in 3 con uscita z1, ed in questo modo viene accettata la seconda a della sottosequenza e riconosciuta come inizio di una nuova; invece un’ulteriore a riporta in 2 con uscita z1 e infine qualunque altro carattere x riporta nello stato 1. Una volta costruiti i grafi di stato si passa a costruire le tabelle di flusso per le due macchine nel seguente modo: a b x 1 2, z1 1, z1 1, z1 2 2, z1 3, z1 1, z1 3 2, z2 1, z1 1, z1 a b x 1 2 1 1 z1 2 2 3 1 z1 3 4 1 1 z1 4 2 3 1 z2 Fig. 5.31 Prima di passare alla seconda fase del procedimento di sintesi, osserviamo che esistono reti sequenziali le quali devono essere portate in uno stato iniziale particolare se si vuole che funzionino correttamente, mentre per altre è del tutto indifferente ai fini del funzionamento lo stato di partenza. Per le prime il problema può essere risolto in due modi : • Si può applicare preventivamente una sequenza di ingresso tale da pilotare la rete nello stato di partenza, qualunque sia lo stato in cui si trova; ciò tuttavia è possibile solo se il grafo di stato è fortemente connesso, cioè solo se ogni stato interno è raggiungibile a partire da qualunque altro. • Se il grafo non è fortemente connesso o se lo stato iniziale deve essere raggiunto in un tempo breve e definito indipendentemente dallo stato in cui la macchina si trova, si può aggiungere un nuovo stato di ingresso, detto di reset, che per qualunque stato interno genera lo stato iniziale come stato successivo. Un altro punto da sottolineare è che, come si è visto nel capitolo 4, esistono tabelle di flusso non completamente specificate, tali cioè che per alcuni stati totali non è definito lo stato successivo; ciò può essere dovuto a due ordini di cause: • uno stato totale (Xi, Sj) non può mai verificarsi a causa di vincoli posti sulla sequenza di - 151 - ingresso, pur potendo presentarsi singolarmente sia Xi che Sj. • Lo stato totale (Xi, Sj) può verificarsi ad un certo passo della sequenza di ingresso, ma nei passi successivi non interessa con quale sequenza di stati di uscita la macchina reagisce alla sequenza di ingresso. b) La seconda fase parte dalla tabella di flusso per arrivare alla realizzazione della rete. Il passo iniziale consiste nella codifica degli stati mediante variabili binarie; spesso ci si riduce alla codifica dei soli stati interni, dal momento che sia gli ingressi che le uscite sono già rappresentate da variabili binarie. Se il numero degli stati interni è n, le variabili per la codifica devono essere in numero pari a log2n: pertanto se n non è potenza di 2, ci saranno certe combinazioni di valori non significativi e di conseguenza funzioni non completamente specificate. La scelta della codifica non è senza conseguenze, poiché può portare ad una struttura più o meno complessa, ma in questa sede non affrontiamo il problema della scelta ottima. Il secondo passo consiste nel sostituire ai simboli della tabella di flusso i codici scelti e nel separare stati e uscite in due tabelle dette rispettivamente tabella delle transizioni degli stati e tabella delle uscite. Da esse si derivano le mappe di Karnaugh per le variabili dello stato successivo e per le variabili dello stato di uscita, sulle quali viene condotto il processo di sintesi della parte combinatoria della rete. In alternativa si ricorre al metodo di Quine-McCluskey. Tuttavia nella sintesi della parte combinatoria occorre tenere conto anche del modello strutturale (v. pagg. 134-135), secondo il quale si vuole realizzare la rete e del fatto che sugli anelli di reazione devono essere inseriti elementi di memoria impulsati, del tipo esaminato nel capitolo precedente. Come sappiamo infatti esistono fondamentalmente due categorie di reti sincronizzate: a) quelle in cui tutti gli ingressi e le uscite primarie sono a livelli e b) quelle in cui esiste almeno un ingresso di natura impulsiva, la cui funzione è decidere l’istante di operazione dell’intera rete. In entrambi i casi però l’informazione di ingresso da cui dipende il funzionamento delle rete è quella codificata dai segnali a livelli e su quella deve essere condotta la sintesi. Pertanto, ammesso che le caratteristiche della rete in esame rientrino in una delle due categorie sopra citate, la specifica del modello strutturale dipende: 1) dalla specifica dei segnali di ingresso. Per esempio se la rete deve avere un ingresso impulsivo e quindi deve essere del tipo di Mealy ritardato, il modello da scegliere è quello della categoria b). 2) Dal tipo di elemento di memoria che si vuole utilizzare. Da esso infatti dipende il numero e l’espressione delle variabili di eccitazione e in definitiva la struttura della parte combinatoria che le genera. Riguardo a questo secondo punto, la scelta dell’elemento di memoria interviene a trasformare la tabella delle transizioni per ciascuna variabile di stato successivo in una o più tabelle, dette tabelle di applicazione dei flip-flop, a seconda che tale elemento abbia una o più variabili di eccitazione. Queste nuove tabelle, in riferimento ai modelli strutturali delle Fig. 5.7 e 5.8, specificano le funzioni: - 152 - ti,j = fi,j(x, y), i = 0, ..., k-1, j = 0, ..., ri-1, x = {x0, x1, ..., xn-1}, y = {y0, y1, ..., yk-1} che governano le variabili di eccitazione ti,j, in accordo alla tabella di eccitazione dell’elemento di memoria scelto. Le tabelle di applicazione vengono quindi trasformate nelle corrispondenti mappe di Karnaugh sulle quali viene condotta la sintesi. Riprendiamo l’esempio della rete che riconosce una sequenza di caratteri, proponendoci di realizzarne la versione di Mealy. Essendo tre gli stati interni, occorrono per la loro codifica due variabili di stato y1 e y2; facciamo i seguenti assegnamenti, consapevoli tuttavia che una scelta piuttosto che un’altra può portare a funzioni combinatorie più o meno costose: stato 1 2 3 – y1 0 0 1 1 y2 0 1 1 0 Codifichiamo inoltre gli stati di ingresso con due variabili x1 ed x2, con le corrispondenze a ≡ 00, b ≡ 01, x ≡ 11 e lo stato di uscita con una variabile z con gli assegnamenti z1 ≡ 0, z2 ≡ 1. Con questa codifica la tabella delle transizioni e quella delle uscite diventano: x1, x2 01 11 10 00 0 0 0 × 01 0 y1, y2 11 1 10 × 0 0 × 0 0 × × × × x1, x2 01 11 10 00 00 01 00 00 ×× 01 y1, y201 11 01 11 00 ×× 00 00 ×× ×× ×× ×× 00 10 ×× z Y1, Y2 Fig. 5.32 Supponiamo di scegliere come elementi di memoria flip-flop JK eccitati sul livello in salita del clock. La parte combinatoria deve generare le funzioni che governano le variabili di eccitazione di tali flip-flop, J1, K1, J2, K2, in accordo alla tabella delle transizioni, dalla quale perciò otteniamo le tabelle di applicazione di Fig. 5.33. Da esse e dalla tabella delle uscite si ottengono le funzioni combinatorie: J1 = x1x2y2 K1 = 1 J2 = x2 K2 = x2y1+x1 z = x2y1 - 153 - con le quali si realizza la rete sequenziale richiesta (Fig. 5.34). x1, x2 00 01 11 00 0 0 0 y1, y2 x1, x2 00 01 11 00 × × × 10 × 01 0 11 × 1 0 × × × × 10 × × × × y1, y2 01 × 11 1 × × × 1 1 × 10 × × × × K1 J1 x1, x2 00 01 11 00 1 0 0 10 × × × × × × × × × 10 × × × × 01 y1, y2 11 10 × y1, y2 x1, x2 00 01 11 00 × × × 10 × 01 0 0 1 × 11 0 1 1 × 10 × × × × J2 K2 Fig. 5.33 x1 z x2 y1 J1 < K1 y2 J2 < K2 Fig. 5.34 - 154 - 1 5.4 - Sintesi delle reti sequenziali asincrone 5.4.1 - Tabelle di flusso normali Le reti sequenziali sincronizzate presentano l’inconveniente che la sequenza di stati di ingresso effettivamente riconosciuta dipende dalla temporizzazione degli impulsi di sincronismo. Infatti il funzionamento di queste reti è corretto solo se un impulso è applicato dopo che ogni transizione delle variabili di eccitazione degli elementi di memoria è terminata, ossia se si fa trascorrere un tempo non inferiore al ritardo ∆R con cui la parte combinatoria propaga le variazioni dei suoi ingressi, a partire dall’istante in cui queste si verificano. Tali variazioni possono essere o cambiamenti degli ingressi secondari conseguenti all’aggiornamento dello stato interno determinato dall’ultimo impulso applicato, oppure cambiamenti dello stato di ingresso. Di tutti i cambiamenti dello stato di ingresso che possano avvenire tra due impulsi consecutivi la rete avverte solo l’ultimo e al contrario il permanere di uno stato di ingresso per un tempo superiore all’intervallo tra due impulsi viene interpretato come una successione di due stati di ingresso identici, del tipo XkXk. Questo comportamento nei confronti della sequenza di ingresso è messo in evidenza dal seguente esempio. Supponiamo che una rete riceva in ingresso una successione di stati appartenenti all’insieme {Xi, i = 1, ..., 4}, codificati con due variabili x1 ed x2 come in tabella: X1 X2 X3 X4 x1 0 0 1 1 x2 0 1 1 0 A partire da un certo istante t0 la sequenza applicata sia X1X4X3X2X1X2X3X4 (Fig. 5.35 in alto): X1 X4 X3 X2 X1 X2 X3 X4 x1 x2 C ∆R t0 t1 X4 t2 t3 t4 X1 X1t5 t6 X3 t7 X4 t Fig. 5.35 Se gli impulsi C sono applicati secondo la sequenza di figura, la rete risulta sensibile alla successione di stati di ingresso X4X1X1X3X4 e non a quella effettivamente presentata. E` evidente che cambiando la temporizzazione cambia la sequenza di ingresso riconosciuta e quindi la risposta della rete. - 155 - Si conclude che se si vuole che una rete sincronizzata si comporti nei confronti di una sequenza di stati di ingresso ritenuta significativa nel modo corretto è indispensabile la conoscenza dell’esatta temporizzazione con cui devono essere applicati gli impulsi C. Ci sono casi in cui questa conoscenza non è disponibile oppure costituisce un vincolo troppo stringente da realizzare e quindi non è possibile utilizzare reti sincronizzate, ma reti sequenziali nelle quali i cambiamenti dello stato interno dipendano esclusivamente dai cambiamenti dello stato di ingresso: le reti adatte a questo scopo sono quelle asincrone, nelle quali non esistono elementi di memoria controllati da segnali di tipo impulsivo. Tuttavia sappiamo che le reti asincrone, in conseguenza del fatto che tutti i cambiamenti dello stato di ingresso sono significativi, richiedono, per un corretto funzionamento, che siano soddisfatti i seguenti vincoli. 1) Ogni cambiamento di ingresso deve avvenire solo quando lo stato interno è stabile e in conseguenza del nuovo stato di ingresso deve essere raggiunto un nuovo stato stabile prima che la successiva variazione di ingresso possa avere luogo (proprietà delle transizioni di ingresso a stati stabili); il minimo intervallo di tempo che intercorre tra due successivi cambiamenti dello stato di ingresso non deve essere inferiore al massimo ritardo con cui lo stato si stabilizza. La proprietà delle transizioni di ingresso a stati stabili tra l’altro può portare ad una rete asincrona più lenta rispetto ad una sincronizzata equivalente dal punto di vista computazionale. 2) Sequenze di ingresso del tipo XkXk non possono essere applicate, poichè una rete asincrona non è in grado di distinguere stati di ingresso identici generando stati di uscita diversi. 3) Poichè nel passaggio da uno stato stabile α, relativo ad uno stato di ingresso Xh, ad uno stato stabile β, conseguente ad uno stato di ingresso Xk, una rete asincrona può passare attraverso una successione di stati instabili, mantenendosi costante lo stato di ingresso Xk, è necessario definire come stato di uscita corrispondente allo stato di ingresso Xk quello associato allo stato β, ignorando quelli associati agli eventuali stati instabili intermedi. Le considerazioni precedenti portano a riconoscere la necessità che la tabella di flusso di una rete asincrona soddisfi ad alcune condizioni affinchè essa possa funzionare correttamente. 1) Prima di tutto occorre che in ogni colonna vi sia almeno uno stato stabile. Questa tuttavia è una condizione necessaria ma non sufficiente, come mostra il seguente esempio. Se la rete si trova nello stato stabile Si con stato di ingresso Xh, in conseguenza della transizione Xh → Xk si porta nello stato stabile Sj, con stato di ingresso Xk (Fig. 5.36a). Tuttavia può accadere anche che la rete, dallo stato stabile Si con stato di ingresso Xh, in conseguenza della stessa transizione di ingresso, si immetta nella sequenza ciclica Si → Sj → Si → ... con stato di ingresso Xk, rimanendovi finchè non si verifica una successiva transizione Xk → Xl, a seguito della quale peraltro la rete si stabilizzerà in uno stato non prevedibile, dipendendo dallo stato attuale in cui la transizione trova la rete (Fig. 5.36b): - 156 - Si Si,Zm Sj,Zn Si Si,Zm Sj,Zn a) b) Sk Sj Sk,Zq Sj,Zp Sj Sj,Zr Si,Zp Fig. 5.36 Segue da questa condizione, e dal fatto che l’uscita di una rete asincrona è sempre quella relativa ad uno stato stabile, che nella tabella di flusso le righe che non contengono stati stabili possono essere eliminate e le uscite associate a stati instabili possono essere qualsiasi, perchè prive di significato. Inoltre se vi sono condizioni di indifferenza sulle uscite, esse possono essere utilizzate con vantaggio per la riduzione della tabella stessa (Fig. 5.37). X1 X2 X1 X2 S1 S1, Z2 S2, S1 S1, Z2 S3, S2 S5, - S3, S3 S4, - S3, Z1 ⇒ S3 S4, - S3, Z1 S4 S4, Z2 S5, S4 S4, Z2 S5, S5 S5, Z1 S4, S5 S5, Z1 S4, Fig. 5.37 2) In secondo luogo, dal momento che lo stato di ingresso può essere aggiornato solo a stati interni stabili, conviene che la tabella di flusso sia strutturata in modo da ridurre per quanto possibile il tempo TStab richiesto per passare da uno stato stabile all’altro ed il tempo TZ necessario perchè lo stato di uscita assuma il valore corrispondente al nuovo stato di ingresso. Se la rete passa attraverso n stati instabili prima di arrivare a quello stabile, è facile verificare che vale la relazione TStab = (n+1)∆R. Il ritardo TStab è minimo quando la rete attraversa al più uno stato instabile, ossia è T Stabmin = 2∆ R . Invece TZ è minimo se lo stato di uscita raggiunge il valore corrispondente allo stato di ingresso con un ritardo pari a quello di propagazione della rete combinatoria, ossia T Zmin = ∆ R . Affinchè TZ sia minimo, tutti gli stati di uscita devono essere ovviamente significativi. Per avere TStab e TZ minimi, è necessario che in ogni colonna - 157 - ad uno stato instabile corrisponda uno stato stabile dello stesso nome e che lo stato di uscita associato allo stato instabile sia specificato e uguale a quello associato allo stato stabile, ossia: f(Xi, Sj) = Sk| Sj ≠ Sk ⇒ f(Xi, Sk) = Sk e g(Xi, Sj) = g(Xi, Sk), ∀Xi Le tabelle di flusso strutturate in modo da soddisfare i punti 1) e 2) e quelle che soddisfano il punto 1) e per le quali l’uscita dipende solo dallo stato interno (macchine di Moore) sono dette tabelle normali e le reti corrispondenti reti asincrone normali. A differenza delle reti sincronizzate che possono essere realizzate sia secondo il modello di Mealy che secondo il modello di Moore, dando la preferenza al secondo quando si vuole una rete il cui lo stato di uscita sia sempre significativo, di solito ha poco senso porsi il problema del modello nel caso delle reti asincrone; infatti, dovendo realizzare reti normali, lo stato di uscita è sempre significativo, dal momento che in ogni colonna della tabella normale l’uscita di uno stato instabile è sempre uguale a quella dello stato stabile corrispondente. 5.4.2 - Sintesi delle reti asincrone normali La sintesi delle reti asincrone passa attraverso le stesse fasi viste per le reti sincronizzate, ossia costruzione della tabella di flusso dalla descrizione a parole e realizzazione della rete secondo il modello strutturale prescelto. Tuttavia è necessario fare in modo che la tabella di flusso sia costruita rispettando i vincoli che la rendono normale. Tali vincoli si trasferiscono nel grafo degli stati nel modo seguente: a) Per ogni arco Xk/Zm che entra in un nodo Si e che proviene da un nodo Sj, i ≠ j, c’è un arco omonimo che esce da Si e si richiude su Si stesso (Fig. 5.38): Si Xk/Zm Xk/Zm Fig. 5.38 b) Non possono esistere due archi che entrano in Si provenendo da nodi diversi etichettati con lo stesso stato di ingresso e stati di uscita diversi; infatti in caso contrario dovrebbero esistere due archi uscenti e rientranti in Si etichettati con i due stati di uscita e lo stesso stato di ingresso, il che non può essere, in quanto da un nodo non possono uscire due archi etichettati con lo stesso stato di ingresso e stati di uscita diversi (Fig. 5.39). - 158 - Si Xk/Zm Xk/Zn Xk/Zm Xk/Zn Fig. 5.39 Per esempio si voglia costruire una rete asincrona che riconosce la sottosequenza di stati di ingresso aba ogni volta che essa si presenta in una sequenza continua costruita con gli stati a, b e x; si esclude che possano presentarsi due stati di ingresso identici consecutivi. Il grafo degli stati e la relativa tabella di flusso sono illustrati in Fig. 5.40. b/0 x/0 a/0 a/0 1 x/0 x/0 x/0 a 2 b/0 b/0 4 a/1 a/1 3 b x 1 2, 0 1, 0 1, 0 2 2, 0 3, 0 1, 0 3 4, 1 3, 0 1, 0 4 4, 1 3, 0 1, 0 b/0 Fig. 5.40 Il procedimento di sintesi procede da questo punto come nel caso delle reti sincronizzate, salvo osservare che, non essendovi di norma latch o flip-flop sui percorsi di retroazione, viene a mancare la parte relativa alla definizione delle tabelle di applicazione dei flip-flop. Vale la pena osservare la somiglianza tra questo grafo (di Mealy) e quello di Fig. 5.30 (di Moore) per lo stesso problema: questa osservazione rende ragione in modo esemplare a quanto affermato circa il fatto che modellare una rete asincrona secondo Mealy o secondo Moore è una questione priva di importanza. Da ultimo facciamo alcune considerazioni sulla la velocità di risposta delle reti asincrone rispetto a quelle sincronizzate. Il tempo di ciclo minimo per una rete sincronizzata è come sappiamo Ts = ∆R+∆M, mentre per una rete asincrona esso è Ta = 2∆R, essendo ∆R il massimo ritardo della parte combinatoria. Supponendo che ∆R sia lo stesso per i due tipi di reti, risulta Ta < Ts solo se ∆R < ∆M; se questa condizione non è verificata, cosa che avviene normalmente in pratica, la rete sincronizzata è più veloce di quella asincrona, contrariamente alla convinzione abbastanza diffusa che le reti asincrone siano le reti più veloci. - 159 - ESERCIZI 1) Progettare una rete sequenziale sincronizzata che in una sequenza di tre bit riconosce se il bit 0 è contenuto esattamente due volte. 2) Progettare una rete sequenziale con un ingresso ed una uscita la quale assume valore 1 se e solo se l’ingresso al tempo t è l’opposto di quello al tempo t-1. 3) Una rete sequenziale possiede un ingresso x ed una uscita z la quale vale 1 se l’ingresso al tempo ti vale 1, mentre agli istanti ti-2 e ti-1 valeva rispettivamente 1 e 0. Progettare la rete. 4) Per il problema dell’ esercizio 3 realizzare una rete asincrona. 5) Un decodificatore seriale possiede un ingresso a livelli r ed un ingresso ad impulsi x e quattro uscite z0, z1, z2, z3. Quando r = 0 tutte le uscite sono 0, indipendentemente dal valore di x. Quando r = 1 il funzionamento del decodificatore è descritto dalla tabella seguente: sequenza di valori di x z0 z1 z2 z3 0 0 1 0 0 0 01 0 1 0 0 1 0 0 0 1 0 11 0 0 0 1 6) Una rete sequenziale nel modo fondamentale possiede due ingressi x1 e x2 ed una uscita z la quale cambia solo nel caso in cui gli ingressi cambiano da (0, 0) a (0, 1). Progettare la rete. 7) In una stanza possono trovarsi una o due persone; la luce nella stanza deve essere accesa se c’è almeno una persona, spenta se non c’è nessuno. Le due persone possono entrare o uscire solo una per volta, ma mentre una entra l’altra può uscire. Realizzare una rete sequenziale che simula la situazione descritta. 8) Realizzare un circuito sequenziale che rileva gli errori nel codice in eccesso di tre, trasmesso in ingresso a partire dal bit meno significativo (il più a destra), in modo che se la sequenza dei valori dei quattro bit trasmessi è diversa da una di quelle valide, l’uscita del circuito diventa 1, altrimenti rimene 0. Si suppone che la sequenza di ingresso venga interrotta non appena il circuito scopre un errore. 9) Un circuito sequenziale asincrono con due ingressi x1, x2 ed una uscita z funziona nel seguente modo. Quando x1 = 1, z cambia da 0 ad1 durante la transizione di x2 da 0 ad 1; qaundo x2 = 1, z cambia da 1 a 0 durante la transizione di x1 da 1 a 0; z diventa 0 se x1 e x2 cambiano insieme. Ogni altro evento di ingresso lascia immutata l’uscita. Progettare il circuito. - 160 - 10) Progettare un circuito sequenziale con un ingresso ed una uscita la quale vale 1 se cinque configurazioni di ingresso consecutive costituiscono una sequenza contenente esattamente tre 1 e due 0 e i primi due valori sono 1. Il circuito ritorna nello stato iniziale quando viene riconosciuta una sequenza completa oppure la sequenza si interrompe. 11) Realizzare un circuito sequenziale asincrono con due ingressi x1 e x2 e due uscite z1 e z2, tale che se uno solo degli ingressi cambia, l’uscita (z1 z2) assume la configurazione di ingresso; se entrambi gli ingressi rimangono stabili o cambiano insieme, l’uscita rimane inalterata. 12) Un circuito sequenziale possiede due ingressi ad impulsi x1 e x2 ed una uscita a livelli z. Ogni volta che arriva un impulso sull’ingresso x1 e, dopo tale impulso, due impulsi arrivano su x2, ma nessun altro su x1, l’uscita diventa 1, altrimenti rimane 0. Quando l’uscita è diventata 1, rimane tale fino al primo impulso su x2, che la riporta a 0. Progettare il circuito. 13) Realizzare una rete sequenziale con un ingresso ed una uscita, la quale vale 1 quando viene riconosciuta la sequenza di ingresso 01xx…x01, dove xx…x è una qualsiasi stringa, eventualmente di lunghezza nulla, di 0 e di 1. 14) L’incrocio tra una strada a grande traffico ed un attraversamento pedonale è regolato da un semaforo che può essere attuato dai pedoni che intendono attraversare la strada. In assenza di richiesta da parte di pedoni, il semaforo sulla strada principale è sempre verde e quello rivolto verso l’attraversamento rosso. Se un pedone fa richiesta di attraversare ed è trascorso un certo tempo prefissato dall’ultima richiesta, il semaforo principale deve passare al rosso, mentre quello del passaggio pedonale deve diventare verde, rimanendovi per un determinato intervallo di tempo; passato tale tempo il semaforo pedonale ritorna rosso e quello della strada principale verde. Progettare una rete sequenziale che controlla il semaforo. 15) Un circuito sequenziale sincronizzato ha un ingresso a livelli x ed una uscita ad impulsi z. Il valore dell’ingresso può cambiare solo in assenza dell’impulso di clock. Se x si mantiene ad 1 per tre impulsi consecutivi del clock, l’uscita diventa 1 in corrispondenza del successivo impulso di clock. In ogni altra circostanza l’uscita rimane 0. a) Sintetizzare il circuito facendo uso di flip-flop JK. b) Mostrare il funzionamento del circuito attraverso un diagramma temporale. 16) Un distributore automatico di cioccolatini accetta monete da 100 e 200 lire per un cioccolatino del costo di 300 lire e dà insieme il resto se la somma depositata è superiore a 300 lire. Sapendo che per ogni moneta inserita vengono generati due segnali x1, x2 secondo il codice mostrato nella seguente tabella, si vuole progettare una rete sequenziale nel modo fondamentale con ingressi x1 e x2 e con due uscite z1 e z2, che riconosce la cifra versata ed effettua le seguenti operazioni: 1) se la cifra è pari al costo, fornisce il cioccolatino (z1z2=10); 2) se la cifra è superiore al costo, fornisce cioccolatino e resto - 161 - (z1z2=11); 3) se una moneta non è valida, restituisce l’intero deposito, ovviamente senza il cioccolatino (z1z2=01); 4) altrimenti mantiene le uscite z1z2=00. moneta x1 x2 nessuna 0 0 100 lire 0 1 200 lire 1 0 falsa 1 1 a) Disegnare il grafo di stato e la tabella di flusso della rete. b) Sintetizzare la rete utilizzando per la parte combinatoria una ROM. Si suppone che x1 e x2 ritornino automaticamente a zero prima che sia inserita una nuova moneta, ma ovviamente non prima che il circuito si sia stabilizzato in un nuovo stato. Infatti se gli ingressi avessero ancora il valore acquistato per effetto dell’ultima moneta quando una nuova viene depositata, accadrebbe che... @#*&!!!, e ciò è dovuto al fatto che una rete asincrona... 17) Costruire il diagramma degli stati di una macchina di Moore che ha due stati di ingresso, I={0,1}, due stati di uscita Z={0,1} ed il seguente comportamento: la sequenza degli stati di ingresso è esaminata dalla macchina a gruppi di quattro stati consecutivi e l’uscita va ad 1 per un periodo di clock se si verifica una delle due sequenze 0110 o 1001. Esempio:sequenza di ingresso01011000011010… sequenza di uscita 00000000000010… 18) Sintetizzare con flip-flop JK la seguente macchina sequenziale, minimizzandola se necessario: 0/0 a 0/0 1/0 0/0 0/0 b 1/0 g 1/1 0/0 1/0 d 0/0 c 0/0 1/1 1/1 f 1/1 - 162 - e 19) Quando un canale di trasmissione binario seriale opera correttamente, tutti i blocchi di 0 consecutivi sono di lunghezza pari e tutti i blocchi di 1 consecutivi sono di lunghezza dispari. Sintetizzare una rete sequenziale di Mealy, usando FF di tipo T, che produca una uscita z ad 1 per un periodo di clock quando si rileva un comportamento erroneo. Disegnare il circuito usando porte NAND e costruire inoltre la tabella di stato della macchina di Moore simile. Esempio x 001000111011000… z 000000100010100… 20)Progettare una rete sequenziale sincrona che simula il gioco dell’oca con un solo giocatore, il cui tracciato è riportato nella seguente figura: 1 P 2 3 vai a 3 4 vai a 7 5 stai fermo un lancio 8 A 7 torna alla partenza 6 torna a 3 Il gioco consiste nell’arrivare esattamente nella casella finale A, a partire dalla casella iniziale P, lanciando successivamente un dado che riporta sulle facce solo i valori 1, 2 e 3; ad ogni lancio il giocatore avanza di un numero di caselle corrispondente al numero estratto e rispettando le condizioni associate alle varie caselle del tracciato. Ogni eccesso di punteggio rispetto alla casella di arrivo fa retrocedere di un numero corrispondente di caselle; ad esempio se il giocatore si trova nella casella 7 e il lancio fa uscire 3, si deve tornare alla casella 8. Utilizzare come elementi di memoria flip-flop di tipo T. La rete ha come ingresso il valore estratto dal lancio del dado e come uscita una variabile che assume valore 1 quando viene raggiunta esattamente la casella di arrivo. 21) Ad un incrocio tra due strade A e B è situato un semaforo che regola il traffico operando ciclicamente nel seguente modo: • mantiene lo stato S0 (A rosso , B giallo) per 1 clock, quindi passa in S1; • mantiene S1 (A verde, B rosso) per almeno 3 clock e comunque fino a quando un veicolo non è presente in direzione B, condizione rilevata da un sensore b, posto lungo B, che assume valore 1; quindi passa in S2; • mantiene S2 (A giallo, B rosso) per 1 clock, quindi passa in S3; - 163 - • mantiene S3 (A rosso, B verde) per almeno 3 clock e comunque fino a quando un veicolo non è presente in direzione A, condizione rilevata da un sensore a, posto lungo A, che assume valore 1; quindi passa in S0. a) Descrivere il diagramma degli stati di un circuito sequenziale di Moore che comanda il semaforo. b) Sintetizzare il circuito utilizzando flip-flop JK. È sufficiente ricavare le funzioni di eccitazione di uno solo dei flip-flop e quelle delle uscite z1 e z2 che comandano il semaforo secondo la tabella: stato S0 S1 S2 S3 codice di comando 00 01 10 11 c) In alternativa sintetizzare la rete utilizzando un contatore binario. 22) Un tale possiede due autorimesse A, B in cui parcheggia le sue auto. Egli vuole installare un dispositivo di apertura automatica che, oltre a togliergli la seccatura dell’apertura e chiusura manuale, sia anche capace di evitargli di cercare quale autorimessa contenga l’auto quando vuole uscire e quale invece è libera quando vuole parcheggiare. Il dispositivo deve disporre di due tasti P ed U; il tasto P verrà premuto (P=1) per parcheggiare e dovrà aprire la prima (nell’ordine A, B) autorimessa disponibile ad accogliere un’auto, il tasto U verrà premuto (U=1) per uscire e dovrà aprire la prima (nell’ordine A, B) autorimessa che contiene un’auto.Il dispositivo deve essere costruito in modo da impedire la pressione contemporanea di entrambi i tasti P ed U. La chiusura avverrà automaticamente dopo un tempo prefissato. Progettare il circuito sequenziale sincrono che realizza il dispositivo ipotizzando che una volta aperta la porta, l’auto sia effettivamente parcheggiata o prelevata. I segnali di uscita siano rappresentati da due variabili Y e Z codificate come segue: 00 nessuna apertura 01 apertura dell’autorimessa B 10 apertura dell’autorimessa A 11 accensione di una luce rossa per avvertire che entrambe le autorimesse sono piene, quando si vuole parcheggiare o entrambe vuote, quando si vuole prelevare un’auto. Usare flip-flop di tipo D e codificare gli stati nella maniera seguente: 00 autorimesse vuote, 01 presente solo un’auto nell’autorimessa B, 10 presente solo un’auto nell’autorimessa A, 11 autorimesse piene. 23) In un impianto di autolavaggio il percorso delle auto è delimitato all’entrata e all’uscita da due sbarre A e B il cui movimento è comandato da un dispositivo che riceve come ingressi i segnali di due fotocellule FA e FB situate in corrispondenza delle sbarre stesse. Il comportamento del dispositivo è il seguente. - 164 - • La sbarra A viene chiusa quando due auto sono passate oltre la fotocellula FA e riaperta quando entrambe le auto sono uscite. • La sbarra B viene aperta quando due auto sono all’interno dell’autolavaggio e richiusa quando sono uscite. Progettare il circuito di comando come rete sequenziale asincrona. 24) Data la tabella di flusso di figura che descrive una rete sequenziale sincronizzata, si supponga di partire dallo stato totale (X2, S3) e si determini la più lunga sequenza di stati di ingresso (con Xi ≠ Xi-1) per la quale le uscite hanno sempre valore corretto, anche nell’intervallo di tempo tra un impulso di clock ed il cambiamento dell’ingresso. X1 X2 X3 X4 S1 S2, 1 S4, 2 S1, 3 S3, 2 S2 S3, 2 S1, 1 S4, 3 S3, 2 S3 S2, 3 S4, 1 S1, 2 S2, 1 S4 S1, 3 S2, 3 S3, 1 S2, 2 25) Progettare una rete sequenziale con due ingressi a livelli x ed y ed una uscita z pure a livelli; la rete esegue la somma logica di x ed y, se lo stato di ingresso attuale è uguale a quello precedente, altrimenti esegue l’or esclusivo di x ed y. 26) Data la seguente tabella di flusso parzialmente specificata, trovare una tabella ridotta compatibile con essa e si disegni lo schema della rete corrispondente. a b c d e 000 −,− a,1 −,− c,1 b,− 010 a,0 b,0 c,− d,− e,0 101 a,1 b,− −,− e,1 d,− 110 c,− a,1 −,− −,− d,− 111 a,0 c,− d,− b,0 e,− 27) Studiare il comportamento della rete di figura, specificando se essa è affetta o meno da oscillazioni, e si disegni l’andamento temporale dell’uscita in funzione degli ingressi a e b. - 165 - a z b 28) L’alettone di coda di un aeromodello può stare in tre posizioni, diritto, alto, basso, ed è comandato a distanza da impulsi radio nel seguente modo. Se l’alettone si trova piegato in alto o in basso, quando arriva un impulso si riporta diritto; se invece è diritto, quando arriva un impulso si piega verso il basso se in precedenza era in alto, o viceversa si piega verso l’alto se era in basso. Progettare una rete sequenziale asincrona che comanda il movimento dell’alettone. Realizzare inoltre la rete in forma sincronizzata senza ingressi (l’impulso viene applicato all’ingresso di sincronismo degli elementi di memoria) e fare vedere che essa è facilmente ottenibile anche dalla tabella di flusso della rete asincrona. (Suggerimento: non è necessario ricercare le classi di compatibilità). 29) Progettare in forma NAND un circuito sequenziale con tre stati di ingresso a, b, c e due stati di uscita z1, z2, il quale riconosce con lo stato di uscita z2 la sottostringa di ingresso nella quale un numero pari di stati b è seguita, anche non immediatamente, da un numero dispari di stati c. 30) Progettare una rete sequenziale sincronizzata con ingressi x1, x2 ed uscita z, che funziona nel seguente modo (vedi figura). x1 x2 z Se sull’ingresso x1 si succedono due 1, mentre x2 è 1 e successivamente si presenta 1 sull’ingresso x2, essendo 0 l’ingresso x1, l’uscita diventa 1 e tale rimane finchè, passando x1 da 1 a 0 con x2 a 0, ritorna anch’essa a 0. L’uscita rimane zero per tutte le eventuali condizioni di ingresso non rispecchiate dal diagramma. Nel progetto si faccia uso di flip-flop T e almeno di un flip-flop JK. 31) Scrivere la tabella di flusso di una rete sequenziale sincronizzata, con ingressi x1, x2 ed una uscita impulsiva z, la quale riconosce se all’ingresso x2 si presenta un impulso 0 → 1 → 0 esattamente nell’intervallo di tempo definito dal presentarsi all’ingresso x1 di due - 166 - impulsi 0 → 1 → 0 → 1 → 0. Tutti gli impulsi possono avere durata arbitraria. 32) Si vuole comandare l’accensione e lo spegnimento di due lampade A e B con due interruttori x ed y, azionabili solo singolarmente, mediante una rete sequenziale che opera con le seguenti modalità: A x Rete Sequenziale y • • • • B quando x ed y sono entrambi aperti le lampade A e B sono spente; la chiusura di x o di y indifferentemente provoca l’accensione della lampada A; la sua apertura ne provoca lo spegnimento; la lampada B si accende quando anche l’altro interruttore viene chiuso; dal momento in cui entrambi gli interruttori sono chiusi e finché non vengono di nuovo aperti entrambi, la lampada A è comandata dal secondo interruttore azionato, la lampada B dal primo. Scrivere la tabella di flusso della rete, precisando se questa può essere realizzata sia in modo sincrono che in modo asincrono e, in caso affermativo, se ne realizzi la versione asincrona. 33) In una stanza ci sono due lampade L1 ed L2, comandate da due fotocellule F1 ed F2 e da due interruttori I1 e I2 situati in corrispondenza delle porte di accesso P1 e P2, come in figura: I1 P1 L1 F2 L2 F1 P2 I2 R.S. Le fotocellule e gli interruttori fanno accendere e spegnere le lampade secono il seguente schema. Nella stanza possono trovarsi una o al più due persone insieme, ma possono entrare solo una per volta. Una fotocellula genera un impulso solo quando rileva una persona che sta entrando, invece un interruttore genera un impulso solo quando una persona esce; i due interruttori sono collegati tra di loro in modo che sia indifferente quale dei due viene attivato. Quando la stanza è vuota le lampade devono essere spente. Se entra una persona da P1, fa accendere L1; se entra da P2, fa accendere L2. Quando la persona esce, non importa - 167 - da quale porta, fa spegnere la lampada che era accesa. Se nella stanza c’è già una persona e ne entra una seconda dalla stessa porta, non provoca alcun effetto; se invece la seconda persona entra dalla porta opposta, fa accendere la lampada che si trovava spenta. Quando una delle due persone esce, non accade nulla se è accesa una sola lampada; altrimenti si spegne la lampada opposta a quella che la persona aveva fatto accendere entrando. Le persone possono lasciare la stanza solo in ordine inverso a quello di entrata. Scrivere la tabella di flusso ridotta di una rete sequenziale asincrona, eventualmente non normale, che riceve in ingresso gli impulsi generati dalle fotocellule e dai due interruttori collegati e produce due uscite per fare accendere e spegnere L1 ed L2 rispettivamente. 34) Facendo uso di flip-flop T, progettare una rete sequenziale sincronizzata di Moore la quale riconosce con un impulso in uscita se in ingresso, a partire dall’istante ti, si presenta la sequenza 0 1 0, essendo stato l’ingresso uguale a 1 1 0 rispettivamente negli istanti ti-3, ti-2, ti-1. Le variazioni dell’ingresso sono sincrone con il clock. 35) Una rete sequenziale asincrona ha il seguente funzionamento. Quando l’ingresso cambia da 0 ad 1, l’uscita della rete cambia pure da 0 ad 1 e rimane 1 finchè l’ingresso rimane 1. Quando l’ingresso cambia da 1 a 0, l’uscita cambia da 1 a 0, quindi di nuovo ad 1 e infine a 0. Se l’ingresso cambia nuovamente da 0 ad 1 quando l’uscita è definitivamente diventata 0, la rete riprende il funzionamento proprio, altrimenti attende che l’ingresso ritorni a 0, conservando immutata l’uscita, dopodiché riprende a funzionare propriamente dall’inizio. Dire se si tratta di una rete normale e svilupparne il progetto. 36) Scrivere la tabella di flusso di una rete sequenziale che accetta in ingresso le cifre tra 0 e 9 e denuncia in uscita il riconoscimento di un qualunque numero compreso tra la vostra data di nascita D, scritta nel formato ggmmaa, ed il numero D+10. 37) Progettare una rete sequenziale con due ingressi, x1 ed x2, ed una uscita z, la quale funziona nel modo seguente; quando x1 diventa 1 e quindi 0, mentre x2 è 0, e successivamente x2 diventa 1 per due volte mentre x1 è 1, l’uscita diventa 1 quando x1 cade a 0 e rimane tale fino al primo 1 su x2 che si presenta mentre x1 è 0. 38) Progettare una rete sequenziale asincrona normale con tre stati di ingresso a, b, c, che riconosce se in una sequenza continua di stati di ingresso sono presenti le sottosequenze acb oppure bac, anche interallacciate. 39) Progettare una rete sequenziale sincronizzata con un ingresso x ed una uscita z, che funziona nel seguente modo. Quando in ingresso si presenta una variazione 0 → 1 oppure 1 → 0 e all’istante precedente l’ingresso era rispettivamente 0 oppure 1, l’uscita diventa 1; in tutti gli altri casi l’uscita rimane 0. Nel progetto si usino flip-flop JK. Esempio: x ...1110100110001... - 168 - y ...0001000101001... 40) Progettare una rete sequenziale sincronizzata con un ingresso x, sincrono con il clock, ed una uscita z, nella quale l’uscita permane ad 1 per un tempo pari al numero di periodi di clock in cui l’ingresso rimane costantemente a zero o ad uno, diminuito di due. Esempio: x: ...0000011101001111001000111111... z: ...0011100100000011000001001111... 41) Ricavare la tabella di flusso della rete di figura e analizzarne il funzionamento: a & + b Y z ⊕ y 42) Progettare una rete sequenziale con due ingressi x1, x2 ed una uscita z, la quale diventa 1 quando entrambi gli ingressi diventano 1, qualunque sia l’ordine secondo il quale essi assumono tale valore (insieme, oppure prima x1 e poi x2 o viceversa). La rete può essere realizzata come asincrona? Motivare la risposta. 43) Progettare una rete sequenziale sincronizzata con due ingressi x1, x2 ed una uscita z che funziona nel modo seguente. Quando l’ingresso x1 cambia da 0 ad 1, mentre x2 è fisso ad 1, l’uscita assume valore 1 al prossimo fronte 0 → 1 che si presenta su x2, mentre x1 è 0 e tale rimane fino al momento in cui x1 cambia di nuovo da 0 ad 1, mentre x2 è 0 (v. figura). x1 x2 z 44) Una compagnia di traghetti vuole distinguere automaticamente al momento dell’imbarco le auto di passo inferiore ad un certo valore L da quelle di passo uguale o superiore. Per questo lungo la corsia di imbarco vengono posizionate due piattaforme mobili A e B, a distanza L l’una dall’altra; quando un’auto esercita con le ruote anteriori una pressione su una piattaforma, si genera un segnale xi (i = A o B) di valore 1, che viene ripoortato a 0 solo quando la piattaforma viene di nuovo premuta dall’auto con le ruote posteriori. I due segnali xA e xB sono inviati in ingresso ad una rete asincrona con due uscite z1 e z2 che assumono valore 10 o 01 rispettivamente nel caso di passo inferiore a L oppure uguale o maggiore. Lo stato di uscita si mantiene fino all’arrivo di - 169 - un’altra auto che lo riporta a 00. (v. figura). Progettare la rete asincrona verso di marcia A L B xB xA R. A. z1 z2 xA xB z1 z2 45) Progettare una rete sequenziale sincronizzata con due ingressi x1 ed x2 ed una uscita z, la quale funziona come segue. Quando su x1 si presenta la sequenza 011 e corrispondentemente su x2 si hanno un numero dispari di 1, l’uscita diventa 1, altrimenti resta 0. Si utilizzino flip-flop di tipo JK. 46) Progettare una rete sequenziale sincronizzata con due ingressi x1 e x2 ed una uscita z, la quale funziona nel modo seguente. Ad ogni impulso di clock la rete legge una nuova coppia di ingresso (x1,x2); quando in ingresso viene riconosciuta la sequenza 10, 00, 01, l’uscita viene posta ad 1 per un periodo di clock quindi ritorna a zero e rimane zero per qualunque altra situazione. La rete riconosce anche sequenze parzialmente sovrapposte. Nel progetto utilizzare flip-flop JK. 47) Una rete sequenziale sincronizzata possiede due ingressi x1 e x2 ed una uscita z e funziona da ritardo programmabile secondo il seguente schema. Se x2 = 0, l’uscita al generico istante t vale z(t) = x1(t-1). Se x2 = 1, l’uscita al generico istante t vale z(t) = x1(t-2). Realizzare la rete utilizzando flip-flop JK. 48) Una rete sequenziale sincronizzata possiede due ingressi x1 e x2 e due uscite z1 e z2 e funziona secondo il seguente schema. Se x2 = 0, l’uscita vale 10 se sull’ingresso x1 si presenta la sequenza 110. Se x2 = 1, l’uscita vale 01 se sull’ingresso x1 si presenta la sequenza 011. In tutti gli altri casi l’uscita vale 11. Realizzare la rete utilizzando flip-flop JK. 49) Una rete sequenziale sincronizzata possiede due ingressi x1 e x2 ed una uscita z e funziona secondo il seguente schema. Quando x2 = 0, e sull’ingresso x1 si presenta la sequenza 101, l’uscita va ad 1 quando x2 va ad 1 e vi rimane fino a quando il primo tra x1 e x2 torna a zero. In tutti gli altri casi l’uscita rimane 0. Realizzare la rete utilizzando flip-flop JK. 50) Progettare una rete sequenziale con due ingressi, x1 ed x2, ed una uscita z, la quale - 170 - funziona nel modo seguente; quando x1 diventa 1 e quindi 0, mentre x2 è 0, e successivamente x2 diventa 1 per due volte mentre x1 è 1, l’uscita diventa 1 quando x1 cade a 0 e rimane tale fino al primo 1 su x2 che si presenta mentre x1 è 0. 51) In una fonderia, per separare cilindri di acciaio in due gruppi in funzione dei diametri d1 ed d2, essi vengono fatti rotolare su un piano inclinato lungo il quale intercettano una o entrambe le fotocellule F1 ed F2 come in figura. Gli impulsi generati dalle fotocellule quando sono oscurate sono elaborati da una rete sequenziale che effettua il riconoscimento dei cilindri e in conseguenza produce un’uscita appropriata per stabilire percorsi differenti per i cilindri di diametro d1 e per quelli di diametro d2. In assenza di cilindri sul piano inclinato, la rete mantiene il percorso stabilito per ultimo. Progettare la rete. d2 d1 F1 F2 52) Realizzare una rete sequenziale sincronizzata con un ingresso x ed una uscita z che funziona nel seguente modo. All’istante generico t l’uscita assume valore 1 in corrispondenza del secondo di due 1 consecutivi che si presentano in ingresso dopo che si sono succeduti su di esso almeno due zeri. In tutti gli altri casi l’uscita vale 0. Usare latch SR. 53) Realizzare una rete sequenziale asincrona normale con due ingressi x1 e x2 ed una uscita z, avente il seguente comportamento. Quando su x1 arriva un impulso positivo, di durata qualsiasi, mentre x2 è zero e successivamente arriva su x2 un impulso positivo, pure di durata qualsiasi, mentre x1 è uno, l’uscita diventa uno e tale rimane fino al successivo impulso positivo su x1, che la riporta a zero. In tutte le altre situazioni l’uscita rimane zero. x1 x2 z - 171 - 54) Progettare una rete sequenziale sincronizzata che in una sequenza binaria di cinque bit riconosce se sono presenti almeno due zeri e due uno. Nel progetto fare uso di flip-flop JK. 55) Progettare una rete sequenziale con due ingressi x ed y ed una uscita z che si comporta nel seguente modo. Quando x (o y) diventa 1 e l’altro ingresso y (o x) rimane 0 e successivamente anch’esso diventa 1, oppure quando entrambi contemporaneamente diventano 1, l’uscita assume valore 1 all’istante in cui y va a 0 e x resta ad 1; l’uscita rimane 1 finché x va a 0, indipendentemente dal fatto che y cambi o rimanga immutato. In tutti gli altri casi l’uscita resta 0. 56) Un circuito sequenziale asincrono con due ingressi x1 e x2 ed una uscita z funziona nel seguente modo. Quando x1 = 0 e x2 cambia da 0 ad 1, l’uscita cambia da 1 a 0, oppure rimane 0. Quando x2 = 1 e x1 cambia da 0 ad 1, l’uscita cambia da 0 ad 1 oppure resta 1. Quando x1 e x2 cambiano insieme, l’uscita viene complementata. Per tutti gli altri stati di ingresso l’uscita diventa o rimane 1. Ricavare la tabella di flusso del circuito. 57) Un circuito sequenziale sincronizzato con due ingressi x1 e x2 ed una uscita z deve riconoscere se sull’ingresso x1 si presenta la sequenza 010 mentre x2 è 1, oppure la sequenza 101 mentre x2 è 0. Le due sequenze possono essere interallacciate. Progettare il circuito utilizzando flip-flop JK. 58) Progettare una rete sequenziale sincronizzata che in una sequenza binaria di cinque bit riconosce se sono presenti almeno due zeri e due uno. Nel progetto si faccia uso di flip-flop JK. 59) Progettare una rete sequenziale sincronizzata che in una sequenza binaria di cinque bit riconosce se sono presenti almeno due zeri non consecutivi e due uno pure non consecutivi. Nel progetto si faccia uso di flip-flop JK. 60) Progettare un circuito asincrono normale con due ingressi x1 ed x2 ed una uscita z, la quale cambia da 0 ad 1 o da 1 a 0 ogni volta che si verifica un cambiamento da 0 ad 1 su uno qualunque dei due ingressi. Non sono possibili cambiamenti simultanei dei due ingressi. 61) E’ ben noto il quesito del lupo, della capra e del cavolo: un tale deve trasferire da una sponda all’altra di un fiume un lupo, una capra ed un cavolo servendosi di una barca che, oltre a lui, può portare solo il lupo, o la capra oppure il cavolo. Quel tale deve fare in modo da non lasciare soli su alcuna delle due sponde il lupo e la capra, perchè il lupo mangerebbe la capra, nè la capra ed il cavolo perchè la capra mangerebbe il cavolo, ma solo al più il lupo ed il cavolo. Quale sequenza di passaggi deve effettuare quel tale per effettuare con successo il trasbordo degli animali e del cavolo? Si vuole realizzare una rete sequenziale sincrona che simula un gioco basato sul quesito sopra ricordato, secondo le seguenti specifiche. La rete possiede due ingressi x1 e x2, mediante i quali si codificano gli eventi barca senza carico, barca con lupo, barca con capra, barca con cavolo. Un giocatore ad ogni passo sceglie l’evento che ritiene corretto nella sequenza risolutiva del quiz, definendo tramite deviatori il valore binaro di x1 e di x2 e la rete evolve in accordo ad esso e alla - 172 - situazione interna corrente, producendo in uscita una delle risposte nuovo passo, errore, successo oppure nessuna risposta. Le uscite sono visualizzate su un display a segmenti luminosi il quale, nel caso di nessuna risposta, cioè prima dell’inizio di una sequenza di gioco, rimane oscuro. Poichè l’intervento del giocatore è asincrono rispetto al clock, è necessario che ogni evento di ingresso selezionato sia memorizzato e acquisito dalla rete al primo impulso di clock utile, in corrispondenza del quale la rete provvede anche a cancellarlo, portando la configurazione di ingresso a quella di default associata all’evento barca senza carico. Progettare la rete che simula il gioco, la logica di sincronizzazione degli ingressi e quella necessaria per la visualizzazione dell’uscita. 62) Progettare due reti sequenziali sincronizzate con le seguenti caratteristiche. Rete 1 La rete possiede due ingressi x1 e x2 ed una uscita z; quando x1 cambia da 0 ad 1, mentre x2 rimane stabile, l’uscita assume il valore di x2; quando x2 cambia da 1 a 0. mentre x1 rimane stabile, l’uscita assume il valore complementare dell’ingresso x1; in tutti gli altri casi l’uscita conserva il proprio valore. Realizzare la rete con flip-flop JK. Rete 2 Anche questa rete possiede due ingressi v1 e v2 ed una uscita u. Quando un impulso si presenta sull’ingresso v1 e successivamente un impulso su v2 ed uno ancora su v1, l’uscita diventa 1 e rimane tale fino ad un nuovo impulso su v2, in corrispondenza del quale ritorna 0. In ogni altra situazione l’uscita conserva valore 0. Progettare la rete con flip-flop D. 63) Un circuito sequenziale sincronizzato possiede due ingressi x1 ed x2 ed una uscita z ed opera nel seguente modo. Quando x2 = 0, z rimane 0 finchè si presenta su x1 un impulso alla fine del quale z diventa 1, mantenendo poi tale valore finchè x2 diventa 1; allora z ritorna a 0 e vi rimane. Quando x2 = 1 e all’ingresso x1 si presenta la sequenza 101, z diventa 1 e mantiene tale valore finchè x2 diventa 0; allora anche z ritorna a 0 e vi rimane. In ogni altro caso z rimane inalterata. Progettare il circuito come macchina di Moore, utilizzando per la parte combinatoria una memoria di sola lettura. x1 x2 z 64) Un circuito sequenziale possiede due ingressi ad impulsi x ed y ed una uscita a livelli z. Gli impulsi sull’ingresso x sono periodici, mentre quelli sull’ingresso y sono casuali, - 173 - ma quando si verificano sono accettati solo se si presentano tra un impulso di x e l’altro. L’uscita z è 1 durante l’intervallo tra due impulsi consecutivi su x, purchè nell’intervallo precedente si sia avuto un impulso su y, altrimenti rimane 0 (v. figura). Progettare il circuito facendo uso di flip-flop JK. x y z 65) Un circuito sequenziale sincronizzato possiede due ingressi x1ed x2 ed un’uscita z. Quando l’ingresso x1 assume valore 0 e lo mantiene per tre periodi di clock consecutivi e durante tale intervallo l’ingresso assume valore 1 e lo mantiene per due periodi di clock consecutivi, l’uscita passa da 0 ad 1 e rimane tale finchè una transizione di x1 da 1 a 0 riporta a 0 anche l’uscita. In tutti gli altri casi l’uscita rimane a zero. Progettare il circuito facendo uso di flip-flop JK. - 174 - Capitolo 6 RETI SEQUENZIALI MODULARI 6.1 - Registri Con il nome di registri si indicano circuiti sequenziali, per lo più sincronizzati, la cui funzione è quella di memorizzare informazione. In generale un registro è costituito da un insieme di n elementi di memoria binari, riferiti con gli interi tra 0 ed n-1, ed è quindi in grado di mantenere l’informazione che può essere rappresentata con n bit. Gli n elementi di memoria costituiscono la parola del registro ed n è la sua lunghezza. In un registro, oltre a segnali di ingresso (dati di ingresso) e a segnali di uscita (dati di uscita), esistono un certo numero di segnali di controllo e di temporizzazione che vengono inviati a tutti gli elementi contemporaneamente; il numero e le funzioni dei segnali di controllo dipendono dal tipo di registro, come ne dipendono le operazioni che possono essere effettuate sui dati memorizzati; si possono così avere segnali di caricamento in parallelo (load) o in serie (serial in), di abilitazione (enable o select), di azzeramento del contenuto (clear); i segnali di temporizzazione si riducono in genere al clock. A seconda degli elementi costituenti, un registro potrà essere trasparente o non trasparente; la Fig. 6.1 riporta uno schema a blocchi generale: On-1 O1 O0 In-1 I1 I0 segnali di controllo e di temporizzazione Fig. 6.1 In relazione al tipo di operazione che è possibile effettuare sui dati, si distinguono due - 175 - categorie fondamentali di registri: i registri paralleli ed i registri di traslazione o registri di scorrimento (shift registers). 6.1.1 - Registri paralleli I registri di questo tipo sono caratterizzati dal fatto che tutti i bit sono sottoposti insieme alle stesse operazioni, indipendentemente dalla posizione che ciascuno occupa nel registro. Le operazioni possibili sono la scrittura nel registro e la lettura del contenuto; in una scrittura, i dati presenti sui terminali di ingresso vengono memorizzati nel registro tutti nello stesso istante, ossia in parallelo, in una lettura sono resi disponibili sui terminali di uscita, pure in parallelo. Come elementi di memoria sono in genere utilizzati latch o flip-flop D o JK di tipo sincronizzato. Lo schema di principio è illustrato nella Fig. 6.2. In scrittura, supponiamo che il segnale a livelli load sia 0: in tal caso l’uscita di entrambe le porte AND sugli ingressi di ciascun flip-flop sono 0 ed i flip -flop stessi mantengono il loro stato. Se invece il segnale load è 1, all’ingresso J di ogni flip-flop è applicato il bit corrispondente del dato I, mentre all’ingresso K è applicato il complemento di tale bit: il flip-flop si trova in condizione di effettuare un’operazione di set o di reset a seconda che il bit ad esso applicato valga 1 oppure 0: in ogni caso memorizza tale bit in corrispondenza dell’impulso di clock. Per effettuare un’operazione di lettura, il segnale oe (output enable), applicato in parallelo sulle uscite di tutti i flip-flop, viene posto ad 1 e ciò determina l’attivazione delle “porte” rappresentate nella figura con dei quadratini le quali rendono il dato memorizzato nei flip-flop disponibile sulle uscite corrispondenti, immediatamente nel caso di dispositivi trasparenti, al successivo impulso di clock nel caso di flip-flop master-slave. On-1 O1 O0 Qn-1 Q1 Q0 Jn-1Kn-1 J1 oe clear K1 J0 K0 clock load In-1 I1 I0 Fig. 6.2 Le porte controllate dal segnale oe sono dispositivi speciali detti porte 3-state, che non implementano alcuna funzione logica, ma consentono o impediscono il propagarsi di un - 176 - segnale dall’ingresso all’uscita, comportandosi come una specie di interruttori comandati da un segnale di controllo (Fig. 6.3); il loro uso rende un dispositivo digitale dotato di alta impedenza sull’uscita. Simbolo circuitale ingresso 0 1 Simboli logici uscita ingresso uscita ingresso controllo controllo uscita controllo Fig. 6.3 Le porte 3-state sono molto utilizzate nei circuiti digitali, principalmente per due scopi: a) realizzare funzioni di OR cablato, cioè soluzioni circuitali in cui una linea di uscita è fisicamente collegata a più linee di ingresso, di una sola delle quali può di volta in volta assumere il livello di segnale: per ottenere ciò occorre che tutte, tranne quella alimentante, possano essere poste in alta impedenza. b) Realizzare linee bidirezionali, ossia linee sulle quali possano essere istradati tanto segnali di entrata quanto di uscita (Fig. 6.4): OR cablato linea bidirezionale Fig. 6.4 In pratica le porte 3-state possono anche non essere elementi circuitali fisicamente distinti, ma è molto più comune che la funzione di alta impedenza sull’uscita sia realizzata direttamente sul componente che ne deve essere dotato (talvolta invece di alta impedenza si parla di open-collector, in riferimento ad una particolare tecnica costruttiva dei dispositivi digitali: elettronicamente c’è differenza tra alta impedenza e oper collector, ma dal punto di vista logico si possono considerare equivalenti). Infine il segnale clear, asincrono rispetto al clock come il segnale load, determina l’azzeramento del contenuto del registro, indipendentemente dal dato presente in ingresso. Le realizzazioni pratiche possono differenziarsi da questo schema per il numero di segnali di controllo e per il modo come essi sono utilizzati; per esempio il segnale clear può mancare; i segnali load, clear, oe possono essere attivi quando valgono 0 e così via; inoltre può essere presente un ulteriore segnale a livelli detto select il quale, in AND con il load, abilita o meno il registro: la sua funzione in una struttura multiregistro è quella di effettuare una selezione del registro o dei registri di volta in volta abilitati ad operare. - 177 - 6.1.2 - Registri di traslazione Questi registri, detti anche shift registers o registri seriali, sono caratterizzati dal fatto che l’ingresso del dato è seriale, dal bit meno significativo (registri di traslazione sinistra) o da quello più significativo (registri di traslazione destra); anche l’uscita è in genere seriale, dal bit più significativo o da quello meno significativo nei due casi, ma non mancano realizzazioni di registri di traslazione con uscite parallele. Ad ogni impulso di clock la configurazione binaria memorizzata nel registro viene fatta traslare rispettivamente verso sinistra o verso destra di un bit, mentre il bit più (o meno) significativo viene perduto e quello meno (o più) significativo assume il valore del bit presente in ingresso. Se il registro è lungo n bit occorrono n impulsi di clock per sostituire completamente il dato memorizzato con un altro. Per esempio consideriamo un registro di traslazione sinistra lungo quattro bit, contenente inizialmente 1011 e sia 0110 il dato che deve esservi caricato; l’operazione è descritta nella seguente figura: situazione iniziale 1 0 1 1 0 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 1 1 0 1 0 primo impulso 1 0 secondo impulso 1 terzo impulso 1 0 quarto impulso 1 0 1 Fig. 6.5 Normalmente uno stesso registro può effettuare sia traslazioni destre sia traslazioni sinistre, a seconda del valore di un segnale di controllo right/left (per esempio R/L = 0 ≡ traslazione destra, R/L = 1 ≡ traslazione sinistra), mentre un segnale serial-in, logicamente equivalente al segnale load dei registri paralleli, abilita l’operazione. Questo modo di funzionamento è reso possibile connettendo l’uscita di un flip-flop all’entrata del flip-flop immediatamente a destra o a sinistra rispettivamente per lo shift destro o sinistro, mentre l’ingresso del flip-flop più significativo è l’ingresso esterno e l’uscita di quello meno significativo l’uscita seriale esterna o viceversa a seconda che si tratti di uno shift destro o sinistro. La Fig. 6.6 mostra uno schema di principio: - 178 - O clear Qn-1 Q1 Q0 Cn-1Dn-1 C1 D1 C0 D0 serial-in clock R/L I Fig. 6.6 Come si può vedere, il segnale serial-in inibisce l’arrivo del clock quando è 0, impedendo qualunque operazione del registro. Quando invece serial-in è 1, il segnale R/L, che agisce come segnale di controllo del multiplexer formato dalle n terne di porte AND e OR, sceglie se il dato I deve essere caricato dal bit meno significativo e corrispondentemente il dato di uscita O prelevato dal bit più significativo o viceversa. Nelle realizzazioni pratiche le funzioni di registro seriale e di registro parallelo si trovano spesso combinate insieme nello stesso componente, il quale può costituire un registro con ingresso seriale e/o parallelo ed uscita pure seriale e/o parallela, il quale viene indicato con il nome di registro universale. La Fig. 6.7 illustra un registro universale a quattro bit. I3 I2 I1 I0 D1 3 1 2 0 D0 SR MUX0 D2 3 1 2 0 MUX1 3 1 2 0 MUX2 D3 MUX3 S1 S2 3 1 2 0 SL clock Q3 Q2 Q1 - 179 - Q0 Fig. 6.7 Gli elementi di registro sono latch o flip-flop D, contrassegnati con D0, D1, D2, D3, ed i loro ingressi sono ottenuti dall’uscita di altrettanti multiplexer, controllati dai segnali S1 ed S2, i quali operano secondo la seguente tabella: S1, S2 00 nessuna operazione 01 shift left: D0 ← SL 1 0 shift right: D3 ← SR 1 1 caricamento parallelo 6.2 - Memorie di lettura-scrittura (RAM) Una RAM (Random Access Memory) è un dispositivo costituito da N elementi binari di memoria, organizzati in M gruppi o locazioni di n elementi ciascuno, in modo che sia N = M×n. Ogni locazione è in grado di memorizzare l’informazione che può essere codificata con n bit, ossia con una parola di n bit ed è individuata da un indirizzo numerico nell’intervallo [0, M-1]. L’accesso ad una locazione avviene in modo indipendente dalla posizione della locazione stessa e in tempo costante: da qui deriva l’appellativo di memoria ad accesso casuale, che a rigore competerebbe anche alle ROM, pur non essendo per esse utilizzato. Le quantità M ed n sono dette rispettivamente capacità della memoria e lunghezza della parola; la capacità è misurata correntemente in migliaia o milioni di parole, per lo più aventi una lunghezza di 8 bit (byte), utilizzando suffissi moltiplicativi quali K (chilo), 1K = 210 ≈ 103, M (mega), 1 M = 220 ≈ 106, G (giga), 1G = 230 ≈ 109. La lunghezza di parola è espressa per lo più in multpli di byte. Per esempio con il termine RAM 128K×8 si fa riferimento ad una memoria RAM di 128×210 = 131072 parole da 8 bit. Le operazioni che possono essere compiute su una RAM sono la lettura, ossia la generazione di una copia del contenuto di una locazione e la scrittura, ovvero la modifica distruttiva del contenuto di una locazione. Per questo la RAM è provvista di un opportuno numero di linee di ingresso, di uscita e di linee bidirezionali, alcune delle quali servono per segnali di controllo, altre per i dati. La struttura interna è formata da una matrice M×n di elementi di memoria, di solito latch asincroni, e da altri circuiti combinatori di controllo e di decodifica (Fig. 6.8). Le linee denominate address, in numero pari a ⎡log2M⎤, definiscono gli indirizzi delle locazioni di memoria; esse sono decodificate internamente in modo da generare, per ogni indirizzo, un segnale di selezione di tutti i latch della locazione avente quell’indirizzo. Il segnale S (select) ha il compito di selezionare l’intero dispositivo, in modo da renderlo operativo; la scelta del tipo di operazione è invece effettuata con il segnale WE (write enable); - 180 - address S WE OE circuiti di controllo e di decodifica per esempio WE = 1 può significare un’operazione di scrittura, WE = 0 una lettura o viceversa. matrice M×n data in/out Fig. 6.8 Uno schema di principio per l’organizzazione interna di una RAM è mostrato in Fig. 6.9, limitatamente ai bit della locazione i-esima: S 0 A0 i Ak-1 S Q S Q R R M-1 WE OE Dn-1 D0 Fig. 6.9 Il segnale S abilita il dispositivo, consentendo o inibendo l’arrivo del segnale di selezione della riga i-esima, generato dal decodificatore degli indirizzi: il segnale WE definisce il tipo di operazione mentre il segnale OE controlla lo stato di alta impedenza delle uscite dei latch. Durante il ciclo di scrittura WE viene posto ad 1 ed OE a 0, per cui le uscite dei latch sono in alta impedenza ed i segnali presenti sulle linee dei dati D0, …, Dn-1 possono essere memorizzati nei rispettivi latch. Invece durante il ciclo di lettura WE vale 0 in modo che gli ingressi dei latch sono inibiti; OE è posto ad 1 e consente che le uscite dei latch siano collegate alle linee dei dati. In assenza di selezione della locazione i-esima, gli ingressi dei latch sono tutti a 0 e pertanto la configurazione memorizzata nella locazione si mantiene. Si definisce tempo di accesso l’intervallo che intercorre tra l’istante in cui l’indirizzo viene presentato sulle line A e l’istante in cui il dato è disponibile sulle linee di uscita; esso è in genere lo stesso anche per il ciclo di scrittura, per cui non si fa distinzione tra lettura e lettura. Valori tipici del tempo di accesso sono intorno a 100÷200 ns per memorie di capacità variabile da 64 - 181 - Kbyte a 1 Mbyte. Il tempo di ciclo invece è il tempo che occorre attendere dall’inizio di un’operazione prima di potere dare inizio ad un’altra operazione; in genere coincide con il tempo di accesso, ma può essere anche superiore ad esso, in quanto a definirlo concorrono ritardi aggiuntivi, non strettamente legati all’operazione effettuata. Le memorie RAM basate su latch sono dette statiche, dal momento che l’informazione una volta memorizzata non ha più bisogno di essere manipolata, ma rimane inalterata finchè il dispositivo è alimentato. Sono molto comuni anche RAM dinamiche, nelle quali per conservare l’informazione si sfrutta una carica elettrica immagazzinata nella capacità di canale di un transistore MOS. Le memorie dinamiche sono preferibili in quanto consentono una densità, intesa come rapporto tra capacità e superficie di silicio necessaria, molto elevata ed un costo più basso delle memorie statiche; per contro hanno l’inconveniente di richiedere periodicamente un ciclo di refresh che, dovendo essere intercalato alle normali operazioni con periodicità dell’ordine del millisecondo, provoca un aumento del tempo di ciclo rispetto alle memorie statiche. Qualunque sia il tipo di celle usate come elementi di memoria, in genere esse sono organizzate in forma di matrice per due ragioni principali: a) una disposizione fisica (layout) secondo un array rettangolare facilita la stesura dei collegamenti tra le celle e la circuiteria di controllo, in quanto consente di allocarli negli spazi tra una cella e l’altra. b) L’indirizzo di una cella, Ai, può essere partizionato in d componenti, che costituiscono un vettore a d dimensioni (Ai1, Ai2, ..., Aid). Ogni componente viene decodificata da un decodificatore separato, che pertanto ha dimensioni e complessità ridotte e al tempo stesso maggiore velocità. La cella di indirizzo Ai viene selezionata attivando simultaneamente tutte le d uscite dei decodificatori, ossia per coincidenza di d segnali di indirizzamento. La più semplice organizzazione ad array è quella unidimensionale, illustrata in Fig. 6.10 per una memoria di M celle: ADDRESS DECODER C0 C1 CM-1 Fig. 6.10 Assai comunemente, specie quando la capacità della memoria è elevata, si usa un layout a due dimensioni, organizzando le celle in una matrice di Mx righe ed My colonne, in modo che Mx×My= M. A sua volta l’indirizzo è diviso in due componenti dette componente di riga ax = ⎡log2Nx⎤ e componente di colonna ay = ⎡log2Ny⎤, ed una cella è selezionata per coincidenza di due segnali X ed Y ottenuti dalla decodifica delle componenti di riga e di colonna. Questa - 182 - organizzazione consente una riduzione non indifferente delle dimensioni del bus degli indirizzi e della circuiteria di accesso rispetto al caso unidimensionale. Infatti se Mx = My ≅ Μ1/2, invece di un decodificatore ⎡log2M⎤×M, ed M amplificatori di pilotaggio sono necessari soltanto due decodificatori ⎡log2M⎤×Μ1/2 e 2Μ1/2 amplificatori. La Fig. 6.11 schematizza questo tipo di X - BUFFER X - D E C O D ER ROW ADDRESS organizzazione. C0,0 C0,1 C0,My-1 C1,0 C1,1 C1,My-1 CMx-1,0 CMx-1,1 CMx-1,My -1 Y - BUFFER Y-DECODER COLUMN ADDRESS Fig. 6.11 Per esaminare la temporizzazione tipica delle memorie RAM, prendiamo in considerazione un componente commerciale assai diffuso, recante la sigla 4116. Si tratta di un chip di RAM dinamica da 16K parole da 1 bit, il cui schema a blocchi è riportato in Fig. 6.12 . Come si vede l’indirizzamento avviene per righe e per colonne tramite un unico bus indirizzi di 7 bit; pertanto sia l’indirizzo di riga sia quello di colonna devono essere memorizzati in appositi buffer, essendo presentati in tempi successivi; la caratterizzazione di un indirizzo come indirizzo di riga o di colonna avviene tramite i segnali di selezione RAS (Row Address Select) e CAS (Column Address Select) e la logica di controllo, alla quale arriva anche il segnale R/W per la specifica dell’operazione; D è il dato di ingresso: esso viene memorizzato in un registro (data in), separato dal registro MDR che è utilizzato solo come registro di uscita. Questo dispositivo di memoria consente vari modi di operazione, dei quali esamineremo solo il modo read, il modo write ed il modo read modify-write. I tempi di ciclo dell’operazione read modify-write, che è la più lunga, vanno da 375 ns a 515 ns, a seconda delle versioni. - 183 - 1/2 decoder di riga Logica di sincronizzazione e di controllo buffer di riga A0....A6 RAS CAS R/W D 1/2 array di celle 1/2 decoder di colonna amplificatori di sense e di refresh 1/2 decoder di colonna 1/2 decoder di riga buffer di colonna data in buffers M D R 1/2 array di celle Fig. 6.12 Il diagramma temporale del ciclo di lettura è mostrato in Fig. 6.13. Quando il segnale RAS scende a zero, l’indirizzo di riga viene memorizzato nei buffer di ingresso e viene abilitato il decodificatore di riga; con un ritardo non inferiore a tRLCL, entro il quale l’indirizzo di colonna deve essersi stabilizzato, anche il segnale CAS scende a zero, provocando la memorizzazione dell’indirizzo di colonna e l’attivazione del relativo decodificatore. Prima dell’azzeramento di CAS, il segnale di lettura/scrittura sale ad uno e dopo un tempo di accesso ta(C), misurato dalla caduta di CAS, il dato letto diventa valido in uscita e rimane tale per un tempo tPXZ dal momento della risalita di CAS; il RAS risale per ultimo e deve rimanere alto per un tempo minimo tw(RH). La somma dei ritardi tw(RL) e tw(RH) determina la durata del ciclo di lettura tc(r). Nei diagrammi le zone tratteggiate hanno il significato di valori di segnale non significativi. - 184 - tc(r) RAS tw(RL) tw(RH) CAS tRLCL ADDRESS riga colonna R/W ta(C) DATA OUT alta impedenza dato valido Fig. 6.13 Nell’operazione di scrittura, la temporizzazione dell’indirizzamento è analoga a quella del ciclo di lettura (prima viene memorizzato l’indirizzo di riga, poi quello di colonna); quello tra i due segnali CAS e R/W che viene fatto cadere per primo determina l’acquisizione del dato nel registro-buffer data in, in modalità early write operation o write operation rispettivamente; il dato non può cambiare prima di un ritardo tH(DRL) dalla caduta di RAS. Il tempo di ciclo è ancora determinato dal periodo del CAS. Il diagramma temporale è illustrato in Fig. 6.14a. Infine l’operazione read modify-write consiste in una lettura seguita da una scrittura allo stesso indirizzo, che pertanto deve essere selezionato solo una volta, con risparmio di tempo. Le due operazioni sono eseguite su controllo del segnale R/W: quando esso cade viene letto il dato con ritardo ta(C) dalla caduta di CAS; quindi, mentre il dato rimane valido in uscita, R/W diventa alto, consentendo l’acquisizione nel registro data in del dato in ingresso (Fig. 6.14b). - 185 - tc(w) a) RAS tw(RL) tw(RH) CAS ADDRESS riga colonna R/W DATA IN dato valido tc(w) b) RAS tw(RL) tw(RH) CAS ADDRESS riga colonna R/W DATA IN dato valido ta(C) DATA OUT alta impedenza dato valido Fig. 6.14 6.3 - Contatori Effettuare un’operazione di conteggio in un campo numerico di n cifre in base β significa incrementare di una unità per volta il valore del numero in esso rappresentato. Partendo da 0 e operando secondo le regole dell’aritmetica in base, dopo βn incrementi, il numero ha un valore pari a βn-1 ed è rappresentato da una sequenza di n cifre tutte uguali a quella che rappresenta - 186 - il valore numerico β-1; un ulteriore incremento di una unità provoca l’azzeramento del campo e la generazione di un riporto in posizione n+1: poichè il campo di rappresentazione ha n posizioni, il conteggio è modulo βn, ovvero è possibile contare da 0 fino a βn-1, per ripartire poi da 0 in modo ciclico. Se il campo è binario, il conteggio è modulo 2n ed un dispositivo in grado di effettuarlo è un contatore binario ad n stadi. Come è stato visto a suo tempo, il flip-flop T è un circuito sequenziale caratterizzato dal fatto che il suo stato cambia ogni volta che viene applicato un impulso all’ingresso di sincronizzazione, mentre l’ingresso T è 1: esso è intrinsecamente un elemento di contatore binario ad uno stadio; pertanto c’è da aspettarsi che in generale un contatore ad n stadi sia realizzabile con n flip-flop T, pur non escludendo la possibilità di utilizzare anche latch o altri flip-flop, in particolare i JK. Oltre a contare il numero di impulsi di ingresso e a memorizzare un numero che rappresenta il valore del conteggio effettuato, un contatore può realizzare anche altre importanti funzioni: 1) può generare un treno di impulsi derivati da impulsi di ingresso, ma a frequenza più bassa, ossia può effettuare divisioni di frequenza; 2) può fornire una sequenza di stringhe binarie da usare in varie applicazioni quale l’indirizzamento di una memoria. 6.3.1 - Contatori sincroni Affrontiamo il problema della sintesi di un contatore osservando che se n è il numero di stadi è naturale identificare gli stati di uscita, che possono essere codificati con le 2n combinazioni di n variabili logiche, con gli stati interni, aderendo quindi al modello di Moore di macchina sequenziale; con riferimento al caso di n = 3, senza che peraltro questo pregiudichi la generalità della trattazione, si ricava immediatamente il grafo degli stati riportato in Fig. 6.15: 0 000 0 1 001 0 1 010 0 1 0 011 1 100 0 1 101 0 1 110 0 1 111 1 Fig. 6.15 Sviluppando da questo il procedimento di sintesi di una rete sequenziale sincronizzata, e tenendo conto dell’utilizzo di flip-flop T sincronizzati quali elementi di memoria, si ottengono le seguenti equazioni caratteristiche del contatore, il quale è detto sincrono per indicare il fatto che tutti i flip-flop sono impulsati insieme: - 187 - T0 = x, T1 = y0x, T2 = y1y0x = y1T1 In generale per lo stadio i-esimo avremo: Ti = yi-1yi-2…y0x = yi-1Ti-1 avendo indicato con x il segnale applicato all’ingresso T del flip-flop di ordine più basso. Riferendoci al caso esemplificato, la Fig. 6.16 mostra le due possibili realizzazioni, ottenute sulla base delle equazioni caratteristiche sopra ricavate, che mettono in evidenza come la commutazione del flip-flop i-esimo avvenga quando tutti i precedenti si trovano nello stato 1 ed arriva un impulso in ingresso; in a) è schematizzata la versione con riporto parallelo, in b) quella con riporto seriale. Nella prima versione, poichè ogni flip-flop può commutare quando tutti gli ingressi della rispettiva porta AND sono 1, la frequenza di conteggio è indipendente dal numero degli stadi ed è data dall’espressione: 1 f ≤ --------------t ff + t g dove tff e tg sono rispettivamente il tempo di risposta di un flip-flop e di una porta logica. D’altra parte però lo stadio i-esimo richiede una porta AND con i ingressi e ciò può costituire un limite realizzativo se il numero degli stadi è abbastanza elevato. Q1 Q0 Q2 C2 T2 C1 T1 C0 T0 x Q2 Q1 C2 T2 C1 T1 a) Q0 C0 T0 x b) Fig. 6.16 Viceversa nella versione con riporto seriale, le uscite dei vari flip-flop, che concorrono a - 188 - determinare la commutazione dello stadio i-esimo, devono attraversare un numero di porte AND crescente con la distanza da i, fino ad un massimo di n-1 porte per l’uscita dallo stadio più significativo; pertanto la frequenza di conteggio diminuisce al crescere del numero degli stadi secondo la legge: 1 f ≤ -------------------------------t ff + ( n – 1 )t g ed è generalmente più bassa di quella di un contatore con riporto parallelo; in compenso ogni porta AND ha soltanto due ingressi. Secondo gli schemi della Fig. 6.16, di fatto il segnale che provoca l’avanzamento del conteggio è il clock, mentre il segnale x ha la funzione di segnale di abilitazione (x = 1) o di disabilitazione (x = 0); se questa funzione non è richiesta, x è tenuto fisso ad 1, per cui è sufficiente applicarlo all’ingresso T0, eliminando di conseguenza la porta AND tra il primo ed il secondo stadio in entrambi gli schemi e riducendo di uno il numero di ingressi alle altre porte AND nello schema a). La Fig. 6.17 mostra le forme d’onda delle uscite Q0, Q1 e Q2, supponendo che i flip-flop commutino sul fronte in salita del clock: clock Q0 Q1 Q2 0 1 2 3 4 5 6 7 0 Fig. 6.17 6.3.2 - Contatori ripple-carry o asincroni La forma più semplice di contatore binario è quella indicata nello schema di Fig. 6.18 per n = 3, basato sull’uso di flip-flop T asincroni eccitati sul fronte in discesa dell’ingresso; poichè la commutazione di ogni flip-flop, a parte il primo, è dovuta al fronte che si genera sull’uscita del flip-flop precedente, questo contatore viene detto ripple carry (a propagazione del fronte del riporto) o anche asincrono, in relazione al fatto che i vari stadi cambiano stato in tempi diversi, in conseguenza della propagazione sequenziale del fronte del riporto. - 189 - Q2 Q1 Q0 T1 ∧ T2 ∧ T0 ∧ x Fig. 6.18 Le forme d’onda delle uscite di questo contatore sono dettagliate nella Fig. 6.19: x Q0 Q1 Q2 0 1 2 3 4 5 6 7 0 Fig. 6.19 Se l’eccitazione di ogni flip-flop oltre al primo viene prelevata dall’uscita complementata Qi del flip-flop precedente anzichè da quella affermata come in Fig. 6.19, si ottiene un contatore ripple carry asincrono decrementante. Lo stesso comportamento si ottiene con flip-flop eccitati sul fronte in salita, prelevando il segnale di eccitazione di ciascuno, tranne il primo, dall’uscita complementata o da quella affermata del precedente, rispettivamente per un contatore incrementante o decrementante. Nella Fig. 6.20 le funzioni di conteggio per incremento e per decremento sono riunite nello stesso dispositivo, utilizzando in ingresso ai flip-flop successivi al primo dei multiplexer comandati da un segnale a livelli up/down; Q2 Q1 0 T∧2 up/down Q0 0 1 1 Q1 Q0 T1 T0 ∧ ∧ x Fig. 6.20 In molte situazioni ha interesse che l’uscita di un contatore non sia il numero binario che - 190 - rappresenta il suo stato interno, bensì un segnale su una di 2n linee, se n è il numero di stadi del contatore. Questo può essere ottenuto semplicemente decodificando le uscite di un contatore binario; tuttavia se si ricorre ad un contatore ripple carry, sulle uscite decodificate si possono presentare degli impulsi spurii (spikes) dovuti al modo caratteristico con cui in questo tipo di contatori avviene l’eccitazione dei vari stadi e ai ritardi interni di commutazione dei flip-flop. Ciò è evidenziato in Fig. 6.21, dove si vede per esempio che l’uscita decodificata Z1 = Q0Q1Q2 presenta, oltre al normale andamento, uno spike che la riporta ad 1 erroneamente. 0 1 2 3 4 5 6 7 Q0 Q1 Q2 Z2 = Q0Q1Q2 strobe Z1 Fig. 6.21 Poichè il problema degli spike è dovuto alla commutazione di due o più flip-flop, la soluzione consiste nel fare in modo che tutti i flip-flop cambino simultaneamente, ricorrendo a contatori sincroni a riporto parallelo, oppure nel far commutare solo un flip-flop per volta. Un’altra tecnica consiste nell’utilizzare un impulso, detto strobe, che attiva il decodificatore solo quando lo stato del contatore si è stabilizzato, come mostra la stessa Fig. 6.21. 6.3.3 - Contatori non binari Un limite dei contatori binari è il fatto che essi contano modulo una potenza di 2, mentre può essere necessario contare modulo un numero qualsiasi, soprattutto quando questi dispositivi sono usati come divisori di frequenza. Il problema può essere risolto sintetizzando un contatore modulo N, con N qualsiasi, secondo il consueto processo di sintesi delle reti sequenziali oppure, quando sia già disponibile un contatore binario con modulo 2n > N, creando connessioni opportune tra le sue uscite ed i suoi ingressi; in particolare nel caso di contatori con clear, si può generare un impulso di azzeramento mediante una porta AND ai cui ingressi sono applicate le uscite dei flip-flop che sono ad 1 per lo stato N. a) Per esempio un contatore modulo 5 sincrono con ingresso di abilitazione può essere realizzato in base al primo approccio secondo lo schema di Fig. 6.22d; b) In alternativa, supponendo di avere a disposizione un contatore binario sincrono dotato di reset asincrono, si può ricorrere alla soluzione di Fig. 6.23. - 191 - 0 000 0 1 0 1 001 010 0 1 0 1 011 1 a) x 1 y2,y1,y0 0 000 000 001 001 000 011 010 000 001 011 000 111 100 000 100 101 ××× ××× 110 ××× ××× 111 ××× ××× 0 1 000 000 001 001 001 010 010 010 011 011 011 100 100 Q2 100 100 000 b) Q1 Q0 C2 T 2 C1 T1 C0 T0 T0 = xy2 T1 = xy0 T2 = xy2+xy0y1 = xy2+T1y1 x d) T2, T1, T0 c) Fig. 6.22 Q2 Q1 Q0 R C2 T2 R C1 T1 R C0 T0 1 Fig. 6.23 Un’altra situazione frequente è quella nella quale è richiesto un contatore che percorra una sequenza di stati diversa da quella naturale; in questi casi si può usare un contatore binario con una rete combinatoria sulle uscite che converta dalla sequenza naturale a quella richiesta, oppure si può progettare un contatore in grado di fornire direttamente tale sequenza. Un tipico caso è quello di un contatore BCD, il quale percorre una sequenza di dieci stati corrispondenti alle cifre decimali codificate in binario; la Fig. 6.24 riporta lo schema di un contatore di tal - 192 - genere, per il quale si utilizzano flip-flop JK: Q3 Q2 Q1 Q0 J3 J2 J1 J0 K3 K2 K1 K0 1 Fig. 6.24 6.3.4 - Contatori ad anello Utilizzando registri di traslazione è possibile realizzare altre famiglie di contatori che, pur non avendo un numero di stadi minimo in rapporto al modulo (il numero di stati è uguale al numero di stadi), tuttavia hanno caratteristiche interessanti per quanto riguarda la facilità di disporre delle uscite decodificate; sono detti genericamente contatori a traslazione e comprendono in particolare i contatori ad anello (ring counters). Un esempio di contatore ad anello a cinque stadi è mostrato in Fig. 6.25; consiste in un registro di shift a cinque bit nel quale l’uscita più significativa è connessa all’ingresso meno significativo: Q4 Q3 Q2 Q1 Q0 D4 D3 D2 D1 D0 C4 R4 C3 R3 C2 R2 C1 R1 C0 S0 reset Fig. 6.25 I singoli stadi del registro sono flip-flop D sincronizzati, dei quali il meno significativo ha un ingresso di set, attraverso il quale è possibile scrivere 1 nel suo stato per inizializzare il contatore; lo stesso impulso serve ad azzerare tutti gli altri stadi, attraverso l’ingresso di reset dei rispettivi flip-flop. Si tratta di un contatore il quale percorre una sequenza ciclica di cinque stati nella quale un’uscita per volta viene posta ad 1; in altri termini le uscite sono direttamente decodificate. Tuttavia questo circuito presenta l’inconveniente di poter entrare in una sequenza ciclica spuria, se a causa di disturbi viene assunto uno stato non previsto, contenente più di un 1. Per questo, come è stato detto, necessita di essere posto in uno stato iniziale valido. Per rimediare all’inconveniente si usa uno schema modificato come quello di Fig. 6.26, nel quale una porta - 193 - AND genera il termine Q3Q2Q1Q0 (in generale per n stadi il termine Qn-2 … Q0) che costituisce l’ingresso dello stadio meno significativo e vale 1 quando tutti gli stadi tranne il più significativo che non interessa sono a 0. In questo modo se il contatore entra in uno stato spurio all’uscita della porta AND si presenta 0 per n-1passi: a quel punto tutti gli ingressi della porta AND sono 1 e pertanto il contatore ritorna automaticamente nella configurazione di partenza 0...01 valida: si tratta di un contatore autocorrettore e autoinizializzante; per esempio se lo stato spurio è 01011, viene realizzata la sequenza: 01011, 10110, 01100, 11000, 10000, 00001. Q4 Q3 D4 C4 Q2 D3 C3 Q1 Q0 D2 C2 D1 C1 Fig. 6.26 - 194 - D0 C0 ESERCIZI 1) Progettare un contatore binario che conta per tre modulo 8. 2) Un contatore binario a tre stadi con clear possiede un ingresso di controllo x che agisce nel modo seguente. Quando x = 0, il contatore conta secondo la sequenza 0, 1, 2, ..., 7, 0, ...; quando x = 1 conta secondo la sequenza 0, 2, 4, 6, 0, ... Realizzare il contatore. 3) Progettare un contatore decadico BCD, ovvero cun contatore che fornisce in uscita il codice 8-4-2-1 degli interi decimali 0 ... 9. 4) Sintetizzare un circuito contatore a tre stadi che percorre ciclicamente la sequenza 0 1 2 3 4 5 6 7 6 5 4 3 2 1 0 1 2 ... , utilizzando nel progetto flip flop JK. 5) Si vuole realizzare un registro universale a quattro bit utilizzando come elementi di memoria dei flip-flop JK. Il registro deve possedere le seguenti funzionalità: • azzeramento; • ingresso parallelo; • shift logico sinistro/destro (coinvolge tutti i bit); • shift aritmetico sinistro/destro (lascia inalterato il bit più significativo); • rotazione logica sinistra/destra. Progettare una rete combinatoria per il controllo delle funzionalità del registro. 6) Progettare una rete combinatoria da accoppiare ad un registro R ad n bit come illustrato in figura, in modo da farlo funzionare in uno dei seguenti modi: 1) contatore binario modulo n, sincrono con riporto seriale; 2) Ri mod n ← R(i-1) mod ni = 0, ..., n-1; 3) contatore ad anello autoinizializzante. Istanziare l’esercizio nel caso n = 4 e nell’ipotesi che i flip flop del registro siano di tipo JK. Jn-1 x Qn-1 Q1 Q0 Rn-1 R1 R0 Kn-1 J1 K1 Rete Combinatoria J0 K0 S0 S1 7) Progettare un registro R a quattro bit, realizzati con flip-flop SR, con le seguenti modalità di funzionamento: - 195 - 1) ingresso parallelo; 2) scorrimento circolare, secondo le specifiche: Ri ← Ri-2 e Ri-2 ← Ri, i = 3, 4 con Ri bit i-esimo del registro; 3) contatore ad anello autoinizializzante e autocorrettore. 8) Progettare un contatore modulo 7 con due ingressi di controllo s1 ed s2 tali che con s1 = 1 ed s2 = 0 viene precaricato con un valore arbitrario compreso tra 0 e 6; con s1 = 0 ed s2 = 0 viene percorsa una sequenza di conteggio decrescente a partire dal valore preimpostato; con s1 = 0 ed s2 = 1 viene percorsa una sequenza di conteggio crescente, sempre a partire dal valore preimpostato. 9) Progettare un contatore decimale con uscita BCD, il quale segue la sequenza di conteggio in verso crescente fino a 9, quindi al proseguire del conteggio, presenta sulle uscite una configurazione di tutti 1; il contatore deve essere riportato a 0 con un impulso di reset. 10) Si vuole progettare una struttura di conteggio che percorra ciclicamente la sequenza 0123 21 2345 43 4567 65 6701 07 ..., utilizzando un contatore binario up/down a tre stadi, un contatore modulo 6 ed un latch SR, oltre a consuete porte logiche. Disegnare lo schema logico della struttura richiesta. 11) Progettare una rete combinatoria da accoppiare ad un registro R ad n bit come illustrato in figura, in modo da farlo funzionare in uno dei seguenti modi: 1) contatore incrementante modulo 10; 2) registro di rotazione aritmetica verso sinistra: Ri ← Ri-1, i = 1, ..., n-2, R0 ← Rn-2, Rn-1 ← Rn-1; 3) registro di traslazione aritmetica verso destra di 2 bit (la traslazione aritmetica propaga verso destra il bit più significativo); 4) registro parallelo sull’ingresso Fare l’ipotesi che i flip-flop siano di tipo D; attenzione, questo implica che per la funzione di contatore occorre prendere opportuni provvedimenti. Qn-1 Q1 Q0 Rn-1 R1 R0 Dn-1 clock D1 Rete Combinatoria D0 S0 S1 12) Progettare un contatore modulo 13 in salita e modulo 15 in discesa. Il modo di conteggio è definito da una variabile a livelli m (m = 0, modo in salita e m = 1, modo in discesa). Il cambiamento del valore di m durante il funzionamento del contatore porta - 196 - quest’ultimo a seguire la sequenza di conteggio opposta a quella corrente, partendo dal valore raggiunto al momento della transizione di m. 13) Progettare un registro universale con le seguenti modalità di funzionamento: a) shift logico sinistro; b) shift aritmetico destro, con estensione del segno; c) contatore asincrono modulo 11 incrementante; d) contatore asincrono modulo 12 decrementante. 14) Progettare un contatore BCD a due cifre, ottenuto collegando opportunamente in cascata due contatori modulo 10, secondo lo schema di figura: Contatore delle decine Contatore delle unità logica di connessione - 197 - Capitolo 7 SISTEMI DI RETI SEQUENZIALI 7.1 - Introduzione Con il termine ASM (Algorithmic State Machine) si indica un sistema digitale in grado di realizzare uno o più processi di calcolo attraverso l’esecuzione di appropriate sequenze di operazioni che applicate a dati in ingresso producono come risultato nuovi dati in uscita. L’esempio più cospicuo e più comune di ASM è costituito dal processore di un sistema di elaborazione. Le operazioni che possono essere eseguite sono caratteristiche di ogni dato sistema (operazioni del sistema) e in genere sono indipendenti tra di loro, per cui le sequenze che si possono formare con esse sono virtualmente illimitate. Poichè il sistema non può decidere autonomamente quali operazioni eseguire ed in quale ordine, occorre fornire dall’esterno anche opportune direttive sotto forma di codici di operazione OP. Le direttive sono pertanto un tipo di informazione che gioca un ruolo diverso dai dati e viene detta informazione di controllo. Per evidenziare la differenza tra dati e controlli, assumeremo che i secondi siano introdotti nel sistema attraverso ingressi specifici, pur non essendo questa distinzione strutturale strettamente necessaria (Fig. 7.1). dati risultati codici di operazione ASM Fig. 7.1 - 199 - Nel seguito ci proponiamo di esaminare il modello sopra schematizzato, sia dal punto di vista strutturale, sia dal punto di vista del funzionamento. Per quanto riguarda il primo punto, poichè qualsiasi struttura logica è formata esclusivamente da reti combinatorie e sequenziali (registri), anche un’ASM deve essere costituita interconnettendo logica combinatoria e registri. Più precisamente, si tratta di un sistema di reti sequenziali, connesse in ciclo. Generalmente le reti componenti sono di tipo sincronizzato e assumeremo che tutti i registri siano impulsati insieme da un unico segnale di clock, il cui periodo definisce il tempo di ciclo T del sistema (Fig. 7.2), somma del tempo elementare TS, ossia l’intervallo tra due impulsi consecutivi durante il quale gli elementi di registro mantengono lo stato (latching), e della durata ∆M dell’impulso, durante il quale gli elementi di registro cambiano stato (enabling). TS ∆M T Fig. 7.2 In realtà la restrizione ad un unico segnale di clock, che tra l’altro implica l’uso di elementi di registro del tipo edge-triggered, non è assoluta, ma esistono anche sistemi per i quali viene utilizzato un clock a più fasi, ossia un insieme {ϕ1, ϕ2, …, ϕk} di k ≥ 2 segnali impulsivi periodici o fasi, dove ϕi è la i-esima fase, aventi tutti lo stesso periodo T. In ogni fase si distinguono ancora i due intervalli, l’uno attivo ∆M e l’altro passivo TS (figura 7.3). Il numero di fasi deve soddisfare la disuguaglianza k·∆M ≤ T. ϕ1 ϕ2 ϕk Ts ∆M Fig. 7.3 Per quanto riguarda le caratteristiche logico-funzionali, si distingue tra sistemi progettati per risolvere un problema o una classe limitata di problemi simili (sistemi special purpose) e sistemi previsti per una varietà virtualmente illimitata di problemi (sistemi general purpose). I primi sono caratterizzati completamente dagli algoritmi, in genere abbastanza pochi, la cui descrizione può costituire pertanto anche la descrizione completa del sistema stesso, purché si utilizzino strumenti descrittivi appropriati ad evidenziare sia il flusso dei dati che quello dei controlli e la loro interazione. Inversamente possiamo dire cge un’ASM speciale è la - 200 - realizzazione di uno o più algoritmi sotto forma di una struttura specializzata. Invece in un sistema general purpose gli algoritmi non sono implementati in strutture fisse, bensì sono organizzati sotto forma di liste ordinate di direttive o ordini (programmi) che determinano l’esecuzione di appropriate sequenze di operazioni del sistema. Risolvere problemi mediante programmi fatti eseguire da un sistema general purpose significa seguire un approccio software, adottando un esecutore universale di algoritmi, mentre il ricorso ad un sistema speciale costituisce una soluzione hardware. La soluzione software ha doti superiori di flessibilità e di economicità, essendo il costo totale ripartito su un numero elevatissimo di applicazioni, contro la maggiore velocità della soluzione hardware. Nel seguito esaminiamo come vengono eseguite le operazioni del sistema. 7.2 - Linguaggi di trasferimento tra registri Un’operazione consiste nell’eseguire una successione di azioni elementari dette micro-operazioni (µ-operazioni), ciascuna delle quali dura un tempo di ciclo e ha l’effetto di sostituire il contenuto di un registro o di più registri con il risultato prodotto da reti combinatorie o con il contenuto di altri registri o con dati esterni. Il cambiamento del contenuto (stato) di un registro viene descritto utilizzando linguaggi speciali per la descrizione dell’hardware o linguaggi RTL (Register Transfer Languages), il cui costrutto principale è la relazione di trasferimento, basata su un operatore detto operatore di trasferimento che ha la seguente sintassi: <identificatore di registro> ← <contenuto di registro> | <espressione> | <dato di ingresso> | <costante> L’identificatore di registro è un nome simbolico con il quale si fa riferimento ad un registro, mentre il contenuto di un registro è il dato in esso memorizzato, specificato dall’identificatore racchiuso tra parentesi quadrate: per esempio [R] significa il contenuto del registro R; inoltre, quando richiesto, si può fare riferimento al valore del singolo bit di un registro, facendo seguire il suo identificatore da un indice numerico, oppure a gruppi di bit facendo seguire l’identificatore del registro dagli estremi dell’intervallo di bit considerati tra parentesi angolate; per esempio R<0, 4> indica il gruppo dei cinque bit meno significativi del registro R. In taluni casi può essere utile adoperare un registro con scopi di indirizzamento degli elementi di tabelle, che possono essere realizzate con RAM o ROM, oppure di altri registri: scriveremo perciò relazioni del tipo M[R] ← [A] intendendo che la locazione della memoria M indirizzata mediante il contenuto del registro R viene scritta con il contenuto del registro A, oppure del tipo - 201 - A ← R[R1] con il significato il registro A viene aggiornato con il contenuto di uno dei registri appartenenti ad uno stesso gruppo e selezionati mediante R1. Una µ-operazione può essere descritta formalmente da una lista di relazioni di trasferimento che si ammette siano eseguite tutte simultaneamente. Per esempio la µ-operazione descritta a parole dalla frase «trasferisci nel registro A la somma del suo contenuto e del dato esterno D e trasferisci nel registro B il contenuto iniziale di A incrementato di 1» viene descritta nel linguaggio dalla seguente lista di relazioni di trasferimento, nella seconda delle quali [A] rappresenta correttamente il valore iniziale di A in virtù della simultaneità delle esecuzioni: A ← [A]+D, B ← [A]+1 L’esecuzione della lista di relazioni di trasferimento che forma una µ-operazione avviene nel tempo di ciclo del sistema in due passi: a) durante l’intervallo TS le parti combinatorie del sistema calcolano i valori delle espressioni scritte a destra dell’operatore di trasferimento; b) nell’intervallo ∆M in cui è presente l’impulso di sincronizzazione tali valori vengono scritti nei registri specificati a sinistra dell’operatore di trasferimento. Poichè tutti i registri sono impulsati insieme, è garantita la simultaneità dei trasferimenti. Inoltre dal momento che lo stesso designatore di registro può figurare a destra e a sinistra dell’operatore di trasferimento, è necessario garantire che l’uscita dei registri non cambi prima che l’impulso di sincronizzazione sia rimosso, in modo da realizzare un’effettiva separazione tra lo stato attuale (da cui dipende il valore dell’espressione nella parte destra della relazione di trasferimento) e lo stato successivo. Questo richiede che i registri siano realizzati mediante dispositivi di memoria non trasparenti. In un linguaggio RTL le espressioni coinvolgono costanti numeriche e/o logiche, dati esterni, registri, legati insieme da operatori logico-aritmetici, senza peraltro entrare nel merito della struttura delle reti che realizzano tali operatori. In altri termini il linguaggio generalmente non scende ai livelli di dettaglio propri dell’algebra della commutazione, ma rimane al livello dei componenti combinatori e sequenziali che sono stati definiti nella prima parte del corso come componenti «modulari» (Decodificatori, Selettori, ROM, PLA, Addizionatori, Moltiplicatori, Registri, Contatori, RAM, ecc.). 7.2.1 - Strumenti per la descrizione delle ASM Uno strumento molto utilizzato per la descrizione di un algoritmo, sia che lo si voglia tradurre in un programma, sia che lo si voglia realizzare in hardware, è il diagramma di flusso: si tratta di un grafo orientato su quale è possibile seguire il flusso dei dati e quello dei controlli utilizzando due tipi di nodi, detti rispettivamente blocchi operazione e blocchi decisione. Il diagramma di flusso, o diagramma ASM, è in grado tanto di evidenziare la struttura - 202 - logica del sistema quanto di esprimere in maniera precisa il concetto di sequenza di intervalli di tempo. In altre parole un diagramma ASM rappresenta compiutamente il comportamento sia del circuito (combinatorio o sequenziale) che esegue operazioni sui dati, sia di quello che controlla le operazioni sui dati secondo le direttive previste dall’algoritmo. La costruzione del diagramma di flusso costituisce il punto di partenza del progetto di un sistema e deve essere condotta con molta attenzione, cercando di evitare errori concettuali e ridondanze inutili che influenzerebbero negativamente la struttura da progettare le sue prestazioni. La difficoltà principale consiste nel definire un algoritmo per il problema in oggetto e nel formalizzarlo partendo dalla sua descrizione a parole. Invece la traduzione dell’algoritmo nel diagramma di flusso è un’operazione più semplice, se ci si attiene alle seguenti regole. Prima di tutto si osservi che un blocco operazione, indicato da un rettangolo, rappresenta sia una µ-operazione, costituita da una lista di relazioni di trasferimento simultanee e avente la durata di un tempo di ciclo, sia uno stato della ASM; un diagramma di flusso ASM descrive pertanto un algoritmo in modo tale che, dato lo stato attuale, lo stato successivo è determinato in modo non ambiguo dalle variabili di stato della macchina. Per esempio un algoritmo puramente sequenziale potrebbe essere descritto dal seguente diagramma (Fig. 7.4): stato 1 Oi stato 2 Oj stato 3 Ok Fig. 7.4 cui corrisponde la ripartizione del tempo tra i vari stati come indicato nella seguente figura: Stato 1 Stato 2 Stato 3 Fig. 7.5 Per comodità spesso in un blocco operazione non viene scritta per esteso la µ-operazione associata, ma il suo nome simbolico seguito dall’elenco dei registri destinatari dei trasferimenti che essa implica, per esempio Oi/R1, R2, …, Rk, mentre la lista delle relazioni di trasferimento viene scritta a parte. Un blocco decisione, che corrisponde allo statement condizionale if c then e1 else e2 oppure if c then e di un linguaggio di programmazione, è il tipo di nodo che consente di realizzare un salto condizionato e di uscire dalla stretta sequenzialità; in riferimento alla ASM, - 203 - esso realizza la situazione in cui lo stato successivo è determinato non soltanto dallo stato attuale, ma anche dal valore di una o più variabili di ingresso. Un blocco decisione è rappresentato con un rombo che contiene un’espressione logica, in generale funzione del contenuto dei registri R1, R2, …, Rk del sistema, del codice di operazione OP e dei dati di ingresso D, nella forma f(R1, R2, …, Rk, OP, …, D); il valore vero (T) o falso (F) di tale espressione determina la selezione di uno dei due punti di uscita dal blocco. Per esempio la figura 7.6 mostra un frammento di diagramma di flusso nel quale viene calcolato in un registro B il valore assoluto di un numero rappresentato in complemento a due e contenuto in un registro A: stato 1 F Αn−1=0 T B ← [A] stato 2 B ← [A]+1 stato 3 Fig. 7.6 In questo caso la ripartizione del tempo tra i vari stati della macchina è la seguente: F: Stato 1 Stato 2 Stato … T: Stato 1 Stato 3 Stato … Fig. 7.7 E’ fondamentale notare che un test non ha bisogno di un tempo di ciclo separato, ma che esso avviene in parallelo alla µ-operazione del blocco operazione che lo precede: vedremo in seguito che questo fatto ha forti conseguenze sulla struttura del sistema. In alternativa a quanto indicato nell’esempio di figura 7.6, un blocco decisione può essere contrassegnato con una variabile logica c, scrivendo separatamente l’espressione che ne definisce il valore in una relazione di traferimento del tipo c ← f(R1, R2, …, Rk, OP, …, D); in questo caso la variabile c è realizzata mediante un registro il cui ingresso è connesso all’uscita di una rete combinatoria che calcola l’espressione. Invece nel caso dell’esempio è l’uscita stessa delle rete combinatoria oggetto del test: questi due diversi approcci hanno un’importanza fondamentale nel definire la classe di sistemi che ne deriva: infatti l’approccio dell’esempio di - 204 - figura 7.6 definisce una macchina di Mealy, l’altro definisce una macchina di Moore. Può accadere spesso che si realizzi una molteplicità di scelte, a seguito delle quali devono essere eseguite µ-operazioni differenti; nel diagramma ciò si traduce nella presenza di un albero di decisione con un ingresso e più uscite, nel quale ogni scelta binaria è determinata dal valore di una variabile logica, secondo lo schema illustrato nella figura 7.8. T T x1 F ⇒ x2 F x1x2x3x4 TTT- TTF- TF-T TF-F F--- T x3 F T x4 F A A BC D B C D E E a) b) Fig. 7.8 In questi casi l’albero di decisione può essere sostituito da un blocco decisione complesso (che in un linguaggio al alto livello corrisponde ad uno statement tipo case), nel quale la condizione risulta costituita dal prodotto logico delle singole condizioni e le uscite, in numero pari alle foglie dell’albero, sono contrassegnate da una stringa di valori binari che codificano globalmente le scelte (Fig. 7.8b). Un esempio significativo di diagramma ASM è quello relativo alla moltiplicazione binaria; come sappiamo, dati due numeri naturali X ed Y di n bit, un algoritmo utilizzato per calcolarne il prodotto P è l’algoritmo di somme e traslazioni, basato sulla relazione: n–1 P = X ⋅ Y = ∑ Y ⋅ xj ⋅ 2 j (7.1) j=0 Essendo xj ∈ {0,1}, i termini Y·xj·2j sono nulli oppure sono uguali al moltiplicando Y traslato verso sinistra di j posizioni: il prodotto P viene calcolato come somma dei termini non nulli e per ragioni di semplicità possiamo pensare di effettuare le somme in maniera iterativa, partendo da 0 e addizionando ad ogni passo il moltiplicando al risultato parziale traslato di una posizione binaria verso destra; ai fini di ciascuna somma è infatti equivalente traslare il moltiplicando verso sinistra o il risultato parziale verso destra. Il risultato è espresso su 2n bit. Volendo definire una struttura hardware per la moltiplicazione, occorre individuare i registri e le reti combinatorie necessari, nonché le loro connessioni e contestualmente disegnare il diagramma di flusso che rispecchia l’organizzazione del moltiplicatore, definendo altresì le - 205 - µ-operazioni in termini dei registri di cui il moltiplicatore dovrà essere dotato. In accordo alla (7.1), la struttura del moltiplicatore può essere formata da un addizionatore parallelo di n+1 bit e da tre registri di n bit, di cui uno, denominato MD, contiene il moltiplicando e gli altri due, AC ed MQ, concatenati insieme e dotati di capacità di shift destro oltre che di ingresso e uscita paralleli, all’inizio dell’operazione contengono rispettivamente 0 ed il moltiplicatore, al termine la metà più significativa e quella meno significativa del prodotto. Infine un registro S contiene il bit più significativo di ciascuna somma parziale, che viene traslato nella posizione più significativa di AC. Il diagramma ASM e la lista delle µ-operazioni richieste per il moltiplicatore sono mostrati in Fig. 7.9, mentre la Fig. 7.10 descrive l’organizzazione dei registri e degli elementi di calcolo. O1/MD, S, AC, MQ, CC F stato 1 CC=0 V MQ0=0 V O3/S, AC, MQ, CC stato 2 F stato 3 O2/ S, AC O1: MD ← Y, S ← 0, AC ← 0, MQ ← X, CC ← 4 O2: AC ← [AC]+[MD], S ← cn O3: S_AC_MQi ← S_AC_MQi+1, S ← 0, CC ← [CC]-1 Fig. 7.9 Y MD S AC MQ P X Adder Fig. 7.10 - 206 - CC Di seguito è riportato un esempio di moltiplicazione per i numeri X = 13 ≡ 1101 e Y = 14 ≡ 1110, evidenziando il contenuto dei registri durante le varie µ-operazioni: µ-operazione MD S AC MQ CC 1110 0 0000 1101 4 0 1110 1101 4 MQ0 = 1: O2 0 0 1 0 1 0 0111 0011 0001 1000 0110 1011 0110 1011 1011 1101 1101 0110 3 2 2 1 1 0 O3 MQ0=0: O3 MQ0=1: O2 O3 MQ0=1: O2 O3 7.2.2 - Caratterizzazione O1 delle operazioni Le operazioni che devono essere eseguite da un sistema per la risoluzione di un problema sono definite inviando dall’esterno la lista dei codici operativi (in un sistema calcolatore questa lista costituisce il programma e può variare da un problema all’altro; in un sistema speciale la lista è fissa e realizzata in hardware). Il sistema deve essere in grado di esaminare e riconoscere ogni codice operativo OP in ingresso e di ordinare l’esecuzione dell’operazione corrispondente; alla fine dell’operazione corrente deve essere riconosciuto il codice successivo per dare luogo ad un’altra operazione e così via. L’attività che precede l’esecuzione di qualunque operazione viene detta decodifica dell’operazione ed è realizzata direttamente nella struttura del sistema. Le attività relative alla decodifica possono essere descritte nel diagramma di flusso mediante un blocco operazione contrassegnato con una µ-operazione il cui effetto è il trasferimento del codice operativo presente in ingresso al sistema in un registro OR (operation register) e da un blocco decisione complesso (o in alternativa da un albero di decisione) che, sulla base del contenuto di OR, attiva l’esecuzione dell’operazione appropriata. In alternativa si può fare a meno di memorizzare il codice operativo, dal momento che esso deve comunque rimanere presente in ingresso per almeno un tempo di ciclo dopo l’avvio del sistema o dopo il termine di ogni operazione. Abbiamo così due schemi possibili, illustrati in Fig. 7.11, nell’ipotesi semplificativa che il sistema esegua due sole operazioni. Le attività che complessivamente hanno luogo dalla successione delle singole operazioni che il sistema può eseguire dal momento in cui entra in attività al momento in cui si arresta consistono nell’alternanza di una fase di decodifica e di una fase di esecuzione di una delle operazioni specificate dal codice operativo. Perciò il diagramma di flusso complessivo del sistema si ottiene facendo seguire al blocco relativo alla decodifica quelli delle singole operazioni istruite dall’esterno in base all’algoritmo da eseguire e stabilendo un arco di richiusura dall’uscita di ciascuna operazione all’ingresso del diagramma di flusso (Fig. 7.12). - 207 - OR ← OP 1 1 [OR] OP 0 0 Fig. 7.11 Un diagramma di flusso ben strutturato deve rispettare alcuni vincoli: 1) esiste un solo ingresso da cui inizia il funzionamento e nessuna uscita; il sistema è sincronizzato con l’esterno in modo che quando viene eseguita un’operazione, il nuovo codice e i dati siano presenti in ingresso; decodifica dell’operazione oper. 1 oper. 2 oper. n Fig. 7.12 2) non possono esistere catene cicliche formate solo da blocchi decisione: un insieme interconnesso di blocchi decisione deve avere necessariamente una struttura aperta ad albero, oppure il ciclo deve essere interrotto con un blocco operazione caratterizzato dalla µ-operazione nulla O0 (No-operation, o NOP) che, lasciando inalterato il contenuto dei registri, ha il compito di dare un significato operativo al tempo di ciclo e di rendere definito lo stato il cui si porta la ASM per effetto della condizione che risulta vera; 3) se in un ciclo è presente come unico blocco operazione un blocco caratterizzato dalla µ-operazione nulla O0, deve esistere nel ciclo almeno un blocco decisione la cui condizione è funzione di informazioni esterne al ciclo, tipicamente di registri modificati da µ-operazioni esterne al ciclo. - 208 - La condizione 2) è soddisfatta per l’intero diagramma se lo è per ogni singola operazione e se la decodifica avviene con la memorizzazione del codice operativo. Se invece il codice operativo non viene memorizzato, ossia manca un registro che separi le entrate dalle uscite, ritardando queste ultime di un periodo di clock, possono sorgere cicli, anche se non sono presenti nei diagrammi delle singole operazioni, quando l’uscita di un singolo diagramma è collegata all’ingresso del diagramma totale (Fig. 7.13); ciò può rendere non definito lo stato della ASM al termine dell’operazione corrente. OP decodifica C O0 esecuzione O0 Oj/... Fig. 7.13 In questa situazione può trovarsi anche la sola porzione di diagramma di flusso relativa alla decodifica, qualora a certi codici operativi non corrisponda alcuna operazione, come indicato in figura; per esempio se un sistema ha 5 operazioni, occorrono tre bit per la loro codifica e pertanto a tre codici non corrisponde alcuna operazione. Anche in questi casi occorre rompere il ciclo inserendovi il blocco operazione della µ-operazione nulla. La condizione 3) infine è richiesta per impedire che il sistema rimanga permanentemente bloccato in un ciclo, senza poterne mai uscire (Fig. 7.14): O0 Oj/A A Fig. 7.14 - 209 - 7.3 - Modello generale del sistema La separazione logica tra flusso dei dati e flusso dei controlli e la loro interazione, che sono stati individuati a livello del diagramma di flusso, si riflette nella struttura implementativa del sistema e giustifica l’affermazione del paragrafo 7.1, secondo la quale un’ASM è un sistema formato da due reti sequenziali interconnesse. Infatti esso può essere diviso in due unità: un’Unità Operativa (UO) che esegue sui dati le operazioni attuate mediante sequenze di µ-operazioni; un’Unità di Controllo (UC) che comanda e dirige l’esecuzione delle operazioni. Questa distinzione comporta che l’intero sistema debba essere formato da due macchine sequenziali connesse in ciclo, secondo lo schema di Fig. 7.15: ingressi esterni UO Xr ≡ x1* x2* … xs* r = 1, …, q = 2s αk* ∈ {0, 1}, 1 ≤ k ≤ m xh* ∈ {0, 1}, 1 ≤ h ≤ s uscite esterne Oj ≡ α1*α2* … αm* UC Fig. 7.15 Le connessioni tra le due unità sono di due tipi: uno è costituito da un insieme di variabili binarie di controllo α1, α2, …, αm prodotte in uscita da UC e trasferite in ingresso ad UO; esse codificano le µ-operazioni Oj, j = 1, …, p che devono essere eseguite da UO in ciascun tempo di ciclo. I nomi delle µ-operazioni coincidono con i codici, in genere non binari, α1* α2* … αm* che le comandano; tra questi viene annoverato anche il codice O0 associato alla µ-operazione nulla. L’altro è un insieme di variabili binarie di condizione x1, x2, …, xs trasmesse come uscita da UO ad UC che definiscono il codice binario Xr, r = 1, …, q = 2s delle condizioni logiche in cui può trovarsi UO e che insieme allo stato interno di UC determina la scelta del codice operativo della prossima operazione da eseguire, nonchè lo stato successivo in cui UC si porterà nel prossimo tempo di ciclo. La parte di controllo UC ha dunque una doppia funzione: 1) generare il codice operativo della µ-operazione che deve essere eseguita da UO in ogni tempo di ciclo; 2) decidere la sequenza delle µ-operazioni che realizzano ogni operazione. Questa sequenza dipende in ogni tempo di ciclo dalle variabili di condizione e poichè queste sono funzione anche del contenuto dei registri di UO dopo ogni µ-operazione, la scelta operata da UC è influenzata dall’esito dell’ultima µ-operazione eseguita da UO. - 210 - Le informazioni esterne (dati e codici operativi) entrano in UO dagli ingressi esterni e i risultati dell’elaborazione (contenuti in registri di UO) sono resi disponibili attraverso le uscite esterne. I codici operativi, se non sono memorizzati nel registro OR di UO, attraversano UO senza modifiche e si presentano all’ingresso di UC codificati da un sottoinsieme delle variabili di condizione: nello schema di Fig. 7.15 si nota una leggera differenza, peraltro inessenziale, rispetto a quello di Fig. 7.1. Inoltre, in riferimento ai due modelli di macchine sequenziali e al fatto che in un sistema di reti sequenziali non possono esistere cicli di informazione diretti, cioè che non si chiudono attraverso registri (il che equivale a dire che in una connessione chiusa non tutte le reti possono essere di Mealy), si può osservare che: 1) UO è sempre una rete sequenziale, perchè si è supposto che contenga almeno un registro. In particolare se dati e codici operativi sono memorizzati in registri e nessuna variabile di condizione dipende dalle variabili di controllo fornite da UC, UO è una macchina di Moore, in quanto le sue uscite esterne e quelle di condizione dipendono solo dal contenuto di registri, ossia dallo stato interno. 2) UO e UC formano un sistema costituito da un ciclo chiuso di due reti sequenziali sincronizzate dallo stesso impulso. Pertanto se UO è di Moore, UC può essere indifferentemente di Moore o di Mealy. Tuttavia se esiste anche una sola variabile di condizione che dipende dalle variabili di controllo, per cui UO è una macchina di Mealy, allora UC deve essere di Moore perchè altrimenti si avrebbe un ciclo di informazione chiuso attraverso le parti combinatorie delle due reti che renderebbe instabile il funzionamento del sistema. Questa situazione si verifica quando l’uscita delle parti combinatorie di UO che calcolano i membri destri delle relazioni di trasferimento delle µ-operazioni (addizionatori, moltiplicatori, comparatori, ecc.) viene inviata direttamente in ingresso a UC. Possiamo dunque individuare tre classi di sistemi, a seconda del tipo di macchina sequenziale su cui sono modellate UO e UC: sistemi Moore-Mealy, sistemi Moore-Moore e sistemi Mealy-Moore. I sistemi Mealy-Mealy, privi di variabili di condizione dipendenti da variabili di controllo, quindi non soggetti a instabilità a causa di cammini chiusi di informazione tra UO e UC non interrotti da registri, ma dipendenti solo da ingressi esterni, sono assimilabili di fatto a sistemi Moore-Mealy. Infine UC può essere in certi casi realizzata come una rete combinatoria, da considerarsi come caso degenere di macchina di Mealy ad un solo stato. 7.4 - Realizzazione dell’Unità Operativa L’unità operativa di un’ASM può essere realizzata in base alla lista delle µ-operazioni, supposta predeterminata in base al progetto degli algoritmi che la ASM deve poter eseguire, e in base ai moduli logici disponibili. Questo approccio è per lo più seguito nella realizzazione di sistemi special-purpose, quando un requisito importante è la velocità di risposta e porta - 211 - all’organizzazione generale illustrata nella Fig. 7.16, nella quale Mi,j, i = 1, ..., n, j = 1, ..., pi sono moduli funzionali combinatori, Rl, l = 1, ..., m, registri e MUXh, h = 1, ..., r, multiplexer. {D} {K} i Rl MUXk Mi, p MUXl Mi,1 Mk, pk Fig. 7.16 Le linee {D} rappresentano i dati in ingresso che devono essere elaborati e {K} e costanti logiche e/o aritmetiche fornite dall’esterno o anche definite internamente al sistema. Nei sistemi special purpose le µ-operazioni sono scelte in funzione delle operazioni previste dal sistema e la loro lista è frutto di tale scelta; ne segue che c’è scarsa relazione tra di loro. Questo modo di procedere ha come risultato che l’aggiunta di nuove operazioni o il cambiamento di qualche algoritmo implica necessariamente l’aggiunta o la scomparsa di µ-operazioni dalla lista e quindi modifiche da apportare alla struttura dell’unità operativa che da tale lista dipende. D’altra parte, se l’unità operativa ha una struttura rigidamente dipendente dalle µ-operazioni e pertanto difficilmente modificabile, in compenso l’attenzione posta al progetto di algoritmi di complessità minima garantisce elevata velocità di operazione, assicurata dalla riduzione del numero dei passi di operazione e dallo sfruttamento del massimo grado di parallelismo (aumento del numero di trasferimenti simultanei per µ-operazione). Un altro approccio separa le operazioni del sistema dalla lista delle µ-operazioni, in modo che questa risulta indipendente dagli algoritmi e in grado di realizzarne uno qualunque, ovvero di eseguire qualunque operazione. In questo caso le µ-operazioni formano un insieme coerente, definito in vista del raggiungimento delle potenzialità funzionali descritte: l’aggiunta di nuove operazioni, o la modifica degli algoritmi per quelle esistenti non ha implicazioni sulla struttura dell’unità operativa, pur pagando questa flessibilità con una riduzione della velocità di risposta. Questa filosofia di progetto in sostanza concepisce una lista di µ-operazioni in cui ogni µ-operazione è formata da una sola relazione di trasferimento; le conseguenze sul piano tecnologico ed economico sono state molto importanti nello sviluppo dei sistemi di calcolo, in quanto la possibilità di costruire in grande quantità unità operative con il proprio repertorio di µ-operazioni ha segnato un cambiamento nella mentalità di progettazione dei sistemi di calcolo ed ha consentito lo sviluppo dei moderni µ-processori. Questi non sono altro che sistemi UO-UC integrati in un unico componente e caratterizzati da una lista di µ-operazioni di tipo generale che consente di definire di volta in volta l’insieme delle operazioni, programmandole in accordo alle µ-operazioni disponibili. In questi sistemi, propriamente detti general-purpose, l’unità operativa è costituita da un componente detto ALU (Arithmetic Logic Unit) che - 212 - racchiude i moduli logici e aritmetici necessari per le operazioni del sistema e da un componente, detto Local Store, che consiste in un gruppo di registri identici utilizzati per memorizzare operandi, risultati parziali, indirizzi, ecc. I moduli dell’ALU ed i registri sono selezionati di volta in volta mediante segnali opportuni di controllo e selezione. Dati e controlli sono scambiati tra ALU, registri e mondo esterno attraverso un sistema di comunicazione denominato bus (Fig. 7.17). {D} ALU {K} Local Store Fig. 7.17 Dal momento che l’esame dell’Unità Operativa di sistemi general-purpose è argomento del corso di Calcolatori Elettronici, in questa sede ci occuperemo prevalentemente del progetto dell’UO di sistemi speciali Per ogni µ-operazione si considera l’espressione che figura a destra in ciascuna relazione di trasferimento e si individua il modulo funzionale (addizionatore, moltiplicatore, ecc.) necessario per il calcolo di tale espressione, a meno che essa non si riduca ad una semplice costante o ad un dato da scrivere in un registro. Al fine di ridurre ingombro, probabilità di guasti, costo del sistema è opportuno valutare il numero di moduli differenti strettamente necessari per la realizzazione di UO, tenendo presente che le µ-operazioni sono eseguite in tempi di ciclo diversi e che quindi un modulo impegnato in una µ-operazione può essere utilizzato da altre µ-operazioni in cicli diversi. Tuttavia non sempre è possibile operare una riduzione del numero dei moduli, e ciò dipende dalla forma delle µ-operazioni. In particolare quando una µ-operazione consiste in più relazioni di trasferimento e in una (o più) di esse è richiesto un modulo la cui funzionalità è inclusa in quella di altri moduli designati per la stessa µ-operazione, esso non può essere sostituito con uno di quelli, poichè le singole relazioni di trasferimento sono simultanee. Per esempio nel seguente caso: O1: A ← [A]+[B], B ← [A]+1 la µ-operazione richiede due addizionatori che non possono essere ridotti ad uno soltanto a causa della simultaneità dei calcoli e dei trasferimenti richiesta. - 213 - I criteri di riduzione del numero dei moduli funzionali ha avuto importanza soprattutto nel passato, quando i sistemi digitali erano realizzati con componenti discreti a tecnologia SSI (porte logiche) ed MSI (moduli combinatori e sequenziali). Con l’avvento delle tecnologie a larghissima scala di integrazione (VLSI, ULSI), questo approccio ha perduto gran parte della sua importanza, in quanto i criteri di ottimo di un progetto si sono spostati a considerare altri parametri direttamente dipendenti dalla tecnologia di fabbricazione dei componenti e che tengono conto della loro assai più grande complessità logica. Oltre ai moduli funzionali l’unità operativa contiene un numero di registri pari al numero degli identificatori diversi che figurano a sinistra nelle relazioni di trasferimento. Infine tra moduli funzionali e registri e tra registri e moduli funzionali sono necessari multiplexer il cui numero e le cui caratteristiche, in riferimento alla Fig. 7.16, possono essere definiti con i seguenti criteri. a) Multiplexer all’ingresso dei registri Per determinare numero e caratteristiche dei multiplexer tra moduli funzionali e registri, come MUXl nella Fi. 7.16, si raggruppano tutte le relazioni che trasferiscono nello stesso registro R e per ciascun gruppo si ricava il numero n costituito dalla somma dei moduli distinti, dei registri, dei dati esterni e delle costanti trasferiti in R. In questo conto rientrano anche relazioni del tipo R ← T(A), dove T( ) rappresenta l’operazione di traslazione del contenuto di un registro. Se n è maggiore di 1, si deve prevedere un multiplexer ad n ingressi tra le uscite di moduli, dati e costanti ed il registro R. È da notare che le variabili logiche possono essere ottenute sotto forma di variabili di controllo trasmesse da UC, mentre le costanti logiche e/o aritmetiche possono essere cablate in UO oppure costituire un ingresso esterno. Una riduzione del numero dei multiplexer e/o del numero dei loro ingressi si può ottenere osservando che spesso i registri figurano in relazioni di trasferimento del tipo R ← 0; in questo caso è inutile prevedere un ingresso aggiuntivo per il multiplexer all’entrata di R o un multiplexer di ingresso ad R per consentire anche la scrittura di 0, ma basta scegliere un registro dotato di un ingresso di clear. Un punto a sè è la realizzazione delle µ-operazione nulla O0: finchè è possibile conviene realizzarla inibendo la scrittura dei registri con un apposito segnale di controllo (load), oppure riscrivendoli in se stessi.. Un’altra situazione molto frequente è quella in cui devono essere implementati dei flag: in questi casi la scelta cadrà su flip-flop, tipicamente di tipo JK, o in certi casi anche su latch SR; saranno esclusi flip-flop D per i quali è complicato assicurare il mantenimento dello stato, cosa viceversa molto semplice per un JK, applicando 0 agli ingressi J e K. Infine è frequente la richiesta della funzione di conteggio (tipicamente per il controllo di cicli), la quale figura in relazioni di trasferimento del tipo: COUNT ← N COUNT ← [COUNT] +1 Apparentemente è coinvolto nella sua realizzazione un registro COUNT, il cui contenuto è - 214 - inizializzato ad un valore N (spesso negativo) e modificato per somma di 1 ad ogni passo; potrebbe perciò sembrare necessario in ingresso al registro un multiplexer a due vie attraverso le quali far fluire il valore iniziale e quello modificato ed un addizionatore per l’aggiornamento; in realtà è molto più semplice utilizzare un contatore up o down con caricamento parallelo. b) Multiplexer all’ingresso dei moduli funzionali La determinazione dei multiplexer, come MUXk in Fig. 7.16, tra registri e moduli funzionali viene ottenuta raggruppando per ogni modulo le parti destre di tutte le relazioni di trasferimento che fanno riferimento ad esso, dopo averle normalizzate in modo da definire tutti gli ingressi del modulo. Per ciascun ingresso si raggruppano tutte le variabili (contenuti di registri e/o dati esterni) e le costanti distinte che possono essere applicate a quell’ingresso come operandi. Per esempio nel caso delle µ-operazioni: O1: A ← [A]+[B] O2: A ← [A]+[B]+1 O3: B ← [A]+1 indicando nell’ordine con I1, I2, I3 gli ingressi dell’addizionatore identificato come unico modulo necessario, ad I1 risulta associato il contenuto del registro A, a I2 quello del registro B e la costante 0, a I3 le costanti 1 e 0: queste ultime si possono raggruppare sotto forma di una sola variabile, scegliendone opportunamente il valore. Se un gruppo contiene solo una costante o una variabile, all’ingresso corrispondente si applica un valore costante o una variabile di tipo α, a seconda che tale ingresso rimanga costante oppure vari da una µ-operazione all’altra. Invece se un gruppo comprende n tra variabili e costanti, tra esse e l’ingresso corrispondente del modulo si deve interporre un multiplexer ad n ingressi. Così nell’esempio precedente a I1 è collegato solo il registro A, a I2 l’uscita di un multiplexer a due ingressi per il contenuto di B e per la costante 1, a I3 una sola variabile α. Questo procedimento è sensibile, per quanto riguarda numero e caratteristiche dei multiplexer, alle scelte possibili che si presentano durante la fase di ridefinizione dei moduli funzionali e all’ordine con cui si scrivono gli operandi nelle espressioni che figurano nelle relazioni di trasferimento e pertanto non garantisce risultati sempre ottimali. Per quanto riguarda infine le variabili di condizione, esse possono essere a) uscite di qualche modulo già presente in UO, b) ingressi esterni del sistema (per esempio il codice di operazione OP), c) uscite di reti aggiuntive previste espressamente per questo scopo in UO e definite dalle funzioni logiche che corrispondono alle variabili di condizione stesse. Esempio Si vuole progettare l’unità operativa di un sistema che esegue la moltiplicazione di due numeri relativi X e Y rappresentati in modulo e segno in un campo di n bit e il calcolo del valore assoluto del contenuto di un registro accumulatore AC, rappresentato in complemento a due. - 215 - La moltiplicazione viene eseguita nel seguente modo. I segni dei fattori vengono preventivamente confrontati per stabilire il segno del risultato che viene mantenuto in un registro fino al termine del calcolo. I moduli dei due fattori, lunghi ciascuno n-1 bit, sono moltiplicati secondo l’algoritmo di somme e traslazioni esaminato in 7.3 utilizzando, oltre all’accumulatore AC, due registri da n bit MD e MQ ed un registro da 1 bit C per il riporto dalla posizione più significativa di AC durante le somme. Inoltre un registro contatore CC serve per gli n-1 passi di calcolo richiesti. I registri MD ed MQ contengono all’inizio il modulo dei due fattori nelle n-1 posizioni meno significative, mentre nel bit di segno è scritto 0 per comodità, essendo stata l’informazione sul segno elaborata in precedenza. Al termine del calcolo le n-1 posizioni più significative di MQ contengono la metà meno significativa del prodotto (la posizione meno significativa di MQ contiene il bit di segno del fattore inizialmente caricato), mentre le n-1 posizioni meno significative di AC contengono la metà più significativa. Un ulteriore passo inserisce il segno nella posizione più significativa di AC: il prodotto con il suo segno occupa dunque 2n-1 posizioni. Per quanto riguarda l’altra operazione, essa è eseguita semplicemente complementando bit a bit l’accumulatore e sommandovi 1, quando è negativo, lasciandolo inalterato altrimenti. La lista delle µ-operazioni ed il diagramma ASM dell’algoritmo sono mostrati in Fig. 7.18. 0 O4 k 1 O1 ACn-1 0 1 1 CCk-1 0 1 MQ0 O0 O5 0 O1: MD ← |Y|, MDn-1 ← 0, MQ ← |X|, MQn-1 ← 0, S ←Yn-1⊕Xn-1, AC ← 0, C ← 0, CC ← n+2 O2 O2: AC ← [AC]+[MD], C ← cn O3: AC ← Td(AC), ACn-1 ← C, C ← 0, MQ ← Td(MQ), MQn-1 ← AC0, CC ← [CC]+1 O3 O4: ACn-1 ← S O5: AC ← [AC]+1 Fig. 7.18 Dalla lista, seguendo il procedimento sopra illustrato, si individuano due moduli funzionali: un addizionatore ed una porta XOR per la determinazione del segno; inoltre sono richiesti i registri: • MD - registro parallelo da n bit, con un ingresso di controllo load (necessaria quindi una - 216 - variabile di controllo α1); • MQ - registro da n bit, parallelo sull’ingresso e sull’uscita e con capacità di shift destro: quindi necessita di due segnali di controllo load e shift (α2 ed α3); • AC - registro di n bit con ingressi ed uscite seriali e paralleli come MQ; AC è coinvolto nei seguenti trasferimenti: AC ← 0 AC ← [AC]+[MD] AC ← Td(AC), ACn-1 ← C ACn-1 ← S AC ← [AC]+1 per realizzare il primo dei quali conviene che sia dotato di ingresso clear (α4); inoltre deve possedere ingressi di controllo load e shift (α5 ed α6) e si dovrà prevedere in ingresso un multiplexer a due vie (α7), in modo da poter memorizzare il risultato • dell’addizione (relazioni 2 e 5) oppure il bit del segno (relazione 4), lasciando immutati tutti gli altri ( in realtà questi saranno riscritti su se stessi ). CC - registro contatore da k = ⎡log2n⎤ bit, con preset parallelo (α8) e abilitazione al conteggio (α9). • C - registro da 1 bit, può essere costituito da un flip flop JK al quale si applica cn all’ingresso J ed una variabile di controllo (α10) all’ingresso K, ponendola ad 1 solo • quando C deve essere azzerato. S - flip-flop D con ingresso di abilitazione (α11). Si identificano quindi i multiplexer tra modulo e registro, raggruppando le relazioni di trasferimento come segue. MD ← |Y|, MDn-1←0 nessun multiplexer MQ ← |X|, MQn-1←0 MQ ← Td(MQ), MQn-1←AC0 1 multiplexer a due ingressi AC ← 0 AC ← AC]+[MD] AC ← Td(AC), ACn-1 ← C 1 multiplexer a quattro ingressi (in due relazioni AC memorizza una somma) ACn-1 ← S AC ← [AC]+1 S ← Yn-1⊕Xn-1 nessun multiplexer CC ← n+2 CC ← [CC]+1 nessun multiplexer C←0 - 217 - C ← cn nessun multiplexer in quanto si tratta di un semplice flip-flop Per determinare i multiplexer tra registri e moduli funzionali, c’è da considerare il solo addizionatore (CC è un contatore); normalizzando le espressioni nelle relazioni di trasferimento che interessano tale modulo, si ha: AC ← [AC]+[MD]+0 AC ← [AC]+1+0 Ad un ingresso dell’addizionatore devono presentarsi [AC] oppure [AC], per cui occorre un multiplexer a due ingressi (α12); al secondo ingresso devono arrivare [MD] o la costante 1, per cui è pure necessario un multiplexer a due ingressi (α13). La codifica delle µ-operazioni è definita dalla seguente tabella; MD MQ AC MUX3 α1 α 2 α3 α4 α5 α6 O1 1 1 0 1 0 0 - 1 0 1 O2 0 0 0 0 1 0 1 0 0 O3 0 0 1 0 0 1 - 0 O4 0 0 0 0 1 0 0 O5 0 0 0 0 1 0 O0 0 0 0 0 0 0 α7 CC C S MUX1 MUX2 α8 α9 α10 α11 α12 α13 1 - 0 0 0 1 - 1 0 0 - - 0 0 0 0 - - 0 0 0 0 0 0 1 - 0 0 0 0 - - Poiché le colonne (1, 2, 4, 8, 10, 11) sono uguali possono essere fuse in una soltanto e così le colonne (3, 6, 9), mentre le colonne 5 e 7 possono essere fuse con le colonne 13 e 12 rispettivamente, specificando in modo opportuno le condizioni di indifferenza. In questo modo le variabili di controllo si riducono a quattro soltanto, ribattezzate α1, α2, α3, α4. La Fig. 7.19 mostra lo schema logico dell’unità operativa. 7.5 - Realizzazione dell’Unità di Controllo L’unità di controllo di un sistema può essere realizzata seguendo due approcci: 1) può essere strutturata in hardware come una rete sequenziale (di Mealy o di Moore, secondo i casi); 2) può essere realizzata in una forma detta microprogrammata o firmware, la quale consiste essenzialmente nel descrivere il sistema mediante un particolare linguaggio di programmazione, detto di microprogrammazione, e memorizzare tale descrizione (microprogramma) in una ROM che costituisce il cuore della parte di controllo. - 218 - Y<n-2, 0> 0 n+2 Yn-1 Xn-1 α1 MD 1 ⊕ 0 1 α4 MUX1 0 1 α1 α3 α3 MUX2 CC 0 S cn α1 α1 ADDER 1 J K C 0 α3 MUX3 α2 α3 AC 0 X<n-2, 0> MQ α1 α2 α1 ACn-1 AC MQ<n-1, 1> MQ0 CC k-1 Fig. 7.19 7.5.1 - Realizzazione hardware La realizzazione in hardware richiede che dal diagramma di flusso venga opportunamente estratta l’informazione relativa alle variabili di controllo e alla loro evoluzione temporale, cosa necessaria perchè le azioni previste per l’unità operativa possano avere luogo nell’ordine stabilito. Infatti il diagramma di flusso descrive mediante i blocchi operazionali le azioni elementari che il sistema deve compiere e mediante i blocchi di decisione la successione temporale di queste azioni in accordo al presentarsi di certi eventi; non è peraltro in grado di esprimere dinamicamente l’evoluzione del sistema in termini dell’evoluzione delle sue variabili di controllo. D’altra parte, dal momento che le azioni elementari (µ-operazioni) sono realizzate utilizzando moduli funzionali e i dati, nei vari passi dell’elaborazione, vengono mantenuti in registri e instradati sui vari percorsi con l’aiuto di multiplexer, è necessario che ai moduli, ai registri e ai multiplexer arrivino negli istanti opportuni i segnali (a livelli e/o ad impulsi ) richiesti perchè essi possano svolgere correttamente le loro funzioni. Si tratta in sostanza di ricavare dal diagramma di flusso, ossia dalla conoscenza delle azioni, l’informazione contenuta sinteticamente nella tabella delle transizioni e nella tabella delle uscite di una rete sequenziale, in particolare della rete che costituisce la parte di - 219 - controllo. A tale scopo si parte ancora dalla costruzione di un grafo, che chiameremo grafo di stato del controllo, i cui nodi rappresentano gli stati della ASM e ai quali sono associati, nodo per nodo, i segnali di controllo coinvolti nel tempo di ciclo in cui ogni stato è stato attuale per la macchina; inoltre, con l’aiuto della lista dei componenti logici che sono stati scelti per realizzare la parte operativa, si specifica se quei segnali devono essere livelli oppure si comportano come impulsi. Riguardo al numero dei nodi del grafo, se si fa riferimento al modello di Moore, in generale c’è corrispondenza uno ad uno tra i blocchi operazione del diagramma di flusso e gli stati del controllo (infatti ogni stato, con l’insieme delle variabili di controllo definite in esso, caratterizza univocamente l’uscita della parte di controllo, costituita dal codice della µ-operazione), con alcune eccezioni: a) due o più µ-operazioni in sequenza possono essere eseguite sotto la medesima configurazione di un sottoinsieme di segnali di controllo, per esempio quando un segnale ha un livello costante alto o basso: in questi casi a due o più blocchi operazione corrisponde uno stesso stato del controllo, che quindi permane per più di un tempo di ciclo; b) può essere necessario introdurre uno o più stati che non corrispondono all’esecuzione di µ-operazioni, ma nei quali viene definito il valore di segnali di controllo che devono trovarsi già stabili negli stati successivi; per esempio se un modulo operazione deve calcolare una funzione in certi momenti ed un’altra in altri momenti, sulla base del livello di un segnale di selezione, occorre prevedere uno stato in cui quel segnale viene definito al livello opportuno, prima di entrare nella sequenza di stati che si riferiscono a ciascuno dei due tipi di elaborazione. c) ogni volta che una µ-operazione, in cui viene modificato il contenuto di un registro, è seguita da un blocco decisione (o da un intero albero di decisione) nel quale viene effettuato un test sul contenuto di quel registro, è necessario introdurre di seguito al nodo relativo alla µ-operazione un nodo aggiuntivo che non corrisponde ad alcuna operazione della parte operativa, ma ha lo scopo di separare l’aggiornamento del registro ed il suo test, assegnandoli a periodi di clock consecutivi; questo evita l’incongruenza di un test su un valore in corso di modifica (non si dimentichi che i registri sono non trasparenti). Dal nodo aggiuntivo si dipartono gli archi che corrispondono alle varie condizioni logiche legate al valore modificato del registro (Fig. 7.20). Oi Oi/A 1 A 0 A=1 A=0 Fig. 7.20 Se invece il modello è quello di Mealy, ad uno stato possono essere associati uno o più - 220 - blocchi operazione in quanto, come si è visto in altra parte, tutte o parte delle uscite del controllo dipendono dalle condizioni di ingresso; in questo caso per ogni sottoinsieme di segnali di controllo, che devono essere attivi per una delle µ-operazioni implicate dallo stato attuale, sarà specificato il particolare stato di ingresso da associare ad esso: questa informazione si desume dai blocchi operazione che sono racchiusi sotto il medesimo stato. Per specificare nel grafo se i segnali di controllo sono attivi a livello alto o basso, ci possono essere vari metodi, per esempio si può fare seguire il nome di un segnale di controllo dal suffisso H o L rispettivamente, oppure più semplicemente se ne può dichiarare il nome nello stato o negli stati in cui esso deve essere attivo, purchè tutti i moduli funzionali richiedano segnali con lo stesso livello di attivazione (alto o basso). Un segnale che viene dichiarato con il suo livello attivo in uno stato ma non nel precedente e nel seguente si configura come un impulso di durata pari ad un ciclo e se l’elemento su cui agisce è sensibile al fronte (per esempio un contatore) questa dichiarazione deve essere fatta ogni volta che quell’elemento deve riceverlo. Viceversa un segnale dichiarato attivo per più stati consecutivi, subisce una variazione di livello nel primo stato della sequenza (quindi ha un fronte), e mantiene poi il livello raggiunto per i cicli corrispondenti, ritornando al livello iniziale nel primo stato successivo in cui non è più asserito. A questo proposito è da osservare che se un segnale deve lavorare a livelli per più di un tempo di ciclo, occorre definirlo con il valore con cui è attivo in tutti gli stati consecutivi in cui è coinvolto; in alternativa esso può essere considerato l’uscita di un latch e occorrono allora due segnali a impulsi, asseriti in stati opportuni, per il set ed il reset del latch. Per esempio il seguente spezzone di grafo formato dalla successione di cinque stati, in tre dei quali è identificato il segnale α con la specifica H, definisce l’andamento temporale di quel segnale come è mostrato in Fig. 7.21: stato 1 α-H stato 2 stato 3 stato 4 α-H α-H stato 5 a) Clock α b) Fig. 7.21 Come si vede il segnale α rimane a livello alto nello stato 1 per un ciclo e negli stati 3 e 4 per due cicli; inoltre l’interposizione dello stato 2 vuoto tra gli stati 1 e 3 determina un secondo fronte in salita di α, oltre a quello iniziale in corrispondenza dello stato 1. Il grafo di stato costruito con le modalità descritte può essere utilizzato per realizzare la parte di controllo direttamente con i metodi di sintesi propri delle reti sequenziali, almeno nei - 221 - casi semplici (pochi stati interni e pochi stati di ingresso), secondo lo schema generale descritto dalla Fig. 7.22. In esso è presente un registro che contiene lo stato attuale del sistema, mentre una logica di generazione dello stato successivo sceglie lo stato successivo in base allo stato attuale e allo stato di ingresso; infine una logica di uscita decodifica lo stato attuale per generare i segnali di controllo per la parte operativa. Generatore x0 degli stati Registro di stato Y0 Y1 Yn-1 xq-1 α0 y0 y1 Rete di decodifica yn-1 α1 αm-1 clock Fig. 7.22 Tuttavia una parte di controllo realizzata in questo modo non evidenzia chiaramente la corrispondenza tra struttura del controllo e struttura dell’algoritmo e qualunque modifica di questo comporta il totale rifacimento della rete. Altri approcci, utilizzando la stessa struttura per esprimere gli stati e la stessa codifica delle variabili di stato e di uscita, consentono un progetto che risponde maggiormente a criteri di chiarezza e di aderenza all’algoritmo; tra questi particolarmente interessanti sono quelli basati sull’idea di ricavare lo stato successivo leggendolo da una tabella (tecnica di table look-up), realizzata mediante una ROM o semplicemente mediante multiplexer, come mostra il seguente esempio. Esempio Applichiamo il metodo al progetto della parte di controllo del sistema descritto dal diagramma ASM di Fig. 7.17, dal quale deduciamo il grafo degli stati illustrato in Fig. 7.23. kACn-1=10 0 k=0 5 kACn-1=11 1 CCk-1= 1 6 2 CC MQ =01 k-1 0 CCk-1MQ0=00 4 Fig. 7.23 - 222 - 3 stato 0: O0 stato 1: O1 (α1) stato 2: O0 stato 3: O2 (α3,α4) stato 4: O3 (α2) stato 5: O4 (α3) stato 6: O5 (α3,α4) Per quanto riguarda la rete combinatoria denominata generatore degli stati in Fig. 7.22, essa verrà realizzata con una tecnica che fa uso di un multilexer per ciascuna variabile di stato; la selezione di tutti multiplexer è effettuata in parallelo mediante le variabili dello stato successivo, mentre gli ingressi sono determinati elaborando le variabili di condizione attraverso semplici reti combinatorie, definite dalla seguente tabella degli stati: stato MUX2 MUX1 MUX0 0 000 k⋅ACn-1 k⋅ACn-1 k 1 001 0 1 0 2 010 CCk-1+MQ0 CCk-1⋅MQ0 CCk-1+MQ0 3 011 1 0 0 4 100 0 1 0 5 101 0 0 0 6 110 0 0 0 Per comprendere come essa è stata realizzata, consideriamo sul grafo lo stato 0: da esso si può passare nello stato 1 per k = 0 e qualunque valore di ACn-1; nello stato 0 stesso per k = 1 e ACn-1 = 0 e infine nello stato 6 per k = 1 e ACn-1 = 1; possiamo così costruire la seguente tavola di verità: k ACn-1 MUX2 MUX1 MUX0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 1 1 1 1 0 da cui si ricavano le espressioni logiche riportate nella prima riga della tabella degli stati; dallo stato 1 si passa sempre allo stato 2, qualunque valore abbiano le variabili di condizione, pertanto nella seconda riga della tabella degli stati si scrive semplicemente 010. Analogamente si procede per le altre righe. La corrispondente struttura è mostrata nella Fig. 7.24. - 223 - 0 1 2 3 4 5 6 7 MUX0 Y0 Y1 Y2 y0 Registro di stato 0 1 2 3 4 5 6 7 MUX1 0 1 2 3 4 5 6 7 y1 y2 clock MUX2 1 MQ0 ACn-1 0 CCk-1 k Fig. 7.24 Per quanto riguarda la generazione delle variabili di controllo, si decodificano le variabili dello stato attuale e si prelevano le variabili di controllo o direttamente dalle uscite appropriate del decodificatore, oppure da gruppi di queste riunite attraverso porte OR, a seconda che una variabile di controllo sia attiva in un solo stato oppure in più di uno; nel caso specifico la rete che produce le variabili di controllo è strutturata come in Fig. 7.25. 0 1 y0 α1 2 α4 α2 α3 3 y1 4 y2 5 6 7 Fig. 7.25 Quando una variabile di controllo deve avere un comportamento a livelli, rimanendo ad valore fisso per più periodi di clock consecutivi, come è stato detto in altra parte, può essere - 224 - generata attraverso l’uscita di un latch SR, il cui set e reset sono effettuati rispettivamente dall’uscita del decodificatore associata al primo e da quella associata all’ultimo dei periodi di clock consecutivi durante i quali il segnale è attivo. Se vi sono problemi di temporizzazione (ad esempio il tempo di commutazione del latch è paragonabile alla durata del tempo Ts), si può anticipare il set effettuandolo mediante l’uscita del decodificatore che corrisponde allo stato assunto dal controllo nel periodo di clock precedente quello in cui la variabile di controllo deve diventare attiva e si può anticipare il reset mediante l’uscita del decodificatore che corrisponde al penultimo dei periodi di clock in cui la variabile è attiva. In ogni caso è necessario tenere conto in modo accurato della temporizzazione, per evitare il rischio di anticipare (o di ritardare) eccessivamente il set ed il reset. 7.5.2 - Realizzazione microprogrammata (firmware) Accanto al metodo illustrato nel paragrafo 7.5.1 per tradurre il diagramma di flusso di un sistema in una struttura hardware che implementa l’algoritmo di controllo, ne esiste un altro il quale consente al tempo stesso di descrivere il controllo di un sistema – e in questo senso ha una funzione analoga a quella del grafo di stato di una ASM – e di realizzarlo. Questo metodo è noto come microprogrammazione ed è basato sulla scrittura di un particolare programma detto microprogramma mediante il quale viene descritto il comportamento dell’algoritmo; lo stesso microprogramma, memorizzato in una ROM, serve per controllare e dirigere le attività dell’unità operativa e in questa funzione costituisce l’essenza di una parte di controllo detta microprogrammata o firmware. Per scrivere un µ-programma è necessario un linguaggio specifico, che è detto linguaggio di microprogrammazione o µ-linguaggio; lo statement fondamentale di un µ-linguaggio è la microistruzione (µ-istruzione), ovvero la descrizione delle funzioni eseguite da un sistema, inteso come insieme delle due parti UO e UC, in un passo elementare; un microprogramma (µ-programma) è l’insieme delle µ-istruzioni che descrivono un’operazione OP in tutti i passi elementari che la compongono. Una µ-istruzione è scritta secondo la seguente sintassi: <etichetta>"|"<frase semplice>|<frase condizionata>{";"<frase condizionata>} | <µ-ordine> <trasferimento condizionato> {";"<trasferimento condizionato>} <etichetta>::= "µh" <frase semplice>::="Oj,µk" <frase condizionata>::="(Cr) Oj , µk" <trasferimento condizionato>::="(Cr) µk" La frase semplice viene interpretata come «esegui la µ-operazione Oj, quindi trasferisci il controllo alla µ-istruzione µk»; quella condizionata asserendo «se la condizione logica Cr = - 225 - f(x1, x2, …, xs) è vera esegui la µ-operazione Oj, quindi trasferisci il controllo alla µ-istruzione µk»; infine il trasferimento condizionato viene interpretato come «se la condizione logica Cr = f(x1, x2, …, xs) è vera trasferisci il controllo alla µ-istruzione µk». I µ-linguaggi possono essere divisi in due grandi famiglie: quelli le cui µ-istruzioni contengono solo frasi condizionate e che sono detti a struttura di frase (phrase structured o ps) e quelli caratterizzati da µ-istruzioni che contengono solo trasferimenti condizionati e che sono detti a struttura di trasferimento (transfer structured o ts). Limitandoci per semplicità in questa trattazione solo ai linguaggi ts, una µ-istruzione nella sua forma più generale è scritta nel seguente modo: µh | Oj (C1) µ1k ; (C2) µ2k ; …; (Cq) µqk e la sua interpretazione è: «esegui la µ-operazione Oj, quindi se la condizione C1 è vera, vai alla µ-istruzione µ1k, altrimenti se è vera la condizione C2 vai alla µ-istruzione µ2k, altrimenti ...». Nel caso in cui due o più simboli di trasferimento siano uguali, la µ-istruzione generale può essere semplificata; per esempio se µsk = µtk = µ*k, i trasferimenti condizionati si riducono al seguente (Cst) µ*k, dove Cst è l’unione delle condizioni Cs e Ct. Nel caso limite in cui tutte le condizioni sono uguali, la µ-istruzione si riduce alla frase semplice: µh | Oj, µk Esaminiamo ora in maggiore dettaglio la relazione tra le condizioni Cr , r = 1, 2, …, q e le variabili di condizione x1, x2, …, xs. Come è stato detto, ogni Cr è una funzione booleana di quelle variabili e dovendo essere vera quando tutte le altre condizioni sono false, una sua possibile espressione è costituita da uno dei q = 2s prodotti completi (mintermini) associato ad una delle q combinazioni binarie distinte, o stati, Xr delle variabili stesse. Per esempio se s = 3 esistono 8 possibili funzioni distinte e una di esse, diciamo x1x2x3, può essere messa in corrispondenza con lo stato 101, scrivendo x1x2x3 = 101 con il che si fa riferimento alla condizione C5 che è vera se x1 = 1, x2 = 0, x3 = 1; analogamente allo stato 111 sarà associata l’espressione x1x2x3, a formare la condizione C7 ≡ x1x2x3 = 111. Due o più condizioni C1, C2, ..., Cr possono inoltre essere sostituite da una condizione composta C12…r, ottenuta dall’unione delle singole condizioni e associabile a tutti gli stati individuati separatamente da esse. La condizione composta è interpretata affermando «se la condizione C1 è vera o la condizione C2 è vera , …, allora». Per esempio alle due condizioni C5 e C7 può essere sostituita la condizione composta C57 ≡ x1x2x3+x1x2x3 = 101+111, interpretabile come «se la condizione C5 è vera o la condizione C7 è vera, allora …»; in alternativa si può utilizzare la forma semplificata x1x3 = 11 - 226 - che significa «se x1 = 1 e x3 = 1, allora …». Notare che quest’ultima notazione, che corrisponde al costrutto case di un linguaggio ad alto livello, consente di individuare direttamente la condizione vera, senza bisogno di scandire tutte le altre. Da ultimo verifichiamo il fatto fondamentale che un µ-programma è realmente in grado di descrivere il comportamento di un sistema, modellato come insieme delle due parti UO e UC interconnesse. A livello di sistema, descrivere il suo comportamento significa specificare ad ogni passo lo stato successivo e lo stato di uscita di ciascuna delle due macchine sequenziali UO e UC; a livello di µ-programma significa definire ad ogni passo la µ-istruzione che deve essere eseguita. Si tratta dunque di individuare la relazione tra macchina sequenziale e µ-programma. Supponiamo che di un sistema sia dato il µ-programma e che sia noto lo stato di ingresso e lo stato interno di UO ad ogni passo elementare; pertanto è noto anche lo stato di ingresso Xr di UC, una volta note le espressioni delle variabili di condizione, nell’ipotesi che tali variabili siano funzione solo di informazioni esterne e/o del contenuto di registri di UO, e non di variabili di controllo (ossia nell’ipotesi che UO sia modellata come macchina di Moore). Al simbolo della generica µ-istruzione µh associamo uno stato di UC e supponiamo che qualunque µ-istruzione riferita in un trasferimento sia ancora una µ-istruzione del µ-programma (µ-programma chiuso); allora lo stato attuale sarà µh e i possibili stati successivi saranno µ1k, µ2k, …, µqk, ciascuno relativo ad uno stato di ingresso di UC Xr , r = 1, 2, …, q. Dato uno specifico stato di ingresso Xr, è nota la condizione logica Cr ad esso associata e quindi lo stato successivo µrk della macchina che modella UC. D’altra parte gli stati di uscita del controllo UC sono rappresentati dai codici delle µ-operazioni Orj e poiché, secondo la sintassi illustrata, nelle µ-istruzioni i codici Orj non dipendono dalle condizioni Cr, lo stato di uscita di PC dipende solo dallo stato interno. Risulta dunque evidente che ogni µ-istruzione definisce una riga di una tabella di flusso di una macchina di Moore, per cui una volta definito l’insieme degli stati di ingresso Xr, degli stati di uscita Oj e degli stati interni µh tramite un µ-programma, è possibile definire la tabella di flusso di una macchina di Moore che descrive il comportamento della parte UC del sistema. Tale tabella ha un numero di colonne pari al numero q di stati di ingresso Xr ed un numero di righe pari al numero di µ-istruzioni del µ-programma; ogni casella riporta lo stato successivo µik. Se il µ-linguaggio comprende anche la lista delle µ-operazioni Oj, il µ-programma descrive compiutamente anche il comportamento della UO, dal momento che essa è definita proprio da tale lista. Possiamo concludere dicendo che un µ-programma chiuso ed una tabella di flusso sono modi equivalenti di descrivere una macchina sequenziale e anzi un µ-programma completo della lista delle µ-operazioni è al tempo stesso la descrizione del comportamento di un sistema e la componente essenziale della sua parte di controllo. - 227 - La scrittura di un µ-programma partendo dal diagramma di flusso procede secondo le seguenti regole. a) Si considera il blocco di ingresso, o uno non ancora considerato, connesso all’uscita di uno già esaminato. b) Se esso è un blocco di decisione si considera, se esiste, l’albero di decisione avente quel blocco come radice e in corrispondenza si scrive una µ-istruzione del tipo: µh | O0 (C1) µ1k ; (C2) µ2k ; …; (Cn) µnk dove il numero n di trasferimenti condizionati è pari al numero di uscite dell’albero. c) Se si tratta di un blocco operativo, seguito da un altro blocco operativo, si scrive una µ-istruzione del tipo: µh | Oj, µk Invece se il blocco operativo è seguito da un blocco decisione, si esamina l’albero di decisione avente come radice il blocco di decisione; se nessuna delle condizioni di tale albero (eventualmente costituito dalla sola radice) dipende da registri modificati dalla µ-operazione del blocco operativo, si considerano insieme questo blocco e l’albero e in corrispondenza si scrive una µ-istruzione del tipo: µh | Oj (C1) µ1k ; (C2) µ2k ; …; (Cn) µnk dove n è ancora il numero di uscite dell’albero. Viceversa se almeno in un blocco dell’albero figura una condizione dipendente dai registri modificati nel blocco operativo in esame, si considerano insieme tale blocco e la porzione di albero (eventualmente vuota) nella quale non esistono condizioni dipendenti dai registri sotto modifica e si scrive una µ-istruzione come la precedente, ovvero: µh | Oj (C1) µ1k ; (C2) µ2k ; …; (Ci) µik salvo che il numero i di trasferimenti condizionati in essa presenti è limitato al numero dei nodi del sottoalbero scelto. Si considera quindi il sottoalbero rimanente e per esso si scrive una µ-istruzione del tipo: µh | O0 (C1) µi+1k ; (C2) µi+2k ; …; (Cl) µnk. Il procedimento è ripetuto fino ad esaurire tutti i blocchi. Come esempio di microprogrammazione, riprendiamo il sistema descritto dal diagramma di flusso di Fig. 7. Con le regole enunciate, il corrispondente microprogramma è il seguente: µ1| O0 (k=0) µ2; (kACn-1=10) µ1; (kACn-1=11) µ8 - 228 - µ2| O1, µ3 µ3| O0 (CCk-1MQ0=00) µ4; (CCk-1MQ0=01) µ5; (CCk-1=1) µ6 µ4| O3, µ3 µ5| O2, µ4 µ6| O4 (k=0) µ2; (k=1) µ7 µ7| O0 (ACn-1=0) µ1; (ACn-1=1) µ8 µ8| O5 (k=0) µ2; (k=1) µ7 Rispetto al grafo degli stati ottenuto per la realizzazione hardware, si noti come questo stile di microprogrammazione tende ad aumentare il numero degli stati della macchina sequenziale (8 invece di 7): ciò è dovuto essenzialmente ad anticipare il più possibile le decisioni prese dal controllo, a vantaggio in definitiva della velocità dell’intero sistema. Lo schema di principio di un controllo microprogrammato in linguaggio ts, prevede una memoria di sola lettura, una rete logica combinatoria che ha la funzione di generare gli indirizzi per la lettura della memoria ed un registro: la parte combinatoria dell’intera rete sequenziale è costituita dalla memoria e dalla rete logica di indirizzamento; si ricordi infatti che una ROM è per sua natura un circuito combinatorio. Ogni cella della ROM contiene una µ-istruzione completa (cioè il codice della µ-operazione Oj, sotto forma di stringa binaria che codifica le variabili di controllo, gli indirizzi delle µ-istruzioni successive µrk e le condizioni logiche associate Cr) e per questo tale schema è detto a memorizzazione di microistruzione (mm). Il numero delle celle è pari al numero delle µ-istruzioni ed ogni cella ha una lunghezza sufficiente ad accogliere la µ-istruzione più lunga ovvero al massimo LO+2s×(s+⎡log2Nµ⎤), dove LO è la lunghezza del campo riservato al codice di µ-operazione, Nµ il numero di µ-istruzioni del µ-programma, s il numero delle variabili di condizione e 2s il numero delle possibili condizioni logiche. I codici delle condizioni logiche e delle µ-istruzioni µrk associate, contenuti nella cella relativa alla µ-istruzione corrente, vengono trasferiti dalla ROM all’ingresso della rete logica la quale, in base allo stato Xr delle variabili di condizione, pure applicato in ingresso, genera l’indirizzo della cella di memoria contenente la prossima microistruzione µik, in base alla condizione logica Ci che risulta vera; la rete logica si può dunque pensare costituita da due parti: una che determina quale delle condizioni logiche è verificata per lo stato di ingresso Xr, l’altra che genera l’indirizzo µik; l’indirizzo µik viene memorizzato nel registro R (Fig. 7.26). - 229 - ROM Cq µqk µh { clock Oj C1 µ1k C2 µ2k { { µik R Rete combinatoria Xr (dalla parte operativa) {αi} (alla parte operativa) Fig. 7.26 Se nella microprogrammazione non si pone alcun vincolo sul numero di trasferimenti condizionati che possono essere presenti in una µ-istruzione, si deve ammettere la possibilità di un numero di trasferimenti pari a 2s, se s è il numero di variabili di condizione presenti nel µ-programma. Questo comporta considerare µ-istruzioni espanse nelle quali figurino tutte le 2s condizioni ottenute dalla codifica delle variabili di condizione. Per esempio se esistono tre variabili di condizione x1, x2, x3, una µ-istruzione del tipo: µh | Oj (x1 = 0) µa; (x1x2 = 10) µb; (x1x2 = 11) µc deve essere espansa in µh | Oj (x1x2x3 = 000) µa; (x1x2x3 = 001) µa; …; (x1x2x3 = 011) µa; (x1x2x3 = 100) µb; (x1x2x3 = 101) µb; …; (x1x2x3 = 110) µc; (x1x2x3 = 111) µc Se tutte le µ-istruzioni sono espanse in questo modo, in ogni cella della ROM i 2s indirizzi di trasferimento specificati in ogni µ-istruzione possono essere associati implicitamente per posizione alle rispettive condizioni logiche, senza bisogno che anche queste siano memorizzate, con risparmio sulla lunghezza di parola; inoltre la rete logica si riduce ad un semplice multiplexer (Figh. 7.27). Tuttavia questa soluzione non è praticabile non appena il numero delle variabili di condizione supera qualche unità, ed il motivo è l’aver fatto ricorso ad un µ-linguaggio verticale generale. In pratica i µ-linguaggi verticali che si considerano sono caratterizzati da un numero di trasferimenti limitato, ossia il numero effettivo n delle variabili di condizione è solo 2 o 3. In questi casi ogni µ-istruzione è espansa in 2n trasferimenti condizionati, i quali vengono ordinati come nel caso generale; la differenza sta nel fatto che le variabili di condizione sono diverse da una µ-istruzione espansa all’altra, per esempio si possono avere due µ-istruzioni - 230 - espanse del tipo: R µ ik Oj αi µ1 k µ2 k µqk 0…0 0…1 MUX µh x1 1…1 xs Fig. 7.27 µh | Oj (x1x2 = 00) µa; (x1x2= 01) µb; (x1x2 = 10) µc; (x1x2 = 11) µd µk | Oj (x1x3 = 00) µa; (x1x3 = 01) µa; (x1x3 = 10) µc; (x1x3 = 11) µc con x3 ≠ x1; questo comporta la necessità di operare una scelta tra le s variabili di condizione in modo da poter continuare a controllare i trasferimenti con un multiplexer. A tale scopo si inseriscono in ogni cella di memoria dei campi in numero pari alle variabili da identificare, ossia n, e ogni campo contiene un codice binario associato ad una delle s variabili di condizione, lungo t = ⎡log2s⎤ bit, con il quale si controlla un multiplexer ⎡log2s⎤×s che ha come ingressi-dati tutte le variabili di condizione, tra quali ne viene selezionata una, diversa da un multiplexer all’altro. Le n variabili selezionate controllano a loro volta un multiplexer 2n×n per la scelta della µ-istruzione successiva (Fig. 7.28)). . Oj C1,h C2,h Cn,h µ1,h µ2,h µn,h Oj C1,k C2,k Cn,k µ1,k µ2,k µn,k αi x1 t t t µr,q R µr,q 00…0 00…1 11…1 xs x1 n×2n xs x1 xs 1≤r≤n 1≤q≤m m = lunghezza del µ-programma Fig. 7.28 - 231 - 7.5.3 - Analisi delle prestazioni Ricordando che T indica il tempo di ciclo del sistema, il tempo medio impiegato per compiere l’operazione i-esima del sistema è dato dalla relazione: Te,i = ni·T (7.2) essendo ni il numero medio di µ-operazioni richieste per quell’operazione; di qui si può desumere il tempo di elaborazione medio del sistema, ossia il tempo mediamente da esso impiegato per compiere una qualunque delle sue v operazioni, nell’ipotesi che esse siano equiprobabili: ⎛ v ⎞ T e = ⎜ ∑ T e, i⎟ ⁄ v ⎜ ⎟ ⎝i = 1 ⎠ (7.3) L’inverso di Te è un parametro che viene assunto come indice significativo per misurare le prestazioni di un sistema e viene misurato in milioni di operazioni al secondo (MIPS). Nella realtà le operazioni non hanno la stessa probabilità di occorrenza, per cui se indichiamo con pi la probabilità dell’operazione i-esima (valutata su base statistica, per esempio attraverso simulazione), avremo: v Te = v ∑ p i T e, i = T ⋅ ∑ p i n i = T ⋅ N i=1 (7.4) i=1 con N numero medio di passi per operazione. Sappiamo che il tempo di ciclo dipende dal tempo elementare e dalla durata dell’impulso di clock secondo la relazione T = TS+∆p. Per calcolare il tempo elementare, ricordiamo che esso è il tempo minimo che può intercorrere tra due impulsi di clock consecutivi in un sistema costituito da due reti sequenziali connesse in ciclo. Se il sistema è del tipo Moore-Mealy o Mealy-Moore, cioè eterogeneo, per il calcolo si deve considerare solo uno spezzone del ciclo, mentre se è del tipo Moore-Moore se ne devono considerare due, a causa del ritardo delle uscite della macchina di Moore. Sia tUO il tempo massimo richiesto per propagare una variabile di controllo αi da un ingresso dell’unità operativa UO ad un registro della stessa, attraverso multiplexer e moduli funzionali e tx il ritardo massimo con cui viene formata una variabile di condizione, a partire dal contenuto di un registro di UO; si osservi che tx in molti casi può essere considerato nullo, e precisamente quando una variabile di condizione è direttamente l’uscita di un registro di UO. Inoltre siano tROM e tRL i tempi massimi di trasmissione nell’unità di controllo, supposta microprogrammata. In riferimento agli schemi Moore-Mealy e Moore-Moore di Fig. 7.29 - 232 - avremo rispettivamente nei due casi: UO UC UO T = T S + ∆ p = ∆ s, z + ∆ i, z + ∆ i, s' + ∆ p = t x + ( t ROM + t RL ) + t UO + ∆ p (7.5) T = max ( T S , T S ) + ∆ p 1 2 (7.6) essendo: UO UC T S = ∆ s, z + ∆ i, s' = t x + t RL 1 UC UO T S = ∆ s, z + ∆ i, s' = t ROM + t UO 2 (7.7) In genere T S << T S , dal momento che tUO è determinato dal modulo funzionale più lento, di 1 2 solito un addizionatore o anche un modulo funzionalmente più complesso, quale ad esempio un moltiplicatore, per cui risulta già tx+tRL < tUO, anche senza considerare il contributo dovuto al tempo di accesso della ROM. i tUO i z tUO UO tx tx z i z tRL+tROM UC s s' s' s s' s i tROM tRL s' Moore-Mealy z s Moore-Moore Fig. 7.29 Nel caso di sistema Mealy-Moore, dove la parte operativa sia realizzata come macchina di Moore anticipato, si ottiene (Fig. 7.30): UC UO UC T = ∆ s, z + ∆ i, z + ∆ i, s' + ∆ p = t ROM + ( t UO + t x ) + t RL + ∆ p - 233 - (7.8) i z tUO+tx UO s' s z i tROM UC tRL s' s Fig. 7.30 Nell’ipotesi che i tempi tUO, tx, tROM e tRL siano gli stessi per i sistemi esaminati, si nota dalle espressioni di T che il tempo di ciclo dei sistemi Moore-Mealy e Mealy-Moore è lo stesso, mentre quello del sistema Moore-Moore è inferiore della quantità tx+tRL, nell’ipotesi, precedentemente fatta, che sia tROM+tUO >> tx+ tRL. Consideriamo infine il caso di un sistema Moore-Moore con l’unità di controllo realizzata come macchina di Mealy ritardata, ossia con un registro R sull’uscita. Poichè tale registro corrisponde ad una macchina di Moore inserita nel ciclo di macchine preesistente e per la R R quale è ∆ s, z = ∆ i, s' = 0 , si ha (Fig.7.): T = max ( T S , T S ) + ∆ p 1 2 UO UC R T S = ∆ s, z + ∆ i, z + ∆ i, s' = t x + ( t RL + t ROM ) + 0 1 R (7.9) UO T S = ∆ s, z + ∆ i, s' = 0 + t UO 2 Queste relazioni mostrano che il tempo di ciclo di questo sistema è ulteriormente ridotto rispetto a quello del sistema Moore-Moore, in quanto, anche nel caso in cui risultasse T S > 1 - 234 - TS 2 sarebbe pur sempre tx+tRL+tROM < tROM+tPO. R z i tUO z tx s' s' s s i i z tRL+tROM s s' Fig. 4.1 Se due sistemi sono equivalenti, il confronto fra i tempi elementari può essere esteso ai tempi medi di elaborazione Te , ma se non lo sono è necessario tenere in conto anche il numero medio N di µ-operazioni per operazione, proprio di ciascuno di essi, oltre ai valori di T. Per esempio in un sistema Moore-Moore ed in uno Moore-Mealy non equivalenti il confronto tra i tempi medi di elaborazione implica un bilancio tra il valore di ni (e quindi di N), che è più elevato nel primo sistema, ed il valore di T che viceversa è più grande per il secondo sistema. Lo stesso criterio può essere seguito nel confronto tra un sistema Moore-Moore ed uno Mealy-Moore, dal momento che dato un sistema Mealy-Moore, ne esiste sempre uno Moore-Mealy ad esso equivalente, quindi con gli stessi valori di ni e di T. Se Te1 e Te2 sono i tempi medi di elaborazione per un sistema Moore-Moore e per un sistema Moore-Mealy (o Mealy-Moore), il rapporto: r = T T e1 N T e2 N2 T2 1 1 ------- = ----- ⋅ ----- (7.10) v dove è N k = ∑ pi ⋅ ni, k , k = 1, 2, mostra che il sistema Moore-Moore è più veloce di quello i=1 Moore-Mealy (o Mealy-Moore) per r < 1, più lento per r > 1. - 235 -
© Copyright 2024 Paperzz