SlideShare uma empresa Scribd logo
1 de 19
Baixar para ler offline
Architettura di esempio
                                                 Ing. Costantino Grana
                                    Università degli Studi di Modena e Reggio Emilia
                                (Stampato il 07/04/2008 - architettura di esempio_16.doc)

Introduzione ......................................................................................................................................... 1 
Struttura................................................................................................................................................ 2 
Formato delle istruzioni ....................................................................................................................... 3 
Microistruzioni ..................................................................................................................................... 4 
Ciclo delle istruzioni ............................................................................................................................ 5 
   Fetch ................................................................................................................................................. 5 
   Execute ............................................................................................................................................. 5 
     Set (SET) ...................................................................................................................................... 5 
     Load (LD) .................................................................................................................................... 5 
     Store (ST) ..................................................................................................................................... 5 
     Add (ADD) .................................................................................................................................. 6 
     Subtract (SUB) ............................................................................................................................. 6 
     Increment (INC) e Decrement (DEC) .......................................................................................... 6 
Unità di controllo ................................................................................................................................. 6 
   Implementazione cablata.................................................................................................................. 7 
     Versione semplificata (solo fetch) ............................................................................................... 7 
     Versione completa (fetch e execute) ............................................................................................ 7 
Parallelizzazione del caricamento del MAR ........................................................................................ 9 
     SET (000) ................................................................................................................................... 10 
     LD (001)..................................................................................................................................... 10 
     ST (002) ..................................................................................................................................... 10 
     ADD (003) ................................................................................................................................. 10 
     SUB (004) .................................................................................................................................. 10 
     INC (005) ................................................................................................................................... 10 
     DEC (006) .................................................................................................................................. 10 
Le istruzioni di salto........................................................................................................................... 11 
Codice operativo e tempi di clock...................................................................................................... 12 
Esempi di programmi per l’architettura ............................................................................................. 13 
   Somma di due numeri .................................................................................................................... 13 
   Prodotto di due numeri................................................................................................................... 14 
Implementazione micro programmata dell’unità di controllo ........................................................... 15 
   Versione senza salti........................................................................................................................ 15 
   Codifica delle istruzioni ................................................................................................................. 17 
   Versione completa con i salti ......................................................................................................... 17 


Introduzione
Il processore di esempio che considereremo ha una struttura interna a singolo bus a 32 bit per lo
scambio di informazioni tra i registri. Le connessioni esterne avvengono tramite un bus dati a 32 bit
e un bus indirizzi a 20 bit. La scelta di avere un bus indirizzi così piccolo (consente di indirizzare
 220 (=1 Mega) parole di memoria) è dovuta alla volontà di evitare istruzioni con lunghezza
variabile. Inizialmente considereremo che la memoria abbia un parallelismo di 32 bit, cioè ad ogni
indirizzo corrisponde una diversa parola di 4 Byte, mentre solo successivamente vedremo come
modificare questa architettura per indirizzare i singoli byte.



                                                                                                                                                          1
Struttura
Internamente il processore è dotato di un registro accumulatore da 32 bit (ACC), di un Memory
Data Register da 32 bit (MDR), di un Memory Address Register da 20 bit (MAR), di un Program
Counter da 20 bit (PC), di un Instruction Register da 32 bit (IR), di due registri relativi alla ALU da
32 bit (ALUA e ALUOUT) e da un registro di FLAG che contiene 4 bit di condizione (Zero, Carry,
Negativo e Overflow). Le connessioni sono illustrate in figura:
                                                                                  ZA
                                                                          0
                                                                                  0
                                                                                               Cin
                          ACC
                                                                                  1


                            IR                                 ALUA                       A
                                                                                              OUT
                          MDR                                                             B
       D0-31




                                 MAR                              ALUOUT
           A0-19




                                 PC                                                           FLAG


I registri connessi al bus hanno tutti un segnale di abilitazione in lettura (OE), cioè abilitano i buffer
tri-state che li connettono al bus, e uno in scrittura (IE), tranne ALUA che è abilitato sempre in
lettura verso la ALU (l’uscita dei flip-flop non passa per un buffer). Inoltre il MDR dispone di due
segnali MDRBUSOE e MDRBUSIE che consentono di attivare l’output e l’input dal bus dati. MDRIE e
MDRBUSIE non possono essere attivi contemporaneamente. MDRBUSOE viene portato all’esterno
come segnale di Write (WR) per la memoria e MDRBUSIE è connesso al Read (RD) della memoria
(la memoria è in lettura e pone i dati sul data bus ed MDR è in scrittura e memorizza tali dati).

Il segnale ZA comanda il multiplexer posto all’ingresso A della ALU e consente di inviare uno zero
alla porta A oppure l’output di ALUA. La porta B è sempre connessa al bus. Il registro FLAG
dispone di un segnale di abilitazione FLAGIE per campionare lo stato della ALU. La ALU è molto
semplice e consente di eseguire le seguenti operazioni:

                                       S1    S0   Operazione
                                       0     0    A and B
                                       0     1    A or B
                                       1     0    A + B + Cin
                                       1     1    A + B’ + Cin


La ALU è costituita da 32 blocchi come il seguente:




2
I segnali di Carry sono connessi in cascata tra di loro, i segnali di zero (Z) e negato (N) vengono
generati rispettivamente dal negato della somma logica di tutti i bit e dal bit più significativo di
ALUOUT. Il Carry della ALU (C) viene generato dal carry out del blocco corrispondente ai bit più
significativi (il bit 31), mentre l’overflow è dato dall XOR dei carry out 30 e 31.

Concludendo sono necessari i seguenti segnali di controllo:

 0    ACCOE
 1    ACCIE
 2    MDROE
 3    MDRIE
 4    MDRBUSOE
 5    MDRBUSIE
 6    MAROE
 7    MARIE
 8    IROE
 9    IRIE
 10   PCOE
 11   PCIE
 12   ALUAIE
 13   ALUOUTOE
 14   ALUOUTIE
 15   FLAGIE
 16   ZA
 17   Cin
 18   S0
 19   S1

Formato delle istruzioni
Per avere una architettura semplice, vale la pena sacrificare un po’ di praticità dal set di istruzioni,
quindi avere meno possibilità, ma ridurre lo sforzo nella realizzazione dell’unità di controllo.
Le istruzioni sono tutte composte da un primo campo a 12 bit che identifica il codice operativo e un
secondo campo a 20 bit che contiene un indirizzo. La funzione dell’indirizzo dipende dall’istruzione
implementata. Questa architettura semplice consente di realizzare numerose funzioni, ma molto
difficilmente si potrà lavorare con dati di dimensione inferiore a 32 bit (come dei caratteri per fare

                                                                                                      3
un esempio) o utilizzare indirizzi negativi (come spostamento per indirizzamenti indiretti). Quindi
la semplicità viene poi pagata in termini di realismo del processore.

31                                   20 19                                                              0
      Codice operativo (opcode)                                  Indirizzo (addr)

Microistruzioni
Tre sono le possibili tipologie di microistruzioni che si possono realizzare: i trasferimenti tra
registri, i trasferimenti con la memoria e le operazioni di ALU. Per i trasferimenti tra registri è
necessario abilitare in scrittura il registro destinazione e in lettura il registro sorgente. È necessario
verificare che con questo schema il campionamento avvenga al momento giusto, per esempio sul
fronte di salita del clock, in modo che il dato venga campionato alla fine del periodo di clock. Ad
esempio la microistruzione
        MAR PC
viene realizzata con MARIE=1 e PCOE=1. I dati scambiati con la memoria richiedono un proprio
ciclo di clock per il campionamento dei dati da parte della memoria (in scrittura) o del MDR (in
lettura). Durante questi trasferimenti il bus locale (interno al processore) non è utilizzato ed è quindi
possibile sfruttarlo per altre operazioni. Siccome il MAR è sempre attivo sul bus indirizzi, è
sufficiente utilizzare i due segnali di controllo del MDR per eseguire le microoperazioni relative
alla memoria:
Read MDR M[MAR]                         MDRBUSIE=1
Write M[MAR] MDR                        MDRBUSOE=1
Le operazioni di ALU hanno bisogno di tutti e quattro i segnali ZA, Cin, S1 e S0 e quindi la tabella
di verità per le operazioni di ALU diventa:

 S1    S0 ZA Cin Operazione                             Risultato
 0     00    -   0 and B                                Sempre 0 (può servire per avere uno zero da
                                                        usare con il decremento)
 0     0    1     -     A and B                         AND
 0     1    0     -     0 or B                          B (inutile)
 0     1    1     -     A or B                          OR
 1     0    0     0     0+B                             B (inutile)
 1     0    0     1     0+B+1                           Incremento
 1     0    1     0     A+B                             Somma
 1     0    1     1     A+B+1                           Somma e incrementa (inutile)
 1     1    0     0     0 + B’                          NOT
 1     1    0     1     0 + B’ + 1                      Negativo, cioè –B
 1     1    1     0     A + B’                          Sottrae e decrementa (può servire per fare un
                                                        decremento)
 1     1    1     1     A + B’ + 1                      Sottrazione

Ogni operazione di ALU necessita inoltre di un registro abilitato in lettura per avere un dato nel
canale B.
Le microistruzioni della ALU vengono sempre scritte specificando prima il canale A, cioè ALUA o
0, poi indicando l’operazione (and, or, +), poi il canale B, cioè il registro abilitato in lettura in forma
vera o negata e infine, se necessario, il valore del Cin. Il risultato viene sempre portato in
ALUOUT. Ad esempio volendo sottrarre il MDR all’accumulatore si indica:
        ALUA ACC
        ALUOUT ALUA + MDR’ + 1



4
Ciclo delle istruzioni
Ogni operazione, come avviene tradizionalmente, è composta da due fasi: Fetch e Execute. La fase
di fetch è seguita sempre da una sottofase che a volte viene indicata come Decode, ma che in questo
caso non è altro che l’incremento del program counter, dato che la decodifica non coinvolge alcun
registro di stato.

Fetch
Le microistruzioni di questa fase sono comuni a tutte le istruzioni:
        MAR PC
        MDR M[MAR]
        IR MDR
È inoltre necessario, come detto, incrementare il PC:
        ALUOUT 0 + PC + 1
        PC ALUOUT
Dal momento che non vi è necessità di tenere separate le due operazioni, possiamo sfruttare il fatto
che durante la lettura il bus locale non viene utilizzato e che durante la prima microistruzione PC sta
già pilotando il bus e possiamo sfruttarlo per effettuare la somma.
Quindi la fase di fetch definitiva diventa:
        MAR PC, ALUOUT 0 + PC + 1
        MDR M[MAR], PC ALUOUT
        IR MDR

Execute
Per delineare le possibili tipologie di istruzioni bisogna considerare che l’architettura ad
accumulatore lavora sempre con la memoria, quindi saranno certo necessarie due operazioni di
lettura e scrittura dell’accumulatore, poi ci saranno alcune operazioni aritmetiche che riguardano il
solo accumulatore. Prenderemo in considerazione in seguito le istruzioni di controllo.

Set (SET)
Volendo impostare in modo immediato il contenuto dell’accumulatore, è possibile realizzare una
istruzione molto semplice che prende il campo ADDR dell’istruzione e lo copia in ACC. Ad
esempio si potrebbe fare:
        MAR IR(addr)
        ACC MAR
Il passaggio per il MAR ci permette di “eliminare” l’opcode, e di trasferire in ACC solo i 20 bit
meno significativi. Una soluzione più brutale potrebbe essere questa:
        ACC IR(addr)
Purtroppo sappiamo che in questo modo in ACC andrebbe a finire anche l’opcode dell’istruzione
SET. La soluzione semplice per questo problema è quindi far sì che questo opcode sia 0!
Ovviamente questo impone dei vincoli progettuali, quindi in generale non sembra una buona idea.

Load (LD)
L’operazione di load carica il contenuto della memoria all’indirizzo specificato nell’accumulatore:
       MAR IR(addr)
       MDR M[MAR]
       ACC MDR

Store (ST)
L’operazione di store scrive il contenuto dell’accumulatore in memoria all’indirizzo specificato:

                                                                                                      5
MAR IR(addr)
       MDR ACC
       M[MAR] MDR

Add (ADD)
La somma esegue l’operazione concettuale ACC = ACC+M[addr]:
       MAR IR(addr)
       MDR M[MAR], ALUA ACC
       ALUOUT ALUA + MDR
       ACC ALUOUT
Vale la pena notare che si può sfruttare il momento di lettura dell’operando per caricare il registro
ALUA con il contenuto dell’accumulatore.

Subtract (SUB)
La differenza non gode della proprietà commutativa, quindi è necessario specificare quale dei due
operandi sia il minuendo e quale il sottraendo. SUB esegue l’operazione ACC = ACC-M[addr]:
         MAR IR(addr)
         MDR M[MAR], ALUA ACC
         ALUOUT ALUA + MDR’ + 1
         ACC ALUOUT
