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.
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).
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.
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 |