Guida introduttiva alla programmazione di una CPLD Max II con Quartus II IDE

1. Introduzione

Una CPLD (Complex Programmable Logic Device) è un dispositivo digitale che permette di programmare le funzioni logiche da implementare all’interno del dispositivo stesso.

Si tratta di un’evoluzione di precedenti dispositivi a logica programmabile come le PAL e le GAL (per maggiori informazione vedere qui) . Una ulteriore evoluzione delle CPLD è rappresentata dalle FPGA (per maggiori informazioni vedere qui) molto più potenti e complesse delle CPLD, e che in genere richiedono una memoria esterna per conservare la configurazione.

L’elemento fondamentale della CPLD è la macrocella, che ne costituisce l’elemento logico atomico.

Nel caso della famiglia di dispositivi Max II della Altera (ora Intel), l’elemento atomico si chiama LE (Logic Element) e differisce dalla classica macrocella delle GAL (prodotto di termini AND-OR):

Sruttura di un LE

Volendo semplificare al massimo, un LE è costituito da una LUT (Look Up Table) con 4 ingressi e da un Flip-Flop. La LUT può essere considerata come una sorta di “PROM di decodifica”, programmandola è possibile realizzare un funzione logica a piacere all’interno dalla LUT. Il Flip-Flop costituisce un elemento atomico di memoria che può essere associato alla funzione logica della LUT (per realizzare, ed esempio, registri, contatori, ecc.).

All’interno di una CPLD di tipo EPM240T100 che andremo a utilizzare ci sono 240 LEs, in più c’è un blocco di memoria EEPROM che conserva la configurazione da caricare all’accensione (CFM), ed un ulteriore blocco di memoria EEPROM utente (UFM).

La programmazione della CPLD consiste nel caricare la configurazione (detta anche bitstream) all’interno della EEPROM CFM e, se utilizzata, all’interno della UFM.

2. Che cosa serve per incominciare

Ore vedremo che “ingredienti” servono per iniziare ad utilizzare le CPLD EPM240T100 che rappresentano le “entry level” della famiglia Max II.

2.1 La scheda CPLD

Ovviamente prima di tutto serve una scheda di “sviluppo” che contenga una CPLD EPM240T100. A tal fine si può utilizzare la CPLD Fun Board che ho realizzato per questo scopo, oppure un’altra scheda commerciale contenente una EPM240T100 o un altra CPLD della stessa famiglia.

Senza andare a scegliere schede costose (> 100$) come questa:

ci si può orientare su una scheda di questo tipo:

o anche questa:

che possono essere acquistate presso i noti siti di e-commerce a partire da circa 6$.

2.2 La scheda MCU (opzionale)

Normalmente le schede commerciali economiche, rispetto alla CPLD Fun Board, non dispongono di alcune “periferiche” come led, pulsanti, display a 7 segmenti, ecc. e non dispongono di un microcontrollore da utilizzare come “generatore di stimoli”. Di conseguenza sarà necessario connettere dispositivi esterni usando, ad esempio, una breadboard e reperendo un’ulteriore scheda con un microcontrollore.

A tal proposito faccio notare che la CPLD funziona a 3.3V, per cui non è agevole usare come scheda MCU un comune Arduino Uno (in quanto funziona a 5V), ma è bene orientarsi verso schede con MCU a 3.3V.

Consiglio di utilizzare una scheda “Maple Mini” che utilizza un MCU ARM Cortex M3 a 32 bit di tipo STM32F103, che è lo stesso utilizzato nella CPLD Fun Board, e che può essere programmato con l’IDE di Arduino. In questo modo si potranno utilizzare gli stessi sketch, avendo cura di apportare eventuali piccoli adattamenti nel caso le connessioni dovessero essere differenti:

Al solito, un “Maple Mini” può essere acquistato sui noti siti a partire da circa 3/4$.

Ovviamente potete anche scegliere un qualsiasi altro MCU come i PIC, purché funzionanti a 3.3V. Ovviamente in questo caso non potrete usare gli “sketch” degli esempi, ma dovrete provvedere autonomamente.

2.3 Il programmatore USB Blaster

Per poter eseguire l’upload della configurazione all’interno della CPLD è necessario utilizzare un opportuno programmatore chiamato USB Blaster. Tale programmatore è facilmente reperibile sui soliti siti a partire da circa 3$ ed è normalmente incluso il cavo flat a 10 conduttori:

 

 

2.4 L’IDE Quartus II

Infine è necessario scaricare ed installare l’IDE Quartus II. Nel seguito utilizzerò la versione 13.0.SP1, in quanto ho necessità di mantenere questa versione per un altro progetto che utilizza una FPGA Cyclone II (è la versione più recente che supporta tale FPGA). Se volete potete provare ad utilizzare l’ultima versione (attualmente è la 17) che comunque supporta le serie Max II, ma è possibile che non coincidano gli screenshot usati nel seguito.

Per scaricare la versione 13.0.SP1 potete usare questo link. E’ necessario creare un account per procedere al download. Vi consiglio di selezionare il tag “Combined Files” e di scaricare il file da circa 4.4GB con tutto il necessario.

3. Configurazione dell’ambiente Quartus II

Come ho già detto in precedenza, tutti gli screenshot si riferiscono alla versione 13.0.SP1 dell’IDE.

Inoltre la configurazione suggerita è riferita alla CPLD Fun Board, ma è comunque consigliata anche per qualsiasi altra scheda di sviluppo utilizzata.

Dal menu principale di Quartus II selezioniamo “File” -> “New Project Wizard…“:

poi “Next >“:

ed inseriamo il nome della cartella del progetto che vogliamo creare. Nell’esempio scriveremo “test1” per tutti i campi come da screenshot. E’ da notare che Quartus II non gradisce nomi con spazi interni.

Poi procediamo avanti con “Next >“:

a ancora con “Next >“:

Ora nel campo “Family” selezioniamo MAX II, nel campo “Package” selezioniamo “TQFP” e nel campo “Available devices” la riga “EP240T100C5“.

Poi andiamo avanti sempre con “Next >“:

e ancora “Next >“:

e finalmente clicchiamo su “Finish“. Ora abbiamo un template vuoto ed è possibile modificare le configurazione.

Dal menu principale di Quartus II selezioniamo “Assignments” -> “Devices…“:

e clicchiamo sul pulsante “Device and Pin Options…“:

e selezioniamo “Enable device-wide reset (DEV_CLRn)” e “Enable device-wide output enable (DEV_OE)“. In questo modo saranno abilitate le funzioni  “DEV_CLRn” e “DEV_OE” della scheda CPLD Fun Board.

Queste sono due importanti funzioni: la prima resetta i Flip-Flop di tutti i LE (Logic Elements) con il tasto “DEV_CLRn”, e la seconda abilita la possibilità di forzare tutti i pin di I/O della CPLD in alta impedenza per mezzo dell’interruttore “DEV_OE”.

Ora configureremo lo stato dei pin della CPLD non utilizzati. Con il termine non utilizzati s’intende non referenziati esplicitamente nella fase di programmazione.

Dalla stessa finestra selezioniamo sulla sinistra “Unused Pins“:

e selezioniamo nel campo “Reserve all unused pins” l’opzione “As input tri-stated weak pull-up“. Questa e la configurazione migliore e più “sicura” per la CPLD Fun Board, ma è consigliata anche in generale.

Ora è il caso di salvare il progetto, che sarà utilizzato nel seguito per il primo esempio di utilizzo, l’immancabile led lampeggiante…

4. Un classico progetto per iniziare: il led lampeggiante

Come da consolidata tradizione il primo progetto di esempio consisterà nel fare lampeggiare un led.

Nel seguito continuerò a fare riferimento alla CPLD Fun Board, ma il contenuto è comunque applicabile anche ad altre schede avendo l’accortezza di modificare i pin fisici rispetto alla configurazione HW della scheda utilizzata.

Inoltre, per rendere ancora più facile la comprensione, si utilizzerà l’ambiente di “schematic entry” e le librerie che permettono di simulare in HW il comportamento della ben nota famiglia di circuiti integrati digitale 7400.  Di conseguenza non verrà fatto nessun accenno all’uso di linguaggi HDL come il VHDL, che richiedono un know-how specifico.

Nel seguito utilizzeremo come base di partenza il progetto test1 precedentemente salvato, andando a realizzare una configurazione della CPLD che, a partire da un clock in ingresso di 36MHz, lo divide con una catena di divisori fino ad ottenere una frequenza di circa 2Hz. Questa ultima verrà usata per fare lampeggiare un led. Il clock di 36MHz verrà prodotto con lo STM32F103 a bordo della CPLD Fun Board.

Nel caso si utilizzi una scheda commerciale, basterà selezionare in ingresso l’oscillatore a 50MHz che di norma equipaggia dette schede. La frequenza prodotta sarà in questo caso di circa 3Hz.

4.1 Edit del progetto

Apriamo il progetto precedentemente salvato dal menu principale di Quartus II con “File” -> “Open Project…” e selezioniamo il file “test1.qfp”. Notare che l’estensione .qfp è usate per i file di progetto di Quartus II:

poi dalla finestra principale:

creiamo un nuovo file per lo schema elettrico da realizzare.

Dal menu principale di Quartus II selezioniamo “File” -> “New…“:

e poi “Block Diagram/Schematic File“. Verrà così creato un nuovo file .bdf:

Ora dobbiamo disegnare lo schema elettrico di ciò che vogliamo realizzare all’interno della CPLD.

Useremo tre contatori 74393 come divisori 1:256.

Selezioniamo quindi l’icona “Symbol Tool” dalla barra dell’editor:

e scriviamo 74393 nel campo “Name“:

premiamo il tasto “OK” e posizioniamo tre contatori 74393 nel foglio usando il tasto sinistro del mouse:

poi premiamo il tasto (fisico) “ESC” e selezioniamo l’icona dello “Orthogonal Node Tool” per fare le connessioni:

e completiamo il tutto come mostrato qui:

Ora di nuovo il tasto “ESC” e riselezioniamo il “Symbol Tool“, poi scriviamo”not” nel campo “Name“:

e posizioniamo due porte NOT come mostrato qui:

 

Ora aggiungeremo un pin d’ingresso (il clock) e uno di uscita (il led). In più aggiungeremo anche un ulteriore pin d’ingresso per un tasto della CPLD Fun Board che collegheremo al segnale “Clear” comune ai tre 74393.

Dopo aver premuto il tasto (fisico) “ESC” selezioniamo il “Pin Tool” e la sotto-selezione “Input“:

e posizioniamo due porte d’ingresso come segue:

e una porta d’uscita per il led selezionando “Pin Tool” e poi “Output“:

e posizioniamo la porta d’uscita come mostrato qui:

Ora per maggiore chiarezza rinominiamo le porte di input/output (pin_name1, …3) come mostrato nel seguito, cliccando due volte su ogni nome da modificare:

A questo punto l’editing è completo, ed è il caso di salvare il tutto.

4.2 Assegnazione dei pin fisici

Ora è necessario associare le porte di input/output ai vari pin fisici della CPLD. Però prima di precedere è opportuno usare un piccolo trucco per rendere i prossimi passi più agevoli. Infatti conviene ora eseguire comunque una compilazione dell’intero progetto, in questo modo saranno automaticamente disponibili sul Pin Planner i nomi delle porte che abbiamo usato nello schematic editor nella fase precedente. Avendo a che fare con dispositivi con 100 e più pin non è cosa da poco…

A tal proposito clicchiamo sull’icona “Compilation“:

e attendiamo il completamento della compilazione:

Se abbiamo fatto tutto per bene, non devono apparire errori, ma solo eventuali warning che ignoreremo.

Ora premiamo sul tasto “OK”  e clicchiamo sull’icona del “Pin Planner“:

Verrà attivata la finestra del Pin Planner:

Questo è il posto dove associare i pin fisici alla porte dello schema elettrico, e dove definirne i parametri elettrici (livelli logici, eventuali pull-up, ecc..).

Ora iniziamo con l’associare i pin fisici usando il campo “Location” nella parte bassa della finestra:

Per assegnare il pin fisico bisogna cliccare all’incrocio della riga della porta da associare con la colonna Location. Nel caso della CPLD Fun Board dallo schema elettrico si ricava che il pin del clock in ingresso (dal pin 29 MCO dello STM32F103) è connesso al pin 14 della CPLD, parimenti il led LED1 è connesso al pin 50 e il tasto USR4 è connesso al pin 54 della CPLD.

Nel caso si utilizzi un’altra scheda sarà necessario apportare i necessari cambiamenti.

Alla fine si avrà:

Ora è necessario apportare alcuni correttivi ad alcuni parametri di default di alcuni pin fisici che tengano conto dello HW della scheda CPLD Fun Board.

Per primo è il caso di attivare la resistenza interna di pull-up del pin 14 (clock) in quanto in alcune condizioni l’uscita MCO dello STM32 si trova in alta impedenza. Così facendo si eviteranno stati “floating“.

Per fare ciò selezioniamo “On” dalla colonna “Weak Pull-Up Resistor” (NOTA: se nella vostra installazione dovessero non apparire alcune colonne, andate con il mouse su un titolo qualsiasi di una colonna e premete il tasto destro. A questo punto selezionate la colonna da aggiungere alla vista corrente):

Poi è necessario tenere conto che il tasto USR4 è connesso ad un circuito analogico per i de-bouncing, di conseguenza deve essere attivato uno Schmitt Trigger in ingresso al pin 54:

A questo punto possiamo chiudere la finestra del Pin Planner (non occorre salvare nulla esplicitamente). Ora è necessario procedere ad una nuova compilazione del progetto come fatto in precedenza:

ed è buona abitudine verificare che tutti i pin assegnati post-compilazione siano corretti. Per fare ciò clicchiamo sulla cartella “Fitter“:

poi sulla cartella “Resource selection“:

e poi sull’elemento “All Package Pins“:

Ora è possibile verificare che tutti i pin corrispondano a quanto atteso.

4.3 Procedura di connessione della USB Blaster

A questo punto siamo pronti per effettuare l’upload. Prima però si deve collegare il programmatore USB Blaster seguendo la procedura prevista nel relativo manuale scaricabile qui.

I passi da eseguire sono nell’ordine:

  1. verificare che il target (la scheda con la CPLD) sia non alimentato;
  2. connettere il programmatore USB Blaster per primo alla USB del PC (verrà così alimentata dal PC);
  3. connettere il cavo piatto JTAG a 10 conduttori al target;
  4. alimentare il target. Nel caso della CPLD Fun Board ciò si traduce nel collegare il connettore USB della scheda ad una seconda presa USB del PC.

Nel video seguente sono mostrati tutti i passi come da procedura:

4.4 Programmazione della CPLD

Dalla finestra principale di Quartus II clicchiamo sull’icona del “Programmer“:

Apparirà la finestra del programmatore:

a questo punto effettuare i seguenti passi:

  • verificare che sia selezionato il programmatore USB Blaster  (1);
  • se non appare premere il pulsante “Hardware Setup…” (2) e selezionarlo;
  • premere il pulsante “Auto Detect” (3) e verificare che non compaiano errori;
  • verificare che tutti i check “Program/Configure and “Verify” (4) siano selezionati;
  • premere il pulsante “Start” (5) per avviare la programmazione.

Attendere il completamento della programmazione.

4.5 Procedura di scollegamento della USB Blaster

Nel caso si volesse scollegare il programmatore USB Blaster è necessario seguire la procedura indicata nel relativo manuale.

I passi da eseguire sono nell’ordine:

  1. scollegare l’alimentazione del target. Nel caso della CPLD Fun Board ciò significa scollegare il cavo USB dalla scheda;
  2. disconnettere il  connettore flat a 10 conduttori (JTAG) dalla scheda;
  3. scollegare la USB Blaster dal connettore USB.

Nel video seguente sono mostrati tutti i passi come da procedura:

4.6 Sketch per la generazione del clock a 36MHz

Abbiamo precedentemente detto che occorre generare un clock da dare in ingresso alla CPLD. Per fare ciò useremo la MCU STM32F103 a bordo della CPLD Fun Board.

Nel caso si utilizzi un’altra scheda, si dovrà fare in modo di portare/generare un segnale di clock verso la CPLD.

Senza entrare nel dettaglio dello HW interno dello STM32F103, useremo il pin MCO che se opportunamente programmato permette di portare all’esterno un clock derivato dal clock interno di sistema:

Schema a blocchi del clock dello STM32F103

Lo sketch che attiva il pin MCO è il seguente:


void setup() {
// put your setup code here, to run once:

// Set the MCO pin to output the clock to the CPLD (GCLK1 pin 14). See STM32F103 Reference Manual RM0008
RCC_BASE->CFGR = RCC_BASE->CFGR | 0x07000000; // Set MCO[2:0] = 111 (inside RCC_CFGR register) for 36MHz clock output
GPIOA->regs->CRH = GPIOA->regs->CRH | 0x00000003; // Set output mode on PA8 @ max freq 50MHz (MODE8[1:0] = 11)
GPIOA->regs->CRH = GPIOA->regs->CRH & 0xFFFFFFF3; // Set output mode on PA8 as general push-pull output (cnf8[1:0] = 00)
GPIOA->regs->CRH = GPIOA->regs->CRH | 0x00000008; // Set output mode on PA8 as alternate push-pull output (cnf8[1:0] = 10)

}

void loop() {
// put your main code here, to run repeatedly:

}


Il risultato finale è mostrato nel video seguente :

Si noti che premendo il tasto RST (reset della MCU) il led smette di lampeggiare per un pò, in quanto durante il reset e successivo reboot cessa il segnale di clock, finché il bootloader cede il controllo al programma utente che lo riattiva.

Si può anche vedere l’effetto del pulsante DEV_CLRn che azzera tutti i Flip-Flop interni della CPLD, facendo azzerare i contatori configurati nella CPLD stessa. Premendo il tasto USR4 si attiva il segnale di Clear dei contatori, ottenendo lo stesso effetto.

Attivando l’interruttore DEV_OE si forzano in alta impedenza tutti i pin di I/O della CPLD, con conseguente interruzione del lampeggio.

5. Bibliografia per approfondire

  • Manuale di Quartus II V13.1 qui;
  • Max II Device Handbook qui;
  • Datasheet MCU STM32F103 qui;
  • Reference Manual RM0008 (MCU STM32F103) qui;
VOTO
3 commenti
  1. Marcello
    Marcello dice:

    Ottimo esempio di come si possono utilizzare queste logiche programmabili.
    Le spiegazioni sono molto chiare e molto dettagliate. Non è facile trovare in rete un tuttorial in italiano che spieghi l’utilizzo passo-passo dell’ IDE Quartus II.
    Ottimo un vero aiuto per chi vuole iniziare a utilizzare una CPLD.

    Approvazioni
  2. Amilcare
    Amilcare dice:

    Ottimo articolo e soprattutto molto dettagliato.
    Ho aggiunto al tuo elaborato la “immagine in evidenza”, quella che vedi in cima all’articolo quando lo apri e in home come pubblicità agli ultimi articoli.
    Se non dovesse essere di tuo gusto basta che vai in modifica al tuo articolo e in fondo all’editor sulla destra e la sostituisci con una a tua scelta.
    Nessuna altra modifica è stata fatta al TUO articolo.
    Saluti Amilcare

    Approvazioni

Lascia un Commento

Vuoi partecipare alla discussione?
Fornisci il tuo contributo!

Lascia un commento