Sarebbe possibile definire anche l’operazione inversa, cioè ACC = M[addr]-ACC. E’ comunque
possibile ottenere lo stesso risultato utilizzando questa sottrazione e negando (in senso aritmetico)
poi il risultato.

Increment (INC) e Decrement (DEC)
Solo come ulteriore esempio presentiamo le funzioni di incremento e decremento. Per l’incremento
non ci sono particolari problemi, dato che è una classica istruzione di ALU priva di parametri:
        ALUOUT 0 + ACC + 1
        ACC ALUOUT
Per quanto riguarda il decremento è possibile sfruttare la sottrazione con decremento, cioè sommare
all’accumulatore il negato di zero che in complemento a due è -1. Per fare questo però bisogna
caricare il canale B della ALU con uno zero che generiamo usando l’AND con uno zero.
        ALUA ACC, ALUOUT 0 and ACC
        ALUOUT ALUA + ALUOUT’
        ACC ALUOUT
Questo esempio è un po’ più complesso, dato che si utilizza il fatto che non è necessario attendere il
corretto trasferimento di ACC in ALUA per preparare ALUOUT con uno 0, dato che il canale B è
assolutamente ininfluente e quindi possiamo in parallelo usare ACC per pilotare la porta B della
ALU e caricare ALUA. Inoltre si vede come possiamo utilizzare ALUOUT come registro sorgente
e come registro destinazione.

Unità di controllo
Per progettare l’unità di controllo è necessario identificare il valore di ogni segnale di controllo (i 19
che abbiamo visto precedentemente) in ogni “istante”. Gli istanti in realtà sono quantizzati dal
segnale di clock che quindi identifica una serie di fasi corrispondenti alle singole microistruzioni.
Chiameremo queste fasi con T seguito da un numero (cominciando da T0), per indicare il periodo di
clock a cui ci stiamo riferendo. È possibile vedere ogni periodo di clock come un indicatore dello
stato presente in un automa a stati finiti che secondo la rappresentazione di Moore associa as ogni
stato un valore delle uscite. Lo stato futuro dipenderà allora dallo stato presente e dagli ingressi. Gli
ingressi in questo caso sono identificati unicamente dal contenuto del campo OPCODE dell’IR. Per

6
chiarezza sul significato dei T, quindi continueremo a indicare T5 la sesta microistruzione
indipendentemente dall’istruzione di cui fa parte.

Implementazione cablata

Versione semplificata (solo fetch)
Riprendiamo in considerazione la fase di fetch e limitiamoci a specificare i segnali interessati a
questa fase, pensiamo quindi ad un processore che faccia solo e unicamente il fetch delle istruzioni
senza eseguirle. Indichiamo poi accanto ad ogni microistruzioni i segnali che devono essere posti a
1 e il valore dei segnali dell ALU.

T0:    MAR       PC, ALUOUT        0 + PC + 1       MARIE, PCOE, ALUOUTIE,
                                                    ZA=0, Cin=1, S1S0=10
T1:    MDR M[MAR], PC              ALUOUT           MDRBUSIE, PCIE, ALUOUTOE
T2:    IR MDR                                       IRIE, MDROE

Da questo schema risulta molto semplice associare ad ogni segnale la sua funzione combinatoria
dipendente solo da T0,T1 e T2 che per la verità hanno solo tre possibili combinazioni, dato che
sono stati mutuamente esclusivi. Lo schema completo dei segnali per questo processore che fa solo
fetch, è il seguente:

MARIE = T0
PCOE = T0
ALUOUTIE = T0
ZA = T0’
Cin = T0
S1 = T0
S0 = T0’
MDRBUSIE = T1
PCIE = T1
ALUOUTOE = T1
IRIE = T2
MDROE = T2

Bisogna poi specificare la funzione di stato futuro per i T e in questo caso è veramente semplice:

T0f = T2
T1f = T0
T2f = T1


Versione completa (fetch e execute)
Passiamo invece ora a considerare l’unità di controllo necessaria a implementare un processore con
tutte le sei istruzioni viste in precedenza. La fase di fetch è esattamente quella vista in precedenza,
quindi andiamo a dettagliare solo le varie possibilità per l’execute.
Il campo OPCODE di IR è direttamente connesso (prima dei buffer di OE) ad un decoder nell’unità
di controllo che consente per ogni istruzione di generare un segnale corrispondente, ad esempio
SET potrebbe essere generato dall’opcode (in esadecimale) 000, LD da 001, ST da 002 e così via.
Non ci sono particolari motivi per avere una codifica o un’altra in questo caso.




                                                                                                     7
SET:
T3,SET:        MAR      IR(addr)              MARIE, IROE
T4,SET:        ACC      MAR                   ACCIE, MAROE

LD:
T3,LD:         MAR      IR(addr)              MARIE, IROE
T4,LD:         MDR      M[MAR]                MDRBUSIE
T5,LD:         ACC      MDR                   ACCIE, MDROE

ST:
T3,ST:         MAR IR(addr)                   MARIE, IROE
T4,ST:         MDR ACC                        MDRIE, ACCOE
T5,ST:         M[MAR] MDR                     MDRBUSOE

ADD:
T3,ADD:        MAR IR(addr)                                  MARIE, IROE
T4,ADD:        MDR M[MAR], ALUA ACC                          MDRBUSIE, ALUAIE, ACCOE
T5,ADD:        ALUOUT ALUA + MDR                             ALUOUTIE, MDROE
                                                             ZA=1, Cin=0, S1S0=10
T6,ADD:        ACC      ALUOUT                               ACCIE, ALUOUTOE

SUB:
T3,SUB:        MAR IR(addr)                                  MARIE, IROE
T4,SUB:        MDR M[MAR], ALUA ACC                          MDRBUSIE, ALUAIE, ACCOE
T5,SUB:        ALUOUT ALUA – MDR’ + 1                        ALUOUTIE, MDROE
                                                             ZA=1, Cin=1, S1S0=11
T6,SUB:        ACC      ALUOUT                               ACCIE, ALUOUTOE

INC:
T3,INC:        ALUOUT         0 + ACC + 1                    ALUOUTIE, ACCOE
                                                             ZA=0, Cin=1, S1S0=10
T4,INC:        ACC      ALUOUT                               ACCIE, ALUOUTOE

DEC:
T3,DEC:        ALUA       ACC, ALUOUT
                                 0 and ACC ALUAIE, ACCOE, ALUOUTIE,
                                           ZA=0, S1S0=00
T4,DEC:        ALUOUT ALUA + ALUOUT’       ALUOUTIE, ALUOUTOE,
                                           ZA=1, Cin=0, S1S0=11
T5,DEC:        ACC ALUOUT                  ACCIE, ALUOUTOE

Per sintetizzare i segnali di controllo, è sufficiente mettere in AND l’indicatore dell’istante in cui il
segnale si deve attivare (deve essere posto a 1) con il segnale relativo all’istruzione corrente. Si
possono poi usare le varie leggi dell’algebra di Boole per semplificare l’espressione, risparmiando
sul numero di porte logiche necessarie:

0   ACCOE = T3·(INC + DEC) + T4·(ST + ADD + SUB)
1   ACCIE = T4·(SET + INC) + T5·(LD + DEC) + T6·(ADD + SUB)
2   MDROE = T2 + T5·(LD + ADD + SUB)
3   MDRIE = T4·ST
4   MDRBUSOE = T5·ST
5   MDRBUSIE = T1 + T4·(LD + ADD + SUB)
8
6    MARIE = T0 + T3·(SET + LD + ST + ADD + SUB)
7    MAROE = T4·SET
8    IROE = T3·(SET + LD + ST + ADD + SUB)
9    IRIE = T2
10   PCOE = T0
11   PCIE = T1
12   ALUAIE = T3·DEC + T4·(ADD + SUB)
13   ALUOUTOE = T1 + T4·(INC + DEC) + T5·DEC + T6·(ADD + SUB)
14   ALUOUTIE = T0 + T3·(INC + DEC) + T4·DEC + T5·(ADD+SUB)
15   FLAGIE = 0
16   ZA = T4·DEC + T5·(ADD+SUB)
17   Cin = T0 + T3·INC + T5·SUB
18   S1 = T0 + T3·INC + T5·(ADD + SUB)
19   S0 = T4·DEC + T5·SUB

La codifica sopra riportata è certamente non minima, dato che assomiglia fortemente ad una sintesi
canonica SP. Non vengono assolutamente utilizzate le indifferenze anche banalmente verificabili.
Per esempio S0 può essere messo ad 1 in T4 sempre, dato che nessun’altra istruzione utilizza S0 in
T4, quindi si potrebbe risparmiare l’AND con il segnale DEC.
Nella realizzazione di una unità di controllo cablata, il numero di segnali cresce enormemente
rispetto a questo esempio, quindi riduzioni di questo tipo diventano indispensabili per evitare
dimensioni eccessive. Inoltre sostituire i segnali T0-6 con una loro codifica, ridurrebbe
notevolmente il numero di segnali da trasportare nell’unità di controllo.
La sintesi SP è piuttosto naturale per questo tipo di sistema, dato che abbiamo supposto i segnali
attivi ad uno. Dal momento che solo pochi di questi segnali si attivano contemporaneamente,
possiamo supporre che per la maggior parte dei casi l’uscita debba essere a 0, riducendo il numero
di mintermini da utilizzare. Parlare di mintermini in questo caso non è realmente appropriato, dato
che le varie configurazioni sono già decodificate, quindi dire ad esempio T3·INC sottointende
chiaramente che T0, T1, T2, T4, T5, T6, LD, ST, ADD, SUB e DEC siano a zero (evitandoci
dunque di specificarli nell’espressione).
È da notare inoltre che FLAGIE è stato volutamente ignorato, dato che in realtà nessuna istruzione
ha bisogno dei flag, anche se certamente dovrebbero impostarli tutte le istruzioni aritmetiche.
La sintesi dello stato futuro diventa leggermente più complessa visto che ci sono istruzioni con
lunghezza variabile. Quindi ad esempio se sono nello stato T4 e l’istruzione è una INC devo andare
allo stato T0, mentre se sono in una DEC devo andare in T5. Proseguendo con la sintesi intuitiva
fatta finora, si ottiene questo risultato:

T0f = T4·(SET + INC) + T5·(LD + ST + DEC) + T6·(ADD + SUB)
T1f = T0
T2f = T1
T3f = T2
T4f = T3
T5f = T4·(LD + ST + ADD + SUB + DEC)
T6f = T5·(ADD + SUB)

Parallelizzazione del caricamento del MAR
L’architettura appena illustrata è ancora incompleta, dato che manca di un aspetto fondamentale,
cioè la gestione dei salti che consente di eseguire istruzioni diverse a seconda di risultati o output.
Però è comunque utile considerare una otimizzazione a quanto illustrato finora.
Abbiamo già visto che se un registro sta pilotando il bus, più di un dispositivo può leggere e
memorizzare il contenuto. Questo può essere utilizzato per eliminare la prima microistruzione di 5

                                                                                                     9
delle istruzioni già viste. Infatti SET, LD, ST, ADD e SUB sfruttano l’indirizzo presente nell’IR per
leggere dalla memoria e devono trasferirlo nel MAR. Si deve altresì notare che il contenuto del
MAR è ininfluente sulle altre microperazioni (a parte l’accesso in memoria). Quindi si potrebbe
sfruttare la terza istruzione del fetch per preparare già il MAR con il contenuto dell’IR. Nel MAR si
dovrebbe trasferire solo il campo Address dell’IR, ma il MAR è collegato ai 20 bit meno
significativi del bus, cioè proprio al campo richiesto, quindi qualsiasi cosa ci sia negli altri bit è
completamente ininfluente. Facendo l’esempio dell’istruzione LD, il risultato sarebbe il seguente:
        MAR PC, ALUOUT 0 + PC + 1
        MDR M[MAR], PC ALUOUT
        IR MDR, MAR MDR                                <<< Qui viene fatta l’aggiunta
        MAR ← IR(addr)                                 <<< Questa μ-istruzione è eliminata
        MDR M[MAR]
        ACC MDR
Questa modifica non influenza in alcun modo le altre istruzioni, dato che non aggiunge nulla alle
istruzioni che non utilizzano la memoria (INC e DEC).
In sostanza le microistruzioni delle varie istruzioni diventano (tra parentesi è indicato il codice
operativo che useremo come riferimento):

SET (000)
       ACC      MAR

LD (001)
       MDR      M[MAR]
       ACC      MDR

ST (002)
       MDR ACC
       M[MAR] MDR

ADD (003)
       MDR M[MAR], ALUA ACC
       ALUOUT ALUA + MDR
       ACC ALUOUT

SUB (004)
       MDR M[MAR], ALUA ACC
       ALUOUT ALUA + MDR’ + 1
       ACC ALUOUT

INC (005)
       ALUOUT 0 + ACC + 1
       ACC ALUOUT

DEC (006)
       ALUA ACC, ALUOUT 0 and ACC
       ALUOUT ALUA + ALUOUT’
       ACC ALUOUT




10
I segnali di controllo da generare diventano allora:

ACCOE = T3·(ST + ADD + SUB + INC + DEC)
ACCIE = T3·SET + T4·(LD + INC) + T5·(ADD + SUB + DEC)
MDROE = T2 + T4·(LD + ADD + SUB)
MDRIE = T3·ST
MDRBUSOE = T4·ST
MDRBUSIE = T1 + T3·(LD + ADD + SUB)
MARIE = T0 + T2
MAROE = T3·SET
IROE = 0
IRIE = T2
PCOE = T0
PCIE = T1
ALUAIE = T3·(ADD + SUB + DEC)
ALUOUTOE = T1 + T4·(INC + DEC) + T5·(ADD + SUB + DEC)
ALUOUTIE = T0 + T3·(INC + DEC) + T4·(ADD + SUB + DEC)
FLAGIE = 0
ZA = T4·(ADD + SUB + DEC)
Cin = T0 + T3·INC + T4·SUB
S1 = T0 + T3·INC + T4·(ADD + SUB)
S0 = T4·(SUB + DEC)

T0f = T3·SET + T4·(LD + ST + INC) + T5·(ADD + SUB + DEC)
T1f = T0
T2f = T1
T3f = T2
T4f = T3·(LD + ST + ADD + SUB + INC + DEC)
T5f = T4·(ADD + SUB + DEC)


Le istruzioni di salto
Parte integrante della programmazione sono le istruzioni di salto che consentono di modificare il
punto di esecuzione del programma. In particolare, fondamentali per implementare funzioni logiche
complesse servono istruzioni di salto condizionato, istruzioni che eseguono la modifica al PC solo
se si verifica una determinata situazione. Le “situazioni” che tipicamente si prendono in
considerazione sono i risultati delle operazioni aritmetiche precedenti. Per tenerne conto abbiamo
già accennato alla presenza di un registro FLAG che abbiamo ignorato finora. Questo registro deve
essere aggiornato con i segnali provenienti dalla ALU ad ogni operazione richiesta dall’utente, cioè
se consideriamo l’istruzione ADD comprensiva di Fetch ed Execute (nella prima versione senza
caricamento parallelo di IR e MAR in T2):

T0:            MAR      PC, ALUOUT         4 + PC         MARIE, PCOE, ALUOUTIE,
                                                          ZA=0, QA=1, Cin=0, S1S0=10
T1:            MDR M[MAR], PC ALUOUT                      MDRBUSIE, PCIE, ALUOUTOE
T2:            IR MDR                                     IRIE, MDROE
T3:            MAR IR(addr)                               MARIE, IROE
T4,ADD:        MDR M[MAR], ALUA ACC                       MDRBUSIE, ALUAIE, ACCOE
T5,ADD:        ALUOUT ALUA + MDR                          ALUOUTIE, MDROE
                                                          ZA=1, Cin=0, S1S0=10, FLAGIE
T6,ADD:        ACC      ALUOUT                            ACCIE, ALUOUTOE


                                                                                                 11
vediamo che vengono eseguite due operazioni di ALU, ma l’unica che deve essere memorizzata nei
FLAG è la seconda, cioè quella relativa ai dati dell’utente, cioè la ADD. I segnali provenienti dai
flag arrivano direttamente alla unità di controllo che li utilizza per realizzare le funzioni logiche
opportune. Iniziamo considerando la struttura di un salto incondizionato:

JMP
T3,JMP:        PC     IR(addr)                               PCIE, IROE

Questo è tutto. Insomma si prende il contenuto del campo ADDR di IR e lo si mette in PC. Al fetch
successivo il PC è già stato modificato opportunamente. Che cosa cambia in un salto condizionato?
semplicemente il trasferimento in PC avviene solo se si verifica la condizione richiesta, quindi se
per esempio vogliamo considerare un salto in caso di risultato Zero dell’operazione precedente:

JZ
T3,JZ,Z:       PC     IR(addr)                               PCIE, IROE

Aggiungiamo alla condizione da verificare anche il flag interessato.
I salti disponibili in questa architettura saranno (vista la ALU a disposizione):

JZ     salta se il flag Z vale 1
JNZ    salta se il flag Z vale 0
JO     salta se il flag O vale 1
JNO    salta se il flag O vale 0
JN     salta se il flag N vale 1
JNN    salta se il flag N vale 0
JC     salta se il flag C vale 1
JNC    salta se il flag C vale 0

Come si realizza questa condizione nell’unità di controllo? Nel caso cablato la soluzione è
particolarmente semplice, infatti il segnale Zero è disponibile già durante T2 (e anche prima) quindi
è sufficiente evitare di andare in T3 se l’istruzione è JZ e Z=0. Purtroppo però JZ non è disponibile
fino a T3, dato che viene calcolato da IR e quindi aspettiamo T3, non facendo niente nel caso di
salto non eseguito (condizione falsa). Consideriamo quindi di aggiungere l’istruzione JZ
all’implementazione cablata vista in precedenza, occupandoci solo dei segnali interessati
dall’istruzione. Queste sono le modifiche necessarie per una realizzazione letterale, cioè verificando
la condizione in T3 (le modifiche sono evidenziate):

IROE = T3·(JMP + JZ·Z + JNZ·Z’ + JO·O + JNO·O’ + JN·N + JNN·N’ + JC·C + JNC·C’)
PCIE = T1 + T3·(JMP + JZ·Z + JNZ·Z’ + JO·O + JNO·O’ + JN·N + JNN·N’ + JC·C + JNC·C’)
T0f = T3·(SET + JMP+JZ+JNZ+JO+JNO+JN+JNN+JC+JNC) + T4·(LD + ST + INC) + T5·(ADD
       + SUB + DEC)


Codice operativo e tempi di clock
Nella tabella seguente sono riportati, per ogni istruzione il codice operativo in decimale e
esadecimale, il codice mnemonico identificativo e il tempo di clock necessario all’esecuzione,
tenendo conto del caricamento anticipato del MAR, con e senza i cicli di clock necessari alla fase di
fetch.




12
Dec   Hex    Istruzione   Clock   Con Fetch
0     000    SET          1       4
1     001    LD           2       5
2     002    ST           2       5
3     003    ADD          3       6
4     004    SUB          3       6
5     005    INC          2       5
6     006    DEC          3       6
7     007    JMP          1       4
8     008    JZ           1       4
9     009    JNZ          1       4
10    00A    JO           1       4
11    00B    JNO          1       4
12    00C    JN           1       4
13    00D    JNN          1       4
14    00E    JC           1       4
15    00F    JNC          1       4


Esempi di programmi per l’architettura
Con la struttura delineata finora è possibile realizzare alcuni programmi molto semplici utilizzando
una sintassi nota come linguaggio Assembly. In questo caso non esistono regole sulla sintassi, dato
che ogni costruttore ne inventa di sue. Senza volere entrare nei dettagli delle caratteristiche
dell’Assembly, basti sapere che su ogni riga si specifica il codice operativo simbolico (detto anche
mnemonico) e gli eventuali operandi che possono essere numerici o simbolici, nel senso che non è
necessario calcolare l’indirizzo delle variabili in memoria, dato che può farlo un programma per
noi. Questo programma si chiama Assemblatore (Assembler).

Somma di due numeri
Vediamo un semplicissimo programma di esempio che somma due valori numerici a 32 bit A e B
impostati in memoria dal caricamento del programma e mette il risultato in una variabile C:

               ld             A
               add            B
               st             C

A:             00001234h
B:             0056789Ah
C:             0

Solitamente i valori esadecimali nei programmi assembly vengono terminati con una h. Inoltre vale
la pena notare che si è utilizzata una sintassi specifica per indicare che una linea non contiene
un’istruzione, ma un valore numerico che non deve essere interpretato.
Supponiamo che questo programma venga convertito in codice macchina e caricato in memoria a
partire dall’indirizzo 0. Utilizzando la codifica degli opcode illustrata precedentemente e scrivendo i
valori in esadecimale, quello che troveremmo sarebbe:




                                                                                                    13
32 bit
                                                12 bit 20 bit
                                      00000     001     0000C
                                      00004     003     00010
                                      00008     002     00014
                                      0000C     000     01234
                                      00010     005     6789A
                                      00014     000     00000

Caricato il programma in memoria, l’esecuzione potrebbe iniziare a partire dall’indirizzo 00000. Il
problema è che terminata la terza operazione il processore eseguirebbe il fetch di una ulteriore
istruzione, in particolare di 00001234, che verrebbe interpretata come SET 01234! Insomma, il
problema è che non disponiamo di una istruzione per interrompere il fetch, cioè per fermare il
processore. Nella realtà questo non è un problema, dato che i processori continuano ad eseguire un
programma di base che solitamente è chiamato sistema operativo. Ma per non dilungarci e andare
fuori tema, limitiamoci a considerare come sia possibile interrompere il ciclo fetch/execute. Questo
effetto si può ottenere con un JMP all’indirizzo dell’istruzione. Il nostro programma a questo punto
diventa:

               ld             A
               add            B
               st             C
Fine:          jmp            Fine

A:             00001234h
B:             0056789Ah
C:             0

Si è utilizzato il simbolo Fine per definire un indirizzo, e in particolare l’indirizzo dell’istruzione
JMP. Anche negli esempi successivi non specificheremo gli indirizzi, ma sfrutteremo i due punti
per definire etichette simboliche da utilizzare come argomenti delle istruzioni. A questo punto
possiamo passare ad un esempio più complesso.

Prodotto di due numeri
Il prodotto di due numeri può essere eseguito in diversi modi, ad esempio con la tecnica che ci è
stata insegnata alle elementari che consiste nell’imparare delle moltiplicazioni fondamentali (le
tabelline) ed estenderle poi opportunamente. La versione più semplice però è l’utilizzo della
definizione, cioè sommare il moltiplicando tante volte quante indicate dal moltiplicatore. È da
sottolineare anche che questa tecnica è anche la più lenta e sconsigliabile in applicazioni reali. Ecco
come potrebbe apparire un programma che moltiplica A e B scrivendo il risultato in C:

Ancora:        ld             C
               add            A
               st             C
               ld             B
               dec            B
               jnz            Ancora
Fine:          jmp            Fine

A:             5
B:             6
C:             0

14
Alla fine di questo programma, il valore di B è stato “rovinato”, dato che lo si è utilizzato come
contatore per verificare quando terminare il ciclo. È inoltre importante notare come sia
fondamentale avere a disposizione una locazione di memoria inizializzata a zero, dato che questa
viene subito utilizzata come raccoglitore iniziale del risultato della moltiplicazione.


Implementazione micro programmata dell’unità di controllo
Versione senza salti
Un approccio alternativo alla realizzazione dell’unità di controllo, consiste nel memorizzare ogni
microistruzione come l’insieme di tutti i segnali di controllo con il loro valore. Questo necessita di
una struttura di memorizzazione (RAM, EEPROM, ROM) alla quale si potrà accedere con un
indirizzo. Al termine del ciclo di clock sarà necessario modificare opportunamente l’indirizzo
prelevando i segnali corretti. Tutto questo lo si può realizzare con un micro Program Counter (μPC)
che può essere incrementato per passare alla microistruzione successiva, può essere azzerato al
termine dell’istruzione, per tornare alla fase di fetch (comune a tutte le istruzioni) e può essere
caricato con il contenuto dell’OPCODE, che diventa un indirizzo nella memoria delle
microistruzioni. Lo schema seguente dovrebbe chiarire il concetto:



                     0
                         0
                                                                            micro            control
    op code                           µPC                    address
                         1
                                                                           control           signals
                         2


                                   Incremento                           microcode memory




Secondo questo schema sono necessari in ogni microistruzione anche i segnali di controllo per il
μPC che si limitano a selezionare quale dei tre ingressi del multiplexer deve essere utilizzato per il
passo successivo. Sono quindi necessari due bit aggiuntivi MC0 e MC1 che selezioneranno
l’ingresso:

                              MC1     MC0    Selezione
                              0       0      0 (μsalto al fetch)
                              0       1      μsalto all’opcode
                              1       0      prossima μistruzione
                              1       1      X (non valido)

Ci sono vari modi per evitare si avere un salto specifico al fetch, ma li vedremo in seguito.
Passiamo invece alla implementazione della architettura che abbiamo illustrato. Sono necessari 19
bit per i segnali di controllo più due per il microcontrollo. Utilizzando la numerazione della prima
tabella dei segnali di controllo possiamo assegnare 19 a MC0 e 20 a MC1 ottenendo uno schema a
21 colonne come il seguente:




                                                                                                   15
ALUOUTOE
                                                                        ALUOUTIE
     Operazione




                                                                                                                                                      MDRBUSOE
                                                                                                                                           MDRBUSIE
                  Indirizzo




                                                                                              ALUAIE
                                                               FLAGIE




                                                                                                                                                                         MDROE


                                                                                                                                                                                         ACCOE
                                                                                                                                   MARIE



                                                                                                                                                                 MDRIE


                                                                                                                                                                                 ACCIE
                                                                                                              PCOE
                              MC1
                                    MC0




                                                                                                                            IROE
                                                                                                       PCIE


                                                                                                                     IRIE
                                                    Cin
                                                          ZA
                                          S1
                                               S0
                              20 19 18         17 16 15 14 13 12 11 10 9                                             8      7       6       5          4          3       2       1       0
                               101              010         1          1                                                            1
 fetch            0
                               10                             1     1                                                                       1
                   1
                               01                                                                                    1                                                    1
                   2
                               10                                                                                           1       1
  LD              3
                               10                                                                                                           1
                   4
                               00                                                                                                                                         1       1
                   5
                               10                                                                                           1       1
  ST              6
                               10                                                                                                                                 1                       1
                   7
                               00                                                                                                                      1
                   8
                               10                                                                                           1       1
 ADD               9
                               10                                                              1                                            1                                             1
                  10
                               101             0    0     1              1                                                                                                1
                  11
                               00                                                   1                                                                                             1
                  12
                               10                                                                                           1       1
 SUB              13
                               10                                                              1                                            1                                             1
                  14
                               101             1    1     1              1                                                                                                1
                  15
                               00                                                   1                                                                                             1
                  16
                               101             0    1     0              1                                                                                                                1
 INC              17
                               00                                                   1                                                                                             1
                  18
                               100             0          0              1                     1                                                                                          1
 DEC              19
                               101             1    0     1              1          1
                  20
                               00                                                   1                                                                                             1
                  21

Gli spazi non riempiti contengono degli zeri. Questa soluzione prevede che il codice operativo sia
esattamente l’indirizzo nella memoria di controllo della prima microistruzione corrispondente
all’istruzione selezionata. Quindi ad esempio l’istruzione LD non sarebbe più 000 come
nell’esempio precedente, ma obbligatoriamente 003.

Purtroppo questa implementazione così come è stata presentata ha un bug sulla fase di esecuzione
del salto all’opcode. Infatti, nella terza microistruzione si trasferisce il contenuto dell’MDR in IR e
contemporaneamente si vorrebbe trasferire questo dato in μPC. Il problema è che i dati vengono
campionati sul fronte di salita del clock, quindi se si legge il contenuto di IR (anche solo il campo
OPCODE) nell’istante in cui questo campiona, si ricava il contenuto precedente dell’IR, quindi
l’indirizzo sbagliato. In realtà vuol dire che si fa il fetch di un’istruzione, ma si esegue la precedente
e questo potrebbe causare molti problemi. Sono possibili varie soluzioni, ma la più semplice –valida
solo per questo specifico caso– è quella di connettere il bus locale all’ingresso 1 del multiplexer di
selezione. In tal modo al termine della fase di fetch, quando viene eseguita la microistruzione (IR
    MDR), sullo stesso fronte di clock viene caricato il codice istruzione (proveniente da MDR) in
IR ed il solo campo OPCODE in uPC. È chiaro che la soluzione alternativa sarebbe inserire un’altra
microistruzione dopo il trasferimento all’IR, ad esempio posticipando PC             ALUOUT, purtroppo
in questo modo si aggiunge un ciclo di clock alla fase di fetch.




16
Codifica delle istruzioni
Abbiamo sottolineato come nel caso di microprogrammazione le istruzioni debbano essere
codificate in modo specifico per puntare all’indirizzo della microroutine corrispondente.
Effettivamente sarebbe più comodo poter utilizzare la stessa codifica utilizzata nel caso di
microarchitettura cablata. Una soluzione semplice si può realizzare specificando con l’op-code non
l’indirizzo, ma piuttosto il blocco di microistruzioni di interesse. Allineando i blocchi a indirizzi
multipli di una potenza di due e riservando loro uno spazio potenza di due, è sufficiente uno shift
cablato per ottenere il risultato voluto. Ad esempio, nel caso precedente sarebbe possibile utilizzare
blocchi da 4 microistruzioni, ristrutturando la memoria così:

                        Istruzione   opcode    Celle utilizzate   Lunghezza
                        Fetch        -         0,1,2              3
                        LD           001       4,5,6              3
                        ST           002       8,9,10             3
                        ADD          003       12,13,14,15        4
                        SUB          004       16,17,18,19        4
                        INC          005       20,21              2
                        DEC          006       24,25,26           3

In questo modo è possibile connettere il bit 2 dell’opcode al bit meno significativo del μPC
realizzando quindi uno shift a sinistra di due bit (moltiplicazione per 4, dimensione del blocco).
Sostanzialmente è come se si inserissero due zeri (con una codifica binaria) a destra del codice
operativo dell’istruzione, producendo così l’indirizzo del μPC.

                                                                  Memoria delle microistruzioni
LD     0000|0000|0001                      0000|0000|0000
ST     0000|0000|0010                      0000|0000|0001
ADD    0000|0000|0011                      0000|0000|0010
SUB    0000|0000|0100                      0000|0000|0011
INC    0000|0000|0101                      0000|0000|0100
DEC    0000|0000|0110                      0000|0000|0101
                                           0000|0000|0110
                                           0000|0000|0111
                                           0000|0000|1000
                                           0000|0000|1001
                                           0000|0000|1010
                                           0000|0000|1011
                                           0000|0000|1100
                                                                                 ...

Il difetto di questa soluzione è chiaramente lo spreco di memoria, evidente dall’indirizzo dell’ultima
microistruzione di DEC che è a 26 rispetto al 21 del caso precedente. È anche possibile pensare ad
una rom che si occupi di tradurre gli opcode in microindirizzi, ma ovviamente si complica
ulteriormente lo schema architetturale.

Versione completa con i salti
Il problema più grosso nella gestione dei segnali di controllo lo si ha con l’implementazione
microprogrammata che non consente di inviare direttamente in uscita il contenuto di un registro, ad
esempio Carry-out. Se alcuni eventi devono essere condizionati al valore dei registri di stato diventa
necessario prevedere l’hardware (multiplexer solitamente) per inviare i vari segnali e poi codificare
nel microcodice i segnali di controllo per decidere quale valore verrà effettivamente selezionato.
                                                                                                   17
Nel caso microprogrammato la questione è più complessa, dato che bisogna dotare il sequencer,
ovvero la parte di architettura che seleziona il prossimo valore del μPC, di ingressi dedicati ai Flag e
nella memoria delle microistruzioni prevedere dei selettori per questi segnali. Le soluzioni possibili
sono molteplici e noi ne vedremo solo una di esempio molto banale e probabilmente non delle
migliori, ma sicuramente semplice e di facile comprensione. Questa struttura si basa proprio sul
concetto che abbiamo visto sopra, cioè di passare da T2 a T3 in un salto condizionato solo se la
condizione specificata è vera. Per questo motivo si possono separare le tre possibilità previste nello
schema base (selezionate con MC1 e MC0) in due blocchi in cascata così:

                                            MC0
                                        0
                                             0
                                                    MC1
                                            1
                                                      0
                                                                     µPC
                        op code                       1



                                                                 Incremento


In questo modo abbiamo separato in due livelli concettuali la selezione, ovvero abbiamo un segnale
che ci dice se dobbiamo eseguire il decode oppure se dobbiamo usare l’altro multiplexer. Questo
multiplexer ci consente di procedere alla microistruzione successiva o di tornare al fetch. Per
comandare il multiplexer di incremento o fetch possiamo decidere in maniera secca 0 o 1 fissi
oppure possiamo lasciare che siano i FLAG a comandarlo. Nasce quindi l’esigenza di inserire un
ulteriore multiplexer (questa volta a 1 bit) per passare i segnali di controllo opportuni:

                                                                                        0
                                                                                        1
                                                                                        C
                                                                                        C’
                               0                                                        Z
                                                                                        Z’
                                                                                        N
                                    0                                                   N’
                                             MC3
                                    1
                                                                                       MC2-0
                                             0
                                                             µPC
                op code                      1



                                                          Incremento


I segnali di controllo MC0, MC1 e MC2 selezionano quale segnale deve decidere se eseguire il
Fetch o se incrementare μPC quindi volendo riprodurre il comportamento della microarchitettura
precedente è possibile utilizzare i segnali come in tabella:

         MC3     MC2     MC1    MC0     Funzione
         1       x       x      x       μsalto all’opcode
         0       0       0      0       0 (μsalto al fetch)
         0       0       0      1       prossima μistruzione (incremento)
         0       0       1      0       se C incremento, altrimenti fetch
         0       0       1      1       se C’ incremento, altrimenti fetch
         0       1       0      0       se Z incremento, altrimenti fetch
         0       1       0      1       se Z’ incremento, altrimenti fetch
18
0              1         1   0     se N incremento, altrimenti fetch
                  0              1         1   1     se N’ incremento, altrimenti fetch

A questo punto non è difficile realizzare i salti condizionati e non. Nella prossima tabella vediamo
la fase di fetch e la realizzazione dei salti. In questo caso si è utilizzata l’architettura con
indirizzamento al byte e il caricamento parallelo di IR e MAR in T2. Resta l’accortezza di ricordare
che il μPC carica i dati dal bus quando si legge l’opcode e non dal IR per quanto detto
precedentemente:




                                           ALUOUTOE
                                           ALUOUTIE
  Operazione




                                           MDRBUSOE
                                            MDRBUSIE
                Indirizzo




                                            ALUAIE
                                             FLAGIE




                                             MDROE

                                             ACCOE
                                             MARIE



                                             MDRIE

                                              ACCIE
                                              PCOE
                            MC3
                            MC2
                            MC1
                                              MC0




                                               IROE
                                               PCIE

                                               IRIE
                                                Cin
                                                QA
                                                ZA
                                                S1
                                                S0



                            23   22   21   20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
                             0    0    0    110010              1           1     1
fetch            0
                             0    0    0    1                       1    1          1
                 1
                             1    0    0    0                                 1   1       1
                 2
 …               …
                            0    0    0    0                               1          1
JMP              x
                            0    0    1    0
 JC             x+1
                            0    0    0    0                               1          1
                x+2
                            0    0    1    1
 JNC            x+3
                            0    0    0    0                               1          1
                x+4
                            0    1    0    0
  JZ           x+5
                            0    0    0    0                               1          1
                x+6
                            0    1    0    1
 JNZ           x+7
                            0    0    0    0                               1          1
                x+8
                            0    1    1    0
  JN            x+9
                            0    0    0    0                               1          1
               x+10
                            0    1    1    1
 JNN           x+11
                            0    0    0    0                               1          1
               x+12
                 …


Il grosso difetto di questa soluzione è che diventa necessario allungare di un ciclo di clock ogni
istruzione di salto. Infatti non è possibile caricare la nuova istruzione e contemporaneamente sapere
già quale condizione verificare. Viene quindi introdotta una microistruzione nulla che serve solo per
verificare lo stato dei segnali ed eseguire un μsalto al fetch in caso di condizione falsa.
Una alternativa a questo schema che non necessiti di una microistruzione vuota, si può realizzare
utilizzando il selettore del multiplexer per comandare direttamente PCIE, ritornando quindi allo
schema precedente per decidere riguardo all’incremento o al fetch.




                                                                                                  19

Mais conteúdo relacionado

Mais de Majong DevJfu

9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud
Majong DevJfu
 
8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes
Majong DevJfu
 
7 - Architetture Software - Software product line
7 - Architetture Software - Software product line7 - Architetture Software - Software product line
7 - Architetture Software - Software product line
Majong DevJfu
 
6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation
Majong DevJfu
 
5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture
Majong DevJfu
 
4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio
Majong DevJfu
 
3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles
Majong DevJfu
 
2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture
Majong DevJfu
 
1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product
Majong DevJfu
 
10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles
Majong DevJfu
 

Mais de Majong DevJfu (20)

9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud
 
8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes
 
7 - Architetture Software - Software product line
7 - Architetture Software - Software product line7 - Architetture Software - Software product line
7 - Architetture Software - Software product line
 
6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation
 
5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture
 
4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio
 
3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles
 
2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture
 
1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product
 
10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles
 
Uml3
Uml3Uml3
Uml3
 
Uml2
Uml2Uml2
Uml2
 
6
66
6
 
5
55
5
 
4 (uml basic)
4 (uml basic)4 (uml basic)
4 (uml basic)
 
3
33
3
 
2
22
2
 
1
11
1
 
Tmd template-sand
Tmd template-sandTmd template-sand
Tmd template-sand
 
26 standards
26 standards26 standards
26 standards
 

Último

Adducchio.Samuel-Steve_Jobs.ppppppppppptx
Adducchio.Samuel-Steve_Jobs.ppppppppppptxAdducchio.Samuel-Steve_Jobs.ppppppppppptx
Adducchio.Samuel-Steve_Jobs.ppppppppppptx
sasaselvatico
 
Scienza Potere Puntoaaaaaaaaaaaaaaa.pptx
Scienza Potere Puntoaaaaaaaaaaaaaaa.pptxScienza Potere Puntoaaaaaaaaaaaaaaa.pptx
Scienza Potere Puntoaaaaaaaaaaaaaaa.pptx
lorenzodemidio01
 
Presentazione tre geni della tecnologia informatica
Presentazione tre geni della tecnologia informaticaPresentazione tre geni della tecnologia informatica
Presentazione tre geni della tecnologia informatica
nico07fusco
 
case passive_GiorgiaDeAscaniis.pptx.....
case passive_GiorgiaDeAscaniis.pptx.....case passive_GiorgiaDeAscaniis.pptx.....
case passive_GiorgiaDeAscaniis.pptx.....
giorgiadeascaniis59
 

Último (20)

Esame di Stato 2024 - Materiale conferenza online 09 aprile 2024
Esame di Stato 2024 - Materiale conferenza online 09 aprile 2024Esame di Stato 2024 - Materiale conferenza online 09 aprile 2024
Esame di Stato 2024 - Materiale conferenza online 09 aprile 2024
 
Scrittura seo e scrittura accessibile
Scrittura seo e scrittura accessibileScrittura seo e scrittura accessibile
Scrittura seo e scrittura accessibile
 
Tosone Christian_Steve Jobsaaaaaaaa.pptx
Tosone Christian_Steve Jobsaaaaaaaa.pptxTosone Christian_Steve Jobsaaaaaaaa.pptx
Tosone Christian_Steve Jobsaaaaaaaa.pptx
 
Quadrilateri e isometrie studente di liceo
Quadrilateri e isometrie studente di liceoQuadrilateri e isometrie studente di liceo
Quadrilateri e isometrie studente di liceo
 
Adducchio.Samuel-Steve_Jobs.ppppppppppptx
Adducchio.Samuel-Steve_Jobs.ppppppppppptxAdducchio.Samuel-Steve_Jobs.ppppppppppptx
Adducchio.Samuel-Steve_Jobs.ppppppppppptx
 
Storia-CarloMagno-TeccarelliLorenzo.pptx
Storia-CarloMagno-TeccarelliLorenzo.pptxStoria-CarloMagno-TeccarelliLorenzo.pptx
Storia-CarloMagno-TeccarelliLorenzo.pptx
 
Vuoi girare il mondo? educazione civica.
Vuoi girare il mondo? educazione civica.Vuoi girare il mondo? educazione civica.
Vuoi girare il mondo? educazione civica.
 
