L’ABC dei microcontrollori su FPGA

Quando in molti progetti è necessario unire alla logica programmabile la funzionalità di un piccolo microprocessore le soluzioni semplici come il core ABC possono essere la risposta.

Ci sia concesso il gioco di parole, ma è un modo per introdurre questa soluzione di progetto basata su FPGA proposta da ACTEL, il cui nome è proprio ABC. Il nome non è casuale perché il core in oggetto è un semplice microprocessore, che in un numero di gate veramente contenuto, sviluppa e supporta le istruzioni basilari richieste ad un qualsiasi micro sia su silicio oppure, come in questo caso, su FPGA. Insomma l’ABC dei microprocessori. Prima di affrontare la sua presentazione è importante sottolineare che stiamo parlando di un oggetto completamente gratuito e sviluppabile a sua volta usando tools gratuiti.

Ambiente di sviluppo

Come anticipato, per lavorare su questo progetto necessitiamo esclusivamente della suite Tools Libero 8.5. Lanciando Libero e seguendo semplicemente  il Wizard, per un nuovo progetto dovrete soltanto definire il nome del progetto stesso selezionando come linguaggio il VHDL (step1), scegliere il componente  desiderato, che per le nostre prove era un A3P250FGG256 (step2) e concludere senza nulla altro aggiungere.  Il risultato sarà come in figura 1.

Figura 1: il wizard per la creazione del progetto.

Figura 1: il wizard per la creazione del progetto.

Da questo punto selezionando l’icona Smart-design, successivamente la sotto voce Smart-design-component e dando un nome al componente, attivate l’ambiente per poter utilizzare tutte le periferiche e le macro riportate a destra della figura 1. Cliccando su core ABC vi verrà chiesto il nome che desiderate attribuire al core e conseguentemente si aprirà la pagina principale relativa alla configurazione del micro (figura 2).

Figura 2: la pagina di configurazione del micro.

Figura 2: la pagina di configurazione
del micro.

Struttura del microprocessore ABC

Approfondiamo la conoscenza del core ABC: essendo un micro sviluppato su FPGA, permette ovviamente la scelta della dimensione del Bus dati fra 8 e 32 bit. Lo stesso vale per il BUS Indirizzi, che può essere configurato come dimensione da 8 a 16 bit, permettendo una ottimizzazione in termini di gate consumati (non dimentichiamo che stiamo parlando di un micro fatto su FPGA, per cui è inutile costruire una macchina superiore alle nostre esigenze). Gli APB (Advanced Peripheral Bus) sono le varie periferiche, che decidiamo di gestire con il nostro core ABC; esse potrebbero essere sia periferiche sviluppate da noi, oppure una delle tante periferiche fornite gratuitamente da ACTEL nell’ambiente stesso. Volendo proporre un esempio potremmo, in modalità del tutto gratuita, collegare a questo sistema una UART, una SPI e un generatore di PWM, come macro (FREE) fornite da ACTEL e nel contempo un controller VGA da noi sviluppato. In ogni caso potremmo utilizzare fino a sedici periferiche collegate al micro ABC attraverso il controller APB. Nel nostro esempio di progetto abbiamo fatto uso del core PWM, fornito gratuitamente e selezionato dalla lista Periferiche (figura 1 a destra in alto). La voce Z register size ci permette di attivare  il registro specifico per le operazioni di loop counter e di indirizzamento indiretto; si noti che la sua dimensione deve essere compatibile con il Bus dati selezionato. Punti importanti della configurazione sono anche la scelta di quanti INPUT e OUTPUT si vogliono usare direttamente (da 1 a 32, ma ricordatevi che la scelta deve essere congrua con la dimensione del BUS dati definito) e quante periferiche (APB slot) verranno usate nel sistema. Una volta effettuate queste scelte dovrete definire se il codice sorgente che scriverete sarà residente su RAM, modalità soft mode (in questo caso verranno usati i blocchi DP RAM interni della A3P250) oppure sarà diffuso nella FPGA stessa, utilizzando i gate interni (HW FPGA TILE). E’ importante indicare che questa soluzione per codici contenuti (meno di 256 / 512 istruzioni) è persino consigliabile, considerato il numero limitato di gate che la soluzione HW consuma. Per fornire dei valori relativi a una FPGA A3P250, si segnala che un micro ABC con un codice da 256 istruzioni caricato in HW mode (usando quindi i gate della FPGA)  il consumo, in termini di TILE circa il 12% della FPGA stessa. Si tenga conto che in questa modalità è anche possibile considerare l’utilizzo di due micro ABC in parallelo, semplificandoli e tagliandoli sulla specifica, in tal caso il loro consumo in termini di gate consumati è ancor più contenuto. Conclude la nostra fase di configurazione la scelta di avere o meno alcune istruzioni di tipo avanzato, qualora aveste scelto la modalità di esecuzione in DP RAM, ad esempio la possibilità di avere istruzioni di moltiplicazione, indirizzamento indiretto alle periferiche APB e dimensione del Bus della porta utilizzata per il caricamento  del codice. Dato che il core può eseguire fetch solo da DP RAM, prima di lanciare l’esecuzione è necessario caricare il codice nella DP RAM stessa. Per questa operazione  il core ABC dispone di una porta specifica e di segnali di controllo, per cui al power up un’unità aggiuntiva (per esempio un piccolo modulo scritto in VHDL) deve provvedere al caricamento, leggendo da una memoria EE PROM seriale esterna e copiandola nella DP RAM stessa. E’ importante evidenziare che per un codice inferiore ai 128 byte è possibile usare la FROM inter na della A3P250, che è a tutti gli effetti una EEPROM disponibile a costo zero.

