
Simulazioni finali
Qui di seguito si riportano i risultati della simulazione di alcune istruzioni effettuate sia con il software di simulazione appositamente realizzato per il processore, sia con ModelSim 5.7f.
Fetch delle istruzioni

figura 22 - Lista completa dei segnali e dei registri del sistema
La figura 22 mostra un elenco di tutti i segnali presenti nel nostro sistema.

figura 23 - Caricamento prima parte dell’istruzione
La figura 23 mostra l’attivazione del segnale rom_rd (abilitazione lettura dalla rom) e l’aggiornamento dei registri rom_dt e temp (vengono caricati i primi 8 bit dell’istruzione).

figura 24 - Caricamento dell’intera istruzione nell’IR
Come si vede dalla figura 24 il caricamento dell’istruzione nell’IR avviene attraverso diverse fasi. La fase cerchiata in rosso rappresenta l’operazione (che avviene sul fronte di discesa) di caricamento della prima metà di istruzione nel registro rom_dt. In seguito (cerchio giallo) il valore caricato in rom_dt viene riversato in un registro di appoggio (tmp). Successivamente viene caricata in IR l’intera istruzione (rom_dt&tmp). E’ interessante notare come sia necessario un tempo delta per la determinazione dello stato prossimo. L’istruzione caricata in questo caso è una istruzione di trasferimento, in particolare una “MOVE”, (i bit più significativi dell’IR sono a 110).
Istruzione MOVE

figura 25 - Variazione di registri implicati nell’operazione di MOVE

figura 26 - Risultato di una MOVE sul registro R3 (MOVE R3, #32)
Dalla figura 25 si vedono le varie fasi che portano all’esecuzione dell’istruzione MOVE R3, #32. La prima fase è quella del caricamento (vista in precedenza) che ha luogo a partire da t=700ns. Da t=1000ns viene caricato nel registro off_op_imm il valore 32, mentre nel registro di indirizzamento-registri (id3) viene caricato il valore 3. Nell’istante t=1200ns il valore 32 viene caricato in R3, come illustrato in figura 26.
Fetch instruction 1 : 1100011000100000
Instruction Decode like : MOVE
Opcode : 6
Destination Register : 3
Immediate Operand : 32
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000000000100000
Reg4 : 0000000000000000000
Reg5 : 0000000000000000000
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000000
Reg9 : 0000000000000000000
Reg10 : 0000000000000000000
Reg11 : 0000000000000000000
Reg12 : 0000000000000000000
Reg13 : 0000000000000000000
Reg14 : 0000000000000000000
Reg15 : 0000000000000000000
figura 27 - Risultato di una MOVE sul registro R3 (MOVE R3, #32) fornito dal nostro simulatore
Si vede anche dal file di log prodotto dal simulatore da noi sviluppato, che l’operazione viene eseguita correttamente.
Istruzione SHIFTL

figura 28 - Variazione dei registri implicati nell’operazione di SHIFTL

figura 29 - Risultato di una SHIFTL sul registro R3 (SHIFTL R3, R3, #4)
Fetch instruction 2 : 1110011001100100
Instruction Decode like : SHIFTL
Opcode : 7
Destination Register : 3
Source Register 1 : 3
Immediate Operand : 4
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000001000000000
Reg4 : 0000000000000000000
Reg5 : 0000000000000000000
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000000
Reg9 : 0000000000000000000
Reg10 : 0000000000000000000
Reg11 : 0000000000000000000
Reg12 : 0000000000000000000
Reg13 : 0000000000000000000
Reg14 : 0000000000000000000
Reg15 :
0000000000000000000
figura 30 - Risultato di una SHIFTL sul registro R3 (SHIFTL R3, R3, #4) fornito dal nostro simulatore
La figura 28 mostra le variazioni che interessano i registri implicati nell’operazione SHIFTL R3, R3, #4. Si nota che l’operazione, come al solito, inizia col caricamento dell’istruzione (in questo caso a partire da t=1200ns), poi prosegue col caricamento del valore 3 in id3 (identifica il registro destinazione), del valore 3 in id2 (individua il registro da cui prender il dato da shiftare), il valore 4 in shn (contiene il numero di posizioni di cui il dato deve essere shiftato). Come si vede dalla figura 29 e dalla figura 30, l’operazione di shift viene eseguita correttamente (t=1700 ns), sia con ModelSim che con il nostro simulatore.
Istruzione SUB

figura 31 - Variazione dei registri implicati nell’operazione di SUB
La figura 31 mostra come un’operazione SUB alteri i registri alu_op1, alu_op2, alu_res. L’uscita dell’ALU (alu_res) rappresenta la differenza tra i due operandi di ingresso. Il risultato viene reso disponibile in uscita sul fronte di discesa del clock.

figura 32 - Risultato di una SUB sul registro R4 (SUB R4, R3, R0)
Fetch instruction 3 : 0010100001100000
Instruction Decode like : SUB
Opcode : 1
Destination Register : 4
Source Register 1 : 3
Source Register 2 : 0
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000001000000000
Reg4 : 0000000000111111111
Reg5 : 0000000000000000000
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000000
Reg9 : 0000000000000000000
Reg10 : 0000000000000000000
Reg11 : 0000000000000000000
Reg12 : 0000000000000000000
Reg13 : 0000000000000000000
Reg14 : 0000000000000000000
Reg15 :
0000000000000000000
figura 33 - Risultato di una SUB sul registro R4 (SUB R4, R3, R0) fornito dal nostro simulatore
Dalla figura 32 e figura 33 invece viene presa in esame la variazione del registro R4 in base ai valori di R3 ed R0. Anche in questo caso l’operazione viene eseguita correttamente sia da ModelSim che dal nostro simulatore.
Istruzione ADD
Un ragionamento del tutto analogo può essere seguito nel caso di un’operazione di ADD. Nelle figure seguenti viene mostrata la variazione degli operandi dell’ALU (figura 34) e dei registri coinvolti nell’operazione ADD R8, R7, R0 (figura 35)

figura 34 - Variazione dei registri implicati nell’operazione di ADD

figura 35 - Risultato di una ADD sul registro R8 (ADD R8, R7, R0)
Fetch instruction 10 : 0001000011100000
Instruction Decode like : ADD
Opcode : 0
Destination Register : 8
Source Register 1 : 7
Source Register 2 : 0
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000001000000000
Reg4 : 0000000000111111111
Reg5 : 0000000000000010010
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000001
Reg9 : 0000000000000000000
Reg10 : 0000000000000000000
Reg11 : 0000000000000000000
Reg12 : 0000000000000000000
Reg13 : 0000000000000000000
Reg14 : 0000000000000000000
Reg15 : 1111111111111101110
figura 36 - Risultato di una ADD sul registro R8 (ADD R8, R7, R0) fornito dal nostro simulatore
La figura 36 mostra che anche il nostro software di simulazione effettua l’operazione correttamente.
Istruzione LOADB

figura 37 - Variazione dei registri implicati nell’operazione di LOADB

tabella 1 - Contenuto del file sorgente img_mem.img

figura 38 - Risultato dell’operazione LOADB R10, (R8)
La figura 37 mostra la variazione del contenuto del registro ram_mar_a dovuta all’istruzione LOADB R10, (R8). Ad ir2 viene assegnato il valore contenuto in R8, dopodichè in ram_mar_a viene caricato il contenuto della locazione di memoria esterna (che contiene l’immagine) puntata da ir2. Il valore sarà pronto in ram_mar_a all’istante t = 6700ns mentre il registro R10 sarà aggiornato all’istante t = 6900ns. Si nota che in R10 è stato scritto il valore esadecimale 35, contenuto nella locazione di memoria di indirizzo 000001(hex) come si può vedere dal confronto tra la tabella 1 e la figura 37, figura 38 e figura 39.
Fetch instruction 12 : 1001010100000000
Instruction Decode like : LOADB
Opcode : 4
Destination Register : 10
Source Register 1 : 8
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000001000000000
Reg4 : 0000000000111111111
Reg5 : 0000000000000010010
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000001
Reg9 : 0000000000000110101
Reg10 : 0000000000000110101
Reg11 : 0000000000000000000
Reg12 : 0000000000000000000
Reg13 : 0000000000000000000
Reg14 : 0000000000000000000
Reg15 :
1111111111111101110
figura 39 - Risultato dell’operazione LOADB R10, (R8) fornita dal nostro simulatore
Istruzione STORB

tabella 2 - Contenuto del file sorgente img_mem.img
La tabella 2 mostra il contenuto del file che rappresenta la nostra memoria in cui è contenuta l’immagine (i valori sono espressi in base esadecimale). Come si vede la differenza tra il pixel in posizione 00000 (cerchiato in rosso) è maggiore di 18 (12hex, soglia fissata per l’individuazione di un contorno).

figura 40 - Contenuto dei registri R9 ed R10 dopo la lettura della memoria
Tali valori sono caricati rispettivamente nei registri R9 ed R10, come si vede dalla figura 40 e figura 41 (che mostrano lo stesso risultato ottenuto con i due diversi sistemi di simulazione) . In R11 è caricata invece la loro differenza.
Fetch instruction 22 : 1011100011001000
Instruction Decode like : STORB
Opcode : 5
Destination Register : 12
Immediate Operand : 200
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000001000000000
Reg4 : 0000000000111111111
Reg5 : 0000000000000010010
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000001
Reg9 : 0000000000010000111
Reg10 : 0000000000000110101
Reg11 : 0000000000001010010
Reg12 : 0000000000000000001
Reg13 : 0000000000000000000
Reg14 : 0000000000000101000
Reg15 : 1111111111111101110
figura 41 - Contenuto dei registri R9 ed R10 dopo la lettura della memoria fornito dal nostro simulatore

figura 42 - Contenuto dei registri R12 e ram_mar durante l’operazione STORB (stato 10)
Visto che la differenza è superiore a 18 si verifica la condizione che avevamo imposto per l’esecuzione della STORB. In R12 viene memorizzato il valore dell’indirizzo della memoria esterna (la stessa memoria img_mem.img) in cui andremo a scrivere il valore 200 (C8hex).

tabella 3 - Contenuto del file img_mem.img dopo l’operazione di STORB
La tabella 3 conferma quanto appena detto, infatti il valore C8 viene caricato nella posizione 40000hex (1000000000000000000 in binario, come si vede dalla figura 42).
Istruzione BRGT

figura 43 - Variazione dei registri implicati in un’istruzione di BRANCH
Ora vediamo il test di funzionamento di istruzioni di BRANCH. La prima istruzione di salto (BRGT IF_2 R15, R11) non deve dare luogo a salto, infatti (come da figura 43) il PC viene incrementato di sole due posizioni e dallo stato 11 (verifica della condizione per il salto) si torna allo stato 2 (stato iniziale). La seconda BRANCH (BRGT ENDIF R3, R0) sarà invece eseguita in quanto in R0 (vedi figura 44) è contenuto un valore minore di quello contenuto in R3. Si passerà quindi per lo stato 12 (evidenziato in giallo) in cui il PC viene aggiornato con il valore contenuto in R14.
Si noti che prima dello stato 11 si passa nello stato 7 (MOVE) per pre-caricare in R14 l’eventuale valore del PC nel caso in cui il salto fosse da eseguire. Se il salto viene eseguito PC<=R14 altrimenti PC<=PC+2. Questo si evince dalle figg. 17a e 17b prese dal file di log del nostro simulatore.

figura 44 – Registri implicati nella condizione di salto BRGT ENDIF,R3,R0
La figura 45 mostra il caso in cui un salto non venga preso. Infatti l’indicatore dell’istruzione caricata successivamente è incrementato di uno rispetto al precedente (dall’istruzione 17 si passa alla 18). La figura 46 invece mostra il caso in cui un salto avvenga. L’istruzione successiva, di cui viene fatto il fetch, ha il valore relativo al salto (in questo caso si passa dall’istruzione 19 all’istruzione 28).
Fetch instruction 16 : 1101110000110010
Instruction Decode like : MOVE
Opcode : 6
Destination Register : 14
Immediate Operand : 50
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000001000000000
Reg4 : 0000000000111111111
Reg5 : 0000000000000010010
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000001
Reg9 : 0000000000000110101
Reg10 : 0000000000000110101
Reg11 : 0000000000000000000
Reg12 : 0000000000000000000
Reg13 : 0000000000000000000
Reg14 : 0000000000000110010
Reg15 : 1111111111111101110
Fetch instruction 17 : 0101111101111100
Instruction Decode like : BRGT
Opcode : 2
Load PC from Register : 14
Source Register 1 : 15
Source Register 2 : 11
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000001000000000
Reg4 : 0000000000111111111
Reg5 : 0000000000000010010
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000001
Reg9 : 0000000000000110101
Reg10 : 0000000000000110101
Reg11 : 0000000000000000000
Reg12 : 0000000000000000000
Reg13 : 0000000000000000000
Reg14 : 0000000000000110010
Reg15 : 1111111111111101110
Fetch instruction 18 : 1101110000111000
Instruction Decode like : MOVE
Opcode : 6
Destination Register : 14
Immediate Operand : 56
Execute done.
figura 45 - Fetch di istruzione seguente ad un salto “non preso”
Fetch instruction 18 : 1101110000111000
Instruction Decode like : MOVE
Opcode : 6
Destination Register : 14
Immediate Operand : 56
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000001000000000
Reg4 : 0000000000111111111
Reg5 : 0000000000000010010
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000001
Reg9 : 0000000000000110101
Reg10 : 0000000000000110101
Reg11 : 0000000000000000000
Reg12 : 0000000000000000000
Reg13 : 0000000000000000000
Reg14 : 0000000000000111000
Reg15 : 1111111111111101110
Fetch instruction 19 : 0100011000011100
Instruction Decode like : BRGT
Opcode : 2
Load PC from Register : 14
Source Register 1 : 3
Source Register 2 : 0
Execute done.
Registers Dump
Reg0 : 0000000000000000001
Reg1 : 0000000000000000000
Reg2 : 0000000000000000000
Reg3 : 0000000001000000000
Reg4 : 0000000000111111111
Reg5 : 0000000000000010010
Reg6 : 0000000000000000000
Reg7 : 0000000000000000000
Reg8 : 0000000000000000001
Reg9 : 0000000000000110101
Reg10 : 0000000000000110101
Reg11 : 0000000000000000000
Reg12 : 0000000000000000000
Reg13 : 0000000000000000000
Reg14 : 0000000000000111000
Reg15 : 1111111111111101110
Fetch instruction 28 : 0000010001000000
Instruction Decode like : ADD
Opcode : 0
Destination Register : 2
Source Register 1 : 2
Source Register 2 : 0
Execute done.
figura 46 - Fetch di un’istruzione seguente un salto “preso”
Istruzione RETURN

figura 47 - Variazione del registro di stato dopo l’istruzione RETURN
L’operazione RETURN (stato 13) ci riporta nello stato 1 (attesa dell’interrupt) come previsto.