CHIẾN THẮNG KÌ THI TUYỂN SINH VÀO LỚP 10 THPT MÔN NGỮ VĂN - PHAN THẾ HOÀI (36...
CHIẾN THẮNG KÌ THI TUYỂN SINH VÀO LỚP 10 THPT MÔN NGỮ VĂN - PHAN THẾ HOÀI (36...CHIẾN THẮNG KÌ THI TUYỂN SINH VÀO LỚP 10 THPT MÔN NGỮ VĂN - PHAN THẾ HOÀI (36...
CHIẾN THẮNG KÌ THI TUYỂN SINH VÀO LỚP 10 THPT MÔN NGỮ VĂN - PHAN THẾ HOÀI (36...
 
Presentazioni Efficaci e lezioni di Educazione Civica
Presentazioni Efficaci e lezioni di Educazione CivicaPresentazioni Efficaci e lezioni di Educazione Civica
Presentazioni Efficaci e lezioni di Educazione Civica
 
discorso generale sulla fisica e le discipline.pptx
discorso generale sulla fisica e le discipline.pptxdiscorso generale sulla fisica e le discipline.pptx
discorso generale sulla fisica e le discipline.pptx
 
Scienza Potere Puntoaaaaaaaaaaaaaaa.pptx
Scienza Potere Puntoaaaaaaaaaaaaaaa.pptxScienza Potere Puntoaaaaaaaaaaaaaaa.pptx
Scienza Potere Puntoaaaaaaaaaaaaaaa.pptx
 
ProgettoDiEducazioneCivicaDefinitivo_Christian Tosone.pptx
ProgettoDiEducazioneCivicaDefinitivo_Christian Tosone.pptxProgettoDiEducazioneCivicaDefinitivo_Christian Tosone.pptx
ProgettoDiEducazioneCivicaDefinitivo_Christian Tosone.pptx
 
Presentazione tre geni della tecnologia informatica
Presentazione tre geni della tecnologia informaticaPresentazione tre geni della tecnologia informatica
Presentazione tre geni della tecnologia informatica
 
LE ALGHE.pptx ..........................
LE ALGHE.pptx ..........................LE ALGHE.pptx ..........................
LE ALGHE.pptx ..........................
 
case passive_GiorgiaDeAscaniis.pptx.....
case passive_GiorgiaDeAscaniis.pptx.....case passive_GiorgiaDeAscaniis.pptx.....
case passive_GiorgiaDeAscaniis.pptx.....
 
descrizioni della antica civiltà dei sumeri.pptx
descrizioni della antica civiltà dei sumeri.pptxdescrizioni della antica civiltà dei sumeri.pptx
descrizioni della antica civiltà dei sumeri.pptx
 
Descrizione Piccolo teorema di Talete.pptx
Descrizione Piccolo teorema di Talete.pptxDescrizione Piccolo teorema di Talete.pptx
Descrizione Piccolo teorema di Talete.pptx
 
Una breve introduzione ad Elsa Morante, vita e opere
Una breve introduzione ad Elsa Morante, vita e opereUna breve introduzione ad Elsa Morante, vita e opere
Una breve introduzione ad Elsa Morante, vita e opere
 
Oppressi_oppressori.pptx................
Oppressi_oppressori.pptx................Oppressi_oppressori.pptx................
Oppressi_oppressori.pptx................
 
Aristotele, vita e opere e fisica...pptx
Aristotele, vita e opere e fisica...pptxAristotele, vita e opere e fisica...pptx
Aristotele, vita e opere e fisica...pptx
 

Architettura dei Calcolatori 07 Architettura Di Esempio 16

  • 1. Architettura di esempio Ing. Costantino Grana Università degli Studi di Modena e Reggio Emilia (Stampato il 07/04/2008 - architettura di esempio_16.doc) Introduzione ......................................................................................................................................... 1  Struttura................................................................................................................................................ 2  Formato delle istruzioni ....................................................................................................................... 3  Microistruzioni ..................................................................................................................................... 4  Ciclo delle istruzioni ............................................................................................................................ 5  Fetch ................................................................................................................................................. 5  Execute ............................................................................................................................................. 5  Set (SET) ...................................................................................................................................... 5  Load (LD) .................................................................................................................................... 5  Store (ST) ..................................................................................................................................... 5  Add (ADD) .................................................................................................................................. 6  Subtract (SUB) ............................................................................................................................. 6  Increment (INC) e Decrement (DEC) .......................................................................................... 6  Unità di controllo ................................................................................................................................. 6  Implementazione cablata.................................................................................................................. 7  Versione semplificata (solo fetch) ............................................................................................... 7  Versione completa (fetch e execute) ............................................................................................ 7  Parallelizzazione del caricamento del MAR ........................................................................................ 9  SET (000) ................................................................................................................................... 10  LD (001)..................................................................................................................................... 10  ST (002) ..................................................................................................................................... 10  ADD (003) ................................................................................................................................. 10  SUB (004) .................................................................................................................................. 10  INC (005) ................................................................................................................................... 10  DEC (006) .................................................................................................................................. 10  Le istruzioni di salto........................................................................................................................... 11  Codice operativo e tempi di clock...................................................................................................... 12  Esempi di programmi per l’architettura ............................................................................................. 13  Somma di due numeri .................................................................................................................... 13  Prodotto di due numeri................................................................................................................... 14  Implementazione micro programmata dell’unità di controllo ........................................................... 15  Versione senza salti........................................................................................................................ 15  Codifica delle istruzioni ................................................................................................................. 17  Versione completa con i salti ......................................................................................................... 17  Introduzione Il processore di esempio che considereremo ha una struttura interna a singolo bus a 32 bit per lo scambio di informazioni tra i registri. Le connessioni esterne avvengono tramite un bus dati a 32 bit e un bus indirizzi a 20 bit. La scelta di avere un bus indirizzi così piccolo (consente di indirizzare 220 (=1 Mega) parole di memoria) è dovuta alla volontà di evitare istruzioni con lunghezza variabile. Inizialmente considereremo che la memoria abbia un parallelismo di 32 bit, cioè ad ogni indirizzo corrisponde una diversa parola di 4 Byte, mentre solo successivamente vedremo come modificare questa architettura per indirizzare i singoli byte. 1
  • 2. Struttura Internamente il processore è dotato di un registro accumulatore da 32 bit (ACC), di un Memory Data Register da 32 bit (MDR), di un Memory Address Register da 20 bit (MAR), di un Program Counter da 20 bit (PC), di un Instruction Register da 32 bit (IR), di due registri relativi alla ALU da 32 bit (ALUA e ALUOUT) e da un registro di FLAG che contiene 4 bit di condizione (Zero, Carry, Negativo e Overflow). Le connessioni sono illustrate in figura: ZA 0 0 Cin ACC 1 IR ALUA A OUT MDR B D0-31 MAR ALUOUT A0-19 PC FLAG I registri connessi al bus hanno tutti un segnale di abilitazione in lettura (OE), cioè abilitano i buffer tri-state che li connettono al bus, e uno in scrittura (IE), tranne ALUA che è abilitato sempre in lettura verso la ALU (l’uscita dei flip-flop non passa per un buffer). Inoltre il MDR dispone di due segnali MDRBUSOE e MDRBUSIE che consentono di attivare l’output e l’input dal bus dati. MDRIE e MDRBUSIE non possono essere attivi contemporaneamente. MDRBUSOE viene portato all’esterno come segnale di Write (WR) per la memoria e MDRBUSIE è connesso al Read (RD) della memoria (la memoria è in lettura e pone i dati sul data bus ed MDR è in scrittura e memorizza tali dati). Il segnale ZA comanda il multiplexer posto all’ingresso A della ALU e consente di inviare uno zero alla porta A oppure l’output di ALUA. La porta B è sempre connessa al bus. Il registro FLAG dispone di un segnale di abilitazione FLAGIE per campionare lo stato della ALU. La ALU è molto semplice e consente di eseguire le seguenti operazioni: S1 S0 Operazione 0 0 A and B 0 1 A or B 1 0 A + B + Cin 1 1 A + B’ + Cin La ALU è costituita da 32 blocchi come il seguente: 2
  • 3. I segnali di Carry sono connessi in cascata tra di loro, i segnali di zero (Z) e negato (N) vengono generati rispettivamente dal negato della somma logica di tutti i bit e dal bit più significativo di ALUOUT. Il Carry della ALU (C) viene generato dal carry out del blocco corrispondente ai bit più significativi (il bit 31), mentre l’overflow è dato dall XOR dei carry out 30 e 31. Concludendo sono necessari i seguenti segnali di controllo: 0 ACCOE 1 ACCIE 2 MDROE 3 MDRIE 4 MDRBUSOE 5 MDRBUSIE 6 MAROE 7 MARIE 8 IROE 9 IRIE 10 PCOE 11 PCIE 12 ALUAIE 13 ALUOUTOE 14 ALUOUTIE 15 FLAGIE 16 ZA 17 Cin 18 S0 19 S1 Formato delle istruzioni Per avere una architettura semplice, vale la pena sacrificare un po’ di praticità dal set di istruzioni, quindi avere meno possibilità, ma ridurre lo sforzo nella realizzazione dell’unità di controllo. Le istruzioni sono tutte composte da un primo campo a 12 bit che identifica il codice operativo e un secondo campo a 20 bit che contiene un indirizzo. La funzione dell’indirizzo dipende dall’istruzione implementata. Questa architettura semplice consente di realizzare numerose funzioni, ma molto difficilmente si potrà lavorare con dati di dimensione inferiore a 32 bit (come dei caratteri per fare 3
  • 4. un esempio) o utilizzare indirizzi negativi (come spostamento per indirizzamenti indiretti). Quindi la semplicità viene poi pagata in termini di realismo del processore. 31 20 19 0 Codice operativo (opcode) Indirizzo (addr) Microistruzioni Tre sono le possibili tipologie di microistruzioni che si possono realizzare: i trasferimenti tra registri, i trasferimenti con la memoria e le operazioni di ALU. Per i trasferimenti tra registri è necessario abilitare in scrittura il registro destinazione e in lettura il registro sorgente. È necessario verificare che con questo schema il campionamento avvenga al momento giusto, per esempio sul fronte di salita del clock, in modo che il dato venga campionato alla fine del periodo di clock. Ad esempio la microistruzione MAR PC viene realizzata con MARIE=1 e PCOE=1. I dati scambiati con la memoria richiedono un proprio ciclo di clock per il campionamento dei dati da parte della memoria (in scrittura) o del MDR (in lettura). Durante questi trasferimenti il bus locale (interno al processore) non è utilizzato ed è quindi possibile sfruttarlo per altre operazioni. Siccome il MAR è sempre attivo sul bus indirizzi, è sufficiente utilizzare i due segnali di controllo del MDR per eseguire le microoperazioni relative alla memoria: Read MDR M[MAR] MDRBUSIE=1 Write M[MAR] MDR MDRBUSOE=1 Le operazioni di ALU hanno bisogno di tutti e quattro i segnali ZA, Cin, S1 e S0 e quindi la tabella di verità per le operazioni di ALU diventa: S1 S0 ZA Cin Operazione Risultato 0 00 - 0 and B Sempre 0 (può servire per avere uno zero da usare con il decremento) 0 0 1 - A and B AND 0 1 0 - 0 or B B (inutile) 0 1 1 - A or B OR 1 0 0 0 0+B B (inutile) 1 0 0 1 0+B+1 Incremento 1 0 1 0 A+B Somma 1 0 1 1 A+B+1 Somma e incrementa (inutile) 1 1 0 0 0 + B’ NOT 1 1 0 1 0 + B’ + 1 Negativo, cioè –B 1 1 1 0 A + B’ Sottrae e decrementa (può servire per fare un decremento) 1 1 1 1 A + B’ + 1 Sottrazione Ogni operazione di ALU necessita inoltre di un registro abilitato in lettura per avere un dato nel canale B. Le microistruzioni della ALU vengono sempre scritte specificando prima il canale A, cioè ALUA o 0, poi indicando l’operazione (and, or, +), poi il canale B, cioè il registro abilitato in lettura in forma vera o negata e infine, se necessario, il valore del Cin. Il risultato viene sempre portato in ALUOUT. Ad esempio volendo sottrarre il MDR all’accumulatore si indica: ALUA ACC ALUOUT ALUA + MDR’ + 1 4
  • 5. Ciclo delle istruzioni Ogni operazione, come avviene tradizionalmente, è composta da due fasi: Fetch e Execute. La fase di fetch è seguita sempre da una sottofase che a volte viene indicata come Decode, ma che in questo caso non è altro che l’incremento del program counter, dato che la decodifica non coinvolge alcun registro di stato. Fetch Le microistruzioni di questa fase sono comuni a tutte le istruzioni: MAR PC MDR M[MAR] IR MDR È inoltre necessario, come detto, incrementare il PC: ALUOUT 0 + PC + 1 PC ALUOUT Dal momento che non vi è necessità di tenere separate le due operazioni, possiamo sfruttare il fatto che durante la lettura il bus locale non viene utilizzato e che durante la prima microistruzione PC sta già pilotando il bus e possiamo sfruttarlo per effettuare la somma. Quindi la fase di fetch definitiva diventa: MAR PC, ALUOUT 0 + PC + 1 MDR M[MAR], PC ALUOUT IR MDR Execute Per delineare le possibili tipologie di istruzioni bisogna considerare che l’architettura ad accumulatore lavora sempre con la memoria, quindi saranno certo necessarie due operazioni di lettura e scrittura dell’accumulatore, poi ci saranno alcune operazioni aritmetiche che riguardano il solo accumulatore. Prenderemo in considerazione in seguito le istruzioni di controllo. Set (SET) Volendo impostare in modo immediato il contenuto dell’accumulatore, è possibile realizzare una istruzione molto semplice che prende il campo ADDR dell’istruzione e lo copia in ACC. Ad esempio si potrebbe fare: MAR IR(addr) ACC MAR Il passaggio per il MAR ci permette di “eliminare” l’opcode, e di trasferire in ACC solo i 20 bit meno significativi. Una soluzione più brutale potrebbe essere questa: ACC IR(addr) Purtroppo sappiamo che in questo modo in ACC andrebbe a finire anche l’opcode dell’istruzione SET. La soluzione semplice per questo problema è quindi far sì che questo opcode sia 0! Ovviamente questo impone dei vincoli progettuali, quindi in generale non sembra una buona idea. Load (LD) L’operazione di load carica il contenuto della memoria all’indirizzo specificato nell’accumulatore: MAR IR(addr) MDR M[MAR] ACC MDR Store (ST) L’operazione di store scrive il contenuto dell’accumulatore in memoria all’indirizzo specificato: 5
  • 6. MAR IR(addr) MDR ACC M[MAR] MDR Add (ADD) La somma esegue l’operazione concettuale ACC = ACC+M[addr]: MAR IR(addr) MDR M[MAR], ALUA ACC ALUOUT ALUA + MDR ACC ALUOUT Vale la pena notare che si può sfruttare il momento di lettura dell’operando per caricare il registro ALUA con il contenuto dell’accumulatore. Subtract (SUB) La differenza non gode della proprietà commutativa, quindi è necessario specificare quale dei due operandi sia il minuendo e quale il sottraendo. SUB esegue l’operazione ACC = ACC-M[addr]: MAR IR(addr) MDR M[MAR], ALUA ACC ALUOUT ALUA + MDR’ + 1 ACC ALUOUT Sarebbe possibile definire anche l’operazione inversa, cioè ACC = M[addr]-ACC. E’ comunque possibile ottenere lo stesso risultato utilizzando questa sottrazione e negando (in senso aritmetico) poi il risultato. Increment (INC) e Decrement (DEC) Solo come ulteriore esempio presentiamo le funzioni di incremento e decremento. Per l’incremento non ci sono particolari problemi, dato che è una classica istruzione di ALU priva di parametri: ALUOUT 0 + ACC + 1 ACC ALUOUT Per quanto riguarda il decremento è possibile sfruttare la sottrazione con decremento, cioè sommare all’accumulatore il negato di zero che in complemento a due è -1. Per fare questo però bisogna caricare il canale B della ALU con uno zero che generiamo usando l’AND con uno zero. ALUA ACC, ALUOUT 0 and ACC ALUOUT ALUA + ALUOUT’ ACC ALUOUT Questo esempio è un po’ più complesso, dato che si utilizza il fatto che non è necessario attendere il corretto trasferimento di ACC in ALUA per preparare ALUOUT con uno 0, dato che il canale B è assolutamente ininfluente e quindi possiamo in parallelo usare ACC per pilotare la porta B della ALU e caricare ALUA. Inoltre si vede come possiamo utilizzare ALUOUT come registro sorgente e come registro destinazione. Unità di controllo Per progettare l’unità di controllo è necessario identificare il valore di ogni segnale di controllo (i 19 che abbiamo visto precedentemente) in ogni “istante”. Gli istanti in realtà sono quantizzati dal segnale di clock che quindi identifica una serie di fasi corrispondenti alle singole microistruzioni. Chiameremo queste fasi con T seguito da un numero (cominciando da T0), per indicare il periodo di clock a cui ci stiamo riferendo. È possibile vedere ogni periodo di clock come un indicatore dello stato presente in un automa a stati finiti che secondo la rappresentazione di Moore associa as ogni stato un valore delle uscite. Lo stato futuro dipenderà allora dallo stato presente e dagli ingressi. Gli ingressi in questo caso sono identificati unicamente dal contenuto del campo OPCODE dell’IR. Per 6
  • 7. chiarezza sul significato dei T, quindi continueremo a indicare T5 la sesta microistruzione indipendentemente dall’istruzione di cui fa parte. Implementazione cablata Versione semplificata (solo fetch) Riprendiamo in considerazione la fase di fetch e limitiamoci a specificare i segnali interessati a questa fase, pensiamo quindi ad un processore che faccia solo e unicamente il fetch delle istruzioni senza eseguirle. Indichiamo poi accanto ad ogni microistruzioni i segnali che devono essere posti a 1 e il valore dei segnali dell ALU. T0: MAR PC, ALUOUT 0 + PC + 1 MARIE, PCOE, ALUOUTIE, ZA=0, Cin=1, S1S0=10 T1: MDR M[MAR], PC ALUOUT MDRBUSIE, PCIE, ALUOUTOE T2: IR MDR IRIE, MDROE Da questo schema risulta molto semplice associare ad ogni segnale la sua funzione combinatoria dipendente solo da T0,T1 e T2 che per la verità hanno solo tre possibili combinazioni, dato che sono stati mutuamente esclusivi. Lo schema completo dei segnali per questo processore che fa solo fetch, è il seguente: MARIE = T0 PCOE = T0 ALUOUTIE = T0 ZA = T0’ Cin = T0 S1 = T0 S0 = T0’ MDRBUSIE = T1 PCIE = T1 ALUOUTOE = T1 IRIE = T2 MDROE = T2 Bisogna poi specificare la funzione di stato futuro per i T e in questo caso è veramente semplice: T0f = T2 T1f = T0 T2f = T1 Versione completa (fetch e execute) Passiamo invece ora a considerare l’unità di controllo necessaria a implementare un processore con tutte le sei istruzioni viste in precedenza. La fase di fetch è esattamente quella vista in precedenza, quindi andiamo a dettagliare solo le varie possibilità per l’execute. Il campo OPCODE di IR è direttamente connesso (prima dei buffer di OE) ad un decoder nell’unità di controllo che consente per ogni istruzione di generare un segnale corrispondente, ad esempio SET potrebbe essere generato dall’opcode (in esadecimale) 000, LD da 001, ST da 002 e così via. Non ci sono particolari motivi per avere una codifica o un’altra in questo caso. 7
  • 8. SET: T3,SET: MAR IR(addr) MARIE, IROE T4,SET: ACC MAR ACCIE, MAROE LD: T3,LD: MAR IR(addr) MARIE, IROE T4,LD: MDR M[MAR] MDRBUSIE T5,LD: ACC MDR ACCIE, MDROE ST: T3,ST: MAR IR(addr) MARIE, IROE T4,ST: MDR ACC MDRIE, ACCOE T5,ST: M[MAR] MDR MDRBUSOE ADD: T3,ADD: MAR IR(addr) MARIE, IROE T4,ADD: MDR M[MAR], ALUA ACC MDRBUSIE, ALUAIE, ACCOE T5,ADD: ALUOUT ALUA + MDR ALUOUTIE, MDROE ZA=1, Cin=0, S1S0=10 T6,ADD: ACC ALUOUT ACCIE, ALUOUTOE SUB: T3,SUB: MAR IR(addr) MARIE, IROE T4,SUB: MDR M[MAR], ALUA ACC MDRBUSIE, ALUAIE, ACCOE T5,SUB: ALUOUT ALUA – MDR’ + 1 ALUOUTIE, MDROE ZA=1, Cin=1, S1S0=11 T6,SUB: ACC ALUOUT ACCIE, ALUOUTOE INC: T3,INC: ALUOUT 0 + ACC + 1 ALUOUTIE, ACCOE ZA=0, Cin=1, S1S0=10 T4,INC: ACC ALUOUT ACCIE, ALUOUTOE DEC: T3,DEC: ALUA ACC, ALUOUT 0 and ACC ALUAIE, ACCOE, ALUOUTIE, ZA=0, S1S0=00 T4,DEC: ALUOUT ALUA + ALUOUT’ ALUOUTIE, ALUOUTOE, ZA=1, Cin=0, S1S0=11 T5,DEC: ACC ALUOUT ACCIE, ALUOUTOE Per sintetizzare i segnali di controllo, è sufficiente mettere in AND l’indicatore dell’istante in cui il segnale si deve attivare (deve essere posto a 1) con il segnale relativo all’istruzione corrente. Si possono poi usare le varie leggi dell’algebra di Boole per semplificare l’espressione, risparmiando sul numero di porte logiche necessarie: 0 ACCOE = T3·(INC + DEC) + T4·(ST + ADD + SUB) 1 ACCIE = T4·(SET + INC) + T5·(LD + DEC) + T6·(ADD + SUB) 2 MDROE = T2 + T5·(LD + ADD + SUB) 3 MDRIE = T4·ST 4 MDRBUSOE = T5·ST 5 MDRBUSIE = T1 + T4·(LD + ADD + SUB) 8
  • 9. 6 MARIE = T0 + T3·(SET + LD + ST + ADD + SUB) 7 MAROE = T4·SET 8 IROE = T3·(SET + LD + ST + ADD + SUB) 9 IRIE = T2 10 PCOE = T0 11 PCIE = T1 12 ALUAIE = T3·DEC + T4·(ADD + SUB) 13 ALUOUTOE = T1 + T4·(INC + DEC) + T5·DEC + T6·(ADD + SUB) 14 ALUOUTIE = T0 + T3·(INC + DEC) + T4·DEC + T5·(ADD+SUB) 15 FLAGIE = 0 16 ZA = T4·DEC + T5·(ADD+SUB) 17 Cin = T0 + T3·INC + T5·SUB 18 S1 = T0 + T3·INC + T5·(ADD + SUB) 19 S0 = T4·DEC + T5·SUB La codifica sopra riportata è certamente non minima, dato che assomiglia fortemente ad una sintesi canonica SP. Non vengono assolutamente utilizzate le indifferenze anche banalmente verificabili. Per esempio S0 può essere messo ad 1 in T4 sempre, dato che nessun’altra istruzione utilizza S0 in T4, quindi si potrebbe risparmiare l’AND con il segnale DEC. Nella realizzazione di una unità di controllo cablata, il numero di segnali cresce enormemente rispetto a questo esempio, quindi riduzioni di questo tipo diventano indispensabili per evitare dimensioni eccessive. Inoltre sostituire i segnali T0-6 con una loro codifica, ridurrebbe notevolmente il numero di segnali da trasportare nell’unità di controllo. La sintesi SP è piuttosto naturale per questo tipo di sistema, dato che abbiamo supposto i segnali attivi ad uno. Dal momento che solo pochi di questi segnali si attivano contemporaneamente, possiamo supporre che per la maggior parte dei casi l’uscita debba essere a 0, riducendo il numero di mintermini da utilizzare. Parlare di mintermini in questo caso non è realmente appropriato, dato che le varie configurazioni sono già decodificate, quindi dire ad esempio T3·INC sottointende chiaramente che T0, T1, T2, T4, T5, T6, LD, ST, ADD, SUB e DEC siano a zero (evitandoci dunque di specificarli nell’espressione). È da notare inoltre che FLAGIE è stato volutamente ignorato, dato che in realtà nessuna istruzione ha bisogno dei flag, anche se certamente dovrebbero impostarli tutte le istruzioni aritmetiche. La sintesi dello stato futuro diventa leggermente più complessa visto che ci sono istruzioni con lunghezza variabile. Quindi ad esempio se sono nello stato T4 e l’istruzione è una INC devo andare allo stato T0, mentre se sono in una DEC devo andare in T5. Proseguendo con la sintesi intuitiva fatta finora, si ottiene questo risultato: T0f = T4·(SET + INC) + T5·(LD + ST + DEC) + T6·(ADD + SUB) T1f = T0 T2f = T1 T3f = T2 T4f = T3 T5f = T4·(LD + ST + ADD + SUB + DEC) T6f = T5·(ADD + SUB) Parallelizzazione del caricamento del MAR L’architettura appena illustrata è ancora incompleta, dato che manca di un aspetto fondamentale, cioè la gestione dei salti che consente di eseguire istruzioni diverse a seconda di risultati o output. Però è comunque utile considerare una otimizzazione a quanto illustrato finora. Abbiamo già visto che se un registro sta pilotando il bus, più di un dispositivo può leggere e memorizzare il contenuto. Questo può essere utilizzato per eliminare la prima microistruzione di 5 9
  • 10. delle istruzioni già viste. Infatti SET, LD, ST, ADD e SUB sfruttano l’indirizzo presente nell’IR per leggere dalla memoria e devono trasferirlo nel MAR. Si deve altresì notare che il contenuto del MAR è ininfluente sulle altre microperazioni (a parte l’accesso in memoria). Quindi si potrebbe sfruttare la terza istruzione del fetch per preparare già il MAR con il contenuto dell’IR. Nel MAR si dovrebbe trasferire solo il campo Address dell’IR, ma il MAR è collegato ai 20 bit meno significativi del bus, cioè proprio al campo richiesto, quindi qualsiasi cosa ci sia negli altri bit è completamente ininfluente. Facendo l’esempio dell’istruzione LD, il risultato sarebbe il seguente: MAR PC, ALUOUT 0 + PC + 1 MDR M[MAR], PC ALUOUT IR MDR, MAR MDR <<< Qui viene fatta l’aggiunta MAR ← IR(addr) <<< Questa μ-istruzione è eliminata MDR M[MAR] ACC MDR Questa modifica non influenza in alcun modo le altre istruzioni, dato che non aggiunge nulla alle istruzioni che non utilizzano la memoria (INC e DEC). In sostanza le microistruzioni delle varie istruzioni diventano (tra parentesi è indicato il codice operativo che useremo come riferimento): SET (000) ACC MAR LD (001) MDR M[MAR] ACC MDR ST (002) MDR ACC M[MAR] MDR ADD (003) MDR M[MAR], ALUA ACC ALUOUT ALUA + MDR ACC ALUOUT SUB (004) MDR M[MAR], ALUA ACC ALUOUT ALUA + MDR’ + 1 ACC ALUOUT INC (005) ALUOUT 0 + ACC + 1 ACC ALUOUT DEC (006) ALUA ACC, ALUOUT 0 and ACC ALUOUT ALUA + ALUOUT’ ACC ALUOUT 10
  • 11. I segnali di controllo da generare diventano allora: ACCOE = T3·(ST + ADD + SUB + INC + DEC) ACCIE = T3·SET + T4·(LD + INC) + T5·(ADD + SUB + DEC) MDROE = T2 + T4·(LD + ADD + SUB) MDRIE = T3·ST MDRBUSOE = T4·ST MDRBUSIE = T1 + T3·(LD + ADD + SUB) MARIE = T0 + T2 MAROE = T3·SET IROE = 0 IRIE = T2 PCOE = T0 PCIE = T1 ALUAIE = T3·(ADD + SUB + DEC) ALUOUTOE = T1 + T4·(INC + DEC) + T5·(ADD + SUB + DEC) ALUOUTIE = T0 + T3·(INC + DEC) + T4·(ADD + SUB + DEC) FLAGIE = 0 ZA = T4·(ADD + SUB + DEC) Cin = T0 + T3·INC + T4·SUB S1 = T0 + T3·INC + T4·(ADD + SUB) S0 = T4·(SUB + DEC) T0f = T3·SET + T4·(LD + ST + INC) + T5·(ADD + SUB + DEC) T1f = T0 T2f = T1 T3f = T2 T4f = T3·(LD + ST + ADD + SUB + INC + DEC) T5f = T4·(ADD + SUB + DEC) Le istruzioni di salto Parte integrante della programmazione sono le istruzioni di salto che consentono di modificare il punto di esecuzione del programma. In particolare, fondamentali per implementare funzioni logiche complesse servono istruzioni di salto condizionato, istruzioni che eseguono la modifica al PC solo se si verifica una determinata situazione. Le “situazioni” che tipicamente si prendono in considerazione sono i risultati delle operazioni aritmetiche precedenti. Per tenerne conto abbiamo già accennato alla presenza di un registro FLAG che abbiamo ignorato finora. Questo registro deve essere aggiornato con i segnali provenienti dalla ALU ad ogni operazione richiesta dall’utente, cioè se consideriamo l’istruzione ADD comprensiva di Fetch ed Execute (nella prima versione senza caricamento parallelo di IR e MAR in T2): T0: MAR PC, ALUOUT 4 + PC MARIE, PCOE, ALUOUTIE, ZA=0, QA=1, Cin=0, S1S0=10 T1: MDR M[MAR], PC ALUOUT MDRBUSIE, PCIE, ALUOUTOE T2: IR MDR IRIE, MDROE T3: MAR IR(addr) MARIE, IROE T4,ADD: MDR M[MAR], ALUA ACC MDRBUSIE, ALUAIE, ACCOE T5,ADD: ALUOUT ALUA + MDR ALUOUTIE, MDROE ZA=1, Cin=0, S1S0=10, FLAGIE T6,ADD: ACC ALUOUT ACCIE, ALUOUTOE 11
  • 12. vediamo che vengono eseguite due operazioni di ALU, ma l’unica che deve essere memorizzata nei FLAG è la seconda, cioè quella relativa ai dati dell’utente, cioè la ADD. I segnali provenienti dai flag arrivano direttamente alla unità di controllo che li utilizza per realizzare le funzioni logiche opportune. Iniziamo considerando la struttura di un salto incondizionato: JMP T3,JMP: PC IR(addr) PCIE, IROE Questo è tutto. Insomma si prende il contenuto del campo ADDR di IR e lo si mette in PC. Al fetch successivo il PC è già stato modificato opportunamente. Che cosa cambia in un salto condizionato? semplicemente il trasferimento in PC avviene solo se si verifica la condizione richiesta, quindi se per esempio vogliamo considerare un salto in caso di risultato Zero dell’operazione precedente: JZ T3,JZ,Z: PC IR(addr) PCIE, IROE Aggiungiamo alla condizione da verificare anche il flag interessato. I salti disponibili in questa architettura saranno (vista la ALU a disposizione): JZ salta se il flag Z vale 1 JNZ salta se il flag Z vale 0 JO salta se il flag O vale 1 JNO salta se il flag O vale 0 JN salta se il flag N vale 1 JNN salta se il flag N vale 0 JC salta se il flag C vale 1 JNC salta se il flag C vale 0 Come si realizza questa condizione nell’unità di controllo? Nel caso cablato la soluzione è particolarmente semplice, infatti il segnale Zero è disponibile già durante T2 (e anche prima) quindi è sufficiente evitare di andare in T3 se l’istruzione è JZ e Z=0. Purtroppo però JZ non è disponibile fino a T3, dato che viene calcolato da IR e quindi aspettiamo T3, non facendo niente nel caso di salto non eseguito (condizione falsa). Consideriamo quindi di aggiungere l’istruzione JZ all’implementazione cablata vista in precedenza, occupandoci solo dei segnali interessati dall’istruzione. Queste sono le modifiche necessarie per una realizzazione letterale, cioè verificando la condizione in T3 (le modifiche sono evidenziate): IROE = T3·(JMP + JZ·Z + JNZ·Z’ + JO·O + JNO·O’ + JN·N + JNN·N’ + JC·C + JNC·C’) PCIE = T1 + T3·(JMP + JZ·Z + JNZ·Z’ + JO·O + JNO·O’ + JN·N + JNN·N’ + JC·C + JNC·C’) T0f = T3·(SET + JMP+JZ+JNZ+JO+JNO+JN+JNN+JC+JNC) + T4·(LD + ST + INC) + T5·(ADD + SUB + DEC) Codice operativo e tempi di clock Nella tabella seguente sono riportati, per ogni istruzione il codice operativo in decimale e esadecimale, il codice mnemonico identificativo e il tempo di clock necessario all’esecuzione, tenendo conto del caricamento anticipato del MAR, con e senza i cicli di clock necessari alla fase di fetch. 12
  • 13. Dec Hex Istruzione Clock Con Fetch 0 000 SET 1 4 1 001 LD 2 5 2 002 ST 2 5 3 003 ADD 3 6 4 004 SUB 3 6 5 005 INC 2 5 6 006 DEC 3 6 7 007 JMP 1 4 8 008 JZ 1 4 9 009 JNZ 1 4 10 00A JO 1 4 11 00B JNO 1 4 12 00C JN 1 4 13 00D JNN 1 4 14 00E JC 1 4 15 00F JNC 1 4 Esempi di programmi per l’architettura Con la struttura delineata finora è possibile realizzare alcuni programmi molto semplici utilizzando una sintassi nota come linguaggio Assembly. In questo caso non esistono regole sulla sintassi, dato che ogni costruttore ne inventa di sue. Senza volere entrare nei dettagli delle caratteristiche dell’Assembly, basti sapere che su ogni riga si specifica il codice operativo simbolico (detto anche mnemonico) e gli eventuali operandi che possono essere numerici o simbolici, nel senso che non è necessario calcolare l’indirizzo delle variabili in memoria, dato che può farlo un programma per noi. Questo programma si chiama Assemblatore (Assembler). Somma di due numeri Vediamo un semplicissimo programma di esempio che somma due valori numerici a 32 bit A e B impostati in memoria dal caricamento del programma e mette il risultato in una variabile C: ld A add B st C A: 00001234h B: 0056789Ah C: 0 Solitamente i valori esadecimali nei programmi assembly vengono terminati con una h. Inoltre vale la pena notare che si è utilizzata una sintassi specifica per indicare che una linea non contiene un’istruzione, ma un valore numerico che non deve essere interpretato. Supponiamo che questo programma venga convertito in codice macchina e caricato in memoria a partire dall’indirizzo 0. Utilizzando la codifica degli opcode illustrata precedentemente e scrivendo i valori in esadecimale, quello che troveremmo sarebbe: 13
  • 14. 32 bit 12 bit 20 bit 00000 001 0000C 00004 003 00010 00008 002 00014 0000C 000 01234 00010 005 6789A 00014 000 00000 Caricato il programma in memoria, l’esecuzione potrebbe iniziare a partire dall’indirizzo 00000. Il problema è che terminata la terza operazione il processore eseguirebbe il fetch di una ulteriore istruzione, in particolare di 00001234, che verrebbe interpretata come SET 01234! Insomma, il problema è che non disponiamo di una istruzione per interrompere il fetch, cioè per fermare il processore. Nella realtà questo non è un problema, dato che i processori continuano ad eseguire un programma di base che solitamente è chiamato sistema operativo. Ma per non dilungarci e andare fuori tema, limitiamoci a considerare come sia possibile interrompere il ciclo fetch/execute. Questo effetto si può ottenere con un JMP all’indirizzo dell’istruzione. Il nostro programma a questo punto diventa: ld A add B st C Fine: jmp Fine A: 00001234h B: 0056789Ah C: 0 Si è utilizzato il simbolo Fine per definire un indirizzo, e in particolare l’indirizzo dell’istruzione JMP. Anche negli esempi successivi non specificheremo gli indirizzi, ma sfrutteremo i due punti per definire etichette simboliche da utilizzare come argomenti delle istruzioni. A questo punto possiamo passare ad un esempio più complesso. Prodotto di due numeri Il prodotto di due numeri può essere eseguito in diversi modi, ad esempio con la tecnica che ci è stata insegnata alle elementari che consiste nell’imparare delle moltiplicazioni fondamentali (le tabelline) ed estenderle poi opportunamente. La versione più semplice però è l’utilizzo della definizione, cioè sommare il moltiplicando tante volte quante indicate dal moltiplicatore. È da sottolineare anche che questa tecnica è anche la più lenta e sconsigliabile in applicazioni reali. Ecco come potrebbe apparire un programma che moltiplica A e B scrivendo il risultato in C: Ancora: ld C add A st C ld B dec B jnz Ancora Fine: jmp Fine A: 5 B: 6 C: 0 14
  • 15. Alla fine di questo programma, il valore di B è stato “rovinato”, dato che lo si è utilizzato come contatore per verificare quando terminare il ciclo. È inoltre importante notare come sia fondamentale avere a disposizione una locazione di memoria inizializzata a zero, dato che questa viene subito utilizzata come raccoglitore iniziale del risultato della moltiplicazione. Implementazione micro programmata dell’unità di controllo Versione senza salti Un approccio alternativo alla realizzazione dell’unità di controllo, consiste nel memorizzare ogni microistruzione come l’insieme di tutti i segnali di controllo con il loro valore. Questo necessita di una struttura di memorizzazione (RAM, EEPROM, ROM) alla quale si potrà accedere con un indirizzo. Al termine del ciclo di clock sarà necessario modificare opportunamente l’indirizzo prelevando i segnali corretti. Tutto questo lo si può realizzare con un micro Program Counter (μPC) che può essere incrementato per passare alla microistruzione successiva, può essere azzerato al termine dell’istruzione, per tornare alla fase di fetch (comune a tutte le istruzioni) e può essere caricato con il contenuto dell’OPCODE, che diventa un indirizzo nella memoria delle microistruzioni. Lo schema seguente dovrebbe chiarire il concetto: 0 0 micro control op code µPC address 1 control signals 2 Incremento microcode memory Secondo questo schema sono necessari in ogni microistruzione anche i segnali di controllo per il μPC che si limitano a selezionare quale dei tre ingressi del multiplexer deve essere utilizzato per il passo successivo. Sono quindi necessari due bit aggiuntivi MC0 e MC1 che selezioneranno l’ingresso: MC1 MC0 Selezione 0 0 0 (μsalto al fetch) 0 1 μsalto all’opcode 1 0 prossima μistruzione 1 1 X (non valido) Ci sono vari modi per evitare si avere un salto specifico al fetch, ma li vedremo in seguito. Passiamo invece alla implementazione della architettura che abbiamo illustrato. Sono necessari 19 bit per i segnali di controllo più due per il microcontrollo. Utilizzando la numerazione della prima tabella dei segnali di controllo possiamo assegnare 19 a MC0 e 20 a MC1 ottenendo uno schema a 21 colonne come il seguente: 15
  • 16. ALUOUTOE ALUOUTIE Operazione MDRBUSOE MDRBUSIE Indirizzo ALUAIE FLAGIE MDROE ACCOE MARIE MDRIE ACCIE PCOE MC1 MC0 IROE PCIE IRIE Cin ZA S1 S0 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 101 010 1 1 1 fetch 0 10 1 1 1 1 01 1 1 2 10 1 1 LD 3 10 1 4 00 1 1 5 10 1 1 ST 6 10 1 1 7 00 1 8 10 1 1 ADD 9 10 1 1 1 10 101 0 0 1 1 1 11 00 1 1 12 10 1 1 SUB 13 10 1 1 1 14 101 1 1 1 1 1 15 00 1 1 16 101 0 1 0 1 1 INC 17 00 1 1 18 100 0 0 1 1 1 DEC 19 101 1 0 1 1 1 20 00 1 1 21 Gli spazi non riempiti contengono degli zeri. Questa soluzione prevede che il codice operativo sia esattamente l’indirizzo nella memoria di controllo della prima microistruzione corrispondente all’istruzione selezionata. Quindi ad esempio l’istruzione LD non sarebbe più 000 come nell’esempio precedente, ma obbligatoriamente 003. Purtroppo questa implementazione così come è stata presentata ha un bug sulla fase di esecuzione del salto all’opcode. Infatti, nella terza microistruzione si trasferisce il contenuto dell’MDR in IR e contemporaneamente si vorrebbe trasferire questo dato in μPC. Il problema è che i dati vengono campionati sul fronte di salita del clock, quindi se si legge il contenuto di IR (anche solo il campo OPCODE) nell’istante in cui questo campiona, si ricava il contenuto precedente dell’IR, quindi l’indirizzo sbagliato. In realtà vuol dire che si fa il fetch di un’istruzione, ma si esegue la precedente e questo potrebbe causare molti problemi. Sono possibili varie soluzioni, ma la più semplice –valida solo per questo specifico caso– è quella di connettere il bus locale all’ingresso 1 del multiplexer di selezione. In tal modo al termine della fase di fetch, quando viene eseguita la microistruzione (IR MDR), sullo stesso fronte di clock viene caricato il codice istruzione (proveniente da MDR) in IR ed il solo campo OPCODE in uPC. È chiaro che la soluzione alternativa sarebbe inserire un’altra microistruzione dopo il trasferimento all’IR, ad esempio posticipando PC ALUOUT, purtroppo in questo modo si aggiunge un ciclo di clock alla fase di fetch. 16
  • 17. Codifica delle istruzioni Abbiamo sottolineato come nel caso di microprogrammazione le istruzioni debbano essere codificate in modo specifico per puntare all’indirizzo della microroutine corrispondente. Effettivamente sarebbe più comodo poter utilizzare la stessa codifica utilizzata nel caso di microarchitettura cablata. Una soluzione semplice si può realizzare specificando con l’op-code non l’indirizzo, ma piuttosto il blocco di microistruzioni di interesse. Allineando i blocchi a indirizzi multipli di una potenza di due e riservando loro uno spazio potenza di due, è sufficiente uno shift cablato per ottenere il risultato voluto. Ad esempio, nel caso precedente sarebbe possibile utilizzare blocchi da 4 microistruzioni, ristrutturando la memoria così: Istruzione opcode Celle utilizzate Lunghezza Fetch - 0,1,2 3 LD 001 4,5,6 3 ST 002 8,9,10 3 ADD 003 12,13,14,15 4 SUB 004 16,17,18,19 4 INC 005 20,21 2 DEC 006 24,25,26 3 In questo modo è possibile connettere il bit 2 dell’opcode al bit meno significativo del μPC realizzando quindi uno shift a sinistra di due bit (moltiplicazione per 4, dimensione del blocco). Sostanzialmente è come se si inserissero due zeri (con una codifica binaria) a destra del codice operativo dell’istruzione, producendo così l’indirizzo del μPC. Memoria delle microistruzioni LD 0000|0000|0001 0000|0000|0000 ST 0000|0000|0010 0000|0000|0001 ADD 0000|0000|0011 0000|0000|0010 SUB 0000|0000|0100 0000|0000|0011 INC 0000|0000|0101 0000|0000|0100 DEC 0000|0000|0110 0000|0000|0101 0000|0000|0110 0000|0000|0111 0000|0000|1000 0000|0000|1001 0000|0000|1010 0000|0000|1011 0000|0000|1100 ... Il difetto di questa soluzione è chiaramente lo spreco di memoria, evidente dall’indirizzo dell’ultima microistruzione di DEC che è a 26 rispetto al 21 del caso precedente. È anche possibile pensare ad una rom che si occupi di tradurre gli opcode in microindirizzi, ma ovviamente si complica ulteriormente lo schema architetturale. Versione completa con i salti Il problema più grosso nella gestione dei segnali di controllo lo si ha con l’implementazione microprogrammata che non consente di inviare direttamente in uscita il contenuto di un registro, ad esempio Carry-out. Se alcuni eventi devono essere condizionati al valore dei registri di stato diventa necessario prevedere l’hardware (multiplexer solitamente) per inviare i vari segnali e poi codificare nel microcodice i segnali di controllo per decidere quale valore verrà effettivamente selezionato. 17
  • 18. Nel caso microprogrammato la questione è più complessa, dato che bisogna dotare il sequencer, ovvero la parte di architettura che seleziona il prossimo valore del μPC, di ingressi dedicati ai Flag e nella memoria delle microistruzioni prevedere dei selettori per questi segnali. Le soluzioni possibili sono molteplici e noi ne vedremo solo una di esempio molto banale e probabilmente non delle migliori, ma sicuramente semplice e di facile comprensione. Questa struttura si basa proprio sul concetto che abbiamo visto sopra, cioè di passare da T2 a T3 in un salto condizionato solo se la condizione specificata è vera. Per questo motivo si possono separare le tre possibilità previste nello schema base (selezionate con MC1 e MC0) in due blocchi in cascata così: MC0 0 0 MC1 1 0 µPC op code 1 Incremento In questo modo abbiamo separato in due livelli concettuali la selezione, ovvero abbiamo un segnale che ci dice se dobbiamo eseguire il decode oppure se dobbiamo usare l’altro multiplexer. Questo multiplexer ci consente di procedere alla microistruzione successiva o di tornare al fetch. Per comandare il multiplexer di incremento o fetch possiamo decidere in maniera secca 0 o 1 fissi oppure possiamo lasciare che siano i FLAG a comandarlo. Nasce quindi l’esigenza di inserire un ulteriore multiplexer (questa volta a 1 bit) per passare i segnali di controllo opportuni: 0 1 C C’ 0 Z Z’ N 0 N’ MC3 1 MC2-0 0 µPC op code 1 Incremento I segnali di controllo MC0, MC1 e MC2 selezionano quale segnale deve decidere se eseguire il Fetch o se incrementare μPC quindi volendo riprodurre il comportamento della microarchitettura precedente è possibile utilizzare i segnali come in tabella: MC3 MC2 MC1 MC0 Funzione 1 x x x μsalto all’opcode 0 0 0 0 0 (μsalto al fetch) 0 0 0 1 prossima μistruzione (incremento) 0 0 1 0 se C incremento, altrimenti fetch 0 0 1 1 se C’ incremento, altrimenti fetch 0 1 0 0 se Z incremento, altrimenti fetch 0 1 0 1 se Z’ incremento, altrimenti fetch 18
  • 19. 0 1 1 0 se N incremento, altrimenti fetch 0 1 1 1 se N’ incremento, altrimenti fetch A questo punto non è difficile realizzare i salti condizionati e non. Nella prossima tabella vediamo la fase di fetch e la realizzazione dei salti. In questo caso si è utilizzata l’architettura con indirizzamento al byte e il caricamento parallelo di IR e MAR in T2. Resta l’accortezza di ricordare che il μPC carica i dati dal bus quando si legge l’opcode e non dal IR per quanto detto precedentemente: ALUOUTOE ALUOUTIE Operazione MDRBUSOE MDRBUSIE Indirizzo ALUAIE FLAGIE MDROE ACCOE MARIE MDRIE ACCIE PCOE MC3 MC2 MC1 MC0 IROE PCIE IRIE Cin QA ZA S1 S0 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0 0 0 110010 1 1 1 fetch 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 2 … … 0 0 0 0 1 1 JMP x 0 0 1 0 JC x+1 0 0 0 0 1 1 x+2 0 0 1 1 JNC x+3 0 0 0 0 1 1 x+4 0 1 0 0 JZ x+5 0 0 0 0 1 1 x+6 0 1 0 1 JNZ x+7 0 0 0 0 1 1 x+8 0 1 1 0 JN x+9 0 0 0 0 1 1 x+10 0 1 1 1 JNN x+11 0 0 0 0 1 1 x+12 … Il grosso difetto di questa soluzione è che diventa necessario allungare di un ciclo di clock ogni istruzione di salto. Infatti non è possibile caricare la nuova istruzione e contemporaneamente sapere già quale condizione verificare. Viene quindi introdotta una microistruzione nulla che serve solo per verificare lo stato dei segnali ed eseguire un μsalto al fetch in caso di condizione falsa. Una alternativa a questo schema che non necessiti di una microistruzione vuota, si può realizzare utilizzando il selettore del multiplexer per comandare direttamente PCIE, ritornando quindi allo schema precedente per decidere riguardo all’incremento o al fetch. 19