Istruzioni e codice  macchina per il core ABC

Definite queste opzioni possiamo procedere alla scrittura del codice. Come ogni micro la maggior parte delle istruzioni lavorano intorno all’accumulatore. Sono previste e supportate istruzioni aritmetiche e logiche sia su accumulatore sia fra accumulatore e variabile in Ram. La Ram di sistema prevede le sue istruzioni di scrittura e lettura, mentre per i loop di controllo esiste uno specifico registro (registro Z) su cui è possibile operare. Le operazioni dirette alle periferiche APB hanno un loro set di istruzioni e si noti che in questo caso è possibile l’indirizza mento indiretto da registro Z. Concludono il set delle istruzioni le operazioni condizionate e di controllo del flusso (Jump, Call e Return), mentre per la gestione della porta di I / O esistono le istruzioni dirette IOWRT e IOREAD.  Il supporto interrupt è dato da un PIN specifico, pertanto in fase di configurazione dovrete definire l’indirizzo a cui salterà  il flusso, in risposta alla richiesta di interrupt esterna. La configurazione dello stato attivo del pin INTRQ è sempre possibile nella fase iniziale delle impostazioni. Le istruzioni condizionate possono usare sia lo stato dell’accumulatore sia quello del registro Z, oppure lo stato della porta INPUT. Va ricordato che è supportata anche la moltiplicazione con estensione a 16 bit. Il micro ABC richiede per quasi tutte le sue istruzioni tre colpi di clock, per cui, supponendo di fornire un clock base di 60Mhz, avremo una macchina di 20 MIPS.

Descrizione programma di prova

Premesso che attualmente il linguaggio disponibile è ancora l’Assembler, la casa madre ha annunciato che sarà fornito a breve un piccolo compilatore C. Si noti comunque che per questo tipo di macchina l’uso del linguaggio Assembler, seppur non trasportabile, è molto semplice e immediato. Il nostro programma di test provvede alla copia in RAM del valore HEX 01 e allo shiftdel medesimo, per accendere in maniera sequenziale dei LED collegati sulla porta di OUTPUT, mentre subito allo start viene programmato il modulo PWM, che è stato istanziato durante la costruzione del progetto nella suite Core Console. Nel dettaglio questo modulo dispone di vari registri di programmazione per l’abilitazione del canale PWM, prescaler della frequenza base, definizione del periodo PWM e della durata parte alta e parte bassa del canale stesso. Si tenga conto che questo modulo è configurabile come numero di canali fino ad un massimo di 16. Anche i registri stessi possono essere dimensionati come larghezza, sempre per permettere la maggior ottimizzazione in termini di gate consumati. Prima di effettuare queste operazioni abbiamo inserito le DEFINE dei registri del core PWM. Dopo la prima istruzione che salta al Main, troviamo le istruzioni che effettuano la init del modulo PWM stesso, usando l’istruzione APBWR, che ci permette di scrivere su uno qualsiasi dei 16 slot periferici disponibili (nel nostro caso lo slot 0). Conclude il semplice programma  l’operazione di scorrimento di un bit a 1 sui primi 4 pin della porta di OUTPUT e la memorizzazione in RAM del valore medesimo Questa memorizzazione è stata inserita per semplice prova, infatti nella parte finale del programma tali valori vengono riletti dalla RAM e riportati sulla porta di OUTPUT. Per permettere una visualizzazione su oscilloscopio di questo scorrimento, abbiamo fatto uso di una chiamata ad una routine di ritardo di 10ms.

Conclusioni

I test eseguiti in laboratorio su una scheda prova, hanno evidenziato una velocità ottenibile di 40MIPS senza particolari ottimizzazioni, ad eccezione dell’accorgimento di piazzare tutto il blocco microprocessore a ridosso della zona RAM (per la A3P250 in alto) per mantenere  i tempi di propagazione contenuti. La figura 3 riporta la simulazione dove è possibile notare i quattro segnali PWM generati come da programma mentre gli Output effettuano lo shift dei bit; la base tempi è stata accorciata per permettere una visualizzazione maggiore dei segnali in uso.

Figura 3: simulazione del progetto.

Figura 3: simulazione del progetto.

 

Figura 4: simulazione del progetto.

Figura 4: simulazione del progetto.

Il core ABC si dimostra interessante soprattutto per la sua adattabilità e flessibilità. Infatti grazie alla scelta dinamica del BUS, alla possibilità di inserire anche istruzioni attualmente non supportate e al basso consumo di gate, è possibile  il suo utilizzo su FPGA di taglio piccolo a basso costo oppure il suo utilizzo multiplo su FPGA di taglio maggiore.

DEF COREPWM 0
DEF PWM_PRESC 0x00
DEF PWM_PERIOD 0x04
DEF PWM_ENAB1 0x08
DEF PWM_ENAB2 0x0C
DEF PWM1_POSEDGE 0x10
DEF PWM1_NEGEDGE 0x14
DEF PWM2_POSEDGE 0x18
DEF PWM2_NEGEDGE 0x1C
DEF PWM3_POSEDGE 0x20
DEF PWM3_NEGEDGE 0x24
DEF PWM4_POSEDGE 0x28
DEF PWM4_NEGEDGE 0x2C
JUMP $Main
$Main
APBWRT DAT16 COREPWM PWM_PRESC 1
APBWRT DAT16 COREPWM PWM_PERIOD 500
// 20uS 50kHZ DI PERIODO PER TUTTI E 4 I PWM
APBWRT DAT16 COREPWM PWM1_POSEDGE 0
APBWRT DAT16 COREPWM PWM1_NEGEDGE 16
APBWRT DAT16 COREPWM PWM2_POSEDGE 16
APBWRT DAT16 COREPWM PWM2_NEGEDGE 32
APBWRT DAT16 COREPWM PWM3_POSEDGE 32
APBWRT DAT16 COREPWM PWM3_NEGEDGE 48
APBWRT DAT16 COREPWM PWM4_NEGEDGE 64
APBWRT DAT16 COREPWM PWM_ENAB1 0x0F
$Start
load 0x01
IOWRT
CALL $Wait10ms
RAMWRT 0x10 ACC
shl0
IOWRT
CALL $Wait10ms
RAMWRT 0x11 ACC
shl0
IOWRT
CALL $Wait10ms
RAMWRT 0x12 ACC
shl0
IOWRT
CALL $Wait10ms
RAMWRT 0x13 ACC
NOP
CALL $Wait10ms
CALL $Wait10ms
CALL $Wait10ms
CALL $Wait10ms
CALL $Wait10ms
CALL $Wait10ms
CALL $Wait10ms
CALL $Wait10ms
CALL $Wait10ms
CALL $Wait10ms
RAMREAD 0x10
IOWRT
CALL $Wait10ms
CALL $Wait10ms
RAMREAD 0x11
IOWRT
CALL $Wait10ms
CALL $Wait10ms
RAMREAD 0x12
IOWRT
CALL $Wait10ms
CALL $Wait10ms
RAMREAD 0x13
IOWRT
CALL $Wait10ms
CALL $Wait10ms
JUMP $Start
$Wait10ms
// 5ms con CLK 50Mhz
LOADZ 41666
$Wait10msInner
DECZ
JUMP IFNOT ZZERO $Wait10msInner
RETURN
Listato del Programma di Prova

 

 

 

Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend