domenica 5 giugno 2016

Cyclone V SoC: Configuriamo ARM DS-5

Precedentemente avevamo visto come collegare la scheda DE1-SoC al computer tramite cavo ethernet, vediamo adesso come configurare al meglio il software DS-5 per essere maggiormente produttivi nella scrittura del software.

In particolare all’interno dello stesso programma riusciremo ad avere sotto controllo il filesystem, i processi ed un terminale per interagire col nostro sistema ed il debug remoto dei nostri programmi.

Come prima operazione cambiamo la password al nostro sistema Linux tramite il comando passwd,questo ci permetterà di collegarci tramite SSH in quanto una password, per quanto semplice sia, è mandatoria.

passwd

Apriamo adesso Eclipse for DS-5 e scegliamo il menù Window / Open Perspective / Other come mostrato nella figura seguente:

ds5_menu_perspective

Scegliamo Remote System Explorer e confermiamo con OK

open_perspective

Apparirà un nuovo pannello, facciamo click col tasto destro del mouse su Local e scegliamo New / Connection

new_connection

Alla richiesta del tipo di sistema remoto scegliamo Linux e facciamo click su Next. Specifichiamo adesso i dati di connessione della scheda e premiamo nuovamente Next.

new_connection_first_step

Selezioniamo ssh.files tra le configurazioni disponibili per utilizzare il protocollo Sftp per accedere al filesystem e premiamo Finish.

new_connection_files

Espandendo la voce DE1SOC e navigando tra i menù avremo adesso la possibilità di copiare file tramite drag-and-drop, visionare e terminare processi ed interagire col sistema tramite terminale.

ds5

NB: Verrà chiesta la password prima di accedere alle risorse del sistema remoto e la prima volta un messaggio di Warning ci informerà che l’autenticità dell’host non può essere stabilita, premete semplicemente Yes in quanto con una connessione diretta tramite ethernet non ci sono particolari problematiche di sicurezza.

rsa_fingerprint

Creiamo adesso un nuovo progetto scegliendo File / New / C Project. Scegliamo GCC come Toolchain, utilizzeremo gli strumenti gratuiti inclusi nella versione ARM DS-5 Community Edition.

w2

Il progetto creato sarà inizialmente vuoto, aggiungiamo un file sorgente scegliendo New / Source File ricordandoci di aggiungere l’estensione .C al nome del file.

w3

Creiamo un semplice Hello Arm con il seguente codice e compiliamo tramite Project / Build All:

hello

Selezioniamo Debug Configurations premendo il triangolino vicino al pulsante Debug, come illustrato nell’immagine seguente:

w5

A questo punto scegliamo come target Linux Application Debug / Application Debug / Connections via gdbserver / Download and debug application visto che andremo a fare il debug di un applicazione Linux. La versione più completa di DS-5 mostrerà in questa schermata anche altre opzioni di cui però non ci occuperemo.

w6

Spostandoci nella scheda adiacente Files scegliamo come Application on host to download tramite il pulsante Workspace l’eseguibile creato in precedenza.

w7

Nei campi Target download directory e Target working directory impostiamo il percorso /home/root

Confermiamo con Apply e chiudiamo la finestra di dialogo. Siamo adesso pronti ad effettuare un debug remoto con strumenti quali breakpoint, esecuzione passo passo e la visualizzazione di dati relativi a variabili e thread. Premiamo semplicemente il pulsante Debug per iniziare.

w8

Una volta terminata la sessione di Debug esplorando i file presenti nel sistema remoto noteremo la presenza dell’eseguibile, che sarà richiamabile anche in modo tradizionale tramite terminale.

fs

Nonostante questo articolo sia meno tecnico del solito, avere a disposizione la corretta procedura può accelerare la messa a punto della propria postazione di sviluppo. Alla prossima.

martedì 24 novembre 2015

FPGA: Numeri a virgola fissa (seconda parte)

Dopo aver introdotto i numeri fixed point vediamo un semplice blocco in VHDL che calcola la circonferenza di un cerchio dato il raggio.


Possiamo vedere come sia stata definita una costante two_pi che intuitivamente conterrà il valore 2 * pi greco.

