Progetto di Reti Logiche A: filtro gaussiano - dresd.org · 3 Progetto di Reti Logiche A: filtro...
Transcript of Progetto di Reti Logiche A: filtro gaussiano - dresd.org · 3 Progetto di Reti Logiche A: filtro...
Progetto di Reti Logiche A: filtro gaussiano
Autori: Alessandro Stranieri Chiara Sandionigi Revisori: Marco D. Santambrogio
Data: 5/6/2005 Versione: 1.0 Stato: Draft
2
Progetto di Reti Logiche A: filtro gaussiano
Diffusione del documento
Documento interno al laboratorio di Microarchitetture, Dipartimento di Elettronica e Informazione, Politecnico di Milano.
3
Progetto di Reti Logiche A: filtro gaussiano
Revisioni
Data Versione Stato Commento
5/6/2005 1.0 Draft Prima stesura del documento
Si ringraziano per l’aiuto Mele Alessandro e Santambrogio Marco.
4
Progetto di Reti Logiche A: filtro gaussiano
Indice delle figure
Figura 1 : Immagini rumorosa e filtrata…………………………………………………………..7 Figura 2 : Risultato dell’Edge Detection…………………………………………………………..8 Figura 3 : EDK - file system.pbd………………………………………………………………….10
5
Progetto di Reti Logiche A: filtro gaussiano
Indice
Introduzione ___________________________________________________6
Specifica del progetto __________________________________________6
Edge detection ________________________________________________6
Descrizione del lavoro ____________________________________________8
Strumenti e ambiente di sviluppo__________________________________8
Architettura base _____________________________________________10
Passaggio da codice C a VHDL ___________________________________11
Testbench ___________________________________________________9
Inserimento del componente _________________ Error! Bookmark not defined.
Gestione software del progetto _______________ Error! Bookmark not defined.
Risultati della sintesi _______________________ Error! Bookmark not defined.
Conclusione e sviluppi futuri _________________ Error! Bookmark not defined.
Bram ___________________________________ Error! Bookmark not defined.
6
Progetto di Reti Logiche A: filtro gaussiano
Introduzione
Specifica del progetto
Questo progetto ha lo scopo di realizzare un IP core (Intellectual Property core) all’interno
di un sistema dedicato. Si tratta principalmente di eseguire una rappresentazione
hardware di un componente in linguaggio di descrizione dell’hardware VHDL e
implementare il device driver, i.e. le funzionalità software che permettono l’effettivo
utilizzo del componente da parte del sistema.
L’obiettivo è implementare in hardware una parte dell’algoritmo di edge detection secondo
una delle sue formulazioni classiche. Il progetto si basa sull’algoritmo Canny, che è uno
degli algoritmi più utilizzati nella computer vision di basso livello, un passo del quale è
costituito da un filtro gaussiano.
Edge detection
Per Edge Detection s’intende l’operazione di tracciamento ed estrapolazione dei contorni a
partire da una versione digitale di un’immagine. Le possibilità d’impiego che questa tecnica
offre sono molte, e soprattutto se ne possono avere esempi sempre più frequenti nella vita
quotidiana. La rilevazione dei contorni è fondamentale nella cartografia satellitare,
permette il riconoscimento di oggetti da parte dei robot, ma può anche essere utilizzata
nei sistemi di sicurezza di banche o laboratori per il riconoscimento del personale, o per
individuare microimperfezioni durante la catena di montaggio di un prodotto. In letteratura
si incontrano svariati algoritmi che implementano l’Edge Detection: il più noto, per
semplicità ed efficacia, è sicuramente quello di Canny. A sua volta l’algoritmo di Canny può
essere trovato in diverse “interpretazioni”. La versione presa in considerazione per lo
svolgimento del progetto consiste di quattro passi :
7
Progetto di Reti Logiche A: filtro gaussiano
1. Image Smoothing
2. Calcolo del Gradiente
3. Non-Maxima Suppression
4. Hysteresis Threshold
Il primo passo dell’algoritmo, l’Image Smothing, è necessario per rimuovere il
rumore presente nell’immagine e, per farlo, si convolve l’immagine con un filtro gaussiano.
Il risultato sarà un’immagine in cui i valori dei pixel che “sporcavano” l’immagine, risultano
più appiattiti verso i valori dei pixel adiacenti(Figura 1).
Figura 1 - Immagini rumorosa e filtrata a confronto
Essendo un contorno nient’altro che una sensibile variazione d’intensità del colore in
una determinata direzione, nell’algoritmo di Canny, come in molti altri, viene sfruttato
l’operatore gradiente. Il calcolo del gradiente, anch’esso realizzato mediante
finestratura, produce, per ogni pixel dell’immagine di partenza, il valore d’intensità del
gradiente e il valore della direzione del gradiente.
La funzione di Non-Maxima Suppression sfrutta le due immagini prodotte dal
passo precedente: l’immagine dei valori d’intensità e dei valori delle direzioni. Per ogni
pixel, perpendicolarmente al valore della direzione, confronta il suo valore di intensità con
il valore dei pixel adiacenti, eliminando i due più bassi e scegliendo come prossimo pixel
8
Progetto di Reti Logiche A: filtro gaussiano
quello non eliminato. In poche parole si percorre il tratto che presenta la variazione
maggiore, evidenziandolo.
A questo punto si ottiene un’immagine con dei contorni approssimativi tracciati, i
pixel dei quali però presentano ancora valori diversi e spesso coincidenti con falsi contorni.
L’Hysteresis Threshold è il passo finale dell’algoritmo e restituisce un’immagine binaria,
in cui cioè ogni pixel assume uno solo di due valori, conseguentemente al fatto che sia di
contorno oppure no. Questo passo sfrutta due valori soglia, per decidere se eleggere un
pixel a contorno. Ispezionando l’immagine, se il valore del pixel è minore della soglia più
bassa, questo viene considerato debole ed eliminato, altrimenti, se il valore supera la
soglia maggiore o è compreso tra le due soglie e il pixel appartiene ad un tratto di pixel
tutti non deboli, viene eletto a pixel di contorno.
Il risultato finale dell’Edge Detection a partire dalla Figura 1 è visibile in Figura 2.
Figura 2 – Risultato dell’Edge Detection
Descrizione del lavoro
Strumenti e ambiente di sviluppo
Il componente realizzato è stato implementato sulla FPGA XC2VP7 della Xilinx presente
sulla scheda Virtex-II Pro Evaluation Kit della Avnet.
La parte implementativa di questo progetto è stata sviluppata utilizzando principalmente i
seguenti strumenti:
• ISE (Integrated Software Environment) versione 6.3i
9
Progetto di Reti Logiche A: filtro gaussiano
• ModelSim XE II versione 5.7c
• EDK (Embedded Development Kit) versione 6.3i
ISE è un prodotto della Xilinx che consente lo sviluppo completo del design di un
componente. Fornisce un ambiente completo per la realizzazione di sistemi dedicati.
Di questo ambiente è stato utilizzato Project Navigator, uno strumento che permette di
creare un sistema e seguirne tutte le fasi di sviluppo con un controllo diretto su ciascuna
di esse.
ModelSim è uno strumento prodotto dalla Mentor Graphics che permette la simulazione e
la verifica delle descrizioni hardware di un componente o di un intero sistema.
EDK è un ambiente di sviluppo per sistemi dedicati prodotto dalla Xilinx.
Dell’ambiente di EDK è stato utilizzato XPS (Xilinx Platform Studio), uno strumento che
permette di sviluppare sistemi dedicati tramite interfaccia grafica.
Architettura base
L’architettura base che rappresenta il punto di partenza del progetto, è rappresentata in
Figura 3.
10
Progetto di Reti Logiche A: filtro gaussiano
Figura 3 EDK - file system.pbd
Essa è costituita da
• un bus di tipo OPB (On chip Peripheral Bus)
• un bus di tipo plb
• due bus di tipo Transparent
• PowerPC
• opb_uartlite
• altri componenti standard di EDK
Il PowerPC è un hard processor.
I componenti possono essere importati direttamente dalla libreria dei componenti standard
di EDK oppure IP core custom.
Il componente opb_uartlite è l’IP core che fornisce la comunicazione seriale.
11
Progetto di Reti Logiche A: filtro gaussiano
Passaggio da codice C a VHDL
Il punto di partenza per la realizzazione del progetto è stato il sorgente C che implementa
una versione dell’algoritmo di Canny. Questa implementazione iniziale presenta nel corpo
del main solo chiamate a funzione: la prima ed ultima usate per inizializzare e rilasciare
variabili e strutture dati, mentre le altre sono corrispondenti ai distinti passi dell’algoritmo
di Canny. Lo “scopo del gioco” consisteva nel descrivere un componente hardware al
quale, una volta inserito nell’architettura, demandare il compito svolto dalla funzione che
implementa il filtro gaussiano. La funzione presente nel codice C:
1. dichiara e istanzia una matrice 7x7, versione discreta di una gaussiana con media
μ = 2,8 e varianza σ =7,25;
2. ciclando attraverso 4 cicli for annidati, “scorre” una finestra della stessa
dimensione sull’immagine, moltiplica elemento per elemento i valori delle due
matrici e somma tutti i prodotti, dividendo poi il risultato per 140;
3. Il risultato è, per ogni finestra, un valore mediato su quegli adiacenti del pixel
centrale.
Per la realizzazione del progetto è stata scelta la seguente strategia:
1. L’IP Core ha cablata al suo interno la matrice gaussiana;
2. Il processore invia uno dopo l’altro i 49 valori costituenti la finestra attuale
sull’immagine, l’IP Core li moltiplica con i corrispondenti valori della matrice
gaussiana e somma ogni risultato, realizzando così una convoluzione “al volo”;
3. Terminata la trasmissione dei valori dei pixel, il processore ordina al componente di
eseguire il calcolo del valore filtrato del pixel e si pone in attesa;
4. Avendo già ottenuto la somma di prodotti della matrice, il componente divide il
valore per 140 e solleva un interrupt per segnalare al processore la disponibilità del
valore.
Struttura del componente L’IP Core utilizzato per implementare la funzione di filtro presenta la seguente struttura:
12
Progetto di Reti Logiche A: filtro gaussiano
Figura 4 – Struttura di un IP Core con PSelect
Il nostro IP core non è altro che un guscio che fa da interfaccia verso il bus, all’interno del
quale sono contenuti i componenti che implementano la vera logica che realizza la
specifica. La sua interfaccia(Figura 5) è standard, e comprende le porte necessarie alla
comunicazione col processore.
13
Progetto di Reti Logiche A: filtro gaussiano
Figura 5 – Interfaccia Standard di un IP Core
Come è facilmente intuibile, OPB_Clk e OPB_Rst sono i segnali di clock e di reset:
quest’ultimo viene utilizzato per l’azzeramento di tutti i registri interni, azione necessaria
all’inizio di ogni finestratura. I segnali coinvolti nel funzionamento del componente sono:
• OPB_ABus: è il bus degli indirizzi. I valori presenti su questa porta hanno una
molteplice funzione. La prima parte dell’indirizzo viene utilizzata per l’abilitazione
dell’IP Core(vedi sotto). La seconda parte viene invece utilizzata per l’Address
Mapping, vale a dire secondo il valore presente sulla porta, il core esegue una
determinata funzione;
• OPB_DBus: è il bus dati. I valori presenti su questa porta costituiranno l’input del
componente;
• OPB_RNW: questo è un segnale di controllo. Il valore presente su questa porta
indicherà l’azione di lettura dal o scrittura sul componente;
• Sln_Dbus: è il bus sul quale il componente porrà il risultato della computazione;
• Interrupt: attraverso questa porta l’IP core segnalerà al processore la disponibilità
del risultato.
14
Progetto di Reti Logiche A: filtro gaussiano
All’interno dell’IP core troviamo:
• PSelect: quando lo spazio d’indirizzamento presente sul bus coincide con lo spazio
d’indirizzamento assegnato al componente, la PSelect lo abilita, rendendo così
visibili e utilizzabili dal core i segnali in ingresso;
• Core: questo è il componente che realizza la logica del componente. In Figura 6 si
può vedere la sua interfaccia:
Figura 6 – Interfaccia del Core
La maggior parte dei segnali è la replica di quelli provenienti direttamente dal processore.
Gli ingressi che dettano il comportamento vero e proprio del Core sono Rd_nWr e
Address.
Comportamento del Core
In tabella 1 è schematizzato il comportamento del Core in funzione di due ingressi.
15
Progetto di Reti Logiche A: filtro gaussiano
Rd_nWr Address(24 to 31)
(HEX) Azione
0 0x00 to 0xC0 Memorizza il valore del pixel, lo moltiplica per il
corrispondente valore della matrice gaussiana e accumula il
risultato.
0 0xC4 Divide per 140 il risultato dell’operazione precedente.
0 0xC8 Resetta il registro dell’interrupt.
1 0xCC Mette sulla porta Output il risultato della computazione.
1 0xD0 Mette sulla porta Output il valore attuale dell’interrupt.
Tabella 1 – Operazioni svolte dal Core
Come si può vedere dalla tabella, il solo segnale di Rd_nWr non sarebbe sufficiente a
determinare l’azione che il Core deve svolgere. Inoltre, poiché nell’architettura utilizzata
viene indirizzato ogni byte, per distinguere tutti e 49 i valori inviati al componente, ogni
indirizzo dista 4 dal successivo. La stessa distanza è mantenuta per il controllo delle altre
operazioni, sebbene in questo caso l’indirizzo funga semplicemente da alfabeto d’ingresso.
Testbench
Terminata l’operazione di concepimento e descrizione del componente, la prima parte di
verifica è stata la simulazione per mezzo di Modelsim. Per gestire la grande quantità di
ingressi controllabili e i diversi scenari che potrebbero presentarsi, è stato necessario
l’utilizzo di un file di testbench. Questo non è altro che una descrizione, sempre in HDL,
all’interno del quale si dichiarano e istanziano i componenti di cui si vuole simulare il
comportamento e se ne pilotano gli ingressi. Affinché la simulazione fosse il più attendibile
possibile, il file di testbench è stato scritto in modo che al componente simulato
arrivassero in ingresso gli stessi segnali che si sarebbero presentati durante l’esecuzione
reale. Nel file si trova quindi un process che, in successione:
1. Resetta tutti i segnali all’intero del componente;
2. abilita l’IP Core mediante il segnale di OPB_select;
16
Progetto di Reti Logiche A: filtro gaussiano
3. manda in successione i 49 valori, rappresentanti una finestra fittizia;
4. ordina la computazione;
5. si pone in attesa dell’interrupt proveniente dal componente;
6. rilevato l’interrupt, tenta di leggere il risultato: se questo coincide con quello atteso
process termina.
Nel codice C che eseguito dall’architettura viene filtrata una finestra fittizia, i cui valori
vengono generati casualmente mediante funzione rand(). Per aderenza a quella che sarà
l’implementazione reale, nella simulazione vengono inviati gli stessi valori. Questi sono
riportati in Tabella 2.
Tabella 2 – Valori utilizzati nella simulazione
Poiché il nostro componente deve eseguire due diversi calcoli, durante la simulazione è
stato importante osservare la correttezza non solo del risultato finale, ma anche quella del
risultato intermedio, e cioè il risultato della convoluzione delle due matrici. Questi sono
rispettivamente:
Convoluzione: 18740; Divisione(arrotondato): 133.
In Figura 7 è possibile vedere come, una volta che è stato inviato l’ultimo valore, sia già
disponibile la versione binaria del risultato di convoluzione.
45 207 70 41 4 180 120 216 104 167 255 63 43 241 252 217 122 150 9 44 165 87 116 100 196 175 21 40 164 233 87 219 94 32 251 56 168 78 166 20 147 37 86 36 68 223 89 141 67
17
Progetto di Reti Logiche A: filtro gaussiano
Figura 7 – Risultato intermedio
A questo punto della simulazione, al componente viene comandato di terminare il calcolo e
di renderlo disponibile. Il componente esegue la divisione e solleva l’interrupt, come si può
vedere dalla Figura 8.
Figura 8 – Risultato finale
Una volta che il risultato è disponibile, questo può essere letto, cioè propagato sulla porta
riservata ai dati in uscita(figura 9).
18
Progetto di Reti Logiche A: filtro gaussiano
Figura 9 – Lettura del Risultato
Inserimento del componente
Il componente gaussian_filter è stato importato in EDK tramite l’opzione Create/Import
Peripheral presente nel menu Tools[1][3].
Esso compare quindi nella finestra Components tra i componenti standard di EDK, come si
vede in Figura 2.
Figura 2 - Componente gaussian_filter
Il segnalibro Components offre una lista di tutti gli IP core standard e importati che
possono essere aggiunti al sistema.
Selezionando il componente gaussian_filter all’interno della lista fornita dalla finestra
Components e spostandolo all’interno dell’area di lavoro contenente il file system.pdb, è
stato possibile inserire il componente nell’architettura base[2].
19
Progetto di Reti Logiche A: filtro gaussiano
Dopo aver inserito il componente all’interno dell’architettura, sono stati configurati i suoi
parametri per permetterne il corretto funzionamento all’interno del progetto.
Ciccando due volte sul componente gaussian_filter, si apre una finestra che mostra le
proprietà del componente come si vede in Figura 10. La finestra Object Properties è una
finestra specifica per ogni componente contenuto nel sistema. Essa permette di
selezionare il nome e la versione del componente, lo spazio d’indirizzamento, i parametri,
le net alle quali sono collegate le porte dell’IP Core considerato e le informazioni relative
agli interrupt che il componente gestisce.
Figura 10 - Proprietà del componente gaussian_filter
I valori di Base Address e di High Address sono stati impostati manualmente guardando i
valori dati al bus a cui è stato collegato il componente e ai componenti già connessi al bus
e assegnando il primo valore libero al componente tramite una politica di tipo
incrementale.
Risultati dell’Inserimento
Al termine dell’inserimento, all’interno della directory principale dell’architettura troviamo
una cartella chiamata pcores, repository dedicata ai componenti custom. Questa di
conseguenza conterrà una cartella dedicata ai file relativi al nostro componente:
20
Progetto di Reti Logiche A: filtro gaussiano
gaussian_filter_v1_00_a. In Figura 11 si può vedere la gerarchia sottostante la cartella
gaussian_filter_v1_00_a.
Figura 11 – Directory gaussian_filter_v1_00_a
La cartella hdl contiene i file vdhl che descrivono l’IP Core, mentre la cartella src i driver
utilizzati nell’architettura, dei quali si parlerà più avanti. Particolare importanza ha la
cartella data, il cui contenuto è visibile in Figura 12.
Figura 12 – Contenuto della directory data
Questi file sono essenziali per il corretto inserimento del componente e per il suo dialogo
col resto dell’architettura, e sono descritti in [3].
• Un file PAO (Peripheral Analyze Order) contiene una lista di file di descrizione
hardware che sono necessari per la sintesi, insieme all’ordine con cui devono essere
compilati.
• Il file MPD (Microprocessor Peripheral Definition) definisce l’interfaccia dell’IP Core.
• Il file MDD (Microprocessor Driver Definition) servirà per customizzare i driver,
come descritto più avanti.
• Il file TCL è direttamente associato al file MDD, ed insieme ad esso serve per
indicare i parametri da riportare nei file MSS e MHS, come ad esempio base address
e high address.
21
Progetto di Reti Logiche A: filtro gaussiano
All’interno della directory principale dell’architettura, sono presenti altri due file molto
importanti, l’MSS e l’MHS, il cui scopo e utilizzo è ampiamente descritto sempre in [2].
• Il file MHS (Microprocessor Hardware Specification) definisce i parametri hardware
dei componenti presenti nell’architettura.
• Il file MSS (Microprocessor Software Specification) viene editato dall’utente e
contiene le direttive per la customizzazione di driver, sistema operativo e librerie.
Gestione software del progetto
Per verificare velocemente la correttezza della descrizione del componente e la bontà del
suo inserimento nell’architettura è stato scelto come target del progetto, la convoluzione di
una sola finestra, composta di valori casuali. Questa costituisce l’operazione atomica
dell’intera funzione di filtraggio che di conseguenza risulterà di facile costruzione una volta
raggiunto con successo il target.
La forma iniziale del programma che utilizzerà il nostro IP Core all’interno dell’architettura,
è molto semplice. Nel main incontriamo soltanto due funzioni:
• init_system(): inizializza un vettore con 49 valori casuali, corrispondenti ad una
finestra 7x7 “srotolata”;
• gaussian_filter(): invia in successione i 49 valori al nostro componente, chiede
l’esecuzione del calcolo.
A questo punto il programma si pone in attesa che sia segnalato un’interrupt. Una volta
rilevato, il programma ordinerà la lettura del risultato e lo stamperà su uart. Cruciali
nell’esecuzione del programma sono le funzioni necessarie alla comunicazione del software
con l’hardware e alla gestione dell’interrupt.
Scrittura dei Driver
Come descritto in precedenza, le operazioni che il componente esegue dipendono dal
valore presente sul bus indirizzi e da un segnale Rd_nWr. Per comandare questi segnali il
software non può interfacciarsi direttamente con il componente, ma ha bisogno di driver
specifici per gestirlo via software. Esistono tre diversi tipi di driver utilizzabili, a seconda
del livello di astrazione a cui si intende operare(per approfondire vedere Bibliografia). In
questo contesto vengono usati dei driver di livello 0, cioè funzioni che comunicano
22
Progetto di Reti Logiche A: filtro gaussiano
direttamente col componente offrendo all’utente delle semplici operazioni, e sono definite
nel file “gaussian_filter_l.h”. Nel nostro caso vengono utilizzate due funzioni, delle quali
vengono riportate le sole intestazioni:
• GaussianFilter_mWriteReg(BaseAddress, RegOffset, Data);
• GaussianFilter_mReadReg(BaseAddress, RegOffset).
E’ facile da intuire che il valore assunto dal segnale Rd_nWr dipenderà dal nome della
funzione: ‘0’ per la prima, ‘1’ per la seconda. L’argomento Base Address è il primo
indirizzo assegnato al componente, mentre tramite RegOffset si accede ad ogni byte
all’interno dello spazio di indirizzamento assegnato all’IP Core. Il terzo argomento della
funzione di scrittura, Data, corrisponde al dato che si vuole inviare al componente.
Come si può vedere sempre all’interno del file “gaussian_filter_l.h”, queste in realtà sono
delle ridefinizioni di funzioni standard della Xilinx, in particolare di:
• void XIo_Out32(XIo_Address OutAddress, Xuint32 Value);
• Xuint32 XIo_In32(XIo_Address InAddress).
Queste sono dichiarate e definite nei file “xio.h” e xio.c” e possono essere utilizzate per
una generale operazione di lettura o scrittura in memoria. E’ importante notare che la
funzione di scrittura è stata ridefinita in modo che il singolo parametro <XIo_Address
OutAddress> sia separato in < BaseAddress + RegOffset >, questo per rendere più
visibile all’utente il fatto che a diverso componente corrisponde diverso base address. Per
ulteriore approfondimento consultare [4].
Gestione dell’interrupt
Una volta che il risutato è disponibile, il componente solleva un’interrupt che in qualche
modo deve essere percepito e gestito dal programma. Al contrario della gestione degli
interrupt con Microblaze che è quasi completamente automatica, con PPC questa risulta
decisamente più articolata. Per prima cosa è necessario scrivere la funzione di gestione
dell’interrupt, cioè la funzione che verrà invocata non appena il processore rileverà
un’interrupt da quella periferica. E’ necessario che la funzione abbia come suffisso
int_handler in modo che successivamente possa essere riconosciuta dal sitema. La
nostra funzione si chiamerà quindi:
void gaussian_filter_int_handler(void).
23
Progetto di Reti Logiche A: filtro gaussiano
Una volta che viene invocata, controlla che l’interrupt sia effettivamente sollevato, lo
resetta e legge il risultato e torna al chiamante.
A questo punto occorre modificare il file MDD relativo al componente come illustrato in
Figura 13.
Figura 13 – File MDD
In questo modo nel file MSS, in corrispondenza del componente, viene aggiunto il
parametro relativo all’interrupt(Figura 14).
Figura 14 – File MSS
Il passo successivo consiste nel collegare la porta Interrupt del IP Core con una porta
adatta al caso del processore. Questo può essere fatto abbastanza agevolmente a partire
dal file system.pbd. Andando su Object Properties, alla sezione Ports, del componente, è
sufficiente impostare una net in corrispondenza della porta Interrupt(Figura 15).
24
Progetto di Reti Logiche A: filtro gaussiano
Figura 15 – Configurazione della net per gaussian_filter
La stessa net va poi configurata per una porta del processore, in questo caso la
EICC405EXTINPUTIRQ, che è la porta per gli interrupt esterni e non critici[5][7]. In altre
parole si tratta di “tirare un filo” da una porta all’altra.
Il buon esito di questa procedura può essere verificato andando su Software Platform
Settings, direttamente dal menu Project. In Figura 16 si vede come il gestore dell’interrupt
sia stato riconosciuto.
25
Progetto di Reti Logiche A: filtro gaussiano
Figura 16 – Riconoscimento del gestore dell’interrupt
L’ultima operazione da compiere, obbligatoria in architetture che utilizzano PPC, consiste
nello scrivere nel corpo del main alcune funzioni per la gestione degli interrupt[5] [6].
Queste sono:
• XExc_Init(): inizializza la gestione degli interrupt;
• XExc_RegisterHandler(XEXC_ID_NON_CRITICAL_INT,
(XExceptionHandler)gaussian_filter_int_handler, (void
*)XPAR_GAUSSIAN_FILTER_1_BASEADDR): inserisce la funzione di gestione
all’interno del vettore degli interrupt;
• XExc_mEnableExceptions(XEXC_NON_CRITICAL): abilita le eccezioni non
critiche.
26
Progetto di Reti Logiche A: filtro gaussiano
Risultati della sintesi
Affinché l’IP Core possa essere importato e inserito all’interno dell’architettura, occorre che
l’HDL che lo descrive sia sintetizzabile. Questo vuol dire che a partire dalla descrizione
hardware del componente, deve essere possibile creare la rete che realizza la funzione
descritta. Sfortunatamente il VHDL originariamente non era inteso come input di un tool di
sintesi, e ciò comporta che non tutto il codice VHDL che si può scrivere può essere
tradotto in hardware[8]. In questo senso il primo grosso ostacolo in cui ci si è imbattuti è
stato quello dovuto all’impossibilità di realizzare il passo della divisione con la stessa
semplicità con cui si potrebbe eseguire nella programmazione sequenziale. Tra le altre
cose, l’incorrere in questa difficoltà ha portato ad una modifica del flusso di lavoro che, se
prima prevedeva il passo di sintesi solo dopo aver scritto e simulato il componente, a quel
punto vedeva necessario un metodico alternarsi di simulazione e prove di sintesi, reso
comunque facile dall’interoperabilità di Project Navigator e Modelsim. Il problema della
sintesi della divisione consiste nel fatto che questa è supportata solo nel caso in cui o
entrambi gli operatori siano costanti o il divisore sia una potenza di due[9]. Dopo vari
tentativi, la soluzione adottata è stata semplicemente quella di sottrarre ad ogni ciclo di
clock il divisore finchè questo si trova ad essere maggiore del dividendo. Lo svantaggio di
questo approccio è che il tempo di disponibilità del risultato è sensibilmente variabile in
dipendenza dal dividendo. Il secondo problema incontrato è stato quello legato alla qualità
della sintesi. Una delle operazioni più importanti che viene effettuata dal nostro IP Core è
quella di ricevere e immagazzinare ben 49 elementi che poi andranno convoluti con la
matrice gaussiana. Per fare questo il primo tentativo è stato quello di immagazzinare
valore per valore in un vettore per poi eseguire in un secondo momento convoluzione e
divisione per mezzo di procedure. Sfortunatamente il risultato della sintesi dava un
componente la cui velocità massima risultava essere di soli 15 Mhz, mentre quelle del
processore doveva essere di 100 Mhz. La causa di una così povera prestazione era dovuta
al gran numero di registri presenti e alle varibili accumulatrici all’interno delle procedure.
Questi infatti comportavano la creazione di un gran numero di FlipFlop(1500 ca.) e di
conseguenza l’aumento di area e percorso critico. Tutto ciò ha portato alla fine a quella
che è la realizzazione attuale del modello comportamentale del componente: é stato
eliminato l’uso di procedure e si è scelto di eseguire l’operazione di convoluzione,
27
Progetto di Reti Logiche A: filtro gaussiano
contemporaneamente al ricevimento dei singoli valori. In questo modo si è riusciti a
raggiungere prestazioni decisamente migliori, con un componente che può operare alla
velocità di 190 Mhz(Figura 17).
Figura 17 – Risultati della Sintesi
Conclusione e sviluppi futuri
Durante lo svolgimento del progetto è stata acquisita una notevole esperienza per quanto
riguarda l’utilizzo degli strumenti ma soprattutto è servita ad una prima comprensione del
funzionamento delle architetture integrate e delle problematiche legate al loro design.
A questo primo passo costituito dalla realizzazione del progetto, seguirà un lavoro di tesi
all’interno del quale potranno prendere posto diverse idee legate al raffinamento
dell’architettura e delle parti che la compongono. Il primo obiettivo da conseguire sarà
quello di rendere possibile l’esecuzione dell’intero algoritmo, tracciando i contorni di
un’immagine reale. In seguito si modificherà lo stesso algoritmo, precisamente nel passo
di Hysteresis Threshold, seguendo un approccio statistico nella scelta di valori di soglia
28
Progetto di Reti Logiche A: filtro gaussiano
locali piuttosto che globali[10]. Per quanto riguarda la descrizione hardware dell’IP Core, si
potrebbe ottenere un vantaggio notevole in velocità, migliorando il metodo di divisione
intera, ad esempio per mezzo di pipeline.
Bram
Nell’architettura base del progetto è stata inserita una bram. Si tratta di un componente
standard di EDK che svolge le funzioni di memoria.
Nell’architettura sono presenti la bram stessa (bram_block) e un controllore per la bram
(opb_bram_if_cntlr), entrambi collegati allo stesso bus di tipo Transparent. Il controllore
per la bram è inoltre collegato al bus a cui è connesso il componente gaussian_filter.
Questo componente non è stato utilizzato nell’ambito del progetto, ma si presta ad un uso
per sviluppi futuri.
29
Progetto di Reti Logiche A: filtro gaussiano
Bibliografia
[1] Leonardo Minò, Vincenzo Rana “Importazione ed utilizzo in EDK di Latch e Flip Flop
come periferiche custom”, versione 6.2, 15 aprile 2004.
[2] Alessandro Stranieri, Chiara Sandionigi “Come aggiungere una periferica in EDK”,
versione 6.3, 22 marzo 2005.
[3] Xilinx “Embedded System Tools Guide”, versione 6.2, 16 giugno 2004, cap.
4/7/15/16/17/19/21.
[4] Alessandro Mele, Francesca Malcotti “Definizione ed utilizzo dei Driver in EDK”,
versione 6.2, maggio 2004.
[5] Using and Creating Interrupt-Based Systems, xapp778 v1.0, 11 gennaio 2005.
[6] Xilinx “Platform User Studio Guide”, versione 6.3, 20 agosto 2004, cap. 5.
[7] Xilinx “Edk PowerPC Tutorial”, versione 6.2.
[8] Xilinx "Synthesis and Verification Design Guide", all'interno di "Xilinx ISE 6 Software
Manuals".
[9] IEEE Standard for VHDL Register Transfer Level (RTL) Synthesis, IEEE Std 1076.6-
1999.
[10] Rishi R. Rakesh, Probal Chaudhuri e C. A. Murthy “Thresholding in Edge Detection: A
Statistical Approach”, IEEE TRANSACTIONS ON IMAGE PROCESSING, VOL. 13, NO.
7, JULY 2004.