163
UNIVERSITA’ DEGLI STUDI DI GENOVA FACOLTA’ DI INGEGNERIA Corso di Laurea Specialistica in Ingegneria Elettronica Dispense per le esercitazioni del corso Sistemi Elettronici Programmabili 1 Prof. Davide Anguita A cura di: Alessandro Ghio Basato sul lavoro di: Stefano Pischiutta Anno Accademico 2006 - 2007 Documento realizzato in L A T E X

Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

  • Upload
    others

  • View
    11

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

UNIVERSITA’ DEGLI STUDI DI GENOVAFACOLTA’ DI INGEGNERIA

Corso di Laurea Specialistica in Ingegneria Elettronica

Dispense per le esercitazioni del corso

Sistemi Elettronici Programmabili 1

Prof. Davide Anguita

A cura di: Alessandro GhioBasato sul lavoro di: Stefano Pischiutta

Anno Accademico 2006 - 2007Documento realizzato in LATEX

Page 2: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Indice

1 Progetto di un sistema digitale 71.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2 Rappresentazione di un sistema digitale . . . . . . . . . . . . . 81.3 Development flow . . . . . . . . . . . . . . . . . . . . . . . . . 121.4 Organizzazione della dispensa . . . . . . . . . . . . . . . . . . 15

2 Hardware Description Languages 172.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.2 VHDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.2.1 Strutture . . . . . . . . . . . . . . . . . . . . . . . . . 192.2.2 Elementi lessicali . . . . . . . . . . . . . . . . . . . . . 262.2.3 Oggetti . . . . . . . . . . . . . . . . . . . . . . . . . . 282.2.4 Tipi di dati e operatori . . . . . . . . . . . . . . . . . . 302.2.5 Consigli pratici . . . . . . . . . . . . . . . . . . . . . . 37

3 Istruzioni concorrenti 393.1 Circuiti combinatori vs. Circuiti sequenziali . . . . . . . . . . 393.2 Istruzioni concorrenti semplici . . . . . . . . . . . . . . . . . . 403.3 Istruzioni concorrenti condizionali . . . . . . . . . . . . . . . . 41

3.3.1 Sintassi . . . . . . . . . . . . . . . . . . . . . . . . . . 413.3.2 Un esempio: multiplexer a 4 ingressi . . . . . . . . . . 41

3.4 Istruzioni concorrenti di selezione . . . . . . . . . . . . . . . . 433.4.1 Sintassi . . . . . . . . . . . . . . . . . . . . . . . . . . 433.4.2 Un esempio: multiplexer a 4 ingressi (con istruzioni di

selezione) . . . . . . . . . . . . . . . . . . . . . . . . . 443.4.3 Un secondo esempio: tabella di verita generica . . . . . 44

4 Istruzioni sequenziali 474.1 Il processo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.1.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . 474.1.2 Processi con sensitivity list . . . . . . . . . . . . . . . . 48

1

Page 3: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

4.1.3 Processi con istruzioni wait . . . . . . . . . . . . . . . 494.2 Istruzioni di assegnazione sequenziale per segnali . . . . . . . . 514.3 Istruzioni di assegnazione sequenziale per variabili . . . . . . . 524.4 Costrutto if...then...else . . . . . . . . . . . . . . . . . . . . . . 54

4.4.1 Sintassi . . . . . . . . . . . . . . . . . . . . . . . . . . 544.4.2 Un esempio: multiplexer a 4 ingressi . . . . . . . . . . 544.4.3 Incomplete branch . . . . . . . . . . . . . . . . . . . . 564.4.4 Incomplete assignment . . . . . . . . . . . . . . . . . . 56

4.5 Costrutto case...when . . . . . . . . . . . . . . . . . . . . . . . 574.5.1 Sintassi . . . . . . . . . . . . . . . . . . . . . . . . . . 574.5.2 Un esempio: multiplexer a 4 ingressi . . . . . . . . . . 58

4.6 Costrutto for...loop . . . . . . . . . . . . . . . . . . . . . . . . 594.6.1 Sintassi . . . . . . . . . . . . . . . . . . . . . . . . . . 594.6.2 Un esempio: XOR bit–a–bit a 8 bit . . . . . . . . . . . 59

5 Progetto di circuiti combinatori 615.1 Operator Sharing . . . . . . . . . . . . . . . . . . . . . . . . . 625.2 Functionality Sharing . . . . . . . . . . . . . . . . . . . . . . . 635.3 Ottimizzazioni di layout . . . . . . . . . . . . . . . . . . . . . 65

6 Progetto di circuiti sequenziali 716.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

6.1.1 Circuiti sequenziali . . . . . . . . . . . . . . . . . . . . 716.1.2 Elementi di memoria . . . . . . . . . . . . . . . . . . . 716.1.3 Classificazione dei circuiti sequenziali . . . . . . . . . . 73

6.2 Circuiti sequenziali sincroni . . . . . . . . . . . . . . . . . . . 746.3 Programmazione di elementi di memoria elementari . . . . . . 75

6.3.1 Positive–Edge–Triggered D Flip–Flop . . . . . . . . . . 766.3.2 FF D con reset asincrono . . . . . . . . . . . . . . . . . 766.3.3 Registro a 8 bit . . . . . . . . . . . . . . . . . . . . . . 786.3.4 RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796.3.5 ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

6.4 Un esempio: contatore sincrono modulo–m programmabile . . 806.4.1 Prima soluzione . . . . . . . . . . . . . . . . . . . . . . 806.4.2 Seconda soluzione . . . . . . . . . . . . . . . . . . . . . 81

6.5 Analisi temporale di circuiti sincroni . . . . . . . . . . . . . . 836.5.1 Massima frequenza di clock . . . . . . . . . . . . . . . 846.5.2 Altre informazioni . . . . . . . . . . . . . . . . . . . . 856.5.3 Output del sintetizzatore Xilinx . . . . . . . . . . . . . 86

6.6 Utilizzo di variabili in circuiti sequenziali . . . . . . . . . . . . 89

2

Page 4: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

6.6.1 Progettazione del contatore modulo–m utilizzando vari-abili . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

7 Macchine a stati finiti 937.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 937.2 Rappresentazione di una FSM . . . . . . . . . . . . . . . . . . 94

7.2.1 Pallogrammi . . . . . . . . . . . . . . . . . . . . . . . . 947.2.2 ASM . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

7.3 Alcune considerazioni sulle FSM . . . . . . . . . . . . . . . . . 1017.3.1 Considerazioni temporali . . . . . . . . . . . . . . . . . 1017.3.2 Macchine di Moore e macchine di Mealy: pro e contro . 101

7.4 Descrizione VHDL di una FSM . . . . . . . . . . . . . . . . . 1037.5 Codifica degli stati . . . . . . . . . . . . . . . . . . . . . . . . 110

8 Look–Up Tables (LUT) 1138.1 Che cos’e una LUT? . . . . . . . . . . . . . . . . . . . . . . . 1138.2 Pro e contro . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1148.3 Codice VHDL per una LUT . . . . . . . . . . . . . . . . . . . 1148.4 Codice per la generazione automatica del VHDL . . . . . . . . 116

9 Hierarchical Design 1199.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

9.1.1 Hierarchical Design: pro e contro . . . . . . . . . . . . 1209.1.2 Costrutti VHDL per il Hierarchical Design . . . . . . . 120

9.2 Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1219.3 Generic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1239.4 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . 1259.5 Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1269.6 Subprogram . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1269.7 Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

10 Parameterized VHDL 12910.1 Attributi di un array . . . . . . . . . . . . . . . . . . . . . . . 12910.2 Array con e senza range . . . . . . . . . . . . . . . . . . . . . 13010.3 Costrutto For...Generate . . . . . . . . . . . . . . . . . . . . . 13110.4 Costrutto if...generate . . . . . . . . . . . . . . . . . . . . . . 13210.5 Array bidimensionali . . . . . . . . . . . . . . . . . . . . . . . 133

10.5.1 Array bi–dimensionale effettivo . . . . . . . . . . . . . 13310.5.2 Array bi–dimensionale emulato . . . . . . . . . . . . . 134

3

Page 5: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

11 Testbench 13511.1 Test di dispositivi digitali . . . . . . . . . . . . . . . . . . . . 13511.2 Creazione di un testbench . . . . . . . . . . . . . . . . . . . . 136

12 Esempi finali e guida a Xilinx ISE Web–Pack 14312.1 Introduzione a Xilinx ISE Web Pack 8.2i . . . . . . . . . . . . 14312.2 Esempi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

12.2.1 Half–Adder asincrono . . . . . . . . . . . . . . . . . . . 14612.2.2 Full–Adder . . . . . . . . . . . . . . . . . . . . . . . . 14812.2.3 Decimal Counter a 2 cifre . . . . . . . . . . . . . . . . 14912.2.4 Calcolo con LUT di funzione trigonometrica . . . . . . 15212.2.5 Generatore di sequenze con FSM . . . . . . . . . . . . 157

12.3 Esempio completo . . . . . . . . . . . . . . . . . . . . . . . . . 15712.3.1 Testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16012.3.2 Soluzione . . . . . . . . . . . . . . . . . . . . . . . . . 160

4

Page 6: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 1

Progetto di un sistema digitale

1.1 Introduzione

I dispositivi digitali sono diventati, negli ultimi 40 anni, sempre piu dif-fusi ed utilizzati in un gran numero di svariate applicazioni. A partire dallaloro prima comparsa, la quantita di transistor in ogni chip e cresciuta espo-nenzialmente, fino a raggiungere anche centinaia di milioni di transistor in unsingolo componente. Se agli albori della storia dei dispositivi hardware essierano prevalentemente usati nei cosiddetti computational systems, ora, graziealla loro sempre maggiore economia di esercizio ed acquisto e alle notevolicapacita di elaborazione, molti sistemi meccanici, comunicazionistici, elet-tronici e di controllo vengono digitalizzati ed introdotti in strutture qualiDSP e FPGA.

Ovviamente, al crescere delle risorse disponibili e delle capacita di elab-orazione, cresce anche la complessita di progetto di tali strutture hw. A talscopo sono nati linguaggi di programmazione che consentono un’ottima as-trazione ad alto livello, in modo da confinare operazioni poco user–friendlyal solo range di azione del cosiddetto sintetizzatore, ovvero quel modulo soft-ware che tradurra le istruzioni dell’utente nello schema logico vero e proprio(sfruttando strutture e porte logiche presenti sulla scheda di destinazione).Sebbene, quindi, un software possa automatizzare alcune operazioni, esso ecomunque in grado di svolgere solo un numero limitato di ottimizzazioni: perbuono che sia, un sintetizzatore non potra mai rendere efficiente uno schemamal progettato o, peggio ancora, errato e mal testato. Pertanto, il progetto ela sintesi di una struttura hardware sono solo due dei molti step che portanoalla creazione di un sistema digitale efficace ed efficiente.

5

Page 7: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

1.2 Rappresentazione di un sistema digitale

Progettare un sistema digitale complesso non e per nulla semplice. Og-ni passo del processo di produzione richiede informazioni sul sistema, chespaziano dalle specifiche di I/O al layout fisico sulla scheda. Per questo sononate diverse rappresentazioni (views) di un sistema, le quali rappresentanodiverse prospettive attraverso le quali vedere l’oggetto in analisi. Vengonoanche dette livelli di astrazione, in quanto consentono di concentrarsi di voltain volta solo su quelle caratteristiche vitali, tralasciando per analisi successiveproblematiche secondarie. Esistono sostanzialmente tre views, qui presentatein ordine di astrazione decrescente:

• Behavioral view

• Structural view o Register Transfer Level (RTL)

• Logic view

• Layout view.

La behavioral view descrive il comportamente e la funzionalita di un sis-tema. Non si occupa di come possa essere implementata una certa operazioneall’interno dell’FPGA, semplicemente definisce gli input e output trattandoil blocco di elaborazione come una black box. Si definisce come il sistemain analisi dovra reagire a determinati input, quali output dovra fornire, segli I/O dovranno essere sincroni con un clock o potranno essere asincroni, ealtro ancora.

La structural view permette di descrivere la struttura interna di un sis-tema. In essa, vengono presentati i blocchi di elaborazione e come essi sonointerconnessi fra loro. La structural view e spesso descritta attraverso unanetlist, ovvero una lista di nodi ed interconnessioni.

Le logic e layout view (spesso unite sotto un’unica rappresentazione, chia-mata physical view) descrivono le caratteristiche fisiche di basso livello delsistema. Si specificano la dimensione dei componenti fisici, il numero di tran-sistor e porte logiche necessarie per le varie operazioni, l’ubicazione di esseall’interno della scheda, il tracciamento e le caratteristiche dei path di con-nessione tra i vari blocchi. Un esempio di physical view e il layout di unascheda. Si parte da un’astrazione a livello di porta logica (AND/OR) fino adarrivare anche alla scelta di quali buffer utilizzare per l’I/O (layout level).

In Figg. 1.1, 1.2, 1.3 e 1.4 viene mostrato un semplice esempio di unhalf–adder a un bit.

6

Page 8: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 1.1: Blocco per un half–adder a un bit

Figura 1.2: Blocco strutturale per un half–adder a un bit

7

Page 9: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 1.3: Layout di una Xilinx Virtex–4 sulla quale e presente (nel cerchio)l’implementazione fisica dell’half–adder

8

Page 10: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 1.4: Ingrandimento del placing su FPGA dell’half–adder

9

Page 11: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

1.3 Development flow

Il Development Flow (DF ) rappresenta il diagramma di flusso di riferi-mento per la progettazione di componenti hw su FPGA. Innanzitutto, essovaria notevolmente sulla base della grandezza del progetto che si vuol realiz-zare, ove per “grandezza” si intende il numero di porte logiche che verrannoutilizzate dal modulo progettato e se esso sfruttera IP–core gia realizzatiprecedentemente. Di solito, si organizzano i progetti secondo la seguenteclassificazione:

• small size design: vengono impiegate meno di 10mila porte logiche e sibasano su eventuali IP–core precedentemente realizzati, ma di piccoledimensioni e limitate funzionalita;

• medium size design (quello di nostro interesse): vengono impiegate tra10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente realizzati, ma di piccole/medie dimensioni e limitate funzion-alita;

• large size design: vengono impiegate piu di 50mila porte logiche e sibasano su eventuali IP–core precedentemente realizzati, completi, com-plessi e spesso a scatola nera. Possono avere come target sia FPGA maanche ASIC.

Concentriamoci su progetti di medio/piccole dimensioni. Il flusso di pro-getto inizia con la descrizione comportamentale, in cui non specifichiamocome un sistema debba essere implementato, ma solo cosa vogliamo che es-so faccia e quali interfacce abbia con l’esterno. Passiamo alla structuralview, implementando (per esempio, in VHDL) i blocchi che ci permettono digarantire che a determinati input corrispondano certi output. Genereremo,quindi, una netlist RTL che descrivera il sistema. Prima di procedere allatraduzione di tale netlist di alto livello in un insieme di porte logiche per laphysical view, dobbiamo verificare che il codice da noi scritto non contengaerrori di alto livello: per esempio, se vogliamo realizzare una macchina a sta-ti finiti (FSM), dobbiamo controllare che il diagramma ASM che la descrivesia corretto nel suo progetto e nella sua implementazione. A tale scopo, siutilizzano i testbench, che sono dei semplici file (per esempio, in VHDL) incui vengono preparati appositi stimoli di input per il controllo delle uscite.In pratica, e come il test di un dispositivo (detto DUT, ovvero Device UnderTest) al classico banco hardware: dobbiamo disporre un generatore di formed’onda (word generator, per esempio) cn gli ingressi che vogliamo, connet-tervi il DUT e osservare le uscite su un Logic State Analyzer. Nel nostro

10

Page 12: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

caso, il generatore di stimoli e scritto dall’utente nel file VHDL, il DUT eil nostro progetto e l’output verra visualizzato su un apposito software ditest (ModelSim, per esempio). Si veda anche la Fig. 1.5. Dovremo, inoltre,preparare eventuali file di constraint per quanto riguarda eventuali vincolitemporali o di posizionamento del dispositivo sulla FPGA.

Figura 1.5: Esempio di schema a blocchi per il test di un DUT. Nel nostrocaso, il generatore di stimoli e il file di testbench, mentre l’oscilloscopio e ilsimulatore (es. ModelSim)

A questo punto, il secondo passo e rappresentato dalla simulazione verae propria del sistema: presi i sorgenti RTL e i testbench preparati, si passaalla verifica che tutto funzioni correttamente. In questo primo passo, non siconsiderano i ritardi delle porte logiche, ma si fa semplicemente un test dialtissimo livello per controllare la bonta sintattica del codice generato.

Il passo successivo e rappresentato dalla sintesi: a partire dalla netlistRTL, si genera una netlist di sintesi, in cui le funzioni di alto livello vengonotradotte in connessioni fra porte logiche, Look–Up–Tables (LUT), buffer ealtri componenti elementari.

Si effettua una seconda simulazione, questa volta piu realistica, in cuisi tiene conto dei ritardi delle porte logiche. Attenzione: non e ancora lasimulazione definitiva, in quanto semplicemente le funzioni di alto livellosono state tradotte in equazioni booleane. In questa fase si tiene conto solodei tempi di setup dei flip–flop, delle porte logiche, ecc. ma non dei ritardidovuti, ad esempio, ad interconnessioni fisiche lunghe.

Se il dispositivo passa brillantemente la cosiddetta timing simulation,si passa al quinto passo, che consiste nel place–and–route: a partire dallanetlist di sintesi e dagli eventuali constraint, le porte logiche trovate vengonofisicamente piazzate su uno schema della FPGA che si vuole usare. Ora siha a disposizione un design completo: le funzioni sono state sintetizzate,e abbiamo anche una traccia di piazzamento (spesso non ottimale) su hw.Viene generata una netlist finale, detta post par–netlist (post place–and–routenetlist).

A questo punto, si simula nuovamente il comportamento del sistema incondizioni quasi reali (simulazione post place–and–route). I risultati tengono

11

Page 13: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 1.6: Development flow

12

Page 14: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

conto (attenzione, in modo approssimato e simulato) di tutti i ritardi, dovutisia a porte logiche sia a piazzamenti e interconnessioni all’interno dell’FPGA.

Se il DUT supera brillantemente anche quest’ultimo step, si passa final-mente alla generazione del bitstream, ovvero del file di programmazione veroe proprio della FPGA. Dato che una FPGA puo essere vista come un array diunita di calcolo elementari, che possono venire connesse ed attivate o menoattraverso dei fuse, semplicemente il bitstream e una matrice di 0 e 1, i qualirappresentano le locazioni ove effettuare i fuse.

L’ultimo step e la verifica del corretto funzionamento del nostro DUTsulla FPGA programmata attraverso il bitstream. Lo schema generale epresentato in Fig. 1.6.

Possiamo, quindi, pensare di dividere idealmente lo sviluppo di un dis-positivo digitale in tre sezioni:

1. Synthesis: comprende tutta la fase che porta dalla stesura del codice(o schematic) sorgente alla generazione della netlist RTL e di sintesi;

2. Verification: comprende lo sviluppo del file di testbench e le varie fasidi test, a partire da quella comportamentale fino alla timing analysisdopo il place–and–route;

3. Physical Design: comprende tutti gli step che portano all’implemen-tazione fisica e al piazzamento dei componenti necessari sulla FPGA. Disolito, si parte da una netlist post–sintesi e si giunge fino al bitstreamdi programmazione.

1.4 Organizzazione della dispensa

Queste pagine vogliono fornire un’introduzione generale al VHDL1, ap-profondendo aspetti importanti nell’ambito dello sviluppo di sistemi anchecomplessi. In particolare:

• nel Cap. 2, introdurremo i linguaggi orientiati alla descrizione hard-ware, descrivendo brevemente alcune caratteristiche del VHDL, oggettodegli approfondimenti dei successivi capitoli;

• nel Cap. 3, analizzeremo i costrutti concorrenti nella programmazioneVHDL, distinguendo fra circuiti combinatori e sequenziali;

1Alcuni spunti sono tratti dal libro P.P. Chu, “RTL Hardware Design Using VHDL”,J. Wiley & Sons.

13

Page 15: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• nel Cap. 4, introdurremo le istruzioni sequenziali, il concetto di processe alcune strutture basilari quali if, case e for ;

• nel Cap. 5, studieremo alcuni aspetti avanzati della progettazione dicircuiti combinatori e della loro ottimizzazione;

• nel Cap. 6, ci concentreremo sui circuiti sequenziale e sull’analisi di queicomponenti fondamentali che li costituiscono: per esempio, elementidi memoria. Vedremo la differenza nell’uso di segnali e variabili, eproveremo a progettare qualche semplice circuito;

• nel Cap. 7, richiameremo alcuni concetti sulle macchine a stati finiti,la loro rappresentazione, la loro codifica e implementazione in VHDL;

• nel Cap. 8, vedremo cosa sono le Look–Up Tables, i vantaggi e gilsvantaggi nell’uso di tale costrutto, come implementare una LUT inVHDL e come generare tale codice in maniera automatizzata;

• il Cap. 9 e dedicato ad aspetti avanzati della programmazione gerar-chica, utile per dispositivi complessi;

• nel Cap. 10 approfondiremo un altro aspetto di progettazione modu-lare, ovvero il VHDL basato su parametri, in modo da personalizzarestrutture molto generali;

• nel Cap. 11 vedremo come effettuare test e simulazione di dispositividigitali;

• infine, nel Cap. 12, verra proposta una brevissima guida all’ambientedi sviluppo Xilinx ISE Web Pack 8.2i e verranno svolti alcuni esercizisignificativi.

14

Page 16: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 2

Hardware DescriptionLanguages

Introdurremo in questo capitolo molti degli aspetti fondamentali dei lin-guaggi per la descrizione hardware, concentrandoci ovviamente sul VHDL.Questo capitolo vuole essere una panoramica generale: maggiori dettagliverranno presentati nei prossimi capitoli.

2.1 Introduzione

Molti linguaggi di programmazione classici (C, Java, C++,...) non siaddicono ad una descrizione hardware efficiente. Una delle caratteristicheprincipali nonche peculiarita dei circuiti hardware e la capacita di esecuzionedi processi in parallelo, normalmente non contemplata da linguaggi quali il C:in essi, le istruzioni sono eseguite in maniera sequenziale seguendo il flow discrittura. Non solo: di solito, le varie subroutine utilizzano risultati ottenutida subroutine precedentemente eseguite, il che comporta anche la necessitadi manterere non solo l’ordine delle istruzioni all’interno di una funzione, maanche l’ordine nel quale tali funzioni vengono chiamate. Nel momento incui si vuole implementare in hardware una certa funzionalita, spesso moltiprocessi possono essere eseguiti in parallelo: non solo, in generale e anchebuona norma mantenere una buona modularita ed indipendenza fra processi,in modo anche da limitare lo scambio dati, spesso problematico a causa diritardi ed interconnessioni. Cio non toglie che esistano degli adattamenti delC all’hw (i cosiddetti HLL, High Level Languages): System–C e stato un(pressoche fallimentare) esempio. Il nuovo trend in quest’ottica riguarda laricerca di traduttori C–to–VHDL, i quali partono da un codice C “spolpato”

15

Page 17: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

delle funzioni che meno si addicono all’hardware e forniscono in uscita un fileVHDL.

E’ palese che, nel momento in cui esiste un linguaggio (per quanto verbose,pesante e poco intuitivo quale il VHDL) nato ad hoc per l’hardware, ognitentativo di riportare linguaggi nativamente sequenziali quali il C ad averele caratteristiche di un HDL (Hardware Description Language) snatura ilcodice stesso. Pertanto, spieghiamo meglio cosa sia un linguaggio orientatoalla descrizione hw.

2.2 VHDL

I primi Hardware Description Languages (HDL) nacquero negli anni ’80per consentire un’agevole descrizione di schemi hw attraverso un linguaggioche fosse un buon trade–off tra esigenze di basso livello (hardware) e altolivello (programmabilita). Infatti, nel momento in cui si svilupparono chipcontenenti sempre una densita maggiore di transistor a parita di superficie,descrivere schemi attraverso netlist scritte a mano divenne, di fatto, impro-ponibile anche per il piu paziente degli implementatori. Fu cosı che ebberoimmediata diffusione VHDL e Verilog. Entrambi hanno frecce al proprioarco, ed entrambi hanno difetti. Una delle caratteristiche molto usate delVHDL e la sua capacita di generazione parametrizzata di entita (semplice-mente, se abbiamo bisogno, ad esempio, di inserire in un chip 16 sommatori,essi possono essere istanziati attraverso un semplice ciclo FOR...GENERATE),ed e per questo che, al momento, forse il VHDL ha un piccolo vantaggio sulVerilog.

VHDL e un acronimo, in verita, di un acronimo: infatti, ‘V’ equivale aVHSIC, acronimo di Very High Speed Integrated Circuit. Nato nei primissimianni ’80, venne diffuso inizialmente dal Dipartimento della Difesa degli USAcome standard per la documentazione hw, ed e stato piu volte modificato nellesue caratterizzazioni attraverso diversi standard. Nel 1987, venne definitodall’IEEE lo standard definitivo, che tutt’oggi utilizziamo. E’ un linguaggiocase–insensitive, ma molti programmi di sintesi sono case–sensitive (!), quindiattenzione. Esistono poi 7 packages IEEE di VHDL, ovvero 7 librerie cheaggiungono funzionalita allo standard base. I principali e piu usati sono:

• 1076.3, in cui vengono definiti alcuni standard per la sintesi hw;

• 1076.6, in cui vengono definiti gli standard per la generazione dellanetlist RTL;

• 1164, il piu usato, in cui vengono definiti molti tipi di dati, utili inoperazioni elementari e bit–a–bit (i cosiddetti tipi std_logic_1164).

16

Page 18: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

2.2.1 Strutture

Il VHDL si basa su alcune strutture chiave, qui disposte in ordine gerar-chico, e che andremo a breve a descrivere in maniera piu approfondita:

• Library : sono le librerie di sistema che contengono i costrutti chiavedel linguaggio, come i tipi di dati;

• Package: sono i pacchetti di strutture dati e hw contenuti all’internodelle librerie (per intenderci, una struttura simile al Java);

• Entity : fornisce la descrizione dell’interfaccia del blocco in analisi,ovvero numero e tipo di I/O;

• Architecture: fornisce la descrizione della funzionalita dell’entity a cuie associata;

• Process : sono i processi in esecuzione concorrente e parallela, contenutiall’interno dell’architecture;

• Configuration: in strutture hw molto grandi, e spesso utile definire piuarchitetture aventi la stessa interfaccia. A quel punto, la configurationpermette di settare per ogni particolare istanza l’architettura voluta.

Partiamo da questo codice elementare, in modo da andare ad analizzarloin tutte le sue parti:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity sum is

Port ( a : in STD_LOGIC;

b : in STD_LOGIC;

s : out STD_LOGIC;

c : out STD_LOGIC);

end sum;

architecture Behavioral of sum is

begin

17

Page 19: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

s <= a xor b;

c <= a and b;

end Behavioral;

Entity

Come detto, la entity fornisce la descrizione generale dell’interfaccia diun dispositivo hardware. La dichiarazione di un’entita e la seguente:

entity entity_name is

Port ( port_1 : direction type;

port_2 : direction type;

...

port_n : direction type);

end entity_name;

In pratica, l’entita definisce il nome del componente che vogliamo proget-tare (nel caso precedente, sum), il numero di porti di I/O (nel caso precedente4, di cui due input e due output), la direzione di ognuno di essi e il tipo (perquest’ultimo aspetto, si rimanda ai prossimi paragrafi). In particolare, unporto puo avere le seguenti configurazioni:

• in, porto di sola lettura e di ingresso per il nostro sistema;

• out, porto di sola scrittura e di uscita per il nostro sistema (attenzione,una volta che si e scritto un valore NON puo piu essere riletto);

• inout, porto di ingresso o uscita, a seconda delle condizioni (attenzione,NON puo essere contemporaneamente di ingresso e uscita);

• buffer, analogo a in e out, ma, in quest’ultimo caso, il valore even-tualmente scritto puo anche essere riletto internamente.

Architecture

L’architettura descrive il comportamento dell’entity a cui e associata,ne determina la funzionalita o gli opportuni legami tra ingressi e uscite (nedefinisce l’implementazione). La struttura classica di una architettura e laseguente:

18

Page 20: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

architecture nome of nome_entity is

{parte dichiarativa}

begin

{istruzioni concorrenti}

end architecture nome;

Quindi, abbiamo che la struttura di un’architettura e divisa dalla parolachiave begin in due sezioni:

• parte dichiarativa, per segnali, tipi, variabili, costanti, sottoprogram-mi e component (si veda il capitolo 9) da utilizzare localmente nellaarchitettura;

• istruzioni concorrenti, le quali possono essere:

– istruzioni di assegnazione di un valore ad un segnale (attenzione,SOLO ad un segnale);

– processi;

– istanze, ovvero connessioni di blocchi dichiarati come componentinella parte dichiarativa e che vengono a tutti gli effetti istanziati.

Le istruzioni comunicano attraverso segnali e sono eseguite in parallelo,e, piu precisamente, in pipeline. Attenzione: non e detto che essevengano eseguite nello stesso ordine in cui sono state scritte. E’ ilsintetizzatore che sceglie come eseguire ogni processo e/o istruzione, etale ordine non e in alcun modo modificabile.

L’architettura di una entita puo essere descritta in tre modi differenti:

1. stile comportamentale: prevede la descrizione della logica attraversouno o piu processi dove si modellizza il comportamento del circuitosenza fornire dettagli dell’implementazione;

2. stile data flow: descrive la funzionalita di un circuito in base alleelaborazioni concorrenti e parallele che subiscono i dati;

19

Page 21: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

3. stile strutturale: utilizza interconnessioni fra componenti e istanze dif-ferenti di vari blocchi, ognuno con una propria architecture e una pro-pria interfaccia. Il componente dev’essere dichiarato con la propriainterfaccia come una qualsiasi altra variabile nella parte dichiarativa,e dev’essere quindi istanziato in maniera concorrente tra le istruzionidell’architettura. Nella creazione dell’istanza, vi sara anche il cosiddet-to port mapping, in cui i porti di I/O del componente vengono connessicon i porti e/o segnali dell’entita in cui vengono istanziati. Appro-fondiremo meglio questi aspetti nel capitolo 9. A livello puramenteintroduttivo, proponiamo un brevissimo esempio:

architecture arch of TOP is

signal n : bit;

component AND

port ( A,B : in bit;

C : out bit);

end component;

begin

istanza_1: AND port map(A => ingr1, B => ingr2, C => n);

end architecture arch;

In questo caso, inseriamo all’interno dell’entita TOP un componente AND,avente due bit di ingresso e uno di uscita. Nel momento in cui istanzi-amo l’oggetto AND all’interno della nostra architettura, connettiamo ipin di ingresso A e B con gli ingressi di TOP, mentre creiamo un link fral’uscita C e il segnale n interno alla nostra architettura.

Configuration

Come gia precedentemente anticipato, una entity puo avere diverse ar-chitectures ad essa associate: puo essere utile qualora vi siano piu dispositiviaventi la stessa interfaccia. Attenzione, pero, alla confusione che ne puonascere: il nome al blocco viene dato dalla entity. Pertanto, si corre il rischiodi avere due istanze di una certa entita ENT che svolgono diverse elaborazionisui dati a seconda della configurazione data ma con lo stesso nome.

In generale, una configuration viene utilizzata solo in fase di test pre–sintesi: supponendo di voler testare due possibili architetture per una entita,la configuration permette un cambio veloce tra piu possibili architetture. None praticamente mai considerato un supporto contemplato dai sintetizzatori:l’utilizzo di una configuration porta spesso al fallimento di una sintesi.

La sintassi del comando e la seguente:

20

Page 22: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

configuration nome_configuration of nome_entity is

for nome_architecture

{operazioni di assegnazione}

end for;

end nome_configuration;

Process

Un processo e costituito da un insieme di istruzioni sequenziali, eseguitepoi nell’ordine in cui sono state scritte dall’utente. Il process comunica conil resto del progetto leggendo e/o aggiornando determinati segnali e porti dientity dichiarate al di fuori di esso. Piu processi sono fra loro concorrenti,ovvero vengono eseguiti in parallelo (piu precisamente, in pipeline), ma, inogni istante, e attiva una sola istruzione per processo. E’ possibile anchevedere un insieme di processi come tante istruzioni concorrenti.

La sintassi e la seguente:

[nome_etichetta:] process [sensitivity_list]

{dichiarazioni}

begin

{istruzioni sequenziali}

end process [nome_etichetta];

I campi tra parentesi quadre [] sono facoltativi. La sezione dichiarati-va definisce elementi locali, visibili solo all’interno del particolare processo.Possono essere dichiarate:

• costanti

• variabili

• tipi

• sottotipi

• elementi di sottoprogrammi.

Il processo si comporta come un loop infinito di un determinato gruppo diistruzioni sequenziali. Un processo puo avere una sensitivity list: in pratica, e

21

Page 23: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

una lista di segnali presenti nella entity e/o architecture, e la variazione di unodi questi segnali provoca l’attivazione del loop del processo. In alternativa,si puo evitare la sensitivity list e porre una delle seguenti istruzioni subitodopo il begin o subito prima della fine del processo:

• wait on sensitivity_list;

• wait for specific_time;

• wait until condition;

Bisogna prestare attenzione, pero, nell’utilizzo della seconda e terza i-struzione: non tutti i sintetizzatori supportano (spesso, anche perche nonsarebbe realistico...) condizioni per quanto riguarda l’attesa di un certo in-tervallo temporale. Il consiglio e quello di utilizzare, qualora fosse possibile,la sensitivity list.

Un processo senza sensitivity list (o, in alternativa, senza condizioniwait) non verra mai eseguito. E’ inoltre importante sottolineare come nonsi possano utilizzare istruzioni wait nel momento in cui e presente una sensi-tivity list. L’eventuale etichetta consente di identificare meglio un processo:all’interno della stessa architettura dev’essere univoco e non deve richiamaredelle parole chiave del VHDL.

Per finire, un piccolo esempio di processo con sensitivity list:

esempio: process(clk)

begin

if rising_edge(clk) then

o <= i;

end if;

end process esempio;

In questo caso, abbiamo implementato il processo per un’architettura diun flip–flop D: sul fronte di salita del clock (il comando rising_edge ha loscopo di controllare il fronte di salita), il segnale sull’uscita o assume il valoredel segnale sull’ingresso i. Il simbolo <= assume il significato di assegnazione,e si legge “gets”. Attenzione, perche il simbolo di assegnazione di un segnaleha un significato ben diverso dal simbolo di assegnazione di una costante ovariabile: approfondiremo meglio questi aspetti nel paragrafo 2.2.3.

22

Page 24: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Package

Il package e una collezione di definizioni che possono essere condivise fradue o piu unita di progetto. Tali unita condivise possono essere:

• tipi di dato

• costanti

• componenti

• sottoprogrammi.

Un package si suddivide in:

• header : contiene le dichiarazioni di tutti gli elementi che potranno es-sere visti dalle entity che utilizzano quel package. Sono quindi presentidichiarazioni di sottoprogrammi, costanti, tipi di dato e componenti;

• body : contiene gli eventuali dettagli implementativi degli elementi del-l’header. Qualora il package non contenesse sottoprogrammi, potrebbeessere formato anche dal solo header.

Esistono package di tipo standard inclusi nel VHDL, e sono quelli di cuiabbiamo gia parlato in precedenza. Per esempio, molti costrutti definiti nellostandard 1164 sono contenuti nel package IEEE.std_logic_1164, il quale emolto utilizzato per la maggiore flessibilita rispetto allo standard classicobit.

La sintassi del package e la seguente:

package nome is

{header}

end;

package body nome is

{body}

end;

Per aggingere un package ad un modulo VHDL, si usa la keyword use.Ad esempio, l’inclusione dello standard 1164 si effettua nel seguente modo:

use IEEE.STD_LOGIC_1164.ALL;

Analogamente al Java, si puo importare tutto il package o solo parte diesso: la parola chiave ALL svolge le funzioni del simbolo *.

23

Page 25: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Library

La prima istruzione in un modulo VHDL (ovvero entity piu la/e architet-tura/e) dev’essere l’importazione di una libreria, qualora poi si intendano uti-lizzare dei package e dei componenti gia realizzati. Per esempio, se (come disolito avviene) si intendono importare package dello standard IEEE, si deveprima di tutto caricare la libreria dell’IEEE stesso. In pratica, la gerarchiae:

Library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

{entity}

{architecture(s)}

2.2.2 Elementi lessicali

Presentiamo qui una serie di elementi lessicali caratterizzanti il VHDL.

Commenti

I commenti devono essere preceduti in VHDL dal simbolo --, e tut-to cio che segue tale simbolo fino al terminatore di riga viene ignorato dalcompilatore. Ad esempio, un commento puo essere:

a <= b; -- al segnale a viene connesso il segnale b

Identificatori

Un identificatore rappresenta il nome di un oggetto in VHDL. Affinchepossa essere considerato tale, un identificatore deve rispettare alcune sempliciregole:

• dev’essere composto solo di lettere, numeri e underscore;

• non puo cominciare con un numero ne un underscore;

• non puo terminare con un underscore;

• non sono permessi due o piu underscore consecutivi.

24

Page 26: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Ad esempio, X10 e un nomevalido, mentre 1A non lo e. Come anticipa-to, il VHDL e (o, meglio, sarebbe) case–insensitive. E’ altrettanto vero chee buona norma essere consistenti con la propria definizione: se dichiariamouna variabile Anno, non e stilisticamente e praticamente molto comodo mod-ificarla di volta in volta in ANNO o anno o quant’altro. Senza contare chealcuni sintetizzatori sono case–sensitive...

Parole chiave

In Fig. 2.1 presentiamo alcune parole chiave del linguaggio VHDL, chenon possono essere utilizzate come nome ne etichetta per segnali, processi,ecc.

Figura 2.1: Parole chiave del VHDL

Numeri, caratteri e stringhe standard

Un numero in VHDL puo essere un intero (come 37 o 98E+7) o un numeroreale (come 1,2345), entrambi supportati dallo standard di definizione. E’altresı possibile rappresentare un numero in altre basi, differenti dalla classicabase 10. Lo standard di definizione per una base differente e il seguente:

base # numero_nella_base_specificata #

Ad esempio, se vogliamo rappresentare 18, possiamo anche esprimerlo inbase 2 come 2#10010# o in base esadecimale come 16#12#. Per facilitare lalettura e la comprensione di numeri lunghi, possiamo suddividerli attraversoun underscore: ad esempio, il numero in base 2 precedente puo essere scrittocome 2#1_0010# senza problemi ne errori.

25

Page 27: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Un carattere in VHDL e compreso all’interno di singoli apici. Ad esem-pio, caratteri sono ’A’ e ’1’. Attenzione: scrivere 1 e ’1’ sono due coseprofondamente differenti. Il primo e un numero, mentre il secondo e uncarattere (quindi, con proprieta ben differenti).

Una stringa e invece compresa fra doppi apici, ed e sempre consideratauna stringa di caratteri: una stringa e, per esempio, "Hello". Ovviamente, epossibile anche esprimere una stringa di bit sotto forma di stringhe di carat-teri, ma, a questo punto, diviene impossibile utilizzare il carattere underscoreper rendere piu leggibile la stringa stessa.

2.2.3 Oggetti

Ci sono quattro tipi di oggetti in VHDL, e sono: costanti, variabili, seg-nali e file. Gli oggetti di tipo file non sono pero sintetizzabili, e permangononello standard solo per una questione di continuita con le versioni precedenti.Gli alias sono spesso considerati il quinto tipo di oggetto del VHDL.

Costanti

Una costante contiene un valore assegnatole in fase di dichiarazione e chenon puo piu venire modificato in seguito. La definizione di una costante puoavvenire nella sezione apposita di processi, architetture, package,... secondola seguente sintassi:

constant nome : tipo_di_dato := valore;

Variabili

La definizione dell’IEEE e “symbolic memory location”, ed e abbastan-za rappresentativa: sostanzialmente, rappresenta una locazione di memorialocale per un processo, in cui, per comodita di programmazione, si effettuauno storage di un certo valore. La sintassi della dichiarazione (da effettuarsinelle dichiarazioni di un processo) e la seguente:

variable nome : tipo_di_dato [:= valore_iniziale];

I campi fra parentesi quadre sono facoltativi. L’assegnazione all’internodi un processo a runtime e da considerarsi senza ritardo, percio effettuatocon l’utilizzo del simbolo :=:

nome := 2;

26

Page 28: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Segnali

Un segnale e uno degli oggetti piu comuni del VHDL. Va dichiarato nellasezione apposita di una architettura, e ha la seguente sintassi:

signal nome : tipo_di_dato [:= valore_iniziale];

Come al solito, le parti fra parentesi quadre sono facoltative. L’inizializ-zazione avviene senza ritardo, percio con il simbolo :=. Un segnale assumeun determinato valore se viene connesso ad un porto di input, ad un altrosegnale, ad una variabile o ad una costante. Il simbolo di assegnazione eil gia citato <=. In tal caso, il segnale modifica il proprio valore SOLO altermine del ciclo del processo, e non istantaneamente: se questo fatto ricalcacio che poi avviene in un circuito reale, e vero pero che obbliga a prestareattenzione. Supponiamo di avere due segnali, a,b, e di inizializzare a:=0.Consideriamo il seguente codice:

a <= a+1;

b <= a;

L’assegnazione del valore 1 al primo passo ad a avviene solo alla finedel ciclo. Pertanto, quando assegnamo b<=a, a ha ancora valore 0. Allafine del ciclo, quindi, b varra 0. Se, invece, dichiariamo a come variabile, emodifichiamo il codice precedente nel seguente modo:

a := a+1;

b <= a;

Tutto andrebbe come vorremmo. Attenzione pero: l’utilizzo sconsider-ato e poco ponderato di variabili puo portare ad un codice non sintetizz-abile. Senza contare che in molti processi puo essere utile sfruttare questapeculiarita del VHDL.

Alias

L’alias non e un vero e proprio oggetto, ma semplicemente un nome alter-nativo per chiamare un oggetto o parte di esso. Viene usato per semplicita diprogrammazione quando si trattano moduli complessi. La maniera piu sem-plice per comprendere l’alias e passare attraverso un esempio. Supponiamodi voler progettare un processore, avente istruzioni a 16 bit. Supponiamoche, per esempio, tali istruzioni siano strutturate nel seguente modo:

• un codice dell’operazione da 8 bit;

27

Page 29: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• due operandi da 4 bit ciascuno.

Puo essere comodo definire tre alias (non si badi alla definizione dei tipi,sara chiara dopo la lettura del paragrafo 2.2.4) nel seguente modo:

-- istruzione a 16 bit

signal word : std_logic_vector(15 downto 0);

-- alias per l’operazione a 8 bit

alias op : std_logic_vector(7 downto 0) is word(15 downto 8);

-- alias per i due operandi

alias reg1 : std_logic_vector(3 downto 0) is word(7 downto 4);

alias reg2 : std_logic_vector(3 downto 0) is word(3 downto 0);

E’, ovviamente, nettamente piu chiaro l’utilizzo di reg1 piuttosto checonsiderare di volta in volta sottostringhe di word. Purtroppo, molti sinte-tizzatori ancora non supportano gli alias, quindi bisogna prestare attenzionenell’utilizzo.

2.2.4 Tipi di dati e operatori

In VHDL ogni oggetto ha un suo tipo, definito attraverso:

• un range o set di valori limitato che tale oggetto puo assumere;

• un set di operazioni che possono essere eseguite dall’/sull’oggetto con-siderato.

Il VHDL e strong typed, ovvero possono essere eseguite su un oggettodi un determinato tipo solo e soltanto quelle operazioni definite per queldeterminato tipo. Per adattare (qualora sia possibile e consentito) un deter-minato oggetto al tipo piu adatto per una certa operazione, esistono funzionidi conversione di tipo, dette anche funzioni di casting, definite nelle libreriestandard. Questa scelta per il VHDL e stata effettuata per semplicita di pro-grammazione e sintesi; d’altra parte, pero, l’utilizzo di operatori di castingrende spesso il codice pesante e difficile da leggere.

Il VHDL e ricco di tipi: accanto ai tipi predefiniti dallo standard orig-inale, si sono affiancati i tipi IEEE, molto utilizzati per l’enorme quantitadi operazioni e valori ad essi applicabili. Partiamo con un’analisi dei tipioriginari, per poi passare ai tipi IEEE.

28

Page 30: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Tipi e operatori predefiniti

Esistono circa 12 tipi originari di VHDL. I principali sono:

• integer: sono i numeri interi. Lo standard non definisce un range divalori preciso, ma garantisce che essi debbano avere almeno un rangepari a [−(231 − 1), (231 − 1)], ovvero almeno 32 bit con segno. Esistonosottotipi (come i positive) per rappresentare, per esempio, numerisolo positivi;

• boolean: definiti nel solo range {true, false};• bit: definiti nel solo range {’0’, ’1’};• bit_vector: definiti come array mono–dimensionale di elementi di tipobit. La sintassi per la definizione e: bit_vector(a downto b), dove a

rappresenta il bit piu significativo (MSB) e b il bit meno significativo(LSB), e la lunghezza totale dell’array e pari a (a − b) + 1;

• time: utilizzato per le variabili di tempo, puo essere misurato in s, ms,ns, ps e fs;

• real: rappresenta i numeri reali, ma e un tipo poco utilizzato perchemolto raramente sintetizzabile;

• character e string: caratteri ASCII e array di questi ultimi.

Originariamente, il tipo bit era nato per rappresentare quantita booleane,limitandole ai soli due casi 1 e 0. In verita, nella pratica esistono molte al-tre necessita: si pensi al caso di indeterminazione, o, ancora, all’alta im-pedenza su un pin. Nacquero cosı i tipi std_logic e il corrispondentestd_logic_vector, definiti nello standard IEEE 1164. Molto utilizzata ela definizione di un nuovo tipo di dato, attraverso la parola chiave type: peresempio, e utile definire dei nomi per identificare gli stati di una FSM. Lasintassi del comando e la seguente:

type nome_tipo is { range_valori }

Ad esempio, potremmo definire nuovi tipi per diversi scopi:

type stato is {countup, countdown}

29

Page 31: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Passiamo a parlare degli operatori standard del VHDL. Sono definitimoltissimi operatori, ed ognuno di essi e applicabile solo a determinati tipidi operandi: in Fig. 2.2 vengono mostrati i principali operatori standard.Attenzione, pero, in quanto un’operazione come l’esponenziale, per quantopresente ed utilizzabile, non sempre viene ottimizzata dal sintetizzatore: per-tanto, una semplice istruzione potrebbe portare ad un’occupazione di schedaenorme, se non addirittura ad un codice non sintetizzabile. Gli operatorisono utili, ma vanno usati con criterio nel momento in cui si voglia realizzareun progetto serio: spesso, e meglio ottimizzare manualmente le operazioni daeseguire sui dati, in modo da usare quasi esclusivamente operatori booleani.

Per quanto riguarda l’ordine di precedenza, esistono regole molto com-plesse per quanto riguarda i vari tipi di operatori: la cosa migliore e che siconsiglia SEMPRE (anche per chiarezza nei confronti di chi poi dovra riu-tilizzare o anche solo leggere e capire il vostro codice) di fare e utilizzare leparentesi per definire manualmente come operare sui dati. In alcuni casi ed’obbligo. Vediamo il seguente esempio. Vogliamo calcolare y = a · b + c · d.Il seguente codice e sbagliato:

y <= a and b or (not c) and d; -- NO!!

Infatti, molti sintetizzatori non saprebbero come compilare il precedentecodice. Il VHDL prevede una gerarchia di operatori, ma molti sintetizzatorinon contemplano una sub–gerarchia fra operatori con la stessa priorita. Ilrisultato e che dovrete riscrivere il codice. Molto piu chiara e corretta e laseguente scrittura:

y <= (a and b) or ((not c) and d); -- Sı!!

Tipi e operatori del package IEEE std logic 1164

I tipi definiti nello standard IEEE 1164 nacquero e vennero definiti peravvicinare la rappresentazione hw/sw del VHDL a quelle che sono le carat-teristiche elettriche dei circuiti reali.

I tipi e gli operatori definiti in questo standard possono essere inclusisemplicemente con le due seguenti righe di codice, da porre in cima ad unmodulo VHDL:

Library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

I tipi piu usati sono:

30

Page 32: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 2.2: Tabella dei principali operatori standard

31

Page 33: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• std_logic: rappresenta un’alternativa al tipo bit, completandolo contutti gli ulteriori possibili valori che puo assumere un segnale reale;

• std_logic_vector: e un vettore di bit di tipo std_logic.

I tipi std_logic possono variare in un range di 9 possibili valori. Inparticolare:

• ’0’ e ’1’: il segnale e forzato a valere 0 oppure 1, con un valore ditensione corrispondente sulla base della logica usata e stabilita dal sin-tetizzatore. Il segnale e forzato da una corrente (detta driving current)che viene fatta materialmente scorrere nel pin;

• ’Z’: alta impedenza, utile nel caso di buffer tri–state;

• ’L’ e ’H’: come ’0’ e ’1’, ma qui la corrente e debole e il segnale vieneforzato ai diversi stati logici sulla base della cosiddetta wired logic;

• ’X’ e ’W’: rappresentano lo stato di indeterminazione nel caso di drivingcurrent e wired logic. Puo essere utilizzato dall’utente e dal simulatorein fase di debug per evidenziare eventuali conflitti o collegamenti nonprecisi;

• ’U’: significa che un segnale non e stato inizializzato ne e stato inalcun modo forzato ad assumere un certo valore. In questo caso, evietata l’assegnazione da parte di un utente, ma e utilizzato in fase disimulazione;

• ’-’: e il simbolo don’t care.

Per quanto riguarda gli operatori, e stato effettuato un overload di moltidei principali operatori presentati in Fig. 2.2. In Fig. 2.3 viene mostrata latabella degli operatori piu usati. Esistono, inoltre, operatori per la conver-sione di tipo, per passare da tipi dello standard 1164 a tipi dello standardVHDL classico. In Fig. 2.4 vengono presentati questi ultimi.

I tipi std_logic_vector sono semplicemente array di std_logic, ovverodi bit. Analogamente a quanto visto per i bit_vector, si puo definire unvettore nel seguente modo:

signal y : std_logic_vector(7 downto 0);

In questo caso, generiamo un segnale y a 8 bit, il cui MSB e il bit piua sinistra. Se volessimo seguire una rappresentazione opposta, potremmoscrivere:

32

Page 34: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 2.3: Operatori di overload per lo standard IEEE 1164

Figura 2.4: Operatori di conversione per lo standard IEEE 1164

33

Page 35: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

signal y : std_logic_vector(0 to 7);

Di solito, la prima e la piu usata. Analogamente a quanto visto in Figg.2.3 e 2.4, esistono operatori di conversione e overload anche per gli array.Peculiarita di questi ultimi sono gli operatori relazionali, di concatenazionee di aggregazione.

Per operatori relazionali, si intendono quegli operatori di confronto perverificare, ad esempio, l’uguaglianza di due vettori. I principali sono: =,>,<.Escluso l’operatore di uguaglianza, che richiede anche egual lunghezza peri due vettori, gli operatori di confronto possono essere utilizzati anche conarray aventi un numero diverso di bit. Per esempio, i seguenti operatorirestituiscono true:

"011" = "011";

"011" > "010";

"0110" < "11";

L’operatore di concatenazione & e molto utilizzato per generare array piugrandi a partire da vettori piu piccoli. Un esempio semplice e il seguente.Supponiamo di avere due vettori, a e b, entrambi a 8 bit, e di voler generareun vettore c a 16 bit. Semplicemente:

c <= a & b;

Si possono eseguire svariati tipi di operazioni. Per esempio, replicare ilMSB due volte:

c <= a(7) & a(7) & a(7 downto 2);

O effettuare uno shift di due posizioni (senza utilizzare l’apposito oper-atore):

c <= a(1 downto 0) & a(7 downto 2);

Infine, gli operatori di aggregazione vengono spesso utilizzati in fase diassegnazione manuale di un certo valore ad un certo segnale. Supponiamodi voler assegnare ad un certo segnale a un valore "10100000". La manierapiu immediata e la seguente:

a <= "10100000";

Esistono delle alternative, talvolta utili. La prima e l’utilizzo della cosid-detta notazione positional association:

34

Page 36: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

a <= (’1’,’0’,’1’,’0’,’0’,’0’,’0’,’0’);

Altra alternativa e la notazione index/value, in cui i bit possono essereassegnati in ordine sparso:

a <= (7=>’1’, 2=>’0’, 1=>’0’, 4=>’0’,

3=>’0’, 6=>’0’, 5=>’1’, 0=>’0’);

Piu comoda e la notazione piped index/value:

a <= (7|5=>’1’, 6|4|3|2|1|0=>’0’);

La parola chiave others permette di assegnare un certo valore a tutti gliindici non utilizzati fino a quel momento nell’espressione in cui si trova. Adesempio, la precedente assegnazione puo divenire:

a <= (7|5=>’1’, others =>’0’);

La parola chiave others e spesso utilizzata nel momento in cui si vuoleinizializzare un intero vettore a 0 o a 1:

a <= (others =>’0’);

-- equivale a

a <= "00000000";

2.2.5 Consigli pratici

Ricapitolando, in VHDL esistono tantissimi operatori, tipi di dato, ogget-ti di svariato tipo, per non parlare dei mille modi in cui si possono definireed assegnare vettori e segnali. Attenzione, pero, all’uso che si fa di questaliberta: non scordiamoci mai che cio che noi programmiamo non e un sem-plice toy dimostrativo sulla completezza del linguaggio, bensı e un qualcosache deve poi essere tradotto in un array di 0 e 1 nel bitstream per program-mare un oggetto composto per lo piu da AND, OR e qualche LUT. Quandopossibile, il consiglio e sempre quello di utilizzare tipi standard IEEE 1164,al piu interi o caratteri, e di mantenere sempre una certa chiarezza nel mo-mento in cui vengono inizializzati e assegnati valori e segnali. Il consiglio equello di scrivere, se necessario, anche un po’ di codice in piu, ma che il tuttosia piu chiaro e immediato. Attenzione, infine, a non usare costrutti troppocomplessi: il sintetizzatore potrebbe riservarvi brutte sorprese...

35

Page 37: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 3

Istruzioni concorrenti

Le istruzioni concorrenti in VHDL sono semplici, eppure molto poten-ti. Se utilizzate in modo efficiente, il collegamento tra le elaborazioni daesse effettuate e lo schema logico e fisico del circuito e diretto. Questo puoaiutare a progettare in maniera piu efficace circuiti anche complessi. Per“modo efficiente” si intende l’utilizzo di costrutti elementari, quali and op-pure or, tralasciando operatori quali l’elevazione a potenza, di difficile edincerta sintesi. Si dividono in 3 gruppi, ovvero istruzioni concorrenti:

1. semplici;

2. condizionali;

3. di selezione;

Vedremo in questo capitolo come le istruzioni semplici siano delle istruzioniconcorrenti condizionali, ma senza condizioni.

3.1 Circuiti combinatori vs. Circuiti sequen-

ziali

Prima di addentrarci nelle istruzioni concorrenti, vediamo come possonoessere classificati i circuiti digitali.

Un circuito combinatorio o circuito basato su logica combinatoria non hamemoria interna ne puo essere diviso in stati di funzionamento. L’output efunzione solo e soltanto degli input, e ad uguali ingressi corrispondono ugualiuscite. Sebbene in un circuito reale vi possa essere un periodo di transitorio,il valore di regime, ottenuto dopo un breve lasso di tempo, sara quello atteso.In termini di implementazione, un circuito combinatorio non presentera nel

36

Page 38: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

proprio schema elementi di memoria (quali flip–flop o latch) o un loop inretroazione.

Un circuito sequenziale, viceversa, e un circuito che al proprio internoprevede la presenza di registri di stato e/o elementi di memoria. L’output diun circuito sequenziale e funzione sia degli input che dello stato attuale delcircuito stesso.

Sebbene le istruzioni concorrenti possano essere utilizzate anche per de-scrivere circuiti sequenziali, in quest’ultimo ambito e preferibile l’utilizzo deiprocessi, che rendono piu chiara e semplice anche il debug del circuito stesso(si veda il Cap. 6 per maggiori dettagli). Le istruzioni concorrenti vengono,invece, ampiamente utilizzate nell’ambito dei circuiti combinatori.

3.2 Istruzioni concorrenti semplici

In generale, un’istruzione concorrente semplice per l’assegnazione di uncerto valore ad un certo segnale segue questa sintassi:

destinazione <= nuovo_valore ritardo;

Quanto appena riportato e la definizione di istruzione di assegnazionesemplice cosı come viene fornita dal VHDL. Un esempio semplice puo essere:

y <= a + b after 10 ns;

Il segnale y assumera un valore pari alla somma di a e b dopo 10 ns: peresempio, potremmo voler forzare i ritardi interni dovuti alla logica combina-toria ad essere pari a 10 ns, o ancora potremmo volerli simulare in fase diprogettazione. Purtroppo, tutto cio non e possibile, ma non a causa di unerrore sintattico, ma di sintesi: non esiste sintetizzatore al mondo in gradodi progettare una logica tale da avere un ritardo voluto a priori. La sintassicorretta anche per la sintesi diviene:

y <= a + b;

Sara il progettista a dover poi, eventualmente, tener conto dei ritardiinterni nel momento in cui il blocco realizzato comunichera con altri blocchihw. Il ritardo dovuto alla logica combinatoria e spesso definito δ-delay. Altranota: in quest’ottica, nulla ci vieta di introdurre un loop in retroazione. Adesempio:

y <= (not y) and b;

37

Page 39: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Il fatto e che la porta NOT comportera un ritardo nell’elaborazione (an-che se semplice...) del segnale. Se y cambia velocemente a causa, per esem-pio, di frequenti variazioni di b, la porta NOT come si comportera? Le uscitesaranno prevedibili e verificabili a priori? In generale, introdurre feedbacke sempre pericoloso, specie in circuiti combinatori, e l’uso in questi casi efortemente sconsigliato.

3.3 Istruzioni concorrenti condizionali

3.3.1 Sintassi

La sintassi per un’istruzione di assegnazione concorrente condizionale epiuttosto semplice, ed e sostanzialmente l’unione di piu istruzioni sempliciattraverso condizioni di attivazione. Vediamo:

segnale <= val_1 when condizione_1 else

val_2 when condizione_2 else

...

val_n when condizione_n else

val_default;

Le varie condizioni sono espressioni booleane che restituiscono valore trueo false. A segnale viene attribuito un valore val_i, dove la i-esima e la primacondizione in ordine che ha restituito valore true. In parole povere, si partiracontrollando la prima condizione; se essa non restituisce true, si passa avalutare la seconda; si prosegue, fino all’i-esima, che supponiamo restituiscatrue: in tal caso, al nostro segnale attribuiremo valore pari a val_i. Senessuna condizione e verificata, dev’essere sempre presente un termine diassegnazione di default. Nei circuiti combinatori, e uno dei costrutti piuutilizzati, ma va prestata attenzione all’ordine di scrittura delle condizioni incaso di condizioni e segnali di selezione complessi.

3.3.2 Un esempio: multiplexer a 4 ingressi

Un multiplexer e semplicemente una specie di interruttore fisico hardwarein grado di connettere l’uscita con uno dei 4 ingressi, ed in particolare conl’input scelto attraverso appositi segnali di pilotaggio. Un multiplexer a 4ingressi e un’uscita (detto anche mux 4–1) in particolare avra:

• 4 segnali di ingresso, supponiamo a 8 bit ciascuno;

• 2 segnali di pilotaggio, per selezionare l’ingresso 1, 2, 3 oppure 4;

38

Page 40: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Tabella 3.1: Tabella di funzionamento per il multiplexer 4–1Input Outputsel o

0 0 a0 1 b1 0 c1 1 d

• un segnale di uscita.

La tabella di funzionamento per il segnale di selezione e riportata in Tab.3.1. Il seguente codice VHDL e sbagliato. Vediamo perche:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mux4 is

Port ( a,b,c,d : in std_logic_vector(7 downto 0);

sel : in std_logic_vector(1 downto 0);

o : out std_logic_vector(7 downto 0));

end mux4;

architecture Behavioral of mux4 is

begin

o <= a when (sel = "00") else

b when (sel = "01") else

c when (sel = "10") else

d;

end Behavioral;

Apparentemente, sembrerebbe tutto ok. Pero attenzione: stiamo utiliz-zando dei segnali dello standard IEEE 1164, e ricordiamo che essi possonoassumere ben 9 valori! Se noi avessimo in ingresso sul segnale di selezioneuna stringa "X0" per un qualche motivo, noi porremmo in uscita il canale d,il che non e corretto! Il codice precedente puo essere modificato in modo dacontemplare anche questi casi patologici:

39

Page 41: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mux4 is

Port ( a,b,c,d : in std_logic_vector(7 downto 0);

sel : in std_logic_vector(1 downto 0);

o : out std_logic_vector(7 downto 0));

end mux4;

architecture Behavioral of mux4 is

begin

o <= a when (sel = "00") else

b when (sel = "01") else

c when (sel = "10") else

d when (sel = "11") else

"XXXXXXXX";

end Behavioral;

Nel caso di segnale di selezione non noto precisamente, poniamo in uscitaun segnale non determinato. Ogniqualvolta cambiera il segnale di selezioneo l’ingresso attualmente selezionato, l’istruzione verra ricontrollata e l’uscitaopportunamente modificata.

3.4 Istruzioni concorrenti di selezione

3.4.1 Sintassi

Nel caso di istruzioni condizionali, un certo segnale di uscita assume uncerto valore sulla base di una o piu condizioni booleane, che possono esseremolto semplici (come nel caso del multiplexer del paragrafo 3.3.2) o anchemolto complesse. Nel caso di condizioni su un singolo segnale, e spesso unavalida alternativa l’utilizzo di istruzioni di assegnazione concorrente di tiposelettivo, ovvero aventi la seguente sintassi:

with segnale_controllo select

segnale <= val_1 when scelta_1,

40

Page 42: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

val_2 when scelta_2,

...

val_n when scelta_n;

Come in precedenza, o si contemplano tutti i casi possibili o e neces-saria una condizione di default. Di fatto, rispetto a quanto visto nel prece-dente paragrafo non cambia nulla, se non per il fatto che si puo controllareun segnale invece che un’espressione booleana anche complessa. La strut-tura di questo tipo di istruzioni ricalca quella di un select/case dei linguaggitradizionali, ed effettua un mapping pressoche immediato di una tabella diverita.

3.4.2 Un esempio: multiplexer a 4 ingressi (con istru-

zioni di selezione)

Riprendiamo l’esempio del mux 4–1 del paragrafo 3.3.2. Modifichiamol’architecture in modo da utilizzare le istruzioni concorrenti di selezione.

architecture Behavioral of mux4 is

begin

with sel select

o <= a when "00",

b when "01",

c when "10",

d when "11",

"XXXXXXXX" when others;

end Behavioral;

Abbiamo utilizzato la keyword others per evitare di scrivere tutte lepossibili combinazioni e offrire una soluzione di default.

3.4.3 Un secondo esempio: tabella di verita generica

Supponiamo di voler implementare il circuito che generi gli output diTab. 3.2. Tale circuito avra un ingresso da 3 bit e un output da 1 bit. Ilcodice corrispondente sara:

library IEEE;

41

Page 43: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Tabella 3.2: Tabella di veritaInput Output

x o0 0 0 00 0 1 10 1 0 10 1 1 01 0 0 11 0 1 11 1 0 11 1 1 1

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity tv is

Port ( x : in std_logic_vector(2 downto 0);

o : out std_logic);

end tv;

architecture Behavioral of tv is

begin

with x select

o <= ’0’ when "000",

’1’ when "001",

’1’ when "010",

’0’ when "011",

’1’ when "100",

’1’ when "101",

’1’ when "110",

’1’ when "111",

’X’ when others;

end Behavioral;

Un’alternativa piu compatta e la seguente, utilizzando la notazione pipe:

architecture Behavioral of tv is

42

Page 44: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

begin

with x select

o <= ’0’ when "000"|"011",

’1’ when "001"|"010"|"100"|"110"|"101"|"111",

’X’ when others;

end Behavioral;

Notiamo, pero, una peculiarita: quando il primo bit di x e pari a 1, aprescindere da quanto valgono gli altri due bit l’uscita e sempre 1. Potremmosemplificare la scrittura precedente con il simbolo don’t care:

architecture Behavioral of tv is

begin

with x select

o <= ’0’ when "000"|"011",

’1’ when "001"|"010"|"1--",

’X’ when others;

end Behavioral;

Attenzione pero: se in input avessimo una stringa "11X" in uscita ot-terremo 1, anche se non e cio che vogliamo. Quindi attenzione all’utilizzodei simboli don’t care, specie se si vogliono contemplare anche casi patologiciquali quelli di segnali indeterminati. E’ possibile scrivere l’espressione prece-dente in forma ancora piu compatta calcolando l’equazione booleana, peresempio, attraverso l’utilizzo delle mappe di Karnaugh. Si verifica, infatti,che o = x2+x1x0+x1x0, dove x2 e il MSB e x0 il LSB. Attenzione, pero, nuo-vamente al fatto che, in questo caso, non gestiamo i casi patologici: talvoltaquesto puo essere un problema.

43

Page 45: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 4

Istruzioni sequenziali

Come puo suggerire il nome stesso, le istruzioni sequenziali vengono es-eguite “in sequenza”, e la loro semantica e ancor piu simile alle classicheistruzioni di un linguaggio di programmazione tradizionale. Molti costruttisequenziali, peraltro, sono incompatibili con la natura concorrenziale propriadel VHDL, e devono percio essere incluse all’interno di un guscio concorrentedetto process e che abbiamo presentato nel paragrafo 2.2.1. Se le istruzioniconcorrenti fornivano, di fatto, un mapping diretto (o quasi...) del codicenelle caratteristiche piu schiettamente hardware, le istruzioni sequenziali,in generale, non possiedono questa proprieta, ma tendono a descrivere inmaniera talvolta anche astratta il comportamento del sistema (in partico-lare, di una entity). Proprio per questa natura quasi astratta, le istruzionisequenziali vanno utilizzate con molta cautela, al fine di ottenere un codicecorretto sotto tutti i punti di vista, non ultima la capacita di essere poisintetizzato.

In questo capitolo, rivedremo molti concetti introdotti sommariamentenel Capitolo 2, e approfondiremo meglio alcuni aspetti fondamentali.

4.1 Il processo

4.1.1 Introduzione

Un process o processo, come gia piu volte detto, e un costrutto che con-tiene un insieme di azioni, le quali devono essere eseguite in maniera sequen-ziale. Tali azioni sono le istruzioni sequenziali, mentre il processo in se puoessere considerato come un’unica istruzione (o costrutto) concorrente.

Le istruzioni sequenziali racchiudono una vasta gamma di costrutti, iquali possono essere utilizzati solo all’interno di un processo. Al contrario di

44

Page 46: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

quanto visto per le istruzioni concorrenti, le istruzioni sequenziali vengonoeseguite nell’ordine in cui sono state scritte. Molti di questi costrutti sonoutilissimi in fase di programmazione, ma non sintetizzabili, percio bisognaprestare attenzione. In questo capitolo, analizzeremo alcuni costrutti:

• wait;

• istruzioni di assegnazione di un certo valore ad un certo segnale;

• istruzioni di assegnazione di un certo valore ad una certa variabile;

• if...then...else;

• case;

• for...loop.

Esistono strutture anche molto piu complesse e potenti, facenti parte delcosiddetto stile di programmazione parametrizzato (si veda il Cap. 10).

Attenzione a non far confusione: una istruzione sequenziale e un’istruzioneVHDL all’interno di un processo; un circuito sequenziale e un circuito dotatodi elementi di memoria e registri di stato. In generale, mentre le istruzioniconcorrenti possono essere utilizzate quasi solo nella descrizione di circuiticombinatori, le istruzioni sequenziali e i processi possono essere usati sia percircuiti combinatori che sequenziali. Per il momento, ci concentreremo suicircuiti combinatori. Per maggiori dettagli sui circuiti sequenziali, si veda ilCap. 6.

Un processo, abbiamo visto, deve avere un evento di attivazione, ovverouna causa scatenante. Tale causa puo essere settata sia attraverso l’utilizzodi una sensitivity list, sia con costrutti come il wait. Procediamo con ordine.

4.1.2 Processi con sensitivity list

La sintassi di un processo con sensitivity list e il seguente:

process(sensitivity_list)

{dichiarazioni}

begin

{istruzioni sequenziali}

end process;

45

Page 47: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

La sensitivity list nient’altro e che una lista di segnali alla variazione deiquali il processo e sensibile. Infatti, analogamente a quanto succede in hw,un processo puo avere due stati: attivato o sospeso. Se e sospeso, il processoe in stato di idle, ovvero non fa nulla, e attende che uno dei segnali dellapropria sensitivity list vari. Nel momento in cui tale transizione arriva, ilprocesso si attiva, e vengono eseguite le istruzioni sequenziali nell’ordine incui sono state scritte dal programmatore. Una volta che tali istruzioni sonoterminate, il processo si sospende in attesa di una nuova variazione di unsegnale della sensitivity list.

Esistono due tipi di processi con sensitivity list: a lista completa edincompleta. Supponiamo di avere 3 segnali:

signal a, b, y : std_logic;

Un processo con sensitivity list completa e il seguente:

process(a,b)

begin

y <= a and b;

end process;

Un qualsiasi variazione di a o b causa l’attivazione del processo e, quindi,un cambio di valore per y. Viceversa, un processo avente sensitivity listincompleta e del tipo:

process(a)

begin

y <= a and b;

end process;

In questo caso, il processo viene attivato solo per variazioni di a. Questosignifica che se anche b cambia valore, e con esso dovrebbe cambiare anchey, in verita finche non cambia a l’uscita non subisce variazioni.

4.1.3 Processi con istruzioni wait

Un processo che presenta una o piu istruzioni di tipo wait al suo internonon ha di sensitivity list. Come anticipato nel paragrafo 2.2.1, le istruzionisono:

• wait on {segnali}: il processo si sospende in quel punto in attesa diuna variazione su uno dei segnali selezionati;

46

Page 48: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• wait until {condizione}: il processo si sospende in attesa che lacondizione divenga true;

• wait for {intervallo_di_tempo}: il processo si sospende per undeterminato periodo di tempo.

Per esempio, il circuito con sensitivity list completa del precedente para-grafo puo essere scritto come:

process

begin

y <= a and b;

wait on a, b;

end process;

Teoricamente, e sintatticamente corretto anche il seguente codice:

process

begin

y <= a and b;

wait on b;

y <= b;

wait on a, b;

end process;

Nella pratica, un utilizzo dei wait di questo tipo e fortemente sconsiglia-to, perche facilmente porta a codice non sintetizzabile. In generale, e semprepreferibile utilizzare una sensitivity list, perche:

• il costrutto wait on e sostanzialmente equivalente e complica la leggi-bilita del codice;

• se le condizioni del costrutto wait until fossero troppo complicate,porterebbero facilmente alla mancata sintesi del circuito;

• in generale, a meno di casi molto patologici, il costrutto wait for none mai sintetizzabile.

47

Page 49: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

4.2 Istruzioni di assegnazione sequenziale per

segnali

Abbiamo affrontato in parte questi argomenti gia nel paragrafo 2.2.3.Ricordiamo che un segnale all’interno di un processo assume il suo valoredefinitivo solo al termine del processo. Pertanto, se noi inizializziamo unsegnale tmp:

signal tmp : integer := 0;

Al primo passo, con il seguente processo, otteniamo y=0 e tmp=1:

process(a)

begin

z <= a;

tmp <= tmp + 1;

y <= tmp;

end process;

Di fatto, y sara in ritardo di un passo rispetto a tmp. Questo permettedi effettuare (per quanto non sia buona norma farlo...) piu assegnazionicontemporanee:

...

signal a,b,c,d : std_logic;

...

process(a,b,c,d)

begin

y <= ’1’;

y <= a and b;

y <= c and d;

y <= a or c;

end process;

Il precedente codice equivale a calcolare direttamente:

...

signal a,b,c,d : std_logic;

...

process(a,b,c,d)

begin

y <= a or c;

end process;

48

Page 50: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Proprio in questa peculiarita si evidenziano le differenze con le variabilie con le istruzioni concorrenti. Un codice come questo, per quanto insensato,e sintetizzabile:

...

signal a,b,c,d : std_logic;

...

process(a,b,c,d)

begin

y <= ’1’;

y <= a and b;

y <= c and d;

y <= a or c;

end process;

Se non utilizzassimo i processi, ma le istruzioni concorrenti:

...

signal a,b,c,d : std_logic;

...

y <= ’1’;

y <= a and b;

y <= c and d;

y <= a or c;

...

Questo codice non sarebbe nemmeno sintetizzabile, in quanto contempo-raneamente vorremmo connettere y al segnale di high, ma anche all’uscita didue AND e di un OR, con evidente conflitto.

4.3 Istruzioni di assegnazione sequenziale per

variabili

Passiamo alla descrizione delle istruzioni per attribuire un certo valore aduna variabile. Sintatticamente, rispetto ai segnali cambia poco: si utilizzail simbolo := invece di <=. Concettualmente, invece, cambia moltissimo:una variabile varia il proprio valore in modo istantaneo nel momento in cuieffettuiamo l’assegnazione. In certi casi, questa puo essere una comodita, mariempire un processo di variabili puo portare all’utilizzo di molte unita dimemoria nonche spesso porta anche a codice non sintetizzabile (nella realta,una variabile non puo cambiare in maniera immediata, ma avra sempre ildelta–delay). Vediamo un semplice codice, in cui utilizziamo solo segnali:

49

Page 51: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

...

signal a,b,c,d : std_logic;

signal tmp : std_logic;

...

process(a,b,c,d)

begin

tmp <= a and b;

tmp <= tmp or c;

y <= tmp and d;

end process;

In questo caso, introduciamo dei loop, in quanto questo codice equivaleal seguente:

...

signal a,b,c,d : std_logic;

signal tmp : std_logic;

...

process(a,b,c,d)

begin

tmp <= tmp or c;

y <= tmp and d;

end process;

Ricordiamo, inoltre, che y assume valore pari all’AND fra il valore di tmpprima dell’aggiornamento e il valore di d. Se utilizziamo una variabile, lecose cambiano molto:

...

signal a,b,c,d : std_logic;

...

process(a,b,c,d)

variable tmp : std_logic;

begin

tmp := a and b;

tmp := tmp or c;

y <= tmp and d;

end process;

In questo caso, avremo y = ((a · b) + c) · d), perche la variabile tmp

viene aggiornata nel proprio valore ad ogni passo. Bisogna prestare atten-zione, perche un uso poco attento di variabili e segnali puo portare a malfun-zionamenti comportamentali. D’altro canto, un utilizzo troppo spinto dellevariabili puo portare a problemi in fase di sintesi o post place–and–route.

50

Page 52: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

4.4 Costrutto if...then...else

4.4.1 Sintassi

La sintassi di questo costrutto e analoga a quella di un qualsiasi altrolinguaggio di programmazione:

if condizione_1 then

{istruzioni sequenziali};

elsif condizione_2 then

{istruzioni sequenziali};

...

else

{istruzioni sequenziali};

end if;

Ogni gruppo di istruzioni sequenziali e detto branch, e, in particolare, sihanno i:

• then branch: gruppo di istruzioni che segue l’if iniziale;

• elsif branch: gruppi di istruzioni che seguono gli elsif ;

• else branch: gruppo di istruzioni che segue l’else finale.

4.4.2 Un esempio: multiplexer a 4 ingressi

Riprendiamo l’esempio, presentato nel paragrafo 3.3.2, del multiplexer4–1. Come detto, puo essere implementato attraverso semplici istruzioni con-correnti. Altrettanto semplicemente puo essere implementato con istruzionisequenziali in un processo. Il codice e il seguente:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mux4 is

Port ( a,b,c,d : in std_logic_vector(7 downto 0);

s : in std_logic_vector(1 downto 0);

o : out std_logic_vector(7 downto 0));

end mux4;

51

Page 53: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

architecture Behavioral of mux4 is

begin

process(a,b,c,d,sel)

begin

if(s="00") then

o <= a;

elsif(s="01") then

o <= b;

elsif(s="10") then

o <= c;

elsif(s="11") then

o <= d;

else

o <= "XXXXXXXX";

end if;

end process;

end Behavioral;

Le differenze con i costrutti analizzati nel Cap. 3 sono, per casi semplici,davvero piccole, ed identificare una scelta ottima tra if e with...select...whene davvero complesso. In generale, e buona norma, mano a mano che sicomplicano le condizioni da analizzare, cercare di utilizzare il costrutto ifassieme ad un processo: rende il tutto piu leggibile. Ad esempio, nel caso diuna doppia condizione annidata, l’utilizzo dell’if e immediato ed intuitivo:

...

signal a,b,c,d : std_logic;

...

process(a,b,c,d)

begin

if(a=’1’) then

if(b=’0’) then

o <= c;

else

o <= d;

end if;

else

52

Page 54: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

if(b=’1’) then

o <= c;

else

o <= d;

end if;

end process;

4.4.3 Incomplete branch

Viene definito branch incompleto un costrutto if in cui non vengonocontemplate tutte le possibili alternative. In parole povere, il seguente codicee un incomplete branch:

...

signal a,b,c : std_logic;

...

process(a,c)

begin

if(a=’1’) then

b <= c;

end if;

end process;

Il segnale b cambia il proprio valore solo se:

• vi e stata una variazione di a o c;

• a ha valore pari a 1.

In caso contrario, b non varia. Se b non e stato ancora mai assegnato adun certo valore, il suo stato e ’U’.

4.4.4 Incomplete assignment

Un costrutto if puo avere molti branch, e un’entita puo avere moltisegnali. In alcuni branch alcuni segnali potrebbero non venire assegnatinuovamente. Facciamo un esempio:

...

signal a,b,c,d : std_logic;

...

process(a,c)

53

Page 55: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

begin

if(a>c) then

b <= c;

elsif (a=c) then

d <= a;

else

d <= ’0’;

end if;

end process;

In questo caso, abbiamo un complete branch, ma nel then branch nonassegnamo alcun valore a d, mentre nei due casi successivi non assegnamoalcun valore a b. Se non modificato, un segnale mantiene il proprio valore.Pero la programmazione e poco precisa. Si consiglia di utilizzare molto rara-mente gli incomplete branch (limitarli ai casi di controllo su fronte di salita diun clock, per esempio) e ancor piu di rado gli incomplete assignment, perchealcuni segnali potrebbero diventare poco gestibili.

4.5 Costrutto case...when

4.5.1 Sintassi

La sintassi del costrutto e la seguente:

case espressione is

when scelta_1 =>

{istruzioni sequenziali};

when scelta_2 =>

{istruzioni sequenziali};

...

when scelta_n =>

{istruzioni sequenziali};

end case;

Si valuta, quindi, il risultato di una certa espressione (booleana o comp-lessa) e si esegue un certo branch (insieme di istruzioni sequenziali) sulla basedi tale risultato. Sono possibili, anche in questo costrutto, casi di incompletebranch o assignment, anche se sconsigliabili. E’ sempre consigliabile l’intro-duzione di una scleta di default, al piu utilizzando la parola chiave others.Questo costrutto e simile a quanto visto nel Cap. 3: come gia detto nel prece-dente paragrafo, costrutti sequenziali in processi sono piu flessibili, semplici

54

Page 56: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

ed affidabili (in termini di sintesi hw) rispetto a costrutti concorrenti, e,quindi, sono in generale preferibili.

4.5.2 Un esempio: multiplexer a 4 ingressi

Riprendiamo per l’ennesima volta il nostro mux 4–1. Possiamo proget-tarlo anche nel seguente modo:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mux4 is

Port ( a,b,c,d : in std_logic_vector(7 downto 0);

s : in std_logic_vector(1 downto 0);

o : out std_logic_vector(7 downto 0));

end mux4;

architecture Behavioral of mux4 is

begin

process(a,b,c,d,sel)

begin

case s is

when "00" =>

o <= a;

when "01" =>

o <= b;

when "10" =>

o <= c;

when "11" =>

o <= d;

when others =>

o <= "XXXXXXXX";

end case;

end process;

end Behavioral;

55

Page 57: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

4.6 Costrutto for...loop

Introduciamo il costrutto for...loop. In verita, in questa forma e rara-mente utilizzato, perche spesso porta a codice non sintetizzabile. Appro-fondiremo questi aspetti e formulazioni alternative per il costrutto for nelCap. 10.

4.6.1 Sintassi

La sintassi e la seguente:

for indice in {range} loop

{istruzioni sequenziali};

end loop;

La variabile indice tiene traccia del numero di iterazioni, che varier-anno all’interno di un range fissato. Il branch verra eseguito, quindi, unnumero determinato di volte. Ne la variabile indice ne il range devono esserepreventivamente dichiarati. Vediamo un esempio.

4.6.2 Un esempio: XOR bit–a–bit a 8 bit

Premesso che esiste un operatore XOR anche per vettori di bit, supponi-amo di volerne realizzare uno nostro. Il codice puo essere:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity xor8 is

Port ( a,b : in std_logic_vector(7 downto 0);

o : out std_logic_vector(7 downto 0));

end xor8;

architecture Behavioral of xor8 is

constant WIDTH : integer := 8;

begin

process(a,b)

begin

for i in (WIDTH-1) downto 0 loop

56

Page 58: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

o(i) <= a(i) xor b(i);

end loop;

end process;

end Behavioral;

Dichiariamo una costante WIDTH per il numero di bit dei vettori, quindiiniziamo il loop avente come indice i e come range 7 (cioe WIDTH-1) fino a0. In tutto, quindi, effettueremo 8 step.

57

Page 59: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 5

Progetto di circuiti combinatori

Progettare circuiti combinatori non e cosı semplice come potrebbe sem-brare ad un primo approccio. Innanzitutto, come gia appare chiaro daiprecedenti capitoli, bisogna porre attenzione a scrivere un codice che siasintetizzabile: per esempio, e necessario evitare condizioni di attesa o ritar-do temporale. Mano a mano che un progetto si fa piu ampio e complesso,e necessario intervenire anche sulla struttura stessa del circuito: sebbene ilVHDL spesso non ricordi molto da vicino uno schematico, bisogna lavorarein modo da rendere piu efficace ed efficiente lo schema conclusivo. In parolepovere, modificare l’input per migliorare l’output.

Da un punto di vista operativo, tutto cio si traduce in alcuni semplicima importanti step:

• progetto iniziale del sistema;

• ottimizzazione del progetto;

• implementazione del progetto ottimizzato;

• ottimizzazione del codice.

Per ottimizzazione del codice VHDL si intende, per esempio, l’utilizzo dicostrutti semplici, al piu scrivendo operatori complessi manualmente, o l’e-liminazione di elementi quali le variabili. In parte, per semplicita in questocapitolo verremo meno a queste idee per quanto riguarda, soprattutto, l’im-plementazione manuale di alcuni operatori quali la somma o la sottrazione,supponendo che tali miglioramenti vengano effettuati dal sintetizzatore.

58

Page 60: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

5.1 Operator Sharing

Una delle piu immediate ottimizzazioni applicabili ad un codice riguar-da la diminuzione del numero di strutture pesanti dal punto di vista com-putazionale e di occupazione di scheda. Non scordiamoci mai che l’outputdel nostro lavoro e pur sempre il bitstream di programmazione, che andrapoi a creare (o non creare) dei fuse su una FPGA. Le FPGA, normalmente,hanno un numero molto grande, ma pur sempre limitato, di porte logiche.Un circuito puo essere considerato migliore di un altro circuito che eseguaanaloghe operazioni se offre una precisione maggiore e/o se occupa un nu-mero di porte logiche e LUT inferiore e/o (nel caso di circuiti sequenziali,che tratteremo nel prossimo capitolo) se fornisce un thorughput maggiore(ovvero, ogni quanti colpi di clock otteniamo un risultato valido).

Ogni componente, sia esso un adder o un multiplexer, ha una sua occu-pazione di scheda che lo caratterizza. E’ ovviamente improponibile pensaredi ricordare l’occupazione di tutti i possibili core hardware. In linea di massi-ma, e comunque intuibile che un multiplexer occupera meno porte logiche diun sommatore, e ancora meno di un moltiplicatore. Anzi, su alcune schede unmoltiplicatore non e neppure presente: pertanto, il sintetizzatore provvederaad usare strutture alternative (ancora piu pesanti sotto tutti i punti di vista).E’ buona norma, quindi, tenere d’occhio anche le risorse hw disponibili sullascheda su cui poi vorremo implementare il nostro circuito.

In particolare, l’operator sharing prevede l’individuazione di risorse cheposssono essere utilizzate da diverse operazioni. Talvolta, cio comporta unaumento del numero totale di componenti: questo e, pero, accettabile seaumentano i core “leggeri” a fronte di una drastica diminuzione di quelli“pesanti”.

Consideriamo il seguente esempio:

process(a,b,c,d)

begin

if(a<c) then

r <= a+b;

else

r <= a+c;

end if;

end process;

In tutto, necessitiamo di due sommatori, un multiplexer (per l’if ) e uncomparatore. Notiamo, pero, come in entrambi i casi sia calcolata una sommatra due quantita. Inoltre, uno dei due operandi e in ambo i casi a. Pertanto,possiamo scrivere il seguente codice, piu efficiente:

59

Page 61: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

process(a,b,c,d)

signal src : std_logic_vector(7 downto 0);

begin

if(a<c) then

src <= b;

else

src <= c;

end if;

r <= src + a;

end process;

In questo modo, utilizziamo un sommatore solo, un comparatore, unmultiplexer per l’if e uno per la selezione di b o c. Abbiamo, quindi, unsommatore in meno e un multiplexer in piu: dato che un mux e molto meno“ingombrante” di un sommatore, questa seconda soluzione e preferibile. Inquesto caso, l’operatore a cui abiamo applicato lo sharing e la somma. Ovvi-amente, all’aumentare del numero di operazioni che risparmiamo aumentanoanche i vantaggi che riusciamo a trarre dall’operator sharing. Spesso, essendoabbastanza facili da individuare, un sintetizzatore e in grado di effettuare inautomatico queste ottimizzazioni.

5.2 Functionality Sharing

La functionality sharing prevede l’ottimizzazione di un circuito sfruttan-do le proprieta delle funzioni e dei core che vengono utilizzati nel circuitostesso. Per esempio, se dobbiamo progettare un microprocessore, non si puopensare di implementare un singolo blocco per ogni possibile operazione: laricerca consta nel voler trovare quelle affinita tra funzioni che permettano disemplificare il numero totale di blocchi da utilizzare. E’ molto piu difficileindividuare la possibilita di functionality sharing rispetto all’operator shar-ing, tanto e vero che non esiste sintetizzatore al mondo in grado di effettuarequesto tipo di considerazioni (se non in casi banali).

Con un esempio tutto risultera piu chiaro. Supponiamo di voler progettareun core in grado di implementare la somma e la sottrazione tra due operandi.Verra calcolata una piuttosto che l’altra quantita sulla base del valore di unsegnale di controllo ctrl. Supponiamo che gil addendi siano del tipo signed,ovvero in complemento a 2. Una soluzione e la seguente:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

60

Page 62: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

use IEEE.STD_LOGIC_UNSIGNED.ALL;

use IEEE.NUMERIC_STD.ALL;

entity addsub is

Port ( a,b : in std_logic_vector(7 downto 0);

ctrl : in std_logic;

r : out std_logic_vector(7 downto 0));

end addsub;

architecture Behavioral of addsub is

signal src0, src1, sum : signed(7 downto 0);

begin

-- trasformiamo a e b in signed

src0 <= signed(a);

src1 <= signed(b);

sum <= src0 + src1 when ctrl=’0’ else

src0 - src1;

-- trasformiamo sum in std_logic_vector

r <= std_logic_vector(sum);

end Behavioral;

In tutto, utilizziamo un sommatore, un sotrattore e un multiplexer. Datoche sommatore e sotrattore non sono lo stesso componente, non possiamoapplicare le tecniche viste nel precedente paragrafo. E’ altrettanto vero,pero, che in complemento a 2 vale la seguente relazione:

a − b = a + b + 1

Dato che un adder ha sempre un ingresso per il carry–in, ovvero il restoin ingresso, l’operazione precedente implica l’utilizzo di un solo sommatore,anche se dobbiamo sommare 3 quantita. A questo punto, possiamo applicarel’operator sharing ed ottenere:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

use IEEE.NUMERIC_STD.ALL;

entity addsub is

61

Page 63: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Port ( a,b : in std_logic_vector(7 downto 0);

ctrl : in std_logic;

r : out std_logic_vector(7 downto 0));

end addsub;

architecture Behavioral of addsub is

signal src0, src1, sum : signed(7 downto 0);

signal cin : signed(0 downto 0);

begin

-- trasformiamo a e b in signed

src0 <= signed(a);

src1 <= signed(b) when ctrl=’0’ else

signed(not(b));

-- calcolo del carry-in

cin <= "0" when ctrl=’0’ else

"1";

sum <= src0 + src1 + cin;

-- trasformiamo sum in std_logic_vector

r <= std_logic_vector(sum);

end Behavioral;

Abbiamo 2 multiplexer, un inverter (per il NOT) e un sommatore: 4 com-ponenti invece di 3, ma risparmiamo un sotrattore (pesante) per introdurreun inverter e un multiplexer (leggeri).

5.3 Ottimizzazioni di layout

Un buon progetto passa anche attraverso l’attenzione che si presta a comeviene generato un circuito alla conclusione del processo di sintesi. Ovvia-mente, l’utente non puo agire sul sintetizzatore. Pero puo utilizzare un po’di furbizia nel codice che si passa al sintetizzatore.

Uno degli aspetti peggiori dei circuiti, siano essi combinatori o sequen-ziali, e rappresentato dalla capacita di prevedere quanto tempo (nel caso dicircuiti combinatori) o quanti cicli di clock (per i sequenziali) passerannoprima di ottenere gli output, una volta forniti gli input. Questa fase delprogetto e molto noiosa, ma altrettanto importante, specie se il blocchettoche si considera e parte integrante di un circuito piu grande, dal quale siotterranno gli ingressi e si forniranno le uscite. Ci sarebbero migliaia di con-siderazioni da fare, ma concentriamoci sull’aspetto temporale attraverso un

62

Page 64: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

esempio semplice. Vogliamo implementare un circuito che fornisca un’uscitay tale che:

y =

{(a · b) + c se ctrl = 0((a ⊕ b) ⊕ c) ⊕ d se ctrl = 1

dove ⊕ e lo XOR bit–a–bit. Un’implementazione diretta e:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity esempio is

Port ( a,b,c,d : in std_logic;

ctrl : in std_logic;

r : out std_logic);

end esempio;

architecture Behavioral of esempio is

begin

process(a,b,c,d,ctrl)

begin

if(ctrl=’0’) then

y <= (a and b) or c;

else

y <= ((a xor b) xor c) xor d;

end if;

end process;

end Behavioral;

Lo schema circuitale e rappresentato in Fig. 5.1. Nasce un problema: sectrl vale 0, abbiamo due stadi di logica di ritardo; altrimenti, ne abbiamo3. Come risultato otteniamo un diverso δ–delay, e quindi un circuito pocopreciso e prevedibile. Come sistemarlo? La prima soluzione e quella diaggiungere un buffer di ritardo sulla prima soluzione. Dato che questa sceltanon e proprio il massimo della vita, si puo sfruttare la proprieta associativadello XOR. Pertanto, si ha:

((a ⊕ b) ⊕ c) ⊕ d = (a ⊕ b) ⊕ (c ⊕ d)

63

Page 65: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Quindi, scriviamo il nostro codice come:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity esempio is

Port ( a,b,c,d : in std_logic;

ctrl : in std_logic;

r : out std_logic);

end esempio;

architecture Behavioral of esempio is

begin

process(a,b,c,d,ctrl)

begin

if(ctrl=’0’) then

y <= (a and b) or c;

else

y <= (a xor b) xor (c xor d);

end if;

end process;

end Behavioral;

In uscita otterremo uno schema come quello di Fig. 5.2, ovvero bilanciato.

64

Page 66: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 5.1: Circuito sbilanciato nei δ–delays

65

Page 67: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 5.2: Circuito bilanciato nei δ–delays, sfruttando la proprietaassociativa dello XOR

66

Page 68: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 6

Progetto di circuiti sequenziali

6.1 Introduzione

6.1.1 Circuiti sequenziali

Come detto nel paragrafo 3.1, un circuito sequenziale e caratterizzatoda un proprio stato interno e da elementi di memoria. Quindi, mentre inun circuito combinatorio gil output, istante per istante, sono funzione solodi quel singolo input, in un circuito sequenziale la funzione che genera leuscite e funzione non solo dell’ingresso istantaneo, ma di tutti gli ingressiprecedenti, i quali vengono memorizzati nello stato interno del circuito. Ilnome “sequenziale” deriva proprio dal fatto che l’output e funzione dellasequenza di input.

I circuiti sequenziali si dividono in asincroni e sincroni : in questi ulti-mi, tutti gli elementi di memoria sono controllati da uno o piu segnali disincronizzazione (clock). I circuiti sequenziali sincroni sono largamente i piuutilizzati e rappresentano l’argomento di interesse per quanto riguarda lanostra trattazione.

6.1.2 Elementi di memoria

Elementi di memoria possono essere aggiunti ad un circuito in due modi:

• la prima tecnica e l’utilizzo di retroazione in un circuito combinato-rio classico. Questa tecnica pero e pericolosa e sconsigliabile a causadei ritardi di propagazione, che possono anche portare ad uscite nondesiderate ne previste;

• la seconda soluzione e rappresentata dall’uso di flip–flop e latch.

67

Page 69: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

In Fig. 6.1 sono presenti i principali tipi di latch e flip–flop (FF). Datoche, sostanzialmente, il latch non e sincrono e, se c e 1 copia l’ingresso d,l’utilizzo di questo elemento puo portare al cosiddetto fenomeno dei runningdelays, ovvero propagazione di ritardi. L’utilizzo di elementi sincroni, quali iflip–flop D in figura, e consigliato, in quanto crea una sorta di cuscinetto, peresempio, nell’I/O di un componente per ammortizzare i ritardi e favorire lapropagazione del dato nel circuito. Non si entra nei particolari dei flip–flop,che dovrebbero essere noti, se non per una notazione: q* rappresenta lo statosuccessivo che assumera il FF.

Figura 6.1: I vari tipi di flip–flop D–type

E’ importante approfondire, invece, le caratteristiche temporali dei flip–flop, mostrate graficamente in Fig. 6.2. Analizziamo le diverse voci:

• Tcq: clock–to–Q delay, ovvero il tempo di propagazione necessario alsegnale d per propagarsi sull’uscita q dopo il sampling del fronte diclock;

• Tsetup: e il setup time, ovvero l’intervallo di tempo per il quale il segnaled deve rimanere stabile prima del fronte del clock;

68

Page 70: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• Thold: hold time, ovvero per quanto tempo dopo il fronte del clock ilsegnale d deve rimanere stabile.

Figura 6.2: Timing diagram di un flip–flop D

Quindi, mentre Tcq rappresenta il classico ritardo di propagazione, gli al-tri due sono vincoli temporali, i quali entrano in gioco in un circuito sincronoper la stima della massima frequenza di clock ammessa: infatti, se i segnalidovessero variare troppo rapidamente (o il periodo di clock fosse troppo pic-colo) violeremmo uno di questi constraints. In particolare, tale violazioneporta il FF in uno stato cosiddetto metastabile.

6.1.3 Classificazione dei circuiti sequenziali

A seconda di come viene organizzata la rete di distribuzione interna delclock per i vari FF, possiamo classificare i circuiti sequenziali in:

• circuiti totalmente sincroni (o, piu semplicemente, circuiti sincroni):tutto il circuito utilizza FF sincronizzati da un unico segnale di clock co-mune a tutto il dispositivo. E’ la soluzione piu utilizzata, in quanto fa-cilita la progettazione, l’interfacciamento, il test e la verifica dei proget-ti. Non solo, e utile sia in sistemi di grandi dimensioni (es. processori)sia in dispositivi elementari (es. contatori);

• circuiti asincroni localmente sincroni : a causa di vincoli progettuali(ad esempio, il piazzamento di certi componenti in parti distanti dellascheda), potrebbe essere difficile far condividere a tutto il sistema lostesso clock. Si puo, pero, dividere il tutto in tanti sotto–sistemi piu

69

Page 71: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

semplici, all’interno dei quali creare circuiti sincroni con un proprioclock. A questo punto, il vero problema consiste nella sincronizzazionetra tali sotto–sistemi: esistono tecniche ad hoc, ma che non tratteremoin quanto non di nostro diretto interesse;

• circuiti totalmente asincroni (o, piu semplicemente, circuiti asincroni):nessun componente del circuito utilizza un clock globale, quindi o i FFvengono auto–gestiti attraverso una politica basata su comuni segnaliusati come clock, oppure ogni flip–flop utilizza un clock proprio e nonlegato a nessun altro segnale di sincronizzazione. Circuiti di questotipo sono di difficile gestione e progettazione, pertanto non verrannotrattati.

6.2 Circuiti sequenziali sincroni

Passiamo ad analizzare i circuiti sequenziali sincroni, ovvero quelli dimaggiore interesse dal nostro punto di vista. Innanzitutto, descriviamo loschema generale di circuito sincrono sequenziale di Fig. 6.3. Il blocco dielaborazione next–state logic riceve in ingresso i segnali di input e, eventual-mente, lo stato del sistema (in pratica, la traccia degli input e output agliistanti precedenti): il suo compito e quello, sulla base di tali informazioni,di generare lo stato successivo per il blocco di calcolo in uscita dal circuito.In pratica, ricevuti gli input, genera i dati per il calcolo dell’output vero eproprio, eseguito poi dalla output logic. Nel mezzo, si introduce un FF ditipo D per la sincronizzazione. Questa e una struttura a stato sincronizzato:esistono varianti a ingressi/uscite registrate, che non prevedono il FF per lostato ma l’aggiunta di un flip–flop in ingresso e/o uscita per sincronizzare gliI/O.

Figura 6.3: Schema a blocchi generale per un circuito sequenziale sincrono

70

Page 72: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Possiamo identificare 3 tipi di circuiti sequenziali:

1. Regular Sequential Circuits: la rappresentazione dello stato e la tran-sizione fra essi e semplice da gestire, come nel caso di contatori oshift–registers. Spesso, lo stesso stato della macchina e l’output delcircuito;

2. Random Sequential Circuits: la gestione della transizione fra stati epiu complessa, in quanto l’assegnazione di essi e randomica rispettoall’output della macchina. E’ il caso delle macchine a stati finiti (FSM)semplici, in cui l’uscita e determinata solo dallo stato del sistema;

3. Combined Sequential Circuits: e l’unione dei due casi precedenti. UnaFSM e utilizzata per la gestione degli stati, ma l’output e generato sullabase di una elaborazione su uno o piu input. Vengono dette macchinea stati finiti con datapath (FSMD), anche se spesso, per semplicita, siusa anche per esse il nome FSM.

Approfondiremo le FSM e le FSMD nel Cap. 7.

6.3 Programmazione di elementi di memoria

elementari

Tutte le schede che si utilizzano sono composte da: slice, ovvero celle dicalcolo elementari (per lo piu AND e OR); slice flip–flop, ovvero celle cont-nenti flip–flop per la sincronizzazione; LUTs, ovvero piccole celle di memoria,in cui l’ingresso e costituito dall’indirizzo della cella di memoria e l’outpute il dato in essa memorizzato (le analizzeremo piu approfonditamente nelCap. 8). Nel momento in cui sintetizziamo un codice VHDL, il sintetizza-tore e in grado di tradurre le nostre righe di codice in componenti presention–board sulla scheda di detinazione del nostro lavoro: e per questo che nonha senso pensare di scrivere un codice VHDL senza conoscere bene su qualedevice vogliamo implementare il nostro circuito. Quindi, se implementiamouna architettura avente il comportamento di un flip–flop D, in automaticoil sintetizzatore trasformera il componente in un elemento della libreria e lopiazzera nelle apposite slice.

Fatta questa premessa, vediamo nei prossimi paragrafi come implementarealcune semplici unita di memorizzazione.

71

Page 73: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

6.3.1 Positive–Edge–Triggered D Flip–Flop

La tabella di attivazione del FF D positive–edge e presente in Fig. 6.1.Vediamo come potrebbe essere implementato:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ffd is

Port ( d : in STD_LOGIC;

clk : in STD_LOGIC;

q : out STD_LOGIC);

end ffd;

architecture Behavioral of ffd is

begin

process(clk)

begin

if rising_edge(clk) then

q <= d;

end if;

end process;

end Behavioral;

Sul fronte di salita del clock (controllato dal comando rising_edge

facente parte dello standard IEEE 1164), il segnale di ingresso viene copiatosull’uscita. Altrimenti, non viene fatto nulla. Come mostrato in Fig. 6.4,il sintetizzatore riconosce che il componente da noi progettato e proprio unflip–flop di tipo D positive–edge triggered.

6.3.2 FF D con reset asincrono

Vediamo un secondo esempio. Modifichiamo la precedente struttura ag-giungendo un reset (ipotizzandolo attivo basso), il quale agisce in manieratotalmente asincrona rispetto al clock: quando vale 0 tale segnale (attivobasso), l’uscita si deve annullare.

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

72

Page 74: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 6.4: Schema RTL di sintesi per un flip–flop D

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ffdr is

Port ( d : in STD_LOGIC;

clk : in STD_LOGIC;

reset : in STD_LOGIC;

q : out STD_LOGIC);

end ffdr;

architecture Behavioral of ffdr is

begin

process(clk, reset)

begin

if reset=’0’ then

q <= ’0’;

elsif rising_edge(clk) then

q <= d;

end if;

end process;

end Behavioral;

Si notino la modifica nella sensitivity list e l’ordine dei branch nell’if : seavessimo controllato il reset dopo il clock, avremmo avuto un comportamentoerrato. Sintetizzando, si ottiene lo schema di Fig. 6.5: nella libreria dellascheda utilizzata, non era contemplato un flip–flop con reset attivo basso,ma solo con un clear attivo alto. Pertanto, cosa accade? Il sintetizzatoreinserisce un inverter al fine di utilizzare il componente disponibile.

73

Page 75: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 6.5: Schema RTL di un flip–flop D con reset asincrono

E se volessimo un reset sincrono? Modifichiamo l’architettura precedentenel seguente modo:

architecture Behavioral of ffdr is

begin

process(clk)

begin

if rising_edge(clk) then

if reset=’0’ then

q <= ’0’;

else

q <= d;

end if;

end if;

end process;

end Behavioral;

In questo caso, la sensitivity list include solo il clock, e il segnale di resetviene analizzato solo sui fronti di salita. Anche il sintetizzatore modifica ilcomponente utilizzato, come mostrato in Fig. 6.6.

6.3.3 Registro a 8 bit

Un registro a 8 bit non e nient’altro che un insieme di 8 FF D classici. Ilcodice e piuttosto semplice:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

74

Page 76: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 6.6: Sintesi RTL di un FF D con reset sincrono

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity reg8 is

Port ( d : in STD_LOGIC_VECTOR (7 downto 0);

clk : in STD_LOGIC;

q : out STD_LOGIC_VECTOR (7 downto 0));

end reg8;

architecture Behavioral of reg8 is

begin

process(clk)

begin

if rising_edge(clk) then

q <= d;

end if;

end process;

end Behavioral;

6.3.4 RAM

La Random Access Memory e uno dei tipi di memoria in assoluto piuutilizzati, ma anche piu difficili da implementare in VHDL. Infatti, tecnica-mente una RAM si puo rappresentare come un insieme di latch, con moltisegnali di handshaking in fase di gestione. Di fatto, si consiglia vivamentedi fare riferimento alla documentazione della propria scheda e sintetizzatoreper verificare (qualora sia prevista...) l’eventuale presenza nelle librerie disistema di un blocco RAM gia realizzato ed utilizzare quel componente.

75

Page 77: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

6.3.5 ROM

La Read–Only Memory e un altro componente molto utilizzato, specieper le LUT (vedi Cap. 8). Rispetto alle RAM, e molto meno efficiente,ma piu semplice da implementare in VHDL: in generale, a struttura casecon indirizzo e dato, il sintetizzatore fa corrispondere un componente ROM.Attenzione: se in una scheda non sono disponibili ROM esterne alla FPGA,l’implementazione delle celle di memoria avverra on–board sulla scheda, congrande occupazione di slice (a meno che, ovviamente, i dati da salvare nonsiano pochi...). Tratteremo meglio in seguito questi aspetti.

6.4 Un esempio: contatore sincrono modulo–

m programmabile

Un contatore modulo–m e un componente hardware che, come dice ilnome stesso, effettua un conteggio, partendo da 0 e terminando quando rag-giunge il valore m − 1, per iniziare nuovamente da 0. Per esempio, un con-tatore modulo–3 effettuera i seguenti passaggi: 0, 1, 2, 0, 1,... Nel nostroesempio, supporremo che m venga espresso a 4 bit: pertanto, il range divalori ammissibili per m variera fra 2 (ovvero "0010") e 15 (ovvero "1111").Nel seguente codice, si potrebbe anche introdurre una notazione mai vistain precedenza, ma utile nel momento in cui si utilizzano i tipi IEEE 1164.Possiamo inserire stringhe esadecimali aggiungendo un prefisso X alla stringadi bit. Ogni carattere esadecimale rappresenta 4 bit: pertanto, il range dim puo essere espresso tra X"2" e X"F". Nel nostro caso, dovendo trattarequantita aritmetiche senza segno, sfrutteremo invece i tipi di dato unsigned

dello standard IEEE 1664. La struttura generale ricalca quella di Fig. 6.3.

6.4.1 Prima soluzione

Vediamo una prima soluzione:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity contm is

Port ( clk : in STD_LOGIC;

reset : in STD_LOGIC;

76

Page 78: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

m : in STD_LOGIC_VECTOR (3 downto 0);

q : out STD_LOGIC_VECTOR (3 downto 0));

end contm;

architecture Behavioral of contm is

signal r_reg : unsigned(3 downto 0);

signal r_next : unsigned(3 downto 0);

begin

-- state-register

process(clk, reset)

begin

if reset=’0’ then

r_reg <= (others => ’0’);

elsif rising_edge(clk) then

r_reg <= r_next;

end if;

end process;

-- next-state logic

r_next <= (others => ’0’) when r_reg=(unsigned(m)-1) else

r_reg + 1;

-- output logic

q <= std_logic_vector(r_reg);

end Behavioral;

La sintesi di questa soluzione in moduli hw di una FPGA Xilinx e presentein Fig. 6.7.

6.4.2 Seconda soluzione

Notiamo che c’e un’opportunita di ottimizzazione attraverso sharing.Infatti, la seguente operazione:

r_reg=(unsigned(m)-1)

richiede l’utilizzo di un decrementatore. Sela riscriviamo come:

r_reg+1=unsigned(m)

77

Page 79: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 6.7: Sintesi della prima soluzione proposta per il contatore modulo–m

potremmo pensare di utilizzare il sommatore per il calcolo di r_next ancheper la condizione del when, eliminando cosı un sottrattore. Possiamo scrivere,quindi, il precedente codice anche nel seguente modo, con l’aggiunta di unterzo segnale “di appoggio”:

architecture Behavioral of contm is

signal r_reg : unsigned(3 downto 0);

signal r_next : unsigned(3 downto 0);

signal r_inc : unsigned(3 downto 0);

begin

-- state-register

process(clk, reset)

begin

if reset=’0’ then

r_reg <= (others => ’0’);

elsif rising_edge(clk) then

r_reg <= r_next;

end if;

end process;

-- next-state logic

r_inc <= r_reg + 1;

r_next <= (others => ’0’) when r_inc=(unsigned(m)) else

r_inc;

-- output logic

q <= std_logic_vector(r_reg);

78

Page 80: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

end Behavioral;

Anche dallo schema di sintesi RTL di Fig. 6.8 appare subito una maggioresemplicita, con l’assenza del sotrattore.

Figura 6.8: Sintesi della seconda soluzione ottimizzata per il contatoremodulo–m

6.5 Analisi temporale di circuiti sincroni

Nel momento in cui sintetizziamo un circuito, sia esso combinatorio osequenziale, sincrono o asincrono, in output otteniamo alcune informazionimolto importanti. Innanzitutto, la piu importante e se il circuito e sintetizz-abile o meno: per quanto possa sembrare banale, nel progetto di componentimolto complessi potrebbe esserci sfuggita una struttura non sintetizzabile, o,magari in qualche tentativo di sharing, potremmo aver creato qualche corto–circuito o conflitto nei collegamenti. Altre informazioni sono l’occupazionetotale di porte logiche e le caratteristiche temporali dell’oggetto realizzato:un buon progetto non deve occupare piu slice di quante non siano effettiva-mente necessarie, e (per circuiti sincroni) deve avere una frequenza massimadi funzionamento quanto piu possibile elevata. Concentriamoci sui circuitisincroni.

Per quanto riguarda quest’ultimo aspetto, e necessaria qualche ulteri-ore precisazione preliminare. Nel momento in cui progettiamo un sistemahw complesso, al fine di incrementarne le prestazioni, possiamo strutturarlosostanzialmente in due modi:

79

Page 81: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• struttura parallela;

• struttura pipeline.

In generale, una struttura parallela e in grado di elaborare contempo-raneamente molti input contemporaneamente, fornendo in uscita gli output.Piu le elaborazioni sui dati sono indipendenti fra loro, piu risulta efficientetale strategia. In uscita si ha un circuito che occupa tendenzialmente molteslide (a causa delle molte strutture di calcolo) e ha una frequenza di funzion-amento non elevatissima a causa della necessaria sincronizzazione fra le variecomponenti. Tale struttura e anche caratterizzata da una latenza (ovvero,il numero di cicli di clock intercorsi fra l’arrivo dell’input e la generazionedel corrispondente output) contenuta e da un throughput (numero di outputvalidi a fronte del numero di cicli di clock intercorsi) variabile a seconda delproblema.

Una struttura pipeline prevede l’elaborazione di un solo input a ciclo diclock, e l’elaborazione successiva di esso su molti stage. L’occupazione totalee di solito piu bassa o in linea con un circuito parallelo, ma ha una frequenzadi clock consentita piu elevata grazie alla sincronizzazione offerta, di fatto,dal clock globale. La latenza iniziale e molto alta (di solito, molto piu alta diuna struttura parallela), mentre per il thoroughput bisogna distinguere duecasi:

• a regime, di fronte ad una frequenza di arrivo degli input di circa uningresso valido ogni ciclo di clock, il thorughput e pari a 1 (efficienzamassima);

• se la frequenza di un nuovo ingresso valido e bassa, la pipeline non eefficiente, e ha un throughput bassissimo.

Quando scegliere una struttura piuttosto che un’altra? Dipende dal prob-lema. Se, a regime, abbiamo un ingresso ogni ciclo di clock e le elaborazionida eseguire sono complesse (e richiedono alcuni cicli di clock) e consigliabilela struttura pipeline.

Approfondiamo, pero, alcuni aspetti temporali per i circuiti sincroni.

6.5.1 Massima frequenza di clock

In Fig. 6.9, viene proposta l’analisi temporale generica per il circuitosequenziale proposto in Fig. 6.3. Oltre ai classici vincoli dovuti al FF (giapresentati nel paragrafo 6.1.2), si aggiungono Tnextmin

e Tnextmax , che rapp-resentano i ritardi di propagazione nello schema per le variazioni dello stato

80

Page 82: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

successivo, generate dall’apposito circuito. A questo punto, al fine di evitareviolazioni del setup time, e immediato verificare che il periodo minimo perun ciclo di clock T ∗

clk e dato dalla seguente formula:

T ∗clk = Tcq + Tnextmax + Tsetup (6.1)

Ovviamente, la frequenza massima di funzionamento e:

f ∗clk =

1

Tcq + Tnextmax + Tsetup(6.2)

Figura 6.9: Analisi temporale di un circuito sequenziale sincrono

6.5.2 Altre informazioni

Oltre alla frequenza massima di funzionamento (di gran lunga la piuimportante), un sintetizzatore e in grado di fornire altre informazioni, utilisoprattutto per l’interfacciamento tra dispositivi all’interno di progetti digrandi dimensioni:

• quanto tempo prima, rispetto al fronte di clock, deve essere stabilel’ingresso al nostro sistema;

81

Page 83: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• quanto tempo dopo, rispetto al fronte di clock, avremo a disposizionel’output desiderato;

• l’eventuale ritardo di propagazione dovuto alla presenza di logica com-binatoria all’interno di unn circuito sequenziale (soluzione raramenteutilizzata).

6.5.3 Output del sintetizzatore Xilinx

Premesso che il sintetizzatore messo a disposizione da Xilinx non e ilmigliore disponibile su mercato, vediamo come leggere un output del sintetiz-zatore. Recuperando l’esempio del contatore del paragrafo 6.4, andiamo, peresempio, ad osservare l’occupazione di porte logiche su una Xilinx Virtex–4:

Macro Statistics

# Adders/Subtractors : 1

4-bit adder : 1

# Registers : 4

Flip-Flops : 4

# Comparators : 1

4-bit comparator equal : 1

Optimizing...

Device utilization summary:

---------------------------

Selected Device : 4vsx25ff668-12

Number of Slices: 6 out of 10240 0%

Number of Slice Flip Flops: 4 out of 20480 0%

Number of 4 input LUTs: 13 out of 20480 0%

Number of IOBs: 10 out of 320 3%

Number of GCLKs: 1 out of 32 3%

Il primo blocco di risultati e quello fornito dal sintetizzatore senza ot-timizzazioni: in pratica, e una traduzione in forma testuale dello schemaRTL di Fig. 6.8. A questo punto, dopo ottimizzazioni varie (per esempio,sul routing e di tipo sharing), troviamo il riassunto dell’occupazione. Per laFPGA selezionata (identificata dal codice 4vsx25ff668-12), abbiamo un’occu-pazione totale di 6 slice di logica, 4 flip–flop, utilizziamo 13 LUT (molte delle

82

Page 84: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

quali per evitare l’utilizzo del sommatore, lento, sostituendolo con locazionidi ROM, ad accesso pressoche istantaneo), 10 porti di I/O (abbiamo 4 bitper m, 4 per l’output, il clock e il segnale di reset) e un segnale di clock (chee stato riconosciuto e sintetizzato come tale). Per quanto riguarda l’analisitemporale abbiamo:

Timing Summary:

---------------

Speed Grade: -12

Minimum period: 2.259ns (Maximum Frequency: 442.684MHz)

Minimum input arrival time before clock: 2.760ns

Maximum output required time after clock: 4.013ns

Maximum combinational path delay: No path found

Ritroviamo le voci presentate in precedenza. Attenzione: si noti comeil tempo di arrivo minimo per un segnale di input prima del fronte di clockdev’essere 2.76 ns, ovvero addirittura superiore al periodo minimo del clock.Com’e possibile? Che senso ha? Il problema nasce dal fatto che il peri-odo minimo di clock e calcolato considerando nulli i tempi di routing dalpad di ingresso/uscita al porto di I/O del nostro componente. Se, infatti,approfondiamo l’analisi, per esempio, della seconda voce, si ha:

===============================================================

Timing constraint: Default OFFSET IN BEFORE for Clock ’clk’

Total number of paths / destination ports: 16 / 4

---------------------------------------------------------------

Offset: 2.760ns (Levels of Logic = 4)

Source: m<2> (PAD)

Destination: r_reg_2 (FF)

Destination Clock: clk rising

Data Path: m<2> to r_reg_2

Gate Net

Cell:in->out fanout Delay Delay

----------------------------------------

IBUF:I->O 3 0.754 0.581

LUT4:I0->O 1 0.147 0.529

LUT4_L:I1->LO 1 0.147 0.157

LUT4:I2->O 1 0.147 0.000

83

Page 85: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

FDC:D 0.297

----------------------------------------

Total 2.760ns

(1.492ns logic, 1.268ns route)

(54.1% logic, 45.9% route)

In poche parole, se eliminiamo i ritardi dovuti al routing e consideriamoi soli delay dovuti alla logica, abbia 1.492 ns, che, pertanto, e inferiore allimite del clock. Per diminuire i ritardi dovuti alla logica (che, in caso dicomponente unico sulla FPGA, possono essere molto fastidiosi), di solito siusano i file di constraint per il sintetizzatore, che forzano l’implementazionein particolari zone della FPGA (magari, in prossimita dei pad di I/O).

Cosa succede se aumentiamo il numero di bit? Magari passando da 4 bita 16 bit?

Device utilization summary:

---------------------------

Selected Device : 4vsx25ff668-12

Number of Slices: 21 out of 10240 0%

Number of Slice Flip Flops: 16 out of 20480 0%

Number of 4 input LUTs: 41 out of 20480 0%

Number of IOBs: 34 out of 320 10%

Number of GCLKs: 1 out of 32 3%

Timing Summary:

---------------

Speed Grade: -12

Minimum period: 4.340ns (Maximum Frequency: 230.420MHz)

Minimum input arrival time before clock: 3.410ns

Maximum output required time after clock: 3.935ns

Maximum combinational path delay: No path found

Vediamo come, complicandosi la logica, a fronte di un aumento piuttostocontenuto dell’occupazione hardware, diminuisca di un fattore 2 la frequenzamassima di funzionamento del nostro device.

84

Page 86: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

6.6 Utilizzo di variabili in circuiti sequenziali

Fino ad ora abbiamo sempre utilizzato i segnali, anche come elementodi memoria. In generale, questa e la tecnica piu sicura e piu usata perl’implementazione di circuiti sequenziali. Tuttavia, non e errato, specie instrutture semplici, utilizzare anche le variabili all’interno dei processi. Datala natura molto locale delle variabili, e conveniente utilizzarle soprattuttocome variabili di “appoggio”. Vediamo la differenza fra segnali e variabiliattraverso un semplice esempio. Ecco il codice:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity varsign is

Port ( a : in STD_LOGIC;

b : in STD_LOGIC;

clk : in STD_LOGIC;

q1 : out STD_LOGIC;

q2 : out STD_LOGIC;

q3 : out STD_LOGIC);

end varsign;

architecture Behavioral of varsign is

signal tmp_sig1 : std_logic;

begin

-- prima soluzione

process(clk)

begin

if rising_edge(clk) then

tmp_sig1 <= a and b;

q1 <= tmp_sig1;

end if;

end process;

-- seconda soluzione

process(clk)

variable tmp_sig2 : std_logic;

begin

if rising_edge(clk) then

85

Page 87: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

tmp_sig2 := a and b;

q2 <= tmp_sig2;

end if;

end process;

-- terza soluzione

process(clk)

variable tmp_sig3 : std_logic;

begin

if rising_edge(clk) then

q3 <= tmp_sig3;

tmp_sig3 := a and b;

end if;

end process;

end Behavioral;

Questo modulo presenta tre uscite, corrispondenti alla stessa elaborazionesul segnale (a · b) ma eseguita in 3 modi diversi. Nel primo caso, utilizziamoil classico segnale per l’aggiornamento; nel secondo, utilizziamo una variabiledi appoggio (in modo da non creare ritardi nella propagazione del risultato);nel terzo, la variabile viene aggiornata dopo l’assegnazione al segnale. Difatto, il primo e il terzo metodo sono equivalenti (come mostrato anche dallasimulaizone temporale comportamentale di Fig. 6.10), e, di fatto, la variabilein questo caso e utilizzata in maniera non utile. Nel secondo caso, la variabileviene istantaneamente aggiornata, quindi otterremo in output su q2 il risul-tato di a·b con un ciclo di clock di anticipo (Fig. 6.10). Questo e, ovviamente,vantaggioso, ma altrettanto pericoloso: in circuiti molto complessi, potrebbenon essere possibile tale aggiornamento istantaneo, e avremmo risultati nonvoluti.

Figura 6.10: Simulazione temporale comportamentale per evidenziare ledifferenze fra segnali e variabili

86

Page 88: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

6.6.1 Progettazione del contatore modulo–m utilizzan-do variabili

Modifichiamo l’architettura dell’esempio del paragrafo 6.4 in modo dautilizzare variabili.

architecture Behavioral of contm is

signal r_reg : unsigned(3 downto 0);

begin

process(clk,reset)

variable q_tmp : unsigned(3 downto 0);

begin

if reset=’1’ then

r_reg <= (others => ’0’);

elsif rising_edge(clk) then

q_tmp := r_reg + 1;

if(q_tmp = unsigned(m)) then

r_reg <= (others => ’0’);

else

r_reg <= q_tmp;

end if;

end if;

end process;

q <= std_logic_vector(r_reg);

end Behavioral;

Il comportamento e identico a quanto visto in precedenza. Ma l’utilizzo divariabili ha giovato anche ai risultati della sintesi? Vediamo le caratteristichedi occupazione e temporali:

Device utilization summary:

---------------------------

Selected Device : 4vsx25ff668-12

Number of Slices: 6 out of 10240 0%

Number of Slice Flip Flops: 4 out of 20480 0%

Number of 4 input LUTs: 11 out of 20480 0%

87

Page 89: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Number of IOBs: 10 out of 320 3%

Number of GCLKs: 1 out of 32 3%

Timing Summary:

---------------

Speed Grade: -12

Minimum period: 2.445ns (Maximum Frequency: 408.956MHz)

Minimum input arrival time before clock: 3.048ns

Maximum output required time after clock: 3.971ns

Maximum combinational path delay: No path found

Utilizziamo un paio di LUT in meno, ma paghiamo questa leggera sem-plificazione con un maggiore ritardo nella logica di connessione interna, e,quindi, con una frequenza di picco leggermente inferiore alla precedente. Taleeffetto e amplificato se passiamo a 16 bit:

Timing Summary:

---------------

Speed Grade: -12

Minimum period: 6.019ns (Maximum Frequency: 166.150MHz)

Minimum input arrival time before clock: 5.102ns

Maximum output required time after clock: 3.933ns

Maximum combinational path delay: No path found

88

Page 90: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 7

Macchine a stati finiti

7.1 Introduzione

Una macchina a stati finiti (finite state machine, FSM ), come dice ilnome stesso, e una macchina caratterizzata da un certo numero di possibilistati interni. A contrario di quanto visto nel precedente capitolo per i circuitisequenziali piu elementari (i Regular Sequential Circuits analizzati in alcuniesempi nel precedente capitolo), la logica di controllo per lo stato interno nelcaso di FSM e piu complesso, tanto da essere considerato randomico.

Una FSM e costituita da 5 entita:

• stati;

• segnali di input;

• segnali di output;

• funzione per il calcolo dello stato successivo (next–state function);

• funzione per il calcolo dell’output (output function).

Lo stato caratterizza per intero una FSM. Il funzionamento e definitodalle transizioni da uno stato al successivo: se tali passaggi sono gestiti daun segnale di clock, si parla di FSM sincrone, ed e il caso di gran lunga piucomune. La output function puo essere funzione semplicemente dello stato,oppure anche degli ingressi al sistema: nel primo caso si parla di macchinadi Moore, nel secondo di macchina di Mealy. Se la FSM svolge calcoli nonbanali sugli input, piu precisamente si parla di FSM con datapath o FSMD.Per semplicita, nel seguito confonderemo FSM e FSMD. Di solito, una FSMcomplessa e una FSMD con uscite di tipo Moore e Mealy.

89

Page 91: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

7.2 Rappresentazione di una FSM

Il progetto di una macchina a stati finiti si basa su una descrizionegrafica astratta, che utilizzi una rappresentazione simbolica degli stati e in-dichi sotto quali condizioni vengono posti in uscita determinati output. Lerappresentazioni piu comuni sono gli state diagram o pallogrammi e gli ASM.

7.2.1 Pallogrammi

Un pallogramma e caratterizzato da stati, indicati con dei bubbles o nodi,e degli archi di transizione. All’interno di un nodo, vi puo essere un’uscitacaratterizzante quel determinato stato: in tal caso si parla di uscite di Moore.Se un arco non contiene una condizione, la transizione allo stato successivoavviene senza incertezze al colpo di clock successivo; viceversa, se un arcocontiene una condizione, la transizione avverra solo quando essa e verificata.Se, su un arco, ad una condizione e associata anche un’uscita, si parla diuscite di Mealy. Un esempio di nodo e archi e riportato in Fig. 7.1.

Figura 7.1: Notazione per un nodo di un pallogramma

Analizziamo un breve esempio. Si consideri la FSM di Fig. 7.2, in cuiviene presentato un ipotetico (e semplificato) schema per un controller dimemoria. Al reset, il sistema si pone in idle, e vi rimane fino a quandoil segnale mem vale 0 (condizione mem’ ). Quando mem vale 1, dobbiamocontrollare anche il valore di rw : se vale 0, abbiamo un’uscita di Mealy we mepari a 1, e passiamo nello stato write; se vale 1, abbiamo la transizione allostato read1. Se ci troviamo in write, avremo un’uscita di Moore we pari a1, e al colpo di clock successivo torneremo in idle. Se ci troviamo in read1,

90

Page 92: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

avremo un output di Moore oe pari a 1, quindi dovremo controllare burst, ecosı via in maniera analoga.

7.2.2 ASM

Spesso, sono piu utilizzati dei diagrammi aventi molto in comune cooipallogrammi, ma talvolta di piu semplice interpretazione: gli AlgorithmicState Machine, o, piu semplicemente, ASM. Gli ASM sono anche piu semplicida tradurre in VHDL, ed esistono molti generatori di codice automatici.Inoltre, con gli ASM e facile descrivere anche le FSMD, piu complesse dadescrivere con pallogrammi. Vediamo quali sono le strutture elementari.

Stato

Uno stato e rappresentato da un rettangolo simile a quello mostrato inFig. 7.3. Analizziamo brevemente i simboli che lo caratterizzano. La stringadi caratteri sulla destra (in questo caso, st) rappresenta il nome associatoallo stato dall’utente: e un nome simbolico e non influisce sul funzionamen-to generale del sistema. La stringa di bit in alto a destra (in questo caso,01) rappresenta il codice identificativo dello stato, e sara poi il codice che lanext–state logic dovra opportunamente generare a runtime. E’ opportuno,quindi, generarla con una certa logica: per facilitare la sintesi hw, puo essereuna buona idea cercare (per quanto possibile) di mantenere piccola la dis-tanza di Hamming1 fra i codici degli stati. In alto a sinistra, il rombo nerosemplicemente indica che lo stato mostrato e lo stato attivato al reset.

Condizione

Una condizione e rappresentata da un rombo, all’interno del quale epresente il segnale da controllare. A seconda che tale segnale valga 0 o 1,lo stato successivo puo variare o si puo avere una diversa uscita di Mealy(analizzeremo il tutto a breve). Un esempio e mostrato in Fig. 7.4, incui controlliamo il valore di IN. Per implementare condizioni piu complesse,semplicemente di rappresentano una cascata di controlli.

Macchine di Moore

Per rappresentare le uscite in una macchina avente solo output di Moore,semplicemente scriviamo all’interno degli stati il valore dell’uscita che vogliamo

1Si ricorda che per distanza di Hamming si intende il numero di bit per i quali dif-feriscono due stringhe binarie. Ad esempio, 001 e 010 hanno distanza 2, 001 e 011 hannodistanza 1 (differiscono per un solo bit, il secondo per la precisione.

91

Page 93: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 7.2: Esempio di pallogramma per un semplificato controller per unamemoria

92

Page 94: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 7.3: Simbolo ASM di uno stato

Figura 7.4: Simbolo ASM per una condizione

93

Page 95: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

forzare a 1. Facciamo un semplice esempio. Supponiamo di voler generare laFSM per un contatore modulo–4 capace di contare in avanti e indietro. Inparticolare, la direzione di conteggio viene controllata attraverso un segnaleDIR, il quale varia pero solo nello stato iniziale (uscita a 0). In tutto, ilnostro componente avra:

• un ingresso per il clock;

• un ingresso per il reset;

• un ingresso per il segnale DIR;

• un output a 2 bit per il risultato del contatore.

Inoltre, la nostra macchina dovra essere caratterizzata da un certo nu-mero di registri interni, per memorizzare le variabili caratterizzanti lo stato.Un possibile ASM e quello presentato in Fig. 7.5, in cui C0 e C1 rappre-sentano rispettivamente LSB e MSB per l’uscita del contatore. Lo schemacomplessivo del componente generato e mostrato, invece, in Fig. 7.6. Sem-plicemente, si nota come, ad ogni stato, si hanno le uscite che dipendonosolo dallo stato in cui ci si trova. In questo caso, abbiamo 7 stati, quindi ilnumero di registri minimo e dato dalla formula:

numreg = �log2 numstati� = �log2 7)� = 3 (7.1)

Macchine di Mealy

Per le macchine di Mealy si utilizzano le uscite condizionate, mostratein Fig. 7.7. Un’uscita condizionata va posta dopo lo stato per il qualedev’essere generata l’eventuale output di Mealy. La cosa migliore e utilizzareun esempio: modifichiamo lo schema del paragrafo precedente. Sfruttandol’ipotesi che il segnale di controllo DIR vari solo all’istante iniziale, si puoproporre lo schema di Fig. 7.8.

Analizziamo questo ASM. Ad ogni passo, analizziamo il segnale DIR, e,a seconda che esso valga 0 o 1, contiamo in avanti o indietro ponendo inuscita i valori contenuto nelle uscite condizionate. Ad esempio, nello statod avremo come output 11 se stiamo contando in avanti, altrimenti 01 secontiamo all’indietro. Lo stato c non necessita di uscite condizionate, inquanto sia che si conti in avanti sia che si conti al contrario l’uscita e sempre10. In questo caso usiamo un output di Moore.

Notiamo subito un grande vantaggio: utilizziamo 4 stati invece di 7. Intermini di registri, possiamo usarne uno in meno. Cio significa una logica di

94

Page 96: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 7.5: ASM di un contatore avanti/indietro modulo–4

95

Page 97: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 7.6: Schematico per il contatore avanti/indietro modulo–496

Page 98: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 7.7: Blocco ASM per l’uscita condizionata

controllo piu semplice. Tutto cio si paga con uno schema piu complesso daanalizzare e meno immediato da tradurre in codice, nonche con una logicaper gli output piu complessa. Nell’ambito di progetti su grande scala, questofatto puo rappresentare un problema.

7.3 Alcune considerazioni sulle FSM

Come gia in precedenza, nel resto della trattazione, a meno di indicazionicontrarie, ci riferiremo sempre a FSM sincrone, gestite da un clock globale.

7.3.1 Considerazioni temporali

Ricordiamoci che una macchina a stati finiti non e nient’altro che un casoparticolare di cicuito sequenziale. Pertanto, essa sara sincronizzata attraversoun clock, mentre la sua logica sara costituita da flip–flop per la gestione deisegnali. Possiamo, quindi, recuperare la trattazione del paragrafo 6.5.1. Lafrequenza di funzionamento massima consentita si otterra secondo la formula(6.2).

7.3.2 Macchine di Moore e macchine di Mealy: pro e

contro

Vedremo meglio le differenze implementative fra una macchina pura-mente di Moore e una puramente di Mealy (o mista Moore/Mealy) nelprossimo paragrafo. A livello introduttivo si puo dire che:

• una macchina di Moore in generale e caratterizzata da una next–state

97

Page 99: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 7.8: ASM di un contatore avanti/indietro modulo–4 sfruttante outputdi Mealy

98

Page 100: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

logic abbastanza complessa e da una logica di uscita elementare (ad unparticolare stato corrisponde una particolare uscita);

• una macchina di Mealy (o mista) e caratterizzata da una next–statelogic piu snella, ma da una logica di output piu difficile (di fatto, icontrolli che nella macchina di Moore vengono eseguiti nella logica distato qui vengono implementati nella output logic).

Quale delle due soluzioni conviene usare? In generale, una soluzionemista e la piu vantaggiosa. Anche perche spesso si puo trovare qualche sem-plificazione per ottenere una logica meno pesante. Tuttavia, ci sono dei casiin cui una macchina di Moore puo essere una buona soluzione (la logica dicontrollo e comunque meno critica della logica di output). Ancora una volta,non esiste una soluzione universalmente ottima, ma tante buone soluzioni aseconda dei problemi che ci troviamo ad analizzare.

7.4 Descrizione VHDL di una FSM

Veniamo, ora, a come descrivere una FSM in VHDL. Come anticipatoin fase di introduzione, esistono molti software in grado di generare il codiceVHDL a partire dal pallogramma o dall’ASM. E’ importante, comunque,sapere analizzare tali codici e, all’occorrenza, modificarli o scriverli per intero.

Il primo consiglio consiste nel creare un nuovo tipo di dato, in mododa nominare gli stati con lo stesso nome presente nell’ASM, per esempio.Ovvero, nell’architecture, introdurre:

TYPE states is ( state_a,

state_b,

state_d,

state_c );

A questo punto, e sufficiente dichiarare due segnali per la gestione internadegli stati (attuale e futuro):

SIGNAL State,

Next_State: states;

Per quanto riguarda l’entity, nessun problema: gli I/O di una macchina astati sono esattamente gli stessi di un qualsiasi altro componente, e vengonodefiniti in modo classico.

Per quanto riguarda l’architecture, dobbiamo prestare qualche attenzionein piu. Sappiamo che una FSM e composta, in sostanza, da 3 parti:

99

Page 101: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

1. una next–state logic per il calcolo dello stato successivo;

2. un registro di stato;

3. una logica per le uscite.

E’ ovvio pensare, quindi, di creare 3 processi all’interno dell’architettura.Riprendiamo l’esempio della FSM di Fig. 7.8. In questo caso, la logica dicontrollo sullo stato e piuttosto semplice: utilizzando le uscite condizionate,di fatto la transizione avviene sempre tra uno stato e il successivo senzaproblemi. Per il registro di stato possiamo quindi scrivere:

-- Registro di stato

REG: process( Ck, Reset )

begin

if (Reset = ’0’) then

State <= state_a;

elsif rising_edge(Ck) then

State <= Next_State;

end if;

end process;

A questo punto, introduciamo la next–state logic per il calcolo dello statosuccessivo. Utilizzando uscite di Mealy, essa risulta piuttosto snella:

-- Next State Logic

FSM: process( State )

begin

CASE State IS

when state_a =>

Next_State <= state_b;

when state_b =>

Next_State <= state_c;

when state_c =>

Next_State <= state_d;

when state_d =>

Next_State <= state_a;

END case;

end process;

Notiamo come questo processo non sia sensibile al clock: semplicemente,in generale la next–state logic entra in gioco quando si modifica lo stato

100

Page 102: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

attuale nell’apposito registro. A quel punto, si ha una variazione di delsegnale State e quindi si attiva il processo per il next–state, che modifica ilsegnale Next_State. Concludiamo con l’output logic:

-- Output Logic

OUTPUTS: process( State )

begin

-- Valori di default:

C0 <= ’0’;

C1 <= ’0’;

-- Output funzione dell’input e dello stato:

CASE State IS

when state_b =>

if (DIR = ’1’) then

C0 <= ’1’;

else

C0 <= ’1’;

C1 <= ’1’;

end if;

when state_c =>

C1 <= ’1’;

when state_d =>

if (DIR = ’1’) then

C0 <= ’1’;

C1 <= ’1’;

else

C0 <= ’1’;

end if;

when OTHERS =>

C0 <= ’0’;

C1 <= ’0’;

END case;

end process;

Anche in questo caso, per semplificare la logica, possiamo pensare chela sincronizzazione avvenga non attraverso una sensibilita ai fronti di clock,bensı alle variazioni del registro di stato. Settati i valori di default, anal-izziamo lo stato e gli input per generare le uscite corrette. Attenzione: sesupponiamo che il segnale DIR possa variare in maniera asincrona e debbanoseguire tale standard anche gli output, e necessario aggiungere l’input al-la sensitivity list. Se, invece, manteniamo valide le supposizioni fatte nellagenerazione dell’ASM, DIR non dev’essre incluso nella list.

101

Page 103: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Il modulo nel suo complesso sara:

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

ENTITY asm2es IS

PORT( -- Clock & Reset:

Ck: IN std_logic;

Reset: IN std_logic;

-- Inputs:

DIR: IN std_logic;

-- Outputs:

C0: OUT std_logic;

C1: OUT std_logic );

END asm2es;

ARCHITECTURE behave OF asm2es IS

TYPE states is ( state_a,

state_b,

state_d,

state_c );

SIGNAL State,

Next_State: states;

BEGIN

-- Next State Logic

FSM: process( State )

begin

CASE State IS

when state_a =>

Next_State <= state_b;

when state_b =>

Next_State <= state_c;

when state_c =>

Next_State <= state_d;

when state_d =>

Next_State <= state_a;

END case;

end process;

-- Registro di stato

102

Page 104: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

REG: process( Ck, Reset )

begin

if (Reset = ’0’) then

State <= state_a;

elsif rising_edge(Ck) then

State <= Next_State;

end if;

end process;

-- Output Logic

OUTPUTS: process( State )

begin

-- Valori di default:

C0 <= ’0’;

C1 <= ’0’;

-- Output funzione dell’input e dello stato:

CASE State IS

when state_b =>

if (DIR = ’1’) then

C0 <= ’1’;

else

C0 <= ’1’;

C1 <= ’1’;

end if;

when state_c =>

C1 <= ’1’;

when state_d =>

if (DIR = ’1’) then

C0 <= ’1’;

C1 <= ’1’;

else

C0 <= ’1’;

end if;

when OTHERS =>

C0 <= ’0’;

C1 <= ’0’;

END case;

end process;

END behave;

103

Page 105: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Cosa cambia se utilizziamo lo schema di Moore? Riportiamo il codicedell’architecture (l’unica a modificarsi):

ARCHITECTURE behave OF asm1es IS

TYPE states is ( state_0,

state_1i,

state_1a,

state_3a,

state_3i,

state_2i,

state_2a );

SIGNAL State,

Next_State: states;

BEGIN

-- Next State Combinational Logic

FSM: process( State )

begin

CASE State IS

when state_0 =>

if (DIR = ’1’) then

Next_State <= state_1a;

else

Next_State <= state_3i;

end if;

when state_3i =>

Next_State <= state_2i;

when state_2i =>

Next_State <= state_1i;

when state_1i =>

Next_State <= state_0;

when state_1a =>

Next_State <= state_2a;

when state_2a =>

Next_State <= state_3a;

when state_3a =>

Next_State <= state_0;

when OTHERS =>

Next_State <= state_0;

END case;

end process;

104

Page 106: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

-- State Register

REG: process( Ck, Reset )

begin

if (Reset = ’0’) then

State <= state_0;

elsif rising_edge(Ck) then

State <= Next_State;

end if;

end process;

-- Outputs Combinational Logic

OUTPUTS: process( State )

begin

-- Set output defaults:

C0 <= ’0’;

C1 <= ’0’;

-- Set output as function of current state and input:

CASE State IS

when state_3i =>

C0 <= ’1’;

C1 <= ’1’;

when state_2i =>

C1 <= ’1’;

when state_1i =>

C0 <= ’1’;

when state_1a =>

C0 <= ’1’;

when state_2a =>

C1 <= ’1’;

when state_3a =>

C0 <= ’1’;

C1 <= ’1’;

when OTHERS =>

C0 <= ’0’;

C1 <= ’0’;

END case;

end process;

END behave;

105

Page 107: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Notiamo come la output logic sia molto piu snella (a stato corrispondeuscita), mentre la next–state abbia il controllo supplementare sul segnaleDIR. Cio che rende, comunque, questa struttura svantaggiosa (in terminiimplementativi) rispetto all’utilizzo di uscite condizionate e il fatto che ilnumero di stati pressoche raddoppia, costringendo ad un numero elevato dicontrolli.

7.5 Codifica degli stati

Per quanto possa sembrare un problema di poco conto, l’assegnazionedegli stati e una questione tutt’altro che da sottovalutare: l’utilizzo di unatecnica “furba” puo far risparmiare non poche porte logiche. L’assegnazionedegli stati si ripercuote nel codice VHDL nella dichiarazione del tipo states:infatti, il sintetizzatore, ad ognuno nei termini nell’elenco, associa un codicebinario crescente. In pratica, se noi scriviamo:

TYPE states is ( state_a,

state_b,

state_d,

state_c );

abbiamo associato allo stato a il codice 0, a b il codice 1, a d il codice 2 e ac il codice 3. Pertanto, la precedente scrittura e la seguente:

TYPE states is ( state_a,

state_b,

state_c,

state_d );

sono differenti, in quanto, nella seconda, abbiamo invertito i codici per c e d.Supponiamo di considerare una FSM con n stati e r registri da un bit.

Le tecniche principali per la cosiddetta codifica degli stati sono:

• Assegnazione sequenziale binaria: in pratica, a stati contigui associ-amo codici a distanza 1 decimale. In parole povere, la codifica avvienein ordine 0, 1, 2, ..., n − 1. Il numero di registri necessari e dato dar = �log2 n�. Il problema di questa tecnica consiste nelle difficolta, pern elevati, delle transizioni fra stati. Supponiamo n = 8: nel momentoin cui dovremo trasformare il segnale di stato da 111 a 000, per es-empio, dovremo cambiare ben 3 bit. Spesso, questa tecnica non vieneutilizzata;

106

Page 108: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• Codifica a distanza di Hamming minima: stati contigui, per quantopossibile, hanno distanza distanza di Hamming minima, e possibilmenteunitaria. Con 4 stati, in binario cio equivale ad una codifica 00, 01,11, 10, analogamente a quanto fatto nell’esempio di Fig. 7.8. Anche inquesto caso, sono necessari r = �log2 n� registri;

• Codifica One–Hot : ad ogni stato e associata una stringa di n bit, tuttia 0 tranne 1. Ad esempio, con 4 stati, si ha 0001, 0010, 0100, 1000.Quindi, si hanno r = n registri. In questo caso, la next–state logic emolto semplice, e consiste in un semplice shifter (si paga tutto cio perocon la proliferazione dei registri);

• Codifica Almost–One–Hot : e identica alla One–Hot, ma uno stato puoavere codifica pari a una stringa di tutti 0. Quindi, sono necessari r =n−1 registri. La next–state logic diviene leggermente piu complessa, edi fatto non si ha un grande guadagno in termini di registri. Pertanto,e raramente utilizzata.

Abbiamo detto che nella dichiarazione del tipo per gli stati in VHDL adogni nome e associato, in ordine, un numero crescente. E se, per esempio,volessimo utilizzare una codifica One–Hot? La cosa piu semplice e utilizzarevariabili dummy. Riprendiamo l’ASM di Fig. 7.8, e supponiamo di usare unacodifica One–Hot. Una possibile scrittura per il tipo di stato in VHDL e:

TYPE states is ( dummy_0000,

state_a,

state_b,

dummy_0011,

state_c,

dummy_0101,

dummy_0110,

dummy_0111,

state_d,

dummy_1001,

dummy_1010,

dummy_1011,

dummy_1100,

dummy_1101,

dummy_1110,

dummy_1111 );

Le variabili dummy non verranno mai utilizzate nel codice, ma servonosolo come “riempitivo” per il sintetizzatore. Per quanto sia inutile, di fatto,

107

Page 109: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

nel codice precedente l’inserimento delle variabili dalla 1001 in poi, e spessoconsigliabile di inserire comunque tutte le possibilita, anche per facilitare ilsintetizzatore: cosı, avra vita facile a capire che si tratta di una codificaOne–Hot.

108

Page 110: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 8

Look–Up Tables (LUT)

8.1 Che cos’e una LUT?

Per Look–Up Table (LUT) si intende una struttura dati, generalmenteun array, usata per sostituire operazioni di calcolo a runtime con una piusemplice operazione di consultazione (Look–Up, in inglese). Il guadagno divelocita puo essere significativo, poiche recuperare un valore dalla memoria espesso piu veloce che sottoporsi a calcoli con tempi di esecuzione dispendiosi.Un tipico esempio di utilizzo di LUT e l’implementazione hardware di fun-zioni trigonometriche: dato che la valutazione di un seno o coseno puo es-sere molto pesante computazionalmente, si salvano i valori (con la precisionedesiderata) nelle LUT, e a runtime sara sufficiente leggere tali valori.

Supponiamo di voler implementare una generica y = f(x). Se decidiamodi utilizzare le LUT, avremo le seguenti corrispondenze:

• x sara l’indirizzo della locazione di memoria;

• y sara il contenuto di tale locazione.

Il numero di celle totali dipende dalla precisione con cui si vuole definirel’ingresso e calcolare l’uscita, sulla base anche del tipo di ROM (in generale)che abbiamo a disposizione. Facciamo un esempio. Supponiamo di volercalcolare una certa funzione con ingressi a 16 bit e uscite con precisionepari a 16 bit. Supponiamo, inoltre, di avere a disposizione ROM da 16 bit.Il calcolo e piuttosto semplice: necessiteremo di 216 = 65536 locazioni perla memorizzazione. Se abbiamo a disposizione tale quantita di spazio, ilrisultato della funzione sara disponibile in un solo colpo di clock (il temponecessario alla lettura della ROM), a prescindere da quanto complicata lafunzione possa essere.

109

Page 111: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Supponiamo, ora, di aver a disposizione ROM da 8 bit: cio significache per salvare un dato dovremo usufruire di 2 locazioni. Senza contareche servira una logica di gestione dell’inidirizzamento per le ROM. In tuttoci serviranno 2 · 216 = 131072 locazioni, piu altro spazio per la logica dicontrollo.

8.2 Pro e contro

Le LUT hanno l’enorme vantaggio di essere indipendenti dalla comp-lessita della funzione, e offrono sempre una soluzione velocissima anche peroperazioni che necessitano di alta precisione. Il problema e che, spesso, nonvi e abbastanza spazio su una FPGA per ospitare on–board tali LUT. Si puofar ricorso ad una memoria esterna, ma parte del vantaggio viene a perdersi acausa della logica di interfacciamento e del tempo perso per via degli accessiin lettura. Per complesso che sia, un CORDIC (il quale permette di calco-lare funzioni trigonometriche) occupa molto meno spazio delle LUT. Senzacontare che, se si riesce ad usare la pipeline, il throughput a regime e ugualeper LUT e CORDIC.

Per diminuire il numero di LUT necessarie si puo ricorrere ad approssi-mazioni o interpolazioni sui valori salvati, ma si perde in precisione (senzacontare che si complica la logica e il throughput rischia di diminuire). Allora,quando usare le LUT? Innanzitutto, se sappiamo che, per esempio, la nostraFPGA dovra sempre e solo calcolare un coseno, potrebbe essere utile usarele LUT; oppure possono essere usate per salvare dei dati in memoria con altaprecisione (per esempio, per certe operazioni e necessario salvare il valoredel log 2, e si puo utilizzare una LUT); piu in generale, possono essere usatequando l’utilizzo di un componente che esegua la corrispondente operazionediventa troppo dispendioso.

8.3 Codice VHDL per una LUT

Una LUT e facilissima da implementare. Vediamo un esempio sempliceper il calcolo di y = x2, supponendo l’ingresso a 4 bit e l’output a 16 bit:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity LUT1 is

110

Page 112: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Port ( addr : in STD_LOGIC_VECTOR (3 downto 0);

clk : in STD_LOGIC;

ris : out STD_LOGIC_VECTOR (7 downto 0));

end LUT1;

architecture Behavioral of LUT1 is

begin

process(clk)

begin

if rising_edge(clk) then

case addr is

when X"0" => ris <= X"00";

when X"1" => ris <= X"01";

when X"2" => ris <= X"04";

when X"3" => ris <= X"09";

when X"4" => ris <= X"0F";

when X"5" => ris <= X"19";

when X"6" => ris <= X"24";

when X"7" => ris <= X"31";

when X"8" => ris <= X"40";

when X"9" => ris <= X"51";

when X"A" => ris <= X"64";

when X"B" => ris <= X"79";

when X"C" => ris <= X"90";

when X"D" => ris <= X"A9";

when X"E" => ris <= X"C4";

when X"F" => ris <= X"E1";

when others => ris <= (others => ’X’);

end case;

end if;

end process;

end Behavioral;

In pratica, scriviamo un unico ciclo select...case per l’indirizzamentoin memoria. Come notiamo dallo schema di Fig. 8.1, il sintetizzatore ri-conosce la struttura a Look–Up Tables, aggiungendo un FF in uscita persincronizzarci con il clock.

111

Page 113: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 8.1: Schema RTL dell’implementazione attraverso LUT

8.4 Codice per la generazione automatica del

VHDL

Ovviamente, mano a mano che i circuiti da implementare attraverso LUTdiventano piu complessi, appare improponibile la scrittura manuale di tuttele righe di codice necessarie. Pertanto, e utile avere come riferimento uncodice piuttosto generale in C/C++/C#, in grado di adattarsi alle nostreesigenze sia per quanto riguarda la funzione da implementare, ma anche i bitdi precisione di I/O. Quanto segue vuol essere un piccolo esempio–guida:

#include "stdafx.h"

#define bin 4

#define bout 8

#using <mscorlib.dll>

using namespace System;

int funzione(int x)

{

return(x*x);

}

char* toBool(int x, int b)

{

char* ris=new char[b];

for(int j=0;j<b;j++)

ris[j]=’0’;

if(x==0)

return ris;

else if(x==1)

112

Page 114: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

{

ris[b-1]=’1’;

return ris;

}

int i=0;

while(x!=1)

{

int r=x%2;

x=(int)(Math::Floor((double)x/2.0));

ris[b-1-i]=(char)(r+48);

i++;

}

ris[b-1-i]=’1’;

return ris;

}

void main()

{

FILE* fp;

fp=fopen("lut.vhd","w");

//intestazione

fprintf(fp,"library IEEE;\n");

fprintf(fp,"use IEEE.STD_LOGIC_1164.ALL;\n");

fprintf(fp,"use IEEE.STD_LOGIC_ARITH.ALL;\n");

fprintf(fp,"use IEEE.STD_LOGIC_UNSIGNED.ALL;\n\n");

//entity

fprintf(fp,"entity LUT1 is\n");

fprintf(fp,"\tPort ( addr : in _

_ STD_LOGIC_VECTOR (%d downto 0);\n", (bin-1));

fprintf(fp,"\t\tclk : in STD_LOGIC;\n");

fprintf(fp,"\t\tris : out _

_ STD_LOGIC_VECTOR (%d downto 0));\n", (bout-1));

fprintf(fp,"end LUT1;\n\n");

//architecture

fprintf(fp,"architecture Behavioral of LUT1 is\n");

fprintf(fp,"begin\n");

fprintf(fp,"\tprocess(clk)\n");

fprintf(fp,"\tbegin\n");

113

Page 115: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

fprintf(fp,"\t\tif rising_edge(clk) then\n");

fprintf(fp,"\t\t\tcase addr is\n");

for(int i=0;i<Math::Pow(2.0,bin);i++)

{

char* x=toBool(i,bin);

int ris=funzione(i);

char* y=toBool(ris,bout);

fprintf(fp,"\t\t\t\twhen \"");

for(int j=0;j<bin;j++)

fprintf(fp,"%c",x[j]);

fprintf(fp,"\" => ris <= \"");

for(int j=0;j<bout;j++)

fprintf(fp,"%c",y[j]);

fprintf(fp,"\";\n");

}

fprintf(fp,"\t\t\t\twhen others => _

_ ris <= (others => ’X’);\n");

fprintf(fp,"\t\t\tend case;\n");

fprintf(fp,"\t\tend if;\n");

fprintf(fp,"\tend process;\n");

fprintf(fp,"end Behavioral;");

fclose(fp);

}

E’ un codice C++, realizzato in Microsoft Visual Studio .NET 2003.La generalita del codice e sottolineata dal fatto che, se si vogliono variarei bit per l’I/O, e sufficiente modificare le definizioni iniziali, mentre, perla funzione da implementare, bisogna modificare l’apposito metodo C++.Il resto e sostanzialmente interfacciamento con file. Il metodo toBool estato realizzato ad hoc per trovare stringhe di caratteri da stampare su file.Il codice cosı realizzato puo essere direttamente importato nell’ambiente disviluppo della FPGA.

114

Page 116: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 9

Hierarchical Design

9.1 Introduzione

La metodologia Hierarchical Design prevede la divisione di un sistemain sotto–moduli in maniera ricorsiva, in modo tale da poter progettare isotto–moduli in maniera indipendente. Con il termine “ricorsivamente” siintende che, a loro volta, i sotto–moduli possono essere divisi in unita ancorapiu elementari, fino ad arrivare a strutture molto semplici da progettare edutilizzare.

Figura 9.1: Esempio di progetto diviso ricorsivamente in unita elementari

115

Page 117: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Consideriamo l’esempio proposto in Fig. 9.1. Il sistema complesso (unmoltiplilcatore sequenziale, ovvero un dispositivo che calcola il risultato diuna moltiplicazione svolgendo una serie sequenziale di somme, utile quandola FPGA utilizzata sia sprovvista di moltiplicatori) viene inizialmente divisoin control path, ovvero un sistema di controllo, e data path per il calcolo veroe proprio delle somme. Il primo dei due sotto–moduli e, di fatto, una FSM eviene diviso sulla base dello schema proposto in Fig. 6.3. Il data path vieneanch’esso suddiviso in registri per la memorizzazione del dato, unita di retee componenti di routing ed interfacciamento. Le unita funzionali sono, poi,dei semplici sommatori e sotrattori (che permettono di contare il numero disomme ancora necessarie).

9.1.1 Hierarchical Design: pro e contro

La divisione di un progetto molto complesso in tanti sotto–moduli el-ementari porta, di fatto, moltissimi vantaggi: un sistema modulare e piusemplice da progettare (specie se il progetto e in team) e molti ocmpo-nenti possono poi essere riutilizzati in lavori successivi. Molto spesso, leaziende di progettazione hardware creano delle proprie librerie di componen-ti, progettati e migliorati nel corso degli anni. Ogni componente e dettoIP–core.

Progettare un sotto–modulo elementare e vantaggioso sia per chi proget-ta, il quale puo concentrarsi sugli aspetti critici dell’unita ottenendo un codicemigliore, sia per il sintetizzatore: e facile mostrare come l’ottimizzazione di unsintetizzatore sia piu efficace su sistemi semplici rispetto a moduli complessi.

Sembrerebbe non esistano difetti in un tale approccio. L’unico grandeproblema di tale approccio e il fatto che l’interfacciamento tra i vari modulipuo divenire pesante: bisogna, quindi, stare attenti a non esagerare con lamodularita. In aiuto, spesso, al posto del codice VHDL possono essere us-ati gli schematici: realizziamo i componenti elementari in VHDL, creiamo isimboli circuitali, e utilizziamo schematics per le interconnessioni. Un appos-ito compilatore provvedera all’istanziazione e alla sintesi del corrispondentecodice.

9.1.2 Costrutti VHDL per il Hierarchical Design

In questo capitolo analizzeremo i principali costrutti VHDL per il Hier-archical Design. Come detto, in casi di interconnessione semplice, puo esserefurbo anche utilizzare gli schematici. I principali costrutti (che abbiamopresentato in maniera approssimativa nel Cap. 2) sono:

116

Page 118: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• Component;

• Generic;

• Configuration;

• Library;

• Package;

• Subprogram.

9.2 Component

Come detto, la metodologia Hierarchical Design si basa sulla creazionedi unita elementari, da includere in dispositivi piu complessi. Tale inclusioneavviene attraverso l’utilizzo del costrutto component. La sintassi generale e:

component nome_component

generic (

{dichiarazioni}

...

);

port (

{porti di I/O}

);

end component;

Per quanto riguarda la parte generic, approfondiremo il discorso nelprossimo paragrafo. Vediamo come passare da una generica entity ad uncomponente. Si consideri la seguente entity:

ENTITY asm1es IS

PORT( Ck: IN std_logic;

Reset: IN std_logic;

DIR: IN std_logic;

C0: OUT std_logic;

C1: OUT std_logic );

END asm1es;

che e la struttura proposta per la FSM di Fig. 7.8. Un componente puoessere dichiarato nel seguente modo:

117

Page 119: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

COMPONENT asm1es

PORT( Ck: IN std_logic;

Reset: IN std_logic;

DIR: IN std_logic;

C0: OUT std_logic;

C1: OUT std_logic );

END COMPONENT;

Se all’interno di un modulo VHDL complesso vogliamo utilizzare un com-ponente, dobbiamo dichiararlo nella sezione dichiarativa di una architettura.Una volta dichiarato, il componente va istanziato, ovvero dobbiamo dire alsintetizzatore come pensiamo di connettere i porti del componente ai seg-nali o porti del nostro dispositivo. Un’istanziazione generica ha la seguentesintassi:

etichetta : nome_component

generic map (

{associazioni}

)

port map (

{associazioni}

);

Le associazioni possono essere effettuate in modo esplicito o implicito.Nel primo caso, ad ogni segnale associamo manualmente un porto del nostrocomponente, e la sintassi e del tipo:

porto => segnale

Nel secondo caso, scriviamo semplicemente l’elenco dei segnali da asso-ciare, e il collegamento e fatto sull’ordine di dichiarazione nella entity e sullabase dell’elenco fornito dal programmatore. Una dichiarazione implicita esempre sconsigliabile, perche rende anche poco chiaro il codice. Supponen-do, quindi, di usare una associazione esplicita, vediamo l’istanziazione perun componente del tipo FSM visto in precedenza:

ARCHITECTURE behavior OF tfsm1_vhd IS

-- Dichiarazione

COMPONENT asm1es

PORT(

Ck : IN std_logic;

118

Page 120: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Reset : IN std_logic;

DIR : IN std_logic;

C0 : OUT std_logic;

C1 : OUT std_logic

);

END COMPONENT;

--Inputs

SIGNAL Clk : std_logic := ’0’;

SIGNAL Res : std_logic := ’0’;

SIGNAL D : std_logic := ’0’;

--Outputs

SIGNAL Tot : std_logic_vector(1 downto 0);

BEGIN

-- Instanziazione

dut: asm1es PORT MAP(

Ck => Clk,

Reset => Res,

DIR => D,

C0 => Tot(0),

C1 => Tot(1)

);

...

END;

9.3 Generic

Il costrutto generic e il metodo per creare e passare un’informazionegenerica ad una entita e componente. Sostanzialmente, e un parametro chepermette di creare un componente molto generale. Supponiamo, ad esempio,di voler scrivere il codice per un registro a W bit, ma senza precisare a prioriil valore di W . La sua entita potrebbe essere:

ENTITY reg IS

GENERIC ( W: natural );

PORT ( Clk: IN std_logic;

Reset: IN std_logic;

119

Page 121: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

D: IN std_logic_vector(W-1 downto 0);

Q: OUT std_logic_vector(W-1 downto 0) );

END reg;

A questo punto, il modulo cosı creato non puo piu essere utilizzato inmaniera indipendente, ma dovra essere sempre istanziato. Per esempio,generiamo due istanze di registri, uno a 4 e il secondo a 16 bit:

ARCHITECTURE behavior OF tfsm1_vhd IS

-- Dichiarazione

COMPONENT reg

GENERIC ( W: natural );

PORT ( Clk: IN std_logic;

Reset: IN std_logic;

D: IN std_logic_vector(W-1 downto 0);

Q: OUT std_logic_vector(W-1 downto 0) );

END COMPONENT;

--Inputs

SIGNAL Clk : std_logic := ’0’;

SIGNAL Reset : std_logic := ’0’;

SIGNAL D4 : std_logic_vector(3 downto 0) := X"0";

SIGNAL D16 : std_logic_vector(15 downto 0) := X"0000";

--Outputs

SIGNAL Q4 : std_logic_vector(3 downto 0);

SIGNAL Q16 : std_logic_vector(15 downto 0);

BEGIN

-- Instanziazione 1

dut4: reg

GENERIC MAP ( W => 4 )

PORT MAP(

Clk => Clk,

Reset => Reset,

D => D4,

Q => Q4

);

-- Instanziazione 2

120

Page 122: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

dut16: reg

GENERIC MAP ( W => 16 )

PORT MAP(

Clk => Clk,

Reset => Reset,

D => D16,

Q => Q16

);

...

END;

9.4 Configuration

Talvolta, e possibile associare piu architetture ad una stessa entita. Pren-diamo il caso della FSM progettata nel paragrafo 7.2.2: abbiamo propostoun’architettura basata su una macchina con output di Moore e una mistaMoore/Mealy, ma la entity era uguale. Si pensi ancora ad un contatore:potremmo realizzare un’architettura per un contatore in avanti e una per uncontatore all’indietro. Nel momento in cui vogliamo dichiarare un compo-nente, occorre pero precisare quale configurazione si voglia usare. La sintassie la seguente:

CONFIGURATION nome_conf OF entita IS

FOR nome_architettura

FOR etichetta: nome_componente

USE ENTITY libreria.entita(architettura);

END FOR;

...

END FOR;

END;

Spesso, in maniera piu semplice, puo essere utilizzata una configurazionediretta in fase di dichiarazione e non di istanziazione. Vediamo un esempio.Supponiamo di aver realizzato un contatore, avente un’architettura su perquando conta in avanti, e giu per contare all’indietro. Se volessimo introdurreun componente contatore in avanti e uno all’indietro, potremmo scrivere:

ARCHITECTURE behavior OF tfsm1_vhd IS

-- Dichiarazione

COMPONENT contatore IS

121

Page 123: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

PORT ( Clk: IN std_logic;

Q: OUT std_logic_vector(7 downto 0) );

END COMPONENT;

FOR av: contatore

USE ENTITY work.contatore(su);

FOR ind: contatore

USE ENTITY work.contatore(giu);

...

A questo punto, si procede tranquillamente utilizzando due istanze av eind di cui poi effettueremo l’istanziazione classica. La libreria work e quellain cui vengono inseriti di default i moduli che generiamo all’interno di unsingolo progetto.

9.5 Library

Una libreria e una raccolta di moduli VHDL, siano essi entita, architet-ture, configurazioni, package,... Spesso, in progetti di grandi dimensioni, eutile raccogliere il nostro lavoro in librerie separate, ad esempio, in base alleoperazioni svolte dai moduli e cosı via. Per creare una libreria, una voltarealizzati i moduli che vogliamo aggiungere, semplicemente si usa l’ambientedi sviluppo e si impone la creazione di una nuova libreria, aggiungendo tuttii file che desideriamo.

Per importare una libreria, si usa la parola chiave library. La struttura egerarchica, ovvero una libreria puo contenere altre librerie al proprio interno.In tal caso, si usa la seguente notazione per la parola chiave use:

library libreria;

use libreria.elemento.all;

La struttura e simile al Java, e la keyword all svolge il ruolo del sim-bolo *. Ovviamente, si puo decidere di importare un’intera libreria, o soloalcune parti di essa: in tal caso vanno precisate con la precedente strutturagerarchica. Nel momento in cui si implementa un progetto, viene sempre ecomunque realizzata una libreria work, importata di default.

9.6 Subprogram

Spesso, se le operazioni da svolgere in differenti punti della nostra ar-chitettura su dati dello stesso tipo sono ripetitive ed identiche, puo essere

122

Page 124: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

comodo definire delle function e procedure: l’unica differenza fra le due e cheuna funzione ritorna un valore di un certo tipo, mentre la procedura e void,ovvero senza valore di ritorno.

Ci concentriamo sulle funzioni, perche sono di gran lunga le piu us-ate. Esse vanno incluse nella parte dichiarativa di una architettura (tra ladichiarazione della architettura e il BEGIN, per capirci), e hanno la seguentesintassi:

FUNCTION funz(parametri : tipi) RETURN tipo IS

{dichiarazioni}

BEGIN

{istruzioni sequenziali}

RETURN risultato;

END;

FUNCTION funz(parametri : tipi) RETURN tipo; viene detta dichia-razione della funzione. Attenzione pero: spesso le funzioni utilizzano variabilial proprio interno, e sappiamo che un uso sconsiderato di queste ultime puoportare alla fallita sintesi. Senza contare che anche funzioni troppo complessepossono condurre ad un codice non implementabile in hw.

Vediamo un breve esempio. In questo caso, vogliamo trovare una funzioneche effettui la seguente operazione: y = (a · b) + c. Possiamo scrivere:

FUNCTION oper(a,b,c : std_logic) RETURN std_logic IS

variable tmp : std_logic;

BEGIN

tmp := (a and b) or (not c);

RETURN tmp;

END;

La variabile tmp e palesemente inutile, ma e stata introdotta con scopiesemplificativi.

9.7 Package

Concludiamo questa carrellata con l’ultimo costrutto, il package. Manoa mano che un sistema diviene sempre piu complesso e racchiude in se sem-pre piu componenti, dichiarazioni, costanti, tipi,..., la parte dicharativa diuna architettura puo diventare effettivamente molto pesante, rendendo pocoleggibile il codice. Il package ha proprio lo scopo di racchiudere in se una

123

Page 125: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

collezione di tutti quegli elementi che altrimenti andrebbro a ridurre la leg-gibilita. Un package creato entra a far parte di default della libreria work, opuo essere manualmente incluso in qualsiasi altra libreria user defined.

Un package e composto da 2 parti: una sezione didichiarazioni e unbody. Nella prima vengono incluse tutte le dichiarazioni generali, nel body leimplementazioni delle eventuali funzioni dichiarate nella sezione dichiarativa.Se non e presente alcun sottoprogramma, non e necessaria la scrittura di alcunbody. La sintassi e la seguente:

-- parte dichiarativa (obbligatoria)

PACKAGE nome IS

{dichiarazioni}

END nome;

-- body (solo con soubprograms)

PACKAGE BODY nome IS

{sottoprogrammi}

END nome;

124

Page 126: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 10

Parameterized VHDL

Progetti sempre piu complessi possono necessitare di strutture molto gen-erali, personalizzabili a seconda delle esigenze di progetto. Esistono costruttiche permettono uno sfruttamento molto generale di strutture parametrizz-abili : lo scopo del progettista diventa, in questi casi, realizzare un moduloquanto piu riutilizzabile.

Un primo esempio di VHDL caratterizzato da parametri e stato propostonel paragrafo 9.3: la keyword generic permette di rendere una entita moltogenerale. In questo capitolo, viene proposta una panoramica generale sualcuni costrutti avanzati, i quali pero sono, al solito, armi a doppio taglio:un uso non controllato puo portare a codice illeggibile, non ottimizzato onon sintetizzabile. Il VHDL con parametri e da utilizzare SOLO quandoeffettivamente necessario e vantaggioso.

10.1 Attributi di un array

Un attributo di un segnale (sia esso un singolo valore o un array) for-nisce informazioni sulle caratteristiche del segnale stesso. La sintassi di unattributo e semplice:

(nome_segnale)’(attributo)

I tipi di attributi sono molti, specie per gli array. Essi spaziano dagli even-ti riguardanti il segnale alle caratteristiche del segnale stesso. Elenchiamo ipiu utilizzati:

• ’event: resituisce un boolean true se il segnale ha subito una modificain uno dei suoi valori;

125

Page 127: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• ’left e ’right: rappresentano estremo sinistro e destro del range diun array;

• ’length: restituisce il numero di elementi totali contenuti nell’array;

• ’range: resituisce il range di indici valido per un certo segnale;

• ’reverse_range: restituisce il range di indici, ma in ordine invertito.

Per esempio, consideriamo il seguente segnale:

signal s1 : std_logic_vector(8 to 15);

Alcuni attributi sono:

• s1’left=8, s1’right=15;

• s1’length=8;

• s1’range=8 to 15;

• s1’reverse_range=15 downto 8.

Gli attributi possono essere utili per cicli for (per ottenere i range pergli indici), ma anche in fase di dichiarazione di segnali. Per esempio:

signal s2 : std_logic_vector(s1’reverse_range);

e equivalente a:

signal s2 : std_logic_vector(15 downto 8);

10.2 Array con e senza range

Spesso, si puo pensare di dichiarare un nuovo tipo di dato, per esempioun array, ma di voler porre dei limiti alla liberta implementativa. Nel mo-mento in cui vogliamo dichiarare un nuovo tipo di array, la dichiarazione hail seguente formato:

type nuovo_array is array(15 downto 0)

of std_logic;

126

Page 128: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Di fatto, dichiariamo un nuovo tipo di vettore di bit, il cui indice saraintero positivo (natural), ma che potra avere al massimo un range per ipropri indici che varia fra 0 e 15. Pertanto, si hanno dichiarazioni consentitee non permesse:

-- ok

signal s1 : nuovo_array(15 downto 8);

signal s2 : nuovo_array(13 downto 0);

-- ERRORE!!

signal s3 : nuovo_array(31 downto 0);

Allo stesso modo, possiamo dichiarare array senza range di valore per gliindici. In tal caso, la dichiarazione diventa:

type nuovo_array_unbound is array(natural range <>)

of std_logic;

10.3 Costrutto For...Generate

I costrutti di generazione caratterizzati dalla keyword generate sonogli unici in tutto il VHDL ad essere considerati quali istruzioni concorrenticontenenti al proprio interni istruzioni anch’esse concorrenti.

In particolare, in questo paragrafo analizziamo il for...generate: questocostrutto e molto utile qualora si debbano implementare molte operazioni diegual tipo sui dati in maniera parallela, oppure nel caso in cui, all’interno diun dispositivo gerarchicamente piu importante, si debbano istanziare molticomponenti di un certo tipo. La sintassi e la seguente:

etichetta: FOR indice IN range GENERATE

{istruzioni concorrenti}

END GENERATE;

Facciamo un breve esempio. Supponiamo di voler implementare un de-coder con un ingresso a di dimensioni settabili attraverso parametro generico,e di voler generare tutti i possibili confronti con i possibili codici che taleinputpuo assumere. Il VHDL corrispondente risulta:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.numeric_std.ALL;

127

Page 129: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

entity bin_decoder is

Generic ( W : natural);

Port ( a : in STD_LOGIC_VECTOR (W-1 downto 0);

code : out STD_LOGIC_VECTOR (2**W-1 downto 0));

end bin_decoder;

architecture Behavioral of bin_decoder is

begin

es: for i in 0 to (2**W-1) generate

code(i) <= ’1’ when i=to_integer(unsigned(a)) else

’0’;

end generate;

end Behavioral;

Oppure, un ciclo for...generate puo essere usato, come detto, per l’is-tanziazione di componenti:

es: for i in (W-1) downto 0 generate

dff_array: dff

port map( clk => clk,

d => q_reg(i+1),

q => q_reg(i));

end generate;

10.4 Costrutto if...generate

Analogamente a quanto visto per il for...generate, anche questo costruttoal suo interno contiene istruzioni concorrenti. L’uso e assolutamente analogoa quanto visto per il for...generate. Un esempio puo essere il seguente:

es: for i in (W-1) downto 0 generate

left_gen: if i=1 generate

tmp(i) <= a(i) xor a(0);

end generate;

else_gen: if i>1 generate

tmp(i) <= a(i) xor a(i-1);

end generate;

end generate;

128

Page 130: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

10.5 Array bidimensionali

Un tipo nativo per descrivere una matrice in VHDL non esiste. Si pos-sono, comunque, sfruttare le proprieta di dichiarazione di tipi per generarearray multi–dimensionali. Esistono, di fatto, due tecniche (in verita si puo an-che costruire un array di array, ma e una tecnica usata pochissimo), entrambevalide.

10.5.1 Array bi–dimensionale effettivo

Concentriamoci su array bidimensionali (sopra le due dimensioni diventaeffettivamente un problema difficile da trattare). E’ possibile definire un tipomatrice nel seguente modo:

TYPE matrice IS array(range_1, range_2)

OF tipo_dato;

Ovviamente, possiamo costruire matrici con limiti per il range o senzalimiti. A questo punto l’inizializzazione puo avvenire nei 3 modi seguenti:

-- associazione in base alla posizione

t1 <= ("0000",

"0110",

"0001");

-- inizializzazione per righe

-- si inizializzano tutte a 0110

t2 <= (others => "0110");

-- inizializzazione completa a 0

t3 <= (others=>(others=>’0’));

L’accesso e la scrittura dati puo avvenire attraverso la seguente notazione:

-- input

t1(1,0) <= ’0’;

-- output

e <= t(2,2);

E’ una notazione molto usata per emulare banchi di RAM onboard suFPGA.

129

Page 131: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

10.5.2 Array bi–dimensionale emulato

Un’alternativa e rappresentata dalla possibilita di rappresentare una ma-trice attraverso un vettore. Se la matrice ha m righe e n colonne, la dimen-sione dell’array sara m · n e, se vogliamo leggere o scrivere l’elemento (i, j),e sufficiente usare un indice k sull’intero array pari a:

k = i · n + j (10.1)

A questo punto, e sufficiente introdurre un classico vettore, e una funzioneper il cambio di indice:

constant R : natural := 4;

constant C : natural := 6;

signal s : std_logic_vector(R*C-1 downto 0);

function ix(i,j : natural) return natural is

begin

return(i*R+j);

end ix;

...

a <= s(2,1);

130

Page 132: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 11

Testbench

11.1 Test di dispositivi digitali

Una volta progettato, un dispositivo digitale deve essere testato. I test ele verifiche per sistemi basati su FPGA esistono a diversi livelli del Develop-ment Flow (si veda il paragrafo 1.3 e la Fig. 1.6): si inizia con una simulazionecomportamentale, per verificare di aver scritto un codice coerente; si passaalle varie simulazioni, con informazioni temporali sempre piu realistiche; in-fine, vi e il test post–implementazione, per verificare che la programmazionesia andata a buon fine.

Nonostante le prime simulazioni siano “astratte”, nel senso che vengonoeffettuate utilizzando un simulatore software (che, per perfetto che sia, none comunque una scheda in un ambiente reale...), mentre l’ultima verifica siamolto concreta, le strutture sono molto simili. Ad un Device Under Test(DUT ) viene connesso in input un generatore di stimoli, mentre le uscite delDUT vengono analizzate da un oscilloscopio o un Logic–State–Analyzer (piuin generale, potremmo parlare di un visualizzatore di output). Lo schemagenerale e quello di Fig. 1.5.

In un caso di test fisico di un componente, il generatore di stimoli puoessere, ad esempio, un Word Generator, il quale e un generatore di formed’onda digitali, ovvero di sequenze di ingresso per il DUT. Il Word Generatorfornisce gli input al DUT, e sul visualizzatore (ad esempio, un Logic–State–Analyzer) potremo confrontare le uscite generate con quelle desiderate, econtrollare il corretto funzionamento del dispositivo.

Nel caso di test simulativo, l’input e fornito da un file VHDL particolare,detto testbench module o testbench, il quale, di fatto, svolge il ruolo del gen-eratore di forme d’onda. Il visualizzatore, invece, e un apposito simulatore:i piu comuni sono ModelSim e, in ambiente Xilinx, Xilinx ISE Simulator. In

131

Page 133: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

particolare, i principali tipi di simulazione sono:

• simulazione comportamentale: non tiene conto dei ritardi dovuti alrouting, alla logica,..., ed e utile per controllare la correttezza e lacoerenza del codice scritto;

• simulazione post place–and–route: il sintetizzatore simula il piazzamen-to su FPGA del nostro dispositivo, e simula il comportamento, tenendoconto di tutti i possibili ritardi, glitch,...

11.2 Creazione di un testbench

Come detto, un testbench e un modulo VHDL che ha, pero, alcunepeculiarita:

• non ha una sua entity, in quanto non dev’essere un componente vero eproprio, ma solo un file che fornisce gli ingressi al simulatore;

• contiene sempre un’istanza del DUT;

• ha sempre dei segnali interni in egual numero rispetto ai porti di I/Odel DUT: in tal modo, vengono connessi gli ingressi e le uscite perl’analisi simulativa;

• in generale, contiene un numeor di processi pari al numero di input:infatti, in ogni processo viene fatto variare secondo una cadenza presta-bilita un certo segnale;

• in generale, non contiene processi con sensitivity list, ma processi construtture wait...for ;

• tale modulo non dev’essere sintetizzato, pertanto si possono utilizzareanche costrutti normalmente non sintetizzabili (quali, per esempio,proprio il wait...for).

In quasi tutti gli ambienti di sviluppo hardware, esistono strumenti per lagenerazione automatica di un testbench per un certo dispositivo. Vediamo,ad esempio, come potrebbe essere scritto un testbench per l’esempio di FSMproposto nel paragrafo 7.2.2.

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.all;

132

Page 134: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

USE ieee.numeric_std.ALL;

ENTITY tfsm_vhd IS

END tfsm_vhd;

ARCHITECTURE behavior OF tfsm_vhd IS

COMPONENT asm1es

PORT(

Ck : IN std_logic;

Reset : IN std_logic;

DIR : IN std_logic;

C0 : OUT std_logic;

C1 : OUT std_logic

);

END COMPONENT;

--Inputs

SIGNAL Ck : std_logic := ’0’;

SIGNAL Reset : std_logic := ’0’;

SIGNAL DIR : std_logic := ’0’;

--Outputs

SIGNAL C0 : std_logic;

SIGNAL C1 : std_logic;

BEGIN

-- Instantiate (DUT)

dut: asm1es PORT MAP(

Ck => Ck,

Reset => Reset,

DIR => DIR,

C0 => C0,

C1 => C1

);

res : PROCESS

BEGIN

reset <= ’0’;

wait for 70 ns;

133

Page 135: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

reset <= ’1’;

wait; -- will wait forever

END PROCESS;

clk: process

begin

ck <= ’0’;

wait for 50 ns;

ck <= ’1’;

wait for 50 ns;

end process;

dir_proc: process

begin

dir <= ’0’;

wait for 450 ns;

dir <= ’1’;

wait;

end process;

END;

Dopo aver istanziato il DUT, abbiamo i 3 processi per gestire i 3 ingressi:

• il reset (attivo basso) viene portato inizialmente a 0 per 70 ns, quindiviene forzato a 1 per il resto della simulazione;

• il segnale DIR viene forzato a 0 per i primi 450 ns, quindi viene portatoa 1 per il resto della simulazione;

• il clock dato in ingresso ha un periodo di 100 ns con un duty cycle del50%, quindi ad una frequenza di 10 MHz.

A questo punto, lanciamo la simulazione comportamentale. Il risultatoe mostrato in Fig. 11.1. Il circuito si comporta correttamente. Possiamo,quindi, passare alla simulazione post place–and–route. l’output di tale sim-ulazione e presentato in Fig. 11.2: si puo notare solo una piccola fase diritardo nella stabilizzazione dell’output, ma per il resto nessun problema.

Fin qui tutto bene, ma ci siamo limitati ad un clock di 10 MHz. Seanalizziamo i file di sintesi, i valori temporali ci dicono che la frequenzamassima di funzionamento e circa 750 MHz, quindi ben al di sopra di quellada noi settata. Proviamo ad incrementare la frequenza del clock a 100 MHz,

134

Page 136: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 11.1: Diagramma temporale per una simulazione comportamentale

Figura 11.2: Diagramma temporale per una simulazione post place–and–route

modificando i periodi in 5 ns. il risultato e mostrato in Fig. 11.3: notiamocome in fase di conteggio all’indietro nascano dei fastidiosi glitch dovuti airitardi della logica. Nessun problema, comunque, se leggiamo gli output sulfronte di salita del clock, come mostrato in Fig. 11.4. Questo, comunque, cifa gia capire come i dati del sintetizzatore siano spesso molto indicativi: esiamo ancora totalmente in fase simulativa!

Figura 11.3: Diagramma post place–and–route a 100 MHz

E se sforiamo la frequenza massima? Supponiamo di voler portare ilcircuito a 1 GHz. Che succede nella post place–and–route? Lo si puo vederein Fig. 11.5: una bella marea di glitch e ritardi, con output totalmente errati.Tutto cio a causa dei ritardi di propagazione.

Concludiamo questo capitolo con un utile consiglio pratico. Spesso, quan-do si vogliono far variare molti segnali con frequenze multiple o sotto–multipledella frequenza del clock, o anche solo per maggiore chiarezza, e utile definirea livello di architecture una costante per il periodo (o semiperiodo) del clockstesso. In parole povere, per esempio:

ARCHITECTURE behavior OF tfsm1_vhd IS

135

Page 137: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 11.4: Ingrandimento di un glitch e un fronte di salita a 100 MHz

Figura 11.5: Diagramma post place–and–route a 1 GHz

136

Page 138: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

-- Component Declaration for the Unit Under Test (UUT)

COMPONENT asm1es

PORT(

Ck : IN std_logic;

Reset : IN std_logic;

DIR : IN std_logic;

C0 : OUT std_logic;

C1 : OUT std_logic

);

END COMPONENT;

--Inputs

SIGNAL Ck : std_logic := ’0’;

SIGNAL Reset : std_logic := ’0’;

SIGNAL DIR : std_logic := ’0’;

--Outputs

SIGNAL C0 : std_logic;

SIGNAL C1 : std_logic;

-- Definizione del semiperiodo

CONSTANT T : time := 50 ns;

BEGIN

...

A questo punto, il processo per il clock, ad esempio, diviene:

clk: process

begin

ck <= ’0’;

wait for T;

ck <= ’1’;

wait for T;

end process;

137

Page 139: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Capitolo 12

Esempi finali e guida a XilinxISE Web–Pack

12.1 Introduzione a Xilinx ISE Web Pack 8.2i

Vediamo come e possibile realizzare un nuovo progetto all’interno del-l’ambiente di sviluppo Xilinx. Il software si presenta, in molti aspetti, similea Visual Studio, e di fatto le funzionalita non sono poi cosı diversi (per quantoprofondamente differenti siano gli obiettivi dei due strumenti). In Fig. 12.1viene mostrato l’ambiente di sviluppo, cosı come si presenta al primo lancio.

La prima cosa da creare e un progetto: all’interno di esso andremoa creare i vari dispositivi, scrivendo i moduli VHDL corrispondenti. Unprogetto e caratterizzato da:

• un nome. Attenzione: l’ambiente Xilinx richiede che nell’intero pathdi creazione della cartella per il nuovo progetto NON vi siano spazi;

• un top–level source, ovvero un dispositivo che, nell’ordine gerarchico,costituisca l’oggetto da implementare fisicamente su scheda;

• il tipo di top–level source: VHDL o schematico;

• il tipo di dispositivo di destinazione del nostro progetto:

– categoria della scheda (militare, general purpose,...);

– famiglia (Virtex–4, Spartan–2,...);

– tipo di device della particolare famiglia;

– package (ovvero, caratteristiche di produzione);

138

Page 140: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 12.1: Interfaccia grafica iniziale dell’ISE Web Pack

– speed–grade, ovvero i nanosecondi di ritardo per ogni grado dilogica;

– sintetizzatore;

– simulatore.

Il tutto e riassunto in Fig. 12.2.

Un nuovo progetto puo essere generato cliccando su File – New Project.A questo punto, se vogliamo creare i file per il nostro progetto, andiamo conil mouse nella finestra Sources, clicchiamo con il testo destro e selezioniamoNew Source. A questo punto dobbiamo selezionare il tipo di file da generare.I principali sono:

• VHDL Module: e un modulo VHDL standard. Se lo selezioniamo, unavolta scleto il nome per il modulo, dovremo indicare l’I/O per il nostrodispositivo, e il codice VHDL verra generato in automatico;

• VHDL Test Bench: e un modulo per il test comportamentale e postplace–and–route del tipo analizzato nel Cap. 11. Al passo successivo,ci viene chiesto quale modulo VHDL o schematico fra quelli disponibiliintendiamo testare;

139

Page 141: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 12.2: Dialog box per le caratteristiche di un nuovo progetto

• Schematic: genera un nuovo schematico da implementare con blocchigia disponibili o realizzati. Molto utile per l’interfacciamento gerar-chico.

Supponiamo di aver creato un modulo o uno schematico, e supponiamoche esso sia il nostro top–level source (se non lo e, supponiamo di settarlocome tale cliccando sul file con il tasto destro e selezionando Set as Top mod-ule, in quanto richiesto da Xilinx). In basso a sinistra, nella finestra Process-es, sono disponibili molte utili voci. Basta cliccare due volte su ognuna diesse per lanciare le funzioni messe a disposizione. Vediamo le principali:

• Synthesize – Check Syntax: permette di verificare che il VHDL scrittosia corretto o le connessioni in uno schematico non creino pericolosicorto–circuiti o conflitti;

• Design Utilities – Create Schematic Symbol: crea il simbolo corrispon-dente al nostro modulo, il quale puo essere poi utilizzato negli schemati-ci;

• View Synthesis Report: permette di visualizzare i report di sinte-si con tutte le caratteristiche temporali e di occupazione del modulorealizzato;

140

Page 142: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

• all’interno del menu Implement Design – Place–and–Route:

– cliccare due volte su Place–and–Route per generare il modellopiazzato su scheda;

– View Design permette di vedere il nostro progetto piazzato suFPGA.

Esiste inoltre il menu Edit Constraints per creare i vincoli temporali e/ospaziali, e il menu Generate Programming File per la creazione del bitstream.

Se, invece, abbiamo creato un testbench, ricordiamoci, per visualizzarlo,si scegliere Behavioral (per la simulazione comportamentale) o Post–Route(per la simulazione post–par) dal menu a tendina Sources. Dal menu XilinxISE Simulator possiamo controllare la sintassi del testbench o lanciare lasimulazione.

12.2 Esempi

Nei prossimi esempi utilizzeremo come scheda di riferimento una Spartan–3 XC3S200, package FT256, speed–grade -5. Vediamo alcune applicazioni,in ordine di complessita crescente.

12.2.1 Half–Adder asincrono

Partiamo con un progetto semplicissimo: un half–adder a un bit asin-crono. Il codice e semplicissimo:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity halfadder is

Port ( A : in STD_LOGIC;

B : in STD_LOGIC;

C : out STD_LOGIC;

O : out STD_LOGIC);

end halfadder;

architecture Behavioral of halfadder is

141

Page 143: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

begin

O <= A XOR B;

C <= A AND B;

end Behavioral;

Generiamo un testbench per verificare che il tutto funzioni correttamente:

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.all;

USE ieee.numeric_std.ALL;

ENTITY test_ha_vhd IS

END test_ha_vhd;

ARCHITECTURE behavior OF test_ha_vhd IS

COMPONENT halfadder

PORT(

A : IN std_logic;

B : IN std_logic;

C : OUT std_logic;

O : OUT std_logic

);

END COMPONENT;

--Inputs

SIGNAL A : std_logic := ’0’;

SIGNAL B : std_logic := ’0’;

--Outputs

SIGNAL C : std_logic;

SIGNAL O : std_logic;

BEGIN

uut: halfadder PORT MAP(

A => A,

B => B,

142

Page 144: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

C => C,

O => O

);

var : PROCESS

BEGIN

A <= ’0’;

B <= ’0’;

WAIT FOR 100 NS;

A <= ’0’;

B <= ’1’;

WAIT FOR 100 NS;

A <= ’1’;

B <= ’0’;

WAIT FOR 100 NS;

A <= ’1’;

B <= ’1’;

WAIT FOR 100 NS;

END PROCESS;

END;

Lanciando la simulazione, si puo verificare il corretto funzionamento delsistema.

12.2.2 Full–Adder

Sulla base dell’half–adder precedente, utilizziamo gli schematici per ot-tenere il full–adder con riporto in ingresso. Dopo aver creato il simbolocircuitale, si puo disegnare lo schema di Fig. 12.3.

Figura 12.3: Esempio di full–adder a un bit realizzato con schematico

143

Page 145: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

12.2.3 Decimal Counter a 2 cifre

Vediamo una struttura piu complessa. Studiamo un contatore di tipoBCD (Binary–Coded Decimal) a 2 cifre. In poche parole, un contatore BCDinterpreta ogni cifra decimale con 4 bit. Quindi, per esempio, 39 equivale a0011 1001(ovvero la codifica binaria di 3 e 9). A questo punto, supponiamodi voler implementare un circuito sequenziale per un contatore decimale a 2cifre. Dovremo gestire la next–state logic, i registri di stato e la logica di out-put. Supponendo di non usare una FSM (cosa sensata, dato che dovremmocontemplare molti stati), i registri di stato e la logica di uscita e piuttostoelementare: semplicemente avremo una trasferimento di dati con trasfor-mazione dal comodo formato unsigned al classico std_logic_vector. Nellanext–state logic, invece, dovremo gestire le trasformazioni dei numeri: per-tanto, quando arriveremo a 9 nel registro delle unita, dovremo tener tracciadell’aumento nel registro delle decine, e riazzereremo il registro delle unita, ecosı via. Supponiamo, quindi, di avere 2 registri interni, implementati con i 4classici segnali, ovvero stato attuale e futuro di: registro delle unita; registrodelle decine. La cosa migliore da fare e dare un’occhiata al codice, nel qualesi e supposta la presenza di un reset asincrono ed attivo basso:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity DecimalCounter is

Port ( clk : in STD_LOGIC;

reset : in STD_LOGIC;

d1 : out STD_LOGIC_VECTOR (3 downto 0);

d10 : out STD_LOGIC_VECTOR (3 downto 0));

end DecimalCounter;

architecture Behavioral of DecimalCounter is

signal d1_r, d10_r : unsigned(3 downto 0);

signal d1_n, d10_n : unsigned(3 downto 0);

begin

-- register

process(clk, reset)

begin

if reset=’0’ then

d1_r <= (others=>’0’);

144

Page 146: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

d10_r <= (others=>’0’);

elsif rising_edge(clk) then

d1_r <= d1_n;

d10_r <= d10_n;

end if;

end process;

-- next-state logic

d1_n <= X"0" when (d1_r=9) else

d1_r+1;

d10_n <= X"0" when (d1_r=9 and d10_r=9) else

d10_r+1 when (d1_r=9) else

d10_r;

-- output

d1 <= std_logic_vector(d1_r);

d10 <= std_logic_vector(d10_r);

end Behavioral;

Il testbench per questo dispositivo e altrettanto semplice:

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.all;

USE ieee.numeric_std.ALL;

ENTITY t_deccount_vhd IS

END t_deccount_vhd;

ARCHITECTURE behavior OF t_deccount_vhd IS

COMPONENT DecimalCounter

PORT(

clk : IN std_logic;

reset : IN std_logic;

d1 : OUT std_logic_vector(3 downto 0);

d10 : OUT std_logic_vector(3 downto 0)

);

END COMPONENT;

145

Page 147: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

--Inputs

SIGNAL clk : std_logic := ’0’;

SIGNAL reset : std_logic := ’0’;

--Outputs

SIGNAL d1 : std_logic_vector(3 downto 0);

SIGNAL d10 : std_logic_vector(3 downto 0);

constant T : time := 5 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)

uut: DecimalCounter PORT MAP(

clk => clk,

reset => reset,

d1 => d1,

d10 => d10

);

res : PROCESS

BEGIN

reset <= ’0’;

wait for (T+T/2);

reset <= ’1’;

wait;

END PROCESS;

ck : process

begin

clk <= ’0’;

wait for T;

clk <= ’1’;

wait for T;

end process;

END;

Al solito, si e deciso di definire una costante T per il semiperiodo delclock. La simulazione comportamentale offre il risultato corretto (si puoverificare per esercizio), mentre per la simulazione post place–and–route il

146

Page 148: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

clock impostato a 100 MHz si e rivelato a frequenza troppo elevata (a causadei ritardi di propagazione, dato che il componente in se puo arrivare oltre i200 MHz). Abbassando il clock a 40 MHz, si ottiene il risultato di Fig. 12.4.

Figura 12.4: Simulazione post–par a 40 MHz per il Decimal Counter a 2cifre: si notano dei glitch, ma sul fronte di salita del clock il dato e pulito

12.2.4 Calcolo con LUT di funzione trigonometrica

Si implementi mediante LUT la seguente funzione:

y = sin(x) (12.1)

per x ∈ [0, 1). L’ingresso sia a 8 bit in binario puro, e l’output si richiedecon precisione pari a 8 bit.

Il grafico della funzione richiesta nell’intervallo e mostrato in Fig. 12.5.La soluzione piu semplice e quella, semplicemente, di rappresentare i bit diingresso e uscita con una classica rappresentazione:

valintero =⌊valfloat · 2bit

⌋(12.2)

Ad esempio, possiamo rappresentare 0.534 a 8 bit come:

v = �0.534 · 256� = 13610 = 100010002

147

Page 149: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

0 0.2 0.4 0.6 0.8 10

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9

Figura 12.5: La funzione y = sin(x) nell’intervallo x ∈ [0, 1)

148

Page 150: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Ovviamente, e necessaria l’aggiunta di un codificatore apposito esternoalla FPGA che trasferisca i dati in maniera adeguata, ma questo non faovviamente parte delle specifiche di progetto. Si noti come non si possaavere overflow, essendo il valore 1 non compreso nell’intervallo di validita dix. Per gli output, possiamo usare la stessa notazione, ovvero:

valfloat = valintero/2bit (12.3)

Notiamo, pero, come il valore massimo del seno sia:

ymax = sin(1 − 2−8

) ≈ 0.8394

Si potrebbe pensare di normalizzare tutti i risultati per 0.84, per esempio,complicando il decoder di uscita (esterno alla FPGA e non di nostro interesse)ma sfruttando tutto il range dei bit che abbiamo a disposizione. Il codiceC++ di generazione del VHDL e il seguente:

#include "stdafx.h"

#define bin 8

#define bout 8

#using <mscorlib.dll>

using namespace System;

double seno(double in)

{

return Math::Sin(in);

}

char* toBool(int x, int b)

{

char* ris=new char[b];

for(int j=0;j<b;j++)

ris[j]=’0’;

if(x==0)

return ris;

else if(x==1)

{

ris[b-1]=’1’;

return ris;

}

149

Page 151: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

int i=0;

while(x!=1)

{

int r=x%2;

x=(int)(Math::Floor((double)x/2.0));

ris[b-1-i]=(char)(r+48);

i++;

}

ris[b-1-i]=’1’;

return ris;

}

void main()

{

FILE* fp;

fp=fopen("lut.vhd","w");

//intestazione

fprintf(fp,"library IEEE;\n");

fprintf(fp,"use IEEE.STD_LOGIC_1164.ALL;\n");

fprintf(fp,"use IEEE.STD_LOGIC_ARITH.ALL;\n");

fprintf(fp,"use IEEE.STD_LOGIC_UNSIGNED.ALL;\n\n");

//entity

fprintf(fp,"entity seno is\n");

fprintf(fp,"\tPort ( addr : in _

_ STD_LOGIC_VECTOR (%d downto 0);\n", (bin-1));

fprintf(fp,"\t\tclk : in STD_LOGIC;\n");

fprintf(fp,"\t\tris : out _

_ STD_LOGIC_VECTOR (%d downto 0));\n", (bout-1));

fprintf(fp,"end seno;\n\n");

//architecture

fprintf(fp,"architecture Behavioral of seno is\n");

fprintf(fp,"begin\n");

fprintf(fp,"\tprocess(clk)\n");

fprintf(fp,"\tbegin\n");

fprintf(fp,"\t\tif rising_edge(clk) then\n");

fprintf(fp,"\t\t\tcase addr is\n");

for(int i=0;i<Math::Pow(2.0,bin);i++)

150

Page 152: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

{

char* x=toBool(i,bin);

double tmp=(double)i/Math::Pow(2.0,bin);

double tmp2=seno(tmp);

int ris=Math::Floor(((tmp2/0.84)*256.0));

char* y=toBool(ris,bout);

fprintf(fp,"\t\t\t\twhen \"");

for(int j=0;j<bin;j++)

fprintf(fp,"%c",x[j]);

fprintf(fp,"\" => ris <= \"");

for(int j=0;j<bout;j++)

fprintf(fp,"%c",y[j]);

fprintf(fp,"\";\n");

}

fprintf(fp,"\t\t\t\twhen others => _

_ ris <= (others => ’X’);\n");

fprintf(fp,"\t\t\tend case;\n");

fprintf(fp,"\t\tend if;\n");

fprintf(fp,"\tend process;\n");

fprintf(fp,"end Behavioral;");

fclose(fp);

}

Analizziamo per prova un paio di uscite. Proviamo a calcolare il seno di0.5, e analizziamone la precisione. In uscita otteniamo 146. A questo punto,traduciamolo secondo lo schema introdotto:

ris =146 ∗ 0.84

256≈ 0.4791

Il seno di 0.5 vale:

sin(0.5) ≈ 0.4794

Calcoliamo i bit di precisione:

|log2 (|sin(0.5) − ris|)| ≈ 11bit

Proviamo a calcolare ora il seno di 0.95. I bit di precisione risultanoessere:

|log2 (|sin(0.95) − 0.8105|)| ≈ 8.4bit

151

Page 153: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

12.2.5 Generatore di sequenze con FSM

Gli esempi con macchina a stati finiti sono stati realizzati utilizzando ilsimulatore DEEDS1, il quale contiene l’ambiente d–FsM per la progettazionee la sintesi di macchine a stati finiti. Non solo: tramite il comando ExportVHDL, viene generato in automatico il codice per la FSM realizzata.

Supponiamo di voler realizzare un generatore di sequenze: esso ha, iningresso, un clock, un reset e due segnali, C0 e C1, tali da comandare l’at-tivazione di un segnale di uscita sull’unico output T ad un preciso colpo diclock. Lo schema e presentato in Fig. 12.6. Supponiamo che la sequenza deidue ingressi di controllo possa variare solo durante il ciclo T0 e resti stabileper i seguenti colpi di clock. A questo punto, possiamo generare una FSMpuramente di Moore o con uscite di Mealy (Figg. 12.7 e 12.8 rispettivamente).

Figura 12.6: Schema del generatore di sequenze

Da un’analisi temporale comportamentale si puo verificare che entrambele soluzioni funzionano correttamente (e stata riportata in Fig. 12.9 l’analisiper la soluzione come macchina di Mealy a titolo di esempio).

12.3 Esempio completo

Vediamo, in conclusione, un esempio completo, a partire dal testo perfinire con l’implementazione e lo schema su scheda.

1Scaricabile all’indirizzo http://esng.dibe.unige.it/netpro/Deeds/Index.htm

152

Page 154: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 12.7: FSM con uscite di Moore per il generatore di sequenze

153

Page 155: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 12.8: FSM con uscite di Mealy

154

Page 156: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 12.9: Analisi temporale comportamentale per la soluzione con FSMMealy

12.3.1 Testo

Si realizzi un Pulse Width Modulation Circuit (PWM). In pratica, essoriceve in ingresso un clock ed un segnale (di dimensione variabile) che vienecodificato nel duty cycle del segnale di uscita. Il segnale di uscita avra unafrequenza 2s volte inferiore, dove s e il numero di bit dell’ingresso, rispetto alclock originario, e un duty cycle pari a w

2s , dove w e il segnale da modulare.Scrivere il codice VHDL per l’implementazione, utilizzando tecniche basatesu generic, e realizzare un testbench per il sistema. Visualizzare simulazionecomportamentale e post–par, nonche il piazzamento su FPGA e le principalicaratteristiche temporali e di occupazione, per un segnale di ingresso a 4 bit.

12.3.2 Soluzione

Viene qui proposta una possibile soluzione. Data la relativa semplicita,dovrebbe essere intuitivo:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity pwm is

Generic ( S : natural );

Port ( clk : in STD_LOGIC;

reset : in STD_LOGIC;

w : in STD_LOGIC_VECTOR (S-1 downto 0);

pulse : out STD_LOGIC);

end pwm;

architecture Behavioral of pwm is

signal r_reg : unsigned(S-1 downto 0);

signal r_next : unsigned(S-1 downto 0);

155

Page 157: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

signal buf_reg : std_logic;

signal buf_next : std_logic;

constant ref : std_logic_vector(S-1 downto 0)

:= (others => ’0’);

begin

-- registri e gestione buffer di output

process(clk, reset)

begin

if(reset=’0’) then

r_reg <= (others => ’0’);

buf_reg <= ’0’;

elsif rising_edge(clk) then

r_reg <= r_next;

buf_reg <= buf_next;

end if;

end process;

-- next-state

r_next <= r_reg + 1;

-- output logic

buf_next <= ’1’ when ((r_reg < unsigned(w)) or (w=ref)) else

’0’;

pulse <= buf_reg;

end Behavioral;

Si noti l’introduzione della costante ref per rendere il controllo indipen-dente dai bit di ingresso. Realizziamo un blocco implementante il pwm a 4bit. Semplicemente:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity pwm4 is

Port ( clk : in STD_LOGIC;

reset : in STD_LOGIC;

w : in STD_LOGIC_VECTOR (3 downto 0);

pulse : out STD_LOGIC);

156

Page 158: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

end pwm4;

architecture Behavioral of pwm4 is

COMPONENT pwm

Generic ( S : natural );

Port ( clk : in STD_LOGIC;

reset : in STD_LOGIC;

w : in STD_LOGIC_VECTOR (S-1 downto 0);

pulse : out STD_LOGIC);

END COMPONENT;

begin

uut: pwm

generic map ( S => 4 )

PORT MAP(

clk => clk,

reset => reset,

w => w,

pulse => pulse

);

end Behavioral;

Testiamolo con un testbench:

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_unsigned.all;

USE ieee.numeric_std.ALL;

ENTITY testpwm4_vhd IS

END testpwm4_vhd;

ARCHITECTURE behavior OF testpwm4_vhd IS

COMPONENT pwm4

PORT(

clk : IN std_logic;

reset : IN std_logic;

w : IN std_logic_vector(3 downto 0);

pulse : OUT std_logic

157

Page 159: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

);

END COMPONENT;

--Inputs

SIGNAL clk : std_logic := ’0’;

SIGNAL reset : std_logic := ’0’;

SIGNAL w : std_logic_vector(3 downto 0)

:= (others=>’0’);

--Outputs

SIGNAL pulse : std_logic;

constant T : time := 5 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)

uut: pwm4 PORT MAP(

clk => clk,

reset => reset,

w => w,

pulse => pulse

);

-- Test Bench Statements

clock : PROCESS

BEGIN

clk <= ’1’;

wait for T;

clk <= ’0’;

wait for T;

END PROCESS clock;

res: process begin

reset <= ’0’;

wait for 5*T;

reset <= ’1’;

wait;

end process;

input: process begin

158

Page 160: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

w <= X"4";

wait for 500 ns;

w <= X"8";

wait;

end process;

END;

Figura 12.10: Simulazione comportamentale del PWM a 4 bit

I risultati di tale simulazione (clock a 100 MHz) sono mostrati in Fig.12.10, e si sono dimostrati corretti. Passiamo alla sintesi. Le principalicaratteristiche temporali ci dicono che:

Timing Summary:

---------------

Minimum period: 3.413ns (Maximum Frequency: 292.972MHz)

159

Page 161: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Minimum input arrival time before clock: 5.195ns

Maximum output required time after clock: 6.216ns

Maximum combinational path delay: No path found

Vediamo subito che, probabilmente, a causa dei ritardi di propagazionesara difficile raggiungere frequenze superiori a circa 100 MHz. Vediamol’occupazione di porte logiche:

Device utilization summary:

---------------------------

Selected Device : 3s200ft256-5

Number of Slices: 5 out of 1920 0%

Number of Slice Flip Flops: 5 out of 3840 0%

Number of 4 input LUTs: 9 out of 3840 0%

Number of IOBs: 7 out of 173 4%

Number of GCLKs: 1 out of 8 12%

Non ci rimane che simulare il comportamento post place–and–route. Lan-ciamo la simulazione. Come mostrato in Fig. 12.11, tutto ok. Attraversoprove iterative, a dispetto dei pessimistici dati (worst case) del sintetizzatore,si puo mostrare come il clock massimo raggiungibile (dato dalla simulazionepost–par) e pari circa a 200 MHz.

Mostriamo, infine, in Fig. 12.12 il piazzamento del nostro dispositivo sul-la Spartan–3: tutto sommato, i dati pessimistici del routing fornito dal sin-tetizzatore non si sono fatti eccessivamente sentire grazie ad un piazzamentotutto sommato fortunato, in quanto non lontanissimo dai pin di I/O.

160

Page 162: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 12.11: Simulazione post place–and–route del PWM a 4 bit

161

Page 163: Dispense per le esercitazioni del corso Sistemi ...unina.stidue.net/Sistemi Elettronici Programmabili... · 10 e 50mila porte logiche e si basano su eventuali IP–core preceden-temente

Figura 12.12: Piazzamento su Spartan–3 del PWM progettato

162