La costante è valorizzata tramite la funzione to_ufixed che provvederà a convertire un numero REAL (ma funziona anche con INTEGER, SIGNED e UNSIGNED)  nel tipo per l'appunto UFIXED senza dover convertire "a mano" il numero nella stringa di bit "00110010", approssimazione di 6.28 data la rappresentazione del numero con soli 3 bit per la parte decimale.

Il valore effettivo ottenuto sarà però 6.25, c'è quindi da porre particolare attenzione alla precisione con la quale si eseguono questo tipo di calcoli, il codice VHDL può infatti facilmente trarre in inganno.

Il raggio è costituito da un numero fixed point ad 8 bit mentre il risultato, per evitare overflow, è un numero di 16 bit, dato che è il prodotto di una moltiplicazione.

Per evitare errori in fase di compilazione bisogna tassativamente seguire le regole di dimensionamento, concepite per evitare problemi involontari di overflow, sotto riportate:



Nel nostro caso ci serviamo della riga A * B della tabella. A'left assume il valore INTEG_BIT-1, dato dal bound sinistro scelto nel tipo ufixed del segnale radius, mentre analogamente B'left vale INTEG_BIT-1, dato dalla costante two_pi.

A'right ed B'right avranno entrambi il valore -DECIM_BIT.

Il risultato dovrà avere, seguendo la tabella, un range pari a 2*(INTEG_BIT-1)+1 downto -2*DECIM_BIT, ovvero 9 downto -6 quindi un numero di 16 bit come già detto.

Il VHDL 2008 coi fixed point ci offre una funzione di ridimensionamento con saturazione (per problematiche di overflow) ed arrotondamento (per problematiche di underflow) chiamata resize per eventualmente adattare il risultato ad un numero con diversa risoluzione, vediamone un esempio:


Dove abbiamo come argomenti di resize il numero da ridimensionare, il bound sinistro ed il bound destro del risultato. In tal modo l'uscita circumference avrà la stessa dimensione di 8 bit dell'ingresso.

Sono disponibili diversi overload della funziona resize e rimando alla Fixed point package user’s guide per una descrizione esaustiva di tutte le funzioni.

Nella funzione resize di default sono abilitati l'arrotondamento e la saturazione, seppur è possibile scegliere di troncare e avvolgere (wrap) il valore per ottenere circuiti di velocità maggiore ed area minore.

Sotto è riportata la vista RTL del circuito generato con arrotondamento e saturazione abilitati

L'implementazione su Cyclone V è di 11 ALM ed 1 blocco DSP. Sotto è riportata una simulazione del blocco sopra descritto:



















E' possibile notare come l'uscita saturi a 31.875 (tutti i bit pari ad 1) in caso di valori d'ingresso eccessivi per la risoluzione utilizzata.

Disabilitando arrotondamento e saturazione, il circuito ottenuto sarà come è facile aspettarsi costituito dal solo moltiplicatore, implementato con un singolo DSP. Purtroppo spesso il risultato così ottenuto è poco utilizzabile.



Per modificare lo stile di arrotondamento e di overflow in tutte le operazioni è possibile modificare le costanti fixed_round_style e fixed_overflow_style nel file fixed_pkg_c.vhdl






Per gestire l'underflow, che può verificarsi quando la parte decimale non ha abbastanza risoluzione per rappresentare il risultato, si può utilizzare una modalità fixed_round in cui la parte decimale viene arrotondata al più vicino valore rappresentabile oppure una modalità fixed_truncate dove sono semplicemente persi i bit meno significativi.

L'underflow può verificarsi nella divisione, dove l'errore può accumularsi a causa della natura iterativa degli algoritmi. Per ridurre l'errore vengono inseriti automaticamente dei bit di guardia (guard bit) che aumentano temporaneamente la risoluzione della parte decimale nei calcoli intermedi. Di default il VHDL 2008 utilizza 3 bit di guardia per operazioni come la divisione.

Per gestire l'overflow è possibile utilizzar la modalità fixed_saturate oppure la modalità fixed_wrap che è spesso il "normale" comportamento dei calcolatori e non comporta l'utilizzo di hardware aggiuntivo, incrementando il numero più grande rappresentabile si otterrà il numero più piccolo.

Per singole operazioni è possibile utilizzare gli overload delle funzioni come per esempio









Non mi rimane che augurarvi buona aritmetica.. coi fixed point!


NB: Per rendere compatibile il codice mostrato con ModelSim e compilabile da Quartus 15 è stato modificato il nome della libreria ieee_proposed in ieee, modificando il file fixed_pkg_c.vhdl di cui si è parlato nel precedente articolo. In tale modo ModelSim non lamenterà la mancanza della libreria ieee_proposed, seppur sia possibile crearla. Compilando il codice con un sintetizzatore con supporto per i fixed point del VHDL 2008 non sarà così necessaria alcuna modifica.

giovedì 1 ottobre 2015

FPGA: Numeri a virgola fissa (prima parte)


Il linguaggio VHDL originariamente non prevede alcun supporto ai numeri decimali, con la ratificazione della versione VHDL-2008 si arricchisce finalmente del supporto per i numeri a virgola fissa ed a virgola mobile.

Sfortunatamente la diffusione del nuovo standard non è rapida e ancora oggi la maggior parte degli strumenti di sviluppo supporta un subset più o meno ampio di tutte le funzionalità.

Quartus e Vivado attualmente non supportano la sintesi dei numeri a virgola fissa (fixed-point) o mobile (floating-point), è però possibile scaricare da http://www.eda.org/fphdl una libreria di supporto che permette di fare da ponte da VHDL-93 a VHDL-2008, permettendone così la sintesi con gli strumenti attuali.

Per poter sintetizzare i fixed point è sufficiente aggiungere al progetto i file fixed_pkg_c.vhdl e fixed_float_types_c.vhdl e dichiarare l'utilizzo del package fixed_pkg tramite

library ieee_proposed;
use ieee_proposed.fixed_pkg.all;

Vediamo in questo articolo un'introduzione ai numeri in virgola fissa e le prestazioni delle principali operazioni aritmetiche.

I numeri a virgola fissa vengono rappresentati stabilendo in una posizione ben definita la virgola, ad esempio è possibile rappresentare il valore 3,25 tramite una stringa di bit composta da 1 bit per il segno, 4 bit per la parte intera e 3 bit per la parte decimale.


00011010 rappresenterà proprio 3,25 in quanto:
- il bit 0 indicherà il segno positivo
- 0011 il valore intero 3 con la classica codifica binaria
- 010 il valore decimale 0.25 in quanto l'unità sarà suddivisa in 3 bit, quindi 2^3=8 valori ed 1/8=0.125 e di conseguenza il valore 010, 2 in codifica binaria, rappresenterà 2*0.125=0.25

Per i numeri a virgola fissa i nuovi tipi introdotti sono sfixed ed ufixed, rispettivamente per i numeri con e senza segno.

I numeri negativi sono rappresentati come usuale in complemento due, invertendo i bit ed aggiungendo 1 al risultato.

Vediamo come dichiarare un segnale di tipo sfixed:

signal x : sfixed (4 downto -3);

Tramite il range possiamo specificare come suddividere la parte intera da quella decimale.
La virgola è situata tra l'indice 0 e -1, avremo quindi 5 bit per la parte intera (compreso il bit di segno) e 3 bit per la parte decimale.

NB: E' importante ricordarsi che la parte intera comprende l'indice 0, quindi la sintassi è più semplicemente: sfixed (INTEG-1 downto -DECIM) dove INTEG è il numero di bit per la parte intera (compreso il bit di segno) e DECIM il numero di bit per la parte decimale.

Vediamo adesso un semplice blocco sommatore:



Dove in particolare, oltre a quanto abbiamo visto, notiamo che la dimensione del risultato z è superiore di un bit rispetto ai due addendi per evitare overflow (ed errori in compilazione).

Vedremo in prossimi articoli ulteriori dettagli sui fixed-point.

Concludo l'articolo con una tabella relativa alle prestazioni dei numeri a virgola fissa con segno, estratte in riferimento ad un dispositivo Cyclone V 5CEFA9F23C8, come quello presente nella scheda BEMICRO CV A9.


NB: L'occupazione di risorse logiche (ALM) è stata misurata con logica puramente asincrona mentre le frequenze massime (in MHz) sono state ottenute registrando gli ingressi e le uscite, ovvero inserendo dei flip-flop per evitare di includere nella misurazione i tempi di propagazione verso i pin esterni e poter utilizzare l'analisi statica di TimeQuest per circuiti sincroni.

I bit sono stati equamente suddivisi tra parte intera+segno e parte decimale, ad esempio se la lunghezza dati in tabella è 8 bit per operando 4 bit rappresentano parte intera e segno e 4 bit la parte decimale. La lunghezza dati del risultata varia in base al tipo di operazione eseguita per non permettere overflow.

Dalla tabella è possibile notare come le prestazioni per somma e moltiplicazione siano in linea con le prestazioni degli interi.

I blocchi DSP della FPGA in oggetto non permettono un trattamento di dati di dimensione 32x32, per questo motivo per tale operazione sono stati utilizzati più blocchi DSP.

La divisione rappresenta sicuramente la nota dolente, in quanto è sintetizzata inferendo l'IP LPM_DIVIDE senza pipeline, per prestazioni di throughput migliori è consigliabile istanziare manualmente tale blocco specificando una pipeline di profondità adeguata per la propria frequenza target o sfruttare le funzionalità di retiming di sintetizzatori in grado di spostare i flip-flop all'interno della logica di divisione, come ad esempio Synplify.

lunedì 7 settembre 2015

Wave Sheet

Qualche volta può essere utile riflettere con carta e penna e nel ragionare sulle forme d'onda può essere comodo disporre di un foglio predisposto appositamente per abbozzare qualche idea.

Voglio condividere con voi un template che ho creato, da stampare in orizzontale:


L'utilizzo è abbastanza intuitivo, nella riga iniziale è possibile scrivere il titolo del foglio mentre sulle righe a sinistra il nome dei vari segnali il cui contenuto sarà scritto all'interno delle forme d'onda.

Spero vi faccia risparmiare tempo e magari contribuisca ad un maggiore ordine anche con questi antichi strumenti

NB: Sebbene sia possibile ottenere un risultato analogo con una tabella l'aspetto è più intuitivo per degli elettronici


FPGA: Engineering Change Orders

Sintesi dell'articolo: Modifichiamo senza una ricompilazione completa alcune parti del progetto come la frequenza di uscita del PLL tramite gli strumenti ECO di Quartus.

Durante il ciclo di sviluppo purtroppo le specifiche possono cambiare all'ultimo minuto, queste modifiche sono chiamate in gergo ECO (Engineering Change Orders) e possono  in alcuni casi essere introdotte per compensare problemi di design del sistema.

Vediamo un ipotetico caso semplificato di ECO e di come Quartus possa venirci ancora un volta incontro.

Supponiamo di avere un design su logiche programmabili ad elevata complessità, quindi con tempi di compilazione elevati, e di avere una specifica iniziale di frequenza di 300 MHz ma di aver scelto un dispositivo troppo lento per implementare a tale velocità il design. Purtroppo ci accorgiamo verso il completamento dei lavori che tale frequenza non è raggiungibile.




Il sistema, al solo scopo di facilitare la comprensione, è rappresentato semplicemente nel diagramma da un doppio moltiplicatore con pipeline.

Il design utilizza come usuale un PLL per generare la frequenza di sistema e dopo aver tanto atteso visualizziamo il fatidico Timing requirements not met da Quartus. La frequenza massima per il nostro sistema che TimeQuest riporta supera di poco i 250 MHz.


Non avendo ulteriore tempo a disposizione decidiamo di accettare 250 MHz come frequenza del nostro sistema.

La procedura "standard" richiederebbe di modificare i parametri del PLL e ricompilare il progetto, così facendo innanzitutto non è detto che la frequenza massima dopo la modifica sia sempre superiore ai 250 MHz.

E' però possibile evitare la compilazione completa, che in sistemi complessi può richiedere diverse ore, cambiando solamente le proprietà relative al PLL, vediamo come.

Nel report di compilazione del Fitter andiamo innanzitutto ad individuare la sezione PLL Usage nella categoria Resource Section, facendo click col pulsante destro sul pll scegliamo Locate Node / Locate in Resource Property Editor.


Verranno visualizzate le proprietà del PLL come mostrato nell'immagine seguente


I campi senza sfondo grigio sono modificabili, cambiamo quindi il moltiplicatore del clock da 6 a 5 nel nostro caso per ottenere un clock di uscita di 250 MHz al posto dei 300 MHz.



Il valore M del moltiplicatore verrà aggiornato di conseguenza e tutti i campi modificati verranno evidenziati in rosso.

Ricordiamo infatti l'equazione della frequenza di uscita del PLL in modalità normale:

Altre equazioni come quelle per la variazione della fase ad esempio sono reperibili nella documentazione di Altera.

Scegliamo adesso Edit / Check and Save All Netlist Changes per applicare le modifiche fatte


Dopo una breve compilazione parziale, composta dalla fase di Fitter parziale ed Assembler del file di programmazione il progetto a 250 MHz sarà pronto per essere caricato sulla FPGA  per la validazione.

Prima però eseguiamo TimeQuest per controllare se abbiamo effettivamente risolto tutti i problemi, le violazioni dei tempi di Setup sono sparite ed andando nella scheda Clocks è possibile vedere che la frequenza in uscita dal PLL è effettivamente stata modificata a 250 MHz.


Non ci rimane che provare il design a 250 MHz.

NB: TimeQuest Timing Analyzer è evidenziato di rosso perché sono presenti alcuni percorsi non vincolati nel design che però non hanno criticità per il semplice design utilizzato da esempio per illustrare le funzionalità ECO.

Quartus ci offre inoltre tramite la finestra Change Manager richiamabile dal menù View / Utility Windows che ci da un resoconto delle modifiche ECO così attuate


Lo strumento permette di esportare in file .TCL le modifiche o di riportare il tutto alla situazione originaria.

Questo flusso di sviluppo rapido è molto utile anche durante l'ottimizzazione di progetti in continua modifica per evitare di eseguire una doppia compilazione se la frequenza desiderata non è raggiungibile.

Oltre al PLL è possibile modificare altre celle elementari così come lo standard, lo slew rate ed il current strenght dei pin di I/O.

NB: A causa della differente struttura dei PLL nei dispositivi Cyclone V le funzionalità ECO non sono supportate, è possibile però utilizzare l'IP Altera PLL Reconfig come descritto nell'application notes 661 di Altera per variare i parametri del PLL a tempo di esecuzione.

lunedì 24 agosto 2015

FPGA: Scripting con TCL

Software EDA (Electronic Design Automation) come Quartus, Vivado, ISE e Synplify Pro utilizzato da diversi produttori di FPGA tra cui la nuova startup cinese Gowin, condividono tutti il linguaggio di scripting TCL (Tool Command Language) per l'automazione di task comuni.

Vediamo innanzitutto come creare ed eseguire un semplice script TCL con Quartus.

Creiamo un nuovo progetto e scegliamo File / New / Tcl Script File e scriviamo all'interno del nuovo file la seguente riga:

puts "Hello World"

Salviamo il file col nome hello_world.tcl ed andiamo sul menù Tools / TCL Scripts...
Si presenterà la seguente schermata, premiamo Run dopo aver selezionato il nostro script.


Un messaggio ci confermerà della corretta esecuzione dello script ma non apparirà alcun messaggio "Hello World" a video. 

Per visualizzare l'output degli script è necessario aprire la relativa finestra andando su View / Utility Windows / Tcl Console


La prima riga conterrà il comando di esecuzione del file di script, chiamato in automatico dalla pressione del pulsante Run precedentemente. E' naturalmente possibile richiamare gli script dalla console TCL scrivendo direttamente il comando source nomefile.tcl.

Sotto al comando è possibile osservare il semplice output che ha generato il nostro script.

Vediamo adesso uno script di maggiore utilità progettuale.

Spesso si ha la necessità di creare molteplici configurazioni di testbench partendo da file già esistenti, l'operazione come abbiamo visto in precedenza richiede diversi passaggi, tra cui la compilazione delle impostazioni del testbench tramite l'interfaccia grafica che è sotto riportata per referenza:


Al crescere del numero dei file l'operazione diventa meccanica e molto fastidiosa, col seguente script TCL possiamo configurare automaticamente in un attimo tutti i nostri testbench, di cui alcuni eventualmente saranno ritoccati manualmente, risparmiando ad ogni modo una notevole quantità di tempo.


Tramite il comando set assegniamo dei valori a delle variabili che potranno essere richiamati tramite la sintassi $nome_variabile.

Nel nostro caso avremo le variabili dir, ext, design_instance_name e run_sim_for a cui assoceremo dei valori fissi.

- dir specifica la cartella contenente i file di testbench

- ext specifica l'estensione dei file di testbench, se non abbiamo problemi di compatibilità con altri software come ad esempio Xilinx ISE, possiamo anche utilizzare l'estensione .vht per differenziare i file di testbench rispetto agli altri.

- design_instance_name specifica il nome dell'istanza sotto test, naturalmente tutte le istanze nei testbench dovranno chiamarsi allo stesso modo.

- run_sim_for specifica il tempo di esecuzione, al pari del campo "End simulation at" nella finestra di dialogo di Quartus sopra mostrata.

E' altresì importante che nei testbench il nome della "entity vuota" corrisponda al nome del file per un corretto funzionamento di questo script. Per necessità diverse è possibile partire da questo script per modificarlo comunque a piacere.

Nelle righe seguenti avviene una ricerca dei file con l'estensione scelta nella cartella specificata dopodiché per ogni file viene estratto il nome senza estensione ed utilizzato per il richiamo dei comandi set_global_assignment specifici di quartus per l'impostazione dei testbench.

Altri EDA dispongono di comandi specifici per l'automazione di diversi task, è necessario quindi consultare la documentazione di ogni software specifico per tali comandi.

NB: Il file .qsf associato al progetto Quartus è a tutti gli effetti uno script TCL creato automaticamente tramite l'interfaccia del programma durante il normale utilizzo, aprendo il file con un editor di testo è possibile visualizzare i comandi per incorporarli nei propri script, se non si vuole ricorrere alla documentazione di Scripting.


Buona automazione con gli script TCL

venerdì 7 agosto 2015

FPGA: Xilinx ISE ed Internet Explorer 11

Oggi vediamo una piccola fix per risolvere un problema che può nascere nel tool di sviluppo Xilinx ISE e nei suoi accessori.

Seppur il software ISE sia ormai superato da Vivado è ancora necessario per poter sviluppare per famiglie di dispositivi come Spartan-6, Virtex-6, Coolrunner e le generazioni precedenti.

Un problema che può verificarsi (verificato su Windows 7) dopo l’aggiornamento di Internet Explorer all’ultima versione è la mancanza di funzionamento di ChipScope Inserter ed ChipScope Pro Analyzer con messaggi di errore come “Can't load ..\..\java6\nt\jre\bin\client\jvm.dll.”

Per risolvere la problematica aggiungiamo nella variabile d’ambiente PATH i seguenti valori se non presenti:

C:\Xilinx\14.7\ISE_DS\ISE\\lib\nt;C:\Xilinx\14.7\ISE_DS\ISE\\bin\nt;C:\Xilinx\14.7\ISE_DS\ISE\bin\nt;C:\Xilinx\14.7\ISE_DS\ISE\lib\nt;C:\Xilinx\14.7\ISE_DS\ISE\..\..\..\DocNav;C:\Xilinx\14.7\ISE_DS\PlanAhead\bin;C:\Xilinx\14.7\ISE_DS\EDK\bin\nt;C:\Xilinx\14.7\ISE_DS\EDK\lib\nt;C:\Xilinx\14.7\ISE_DS\EDK\gnu\microblaze\nt\bin;C:\Xilinx\14.7\ISE_DS\EDK\gnu\powerpc-eabi\nt\bin;C:\Xilinx\14.7\ISE_DS\EDK\gnuwin\bin;C:\Xilinx\14.7\ISE_DS\EDK\gnu\arm\nt\bin;C:\Xilinx\14.7\ISE_DS\EDK\gnu\microblaze\linux_toolchain\nt_be\bin;C:\Xilinx\14.7\ISE_DS\EDK\gnu\microblaze\linux_toolchain\nt_le\bin;C:\Xilinx\14.7\ISE_DS\common\bin\nt;C:\Xilinx\14.7\ISE_DS\common\lib\nt;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\

E’ anche possibile creare una variabile dell’utente al posto della variabile di sistema per risolvere in modo ancora più rapido ed evitare di controllare tutti i percorsi esistenti.

Dove è possibile naturalmente adattare alla propria versione di ISE i PATH e rimuovere il percorso per la versione Java di Oracle se non installata.