Esame di Architettura degli Elaboratori
Anno accademico 2004-2005

Specifiche del progetto Reti Logiche

Scopo di questa esercitazione è il progetto e la realizzazione completa di un'architettura di processore attraverso strumenti di emulazione circuitale. L'architettura in questione dovrà supportare un insieme minimale di istruzioni assembler, utilizzando le quali dovrà essere implementato un algoritmo (vedi programma di test sotto). Tale programma dovrà essere ideato e memorizzato dai componenti del gruppo, e risulterà essere il test funzionale principale dell'architettura realizzata.

Strumenti per l'esercitazione


Il tool utilizzato per l'emulazione circuitale è RETRO, per il quale trovate tutte le informazioni (originali) su

http://www.ee.uwa.edu.au/~braunl/retro/

Scarica qui RETRO.

Retro è stato realizzato da B. "Toy" Chansavat e Thomas Braunl, ed è distribuito sotto GNU public license.

Scopo e richieste del progetto

La progettazione dell'architettura del processore (di seguito CPU) deve essere mirata all'implementazione di un insieme di istruzioni del linguaggio assembler previsto per la CPU stessa. L'insieme di tali istruzioni è ovviamente ridotto e non significativo in termini di utilizzo pratico, in quanto la finalità del progetto è unicamente didattica, e in quanto esistono limiti pratici alla complessità di realizzazione dell'architettura finale.
Per la realizzazione dell'architettura della CPU ci si avvale della libreria Standard di componenti messi a disposizione da RETRO.
Tra questi componenti architetturali, esistono componenti di basso livello (es. porte logiche, collegamenti, bus) ed esistono componenti più complessi (es. multiplexer, decoder, flip-flop, registri, ROM, RAM, sommatori...) che possono essere utilizzati senza limiti (se non quelli fisici legati alla dimensione della "basetta" virtuale di RETRO).
Il requisito fondamentale riguardo all'esigenza di avere una progettazione completa dell'architettura richiede che ogni componente complesso utilizzato almeno una volta nell'architettura realizzata debba essere progettato e realizzato in emulazione, usando una "basetta" separata di RETRO. Di fatto, quindi, ogni componente registro, multiplexer, sommatore, ecc. deve essere progettato e realizzato (in forma prototipale) almeno una volta a partire dalla sintesi circuitale basata sulle sole porte logiche AND, OR, NOT. A tale scopo, dovranno essere descritte le fasi di progetto e sintesi, mostrando i dettagli dei metodi di sintesi utilizzati (mappe di Karnaugh, metodo Quine-MkCluskey, ecc.). La dimostrazione di funzionamento dei singoli componenti complessi dovrà essere possibile, prevista e supportata dall'implementazione attraverso RETRO (ad esempio predisponendo opportunamente led e display per semplici funzioni di test).
Nella realizzazione finale della CPU non si utilizzeranno di fatto i componenti progettati (in quanto non importabili come macro-oggetti), ma si utilizzeranno i componenti della libreria standard di RETRO.
Gli unici componenti complessi che non devono essere realizzati malgrado risultino utilizzati sono: clock, generatori di impulsi, RAM, ROM, e tutti i dispositivi di visualizzazione (display, led, ecc).

Tutta la fase di progetto e sintesi dei costituenti della CPU deve essere opportunamente documentata in una relazione finale alla quale saranno allegati i file di RETRO per il test di funzionamento. La relazione dovrà essere consegnata in formato elettronico (.pdf, .ps o .html) entro le date che saranno definite in seguito.

Elementi essenziali dell'architettura della CPU

L'architettura della CPU è a 8 bit e deve necessariamente prevedere i seguenti elementi costituenti l'architettura stessa:

  • ALU: unità aritmetico-logica per supportare l'insieme delle operazioni sui dati richieste dall'architettura
  • ACC: registro accumulatore a 8 bit, utilizzato per memorizzare i dati/risultati della ALU o i dati da/verso la memoria
  • CodeRegister: registro per il mantenimento e gestione del codice operativo dell'istruzione in esecuzione
  • AddressRegister: registro di indirizzamento a 8 bit, utilizzato per mantenere l'indirizzo di memoria dell'eventuale operando di un'istruzione assembler della CPU.
  • DATA:registro per il mantenimento degli operandi costanti delle istruzioni
  • PC: (program counter) registro a 8 bit che punta alla prossima istruzione assembler da eseguire durante l'esecuzione di un programma memorizzato in RAM.
  • RAM: memoria costituita da 256 locazioni da un byte, indirizzate da 00hex a FFhex, sulle quali potranno essere memorizzati programmi e dati
  • Clock di sistema: segnale che governa l'evoluzione dell'architettura.
  • Generatore di Impulsi (pulse pattern generator): meccanismo di astrazione del concetto di microprogramma, che determina la temporizzazione delle fasi di esecuzione delle microistruzioni, e delle componenti architetturali coinvolte, secondo il classico schema di un'architettura CISC. Su questo oggetto saranno definite in seguito le assunzioni che permettono di semplificare l'architettura stessa.
  • Rete di controllo: agisce sulla base dei segnali ottenuti dal generatore di impulsi, e attraverso la codifica del codice operativo della istruzione in esecuzione, per determinare la effettiva sequenza dei segnali di controllo che governano l'evoluzione della elaborazione della CPU (dipendente dal tipo di istruzione in esecuzione).

Per maggiore chiarezza, verranno forniti esempi di architetture simili che possano risultare di ausilio nella comprensione e progettazione dell'architettura richiesta (es. analizzate cpu2.toy contenuto nel pacchetto di installazione di RETRO).

Le istruzioni della CPU

Si definisce ora l'insieme delle istruzioni assembler che devono essere supportate dall'architettura realizzata.
Tutte le operazioni aritmetiche si intendono realizzate su valori binari interi a 8 bit, espressi in complemento a due.
Fanno eccezione i valori degli indirizzi di RAM che si assumono espressi su 8 bit in binario naturale (256 Byte indirizzabili).
Le uniche istruzioni con operando e gli operandi leciti sono espressamente citati.
Elenco delle istruzioni assembler da implementare per la CPU:

SOLUZIONE A (tutte le matricole del gruppo tutte dispari)

Nome

Argom.

Descrizione

loadD

const

DATA = const

reset

-

ACC = 0

subD

-

ACC = ACC - DATA

add

$addr

ACC = ACC + mem(addr)

store

$addr

mem(addr) = ACC

bgZ

offset

if (ACC > 0) then PC = PC + offset

jump

offset

PC = PC + offset

abs

-

If (ACC>=) then ACC = ACC else ACC=-ACC

SOLUZIONE B (tutte le matricole del gruppo tutte pari)

Nome

Argom.

Descrizione

loadD

const

DATA = const

reset

-

ACC = 0

subD

-

ACC = ACC - DATA

add

$addr

ACC = ACC + mem(addr)

store

$addr

mem(addr) = ACC

bgZ

offset

if (ACC > 0) then PC = PC + offset

jump

offset

PC = PC + offset

cnz

-

ACC=ACC[0]+…+ACC[7]

SOLUZIONE C (le matricole del gruppo pari sono più di quelle dispari)

Nome

Argom.

Descrizione

loadD

const

DATA = const

Reset

-

ACC = 0

subD

-

ACC = ACC - DATA

Add

$addr

ACC = ACC + mem(addr)

store

$addr

mem(addr) = ACC

bgZ

offset

if (ACC > 0) then PC = PC + offset

jump

offset

PC = PC + offset

bp

-

ACC=1 se il numero di “1” in ACC è dispari, ACC= 0 altrimenti.

SOLUZIONE D (le matricole del gruppo dispari sono più di quelle pari)

Nome

Argom.

Descrizione

loadD

const

DATA = const

Reset

-

ACC = 0

subD

-

ACC = ACC - DATA

add

$addr

ACC = ACC + mem(addr)

store

$addr

mem(addr) = ACC

bgZ

offset

if (ACC > 0) then PC = PC + offset

jump

offset

PC = PC + offset

d2b

 

Cambio di rappresentazione di ACC da BCD a binario

 

  • loadD: DATA := const ; il registro DATA viene caricato con il valore const. const è l’operando di questa istruzione e viene considerato come una costante di un byte.
  • Reset: ACC := 0 ; il registro ACC viene caricato con 0.
  • subD: ACC := ACC – DATA ; il registro ACC viene ad assumere il valore ottenuto dal valore attuale al quale si sottrae in binario il valore contenuto nel registro DATA. Non devono essere gestiti i casi di overflow.
  • add: ACC := ACC + mem(addr) ; il registro ACC viene ad assumere il valore ottenuto dal valore attuale al quale si somma in binario il valore contenuto in RAM all'indirizzo addr (indirizzo immediato). Non devono essere gestiti i casi di overflow. addr è l'operando di questa istruzione.
  • store: mem(Address) := ACC ; questa operazione scrive in RAM alla locazione Address (indirizzo immediato) il valore contenuto nel registro ACC. Address è l'operando di questa istruzione. Es. mem(87hex) := ACC.
  • bgZ: if (ACC > 0) then PC :=PC + Offset ; questa istruzione causa l'aggiornamento condizionale (se ACC > 0) del program counter (PC), eventualmente sommandogli il valore immediato Offset (8 bit in complemento a due). Offset è l'operando di questa istruzione.
  • PC :=PC + Offset ; questa istruzione causa l'aggiornamento incondizionato del program counter (PC), sommando il valore immediato Offset (8 bit in complemento a due). Offset è l'operando di questa istruzione.
  • abs: questa istruzione aggiorna il valore del registro ACC col valore assoluto di quanto contenuto.
  • cnz: ACC:=ACC[0]+…+ACC[7]; questa istruzione aggiorna il valore del registro ACC col numero di bit a “1” contenuti nel registro stesso
  • bp;  questa istruzione si può considerare come la primitiva per implementare un controllo di parità, imposta ACC=1 se il numero di “1” in ACC è dispari, ACC= 0 altrimenti.
  • d2b: questa istruzione aggiorna ACC cambiando la rappresentazione del numero memorizzato che deve essere in formato BCD (cioè base decimale, dove per ogni cifra vengono usati 4 bit) a due cifre, con  la relativa rappresentazione binaria.

Il ciclo generico di esecuzione di un'istruzione assembler per l'architettura in esame risulta genericamente definito attraverso le fasi di:

  • fetch del codice operativo dell'istruzione da eseguire (nel Code Register) e aggiornamento PC
  • decodifica del codice operativo dell'istruzione da eseguire
  • caricamento dell'indirizzo dell'eventuale operando dell'istruzione sull'Address Register
  • fetch dell'eventuale operando dell'istruzione (direttamente alla ALU) e eventuale aggiornamento PC
  • esecuzione dell'operazione da parte della ALU, che coinvolge ACC e l'eventuale operando
  • store del risultato sul registro ACC

Si noti come la sequenza di queste fasi possa essere considerata uno (statico) schema del microprogramma per ognuna delle istruzioni richieste. Questa assunzione semplifica la fase di progetto e realizzazione, in quanto permette di definire un pattern statico di temporizzazione dell'architettura nelle sue micro-costituenti.
Ognuna delle fasi descritte deve essere realizzata attraverso la definizione di un insieme statico di pattern di temporizzazione, utilizzando il pattern generator, i cui segnali possono essere dinamicamente mascherati attraverso la rete di controllo (che risulta molto semplice) basata sull'interpretazione del codice operativo della istruzione in esecuzione. Si rimanda all'analisi della rete di esempio (cpu2.toy) per maggiori dettagli. Sono da privilegiare le scelte architetturali volte all'ottimizzazione dell'architettura stessa. Non è ammessa la semplificazione data dal considerare tutte le istruzioni seguite da operando fittizio (non si devono quindi sprecare i Byte di RAM per semplificare l'aggiornamento del PC quando si eseguono istruzioni senza operando).

Per quello che riguarda il progetto di alto livello dell'architettura, la relazione dovrà documentare le scelte, i criteri, e gli accorgimenti usati per ottenere un'architettura che soddisfi al meglio i requisiti minimi definiti. In particolare si ponga attenzione alle diverse modalità di implementazione delle istruzioni richieste, selezionando quelle che si ritengono migliori o meno complesse.

Programma di Test

 

L’ultima parte di progetto concerne l’implementazione di un programma assembler (che si basi sulle istruzioni definite sopra) che risolva uno dei seguenti problemi (in base all’architettura assegnata in base alle matricole):

  • Soluzione A: implementare un programma che, dato una sequenza di interi con segno (ciascuno memorizzato in 1 Byte)  memorizzata in un vettore, imposti tali valori al corrispettivo valore assoluto
  • Soluzione B e C: dato un indirizzo di memoria, il programma deve essere in grado di  implementare un meccanismo di branch on parity ossia deve segnalare un determinato errore nel caso tale cella non contenga un numero pari di bit (salto ad una istruzione che gestisce l’errore), oppure che concluda normalmente la computazione.
  • Soluzione D: prendere degli elementi da un vettore, contenenti numeri con rappresentazione BCD a due cifre e trasformarli nella corrispondente rappresentazione binaria.

N.B. Si richiede di scrivere un programma rilocato staticamente che effettui quanto richiesto secondo lo schema di algoritmo che segue (i dettagli sono lasciati alla fantasia dei costituenti dei gruppi, e lo schema presentato non è in alcun modo vincolante).
Si assuma di avere l'area del codice in RAM a partire dagli indirizzi 00hex fino all'indirizzo AFhex.
Si assuma di avere l'area dei dati in RAM a partire dall'indirizzo B0hex fino all'indirizzo FFhex.
La locazione B0hex contiene un valore intero positivo Size (min:01, max:0A) che rappresenta la dimensione in Bytes del pattern da ricercare in RAM. Nei Bytes immediatamente successivi si trova memorizzato il pattern composto da Size Bytes.