• Non ci sono risultati.

4. Progettazione del sistema elettronico per l’applicazione FTI in tempo reale.

N/A
N/A
Protected

Academic year: 2021

Condividi "4. Progettazione del sistema elettronico per l’applicazione FTI in tempo reale."

Copied!
55
0
0

Testo completo

(1)

4. Progettazione del sistema elettronico

per l’applicazione FTI in tempo reale.

4.1. Introduzione.

Lo sviluppo del firmware DSP e del progetto su FPGA è stato condotto facendo particolare riferimento alla prima delle tre applicazioni astronomiche, la Fast Transient Imaging, che risulta essere l’applicazione base da cui è possibile ottenere le altre due con integrazioni a livello del software DSP.

Il capitolo quarto illustra i passi compiuti nella progettazione della scheda di elaborazione, con particolare riguardo al progetto dello FPGA e del DSP che la costituiscono. Il risultato finale è il raggiungimento di una versione, funzionante in tempo reale, di sistema elettronico per l’acquisizione ed elaborazione dati per l’esperimento di FTI. Questo sistema potrà essere utilmente usato per il testing dell’intero sistema SPADA comprensivo quindi dei sensori su telescopio.

Nei paragrafi seguenti vengono descritte le tre fasi successive di sviluppo: la fase di conoscenza e prova della scheda C6713, la fase di programmazione dello FPGA e infine la programmazione del DSP.

4.2. Fase di prova della scheda.

Poiché la scheda C6713 Compact è di recente fabbricazione la casa di produzione Orsys ci ha fornito la prima release del materiale informativo ed essendo tra i primi acquirenti a sviluppare un’applicazione su di essa è stata

(2)

necessaria una prima fase di approfondimento della documentazione e di prova della scheda e degli esempi dimostrativi forniti.

La documentazione oltre all’ ”hardware reference guide” comprende una “board library” formata da un gruppo di driver a basso livello che permettono di gestire l’hardware ausiliario della C6713. Gli esempi mostrano come utilizzare questa board library e sono stati il punto di partenza per lo sviluppo della nostra propria applicazione.

Durante la prova delle applicazioni di esempio, non senza fatica, sono stati rilevati alcuni errori di sistema confermati e successivamente corretti dalla casa produttrice in una seconda versione della documentazione tra cui:

• Un errato assegnamento nel constraints file della piedinatura dei connettori Micro-line.

• Un malfunzionamento delle interruzioni a causa di un errore nell’allineamento della tabella delle funzione di handler collegate alle interruzioni di programma.

• Un errore nella generazione del valore di clock sia della EMIF che del processore rispetto a quelli forniti nella documentazione.

Acquisita una certa conoscenza della scheda e una buona dimestichezza con i software di sviluppo è stato possibile iniziare la fase di programmazione di DSP e FPGA secondo la partizione delle specifiche funzioni loro assegnate nel capitolo tre.

4.3. Sviluppo FPGA.

Si è scelto di utilizzare la scheda C6713 nella configurazione con il DSP come master e lo FPGA come slave. Questa scelta è stata guidata dalla decisione di utilizzare la logica programmabile dello FPGA per implementare una struttura di base fissa e con compiti univoci e ripetitivi mentre al DSP sono stati affidati tutti i

(3)

restanti compiti di gestione particolare delle interfacce e dei trasferimenti. E’ stato necessario quindi sviluppare per prima la parte di programmazione dello FPGA per svolgere le operazioni di conteggio e le altre operazioni base descritte nel capitolo terzo.

4.3.1. Flusso di progetto.

Il flusso di progetto per lo sviluppo del modulo FPGA consiste in due parti: • Lo sviluppo del sistema FPGA, scrivendo codice in VHDL,

compilandolo e simulando con l’ausilio del software Xilinx e generando, alla fine delle fasi di sintesi e piazzamento, un file di configurazione .bit che può essere scaricato sulla C6713, via JTAG, per il debugging, ma che non può essere immagazzinato permanentemente nella memoria flash della scheda.

• La conversione del file di configurazione in un file di codice C può essere realizzata facendo creare al software Xilinx ISE un file di uscita .rbt . Questo viene poi processato da un tool denominato BinToHex il quale genera il file .c desiderato. A questo punto, includendo questo file .c nel progetto su DSP, il codice dello FPGA viene collegato alla nostra applicazione.

Il programma che gira su DSP utilizza le informazioni contenute in tale file per caricare lo FPGA.

Per finire tutta l’applicazione DSP verrà poi memorizzata in modo permanente sulla memoria flash della scheda con il Flash File System.

(4)

4.3.2. Architettura VHDL

Il modulo FPGA, descritto mediante il linguaggio VHDL, si basa sulla struttura convenzionale del busmaster Microline (BSP) che permette di utilizzare la scheda come una scheda CPU micro-line.

Figura 4.1: Diagramma a blocchi dei collegamenti tra FPGA con struttura BSP ed esterno.

Si è scelta questa configurazione perché generale e vicina allo standard delle C6x1xCPU e dunque riutilizzabile in modo scalabile in futuro, anche se per la nostra applicazione non è necessaria la connessione alla HPI e a tutti i connettori della micro-line.

Per implementare le funzionalità viste nel capitolo precedente sono necessari: l’utilizzo di 60 piedini micro-line da usare come ingressi per i segnali provenienti dallo SPADA, la connessione con l’interfaccia EMIF per effettuare il caricamento della configurazione e i trasferimenti tra registri interni allo FPGA e memoria

(5)

SRAM, la connessione con la streaming port e il data mover per l’accesso al link firewire direttamente o via DSP e l’uso dei LED per funzioni di debugging.

L’EMIF risulta quindi l’interfaccia predisposta per trasferimenti di dati ad alta velocità tra DSP e FPGA.

Figura 4.2: Connessioni tra FPGA e l’interfaccia EMIF del DSP.

Lo FPGA è visto come una periferica montata sullo spazio di memoria del DSP, quindi deve decodificare le linee di controllo dell’EMIF per determinare se viene acceduto dal processore. L’accesso può avvenire solo attraverso le linee CE2 e CE3 che individuano gli spazi di indirizzi riservati nel progetto allo FPGA.

I segnali di abilitazione dei byte e di controllo vengono opportunamente utilizzati nel nostro modulo per ottenere le operazioni di lettura e scrittura volute, mentre i

(6)

segnali di arbitraggi del bus, data la configurazione dello FPGA come slave, non sono significativi.

Per quanto riguarda il clock, lo FPGA lo riceve dall’EMIF e la sua frequenza è programmabile a livello del PLL controller del DSP, ed è stata impostata ad un valore pari a 90 MHz.

Al riguardo delle interruzioni, lo FPGA ha a disposizione due interruzioni mascherabili filate direttamente con il DSP: la CPU_EXT_INT4 e CPU_EXT_INT5, configurate per essere sensibili al fronte in salita del segnale applicato. Vi è la possibilità di utilizzare altre due interruzioni passando tramite il PLD, ma nel nostro progetto non ce n’è stato bisogno.

Figura 4.3: Diagramma a blocchi delle linee di Interruzioni tra FPGA e DSP. Lo FPGA ha accesso diretto alla data mover port del LLC usata per il trasferimento di dati sia in modo asincrono che isocrono attraverso la firewire. Per il dettaglio delle funzioni delle linee di stato e di controllo mostrate sotto si rimanda alla bibliografia [42] e [61].

(7)

Figura 4.4: Diagramma a blocchi delle linee di stato e controllo tra FPGA eLLC. La struttura progettata utilizza un modulo principale per l’elaborazione dei dati detto SDPM (Spada Data Processing Module), un secondo modulo per la gestione dei trasferimenti firewire che si connette al data mover detto DM_PORT, un modulo Clock Manager che riceve il clock dalla EMIF e lo distribuisce opportunamente ai moduli interni, un modulo che funge da multiplexer con buffer tristate per gestire il bus dati nelle operazioni di I\O, un po’ di logica di collegamento per generare a partire dai segnali di controllo del DSP le corrette abilitazioni per i moduli interni ed infine gli I/O Buffer a cui collegare tutti gli ingressi non utilizzati per evitare di lasciare i pin non utilizzati in alta impedenza.

(8)
(9)

Vediamo ora nel dettaglio la struttura dei singoli moduli.

4.3.3. Spada Data Processing Module (SDPM)

Il top module Spada Data Processing Module è costituito dai sottomoduli: • Ic_counter.

• Write valid state machine • Timer.

• Gate Interlock. e da:

• Un modulo che funge da multiplexer per la scrittura verso il DSP. • Una matrice di registri di 30 righe x 32 colonne per immagazzinare le

uscite dei contatori.

• Un vettore per registrare la condizione di saturazione dei 60 contatori. • Un registro di informazione a 32 bit.

• Un registro a 1 bit per la validazione di scrittura. • Due registri di configurazione a 32 bit.

(10)

Figura 4.6: Schema a blocchi completo del modulo SDPM.

L’idea di funzionamento generale del modulo è la seguente: il DSP carica la configurazione della finestra di acquisizione in modo asincrono sul cfg_reg, successivamente lo notifica alla logica di controllo mediante il write valid bit WR_I=1. La relativa macchina a stati controlla che il WR_I sia alto per almeno due cicli di clock, in tal caso procede ad abilitare tramite il Data_en il registro sincrono cfg_reg_FF che carica la finestra temporale al clock successivo. Allo stesso ciclo di clock in cui viene caricata la finestra temporale valida, viene settato anche il Load New Data che va ad abilitare il Timer.

Il timer, una volta abilitato, utilizza la finestra temporale valida per generare un impulso lungo un ciclo di clock periodico con periodo pari alla finestra temporale impostata. Questo impulso va in uscita a generare una interruzione sulla

(11)

EXT_INT5, per notificare al DSP la disponibilità di nuovi dati da trasferire, e contemporaneamente va in modo sincrono ad azzerare i contatori e ad abilitare la scrittura dei conteggi nella matrice di dati e della configurazione attuale nel count_info_reg. Si osserva come la matrice dove sono immagazzinati i conteggi sia 30x32, per ottenere la massima velocità; infatti poiché il DSP lavora a 32 bit si preferisce caricare in ogni riga della matrice il risultato di due contatori a 16 bit successivi rispettivamente nella parte alta e nella parte bassa del registro.

Nel caso che un contatore saturi questo viene segnalato nella rispettiva posizione del vettore Saturation a 60 posizioni.

Il registro di informazione riceve nei primi 14 bit il valore della finestra temporale attualmente caricata nel registro di configurazione sincrono, inoltre riceve in 6 bit le informazioni di saturazione raggruppando i contatori in sei gruppi da dieci. Il modulo che funge da multiplexer gestisce l’accesso in lettura del DSP attraverso la EMIF: a seconda dell’indirizzo ricevuto manda in uscita i dati di una delle 30 righe della matrice oppure il registro di informazione o il registro di configurazione.

Infine il modulo Gate Interlock gestisce due segnali di controllo secondo le specifiche e in particolare fa scattare l’Interlock se si verifica una saturazione su qualcuno dei contatori e si è in modalità “safety”.

Vediamo ora nel dettaglio la struttura dei singoli sottomoduli, premettendo che si tratta di un progetto sincrono statico e che il clock (clk) e il reset (rst) di sistema si propagano a tutti i moduli.

4.3.3.1. Contatori

I 60 contatori a 16 bit costituiscono l’interfaccia tra i sensori SPAD e il sistema di elaborazione. In particolare, ogni modulo conteggia il numero dei fotoni rivelati dal relativo sensore SPAD all’interno della finestra temporale.

(12)

Figura 4.7: A sinistra il blocco logico IC_counter con i segnali di ingresso e uscita; a destra struttura interna dello stesso modulo.

La struttura interna di questo blocco comprende due sotto moduli, il primo, modulo Retp, sincronizza il segnale asincrono esterno con il clock di sistema e il secondo conta le occorrenze del segnale sincronizzato.

La struttura interna del modulo Retp utilizza due rising edge sensitive flip flop con reset asincrono collegati come mostrato in Figura 4.8, ottenendo, per ogni impulso asincrono in ingresso un impulso sincrono in uscita della durata di un ciclo di clock.

Figura 4.8: Blocco Retp di sincronizzazione.

Il modulo Counter realizza un contatore a N=16 bit con saturazione, enable e clear sincroni e reset asincrono. Il comportamento del circuito in corrispondenza di un fronte in salita del segnale di clock è descritto nella seguente tabella a pagina seguente.

(13)

Enable Clear count

1 0 count=count+1 0 1 count=0 1 1 count=1 0 0 count=count

Si osserva la presenza del pre-load nel caso di enable e clear entrambi alti. In questa situazione si avrebbe l’azzeramento contemporaneamente a un impulso esterno, quindi si fa partire il conteggio da 1 per non perdere il primo impulso.

4.3.3.2. Write Valide State Machine.

Questa macchina a stati controlla l’interfaccia Write_validation_bit e quando l’uscita di questa diventa attiva per almeno due cicli di clock (due per evitare errori aleatori) abilita il Cfg_reg_load e il Load_new_data. Queste abilitazioni avvengono a distanza di un periodo di clock. Ciò permette prima il caricamento sincrono dei dati validi nel Cfg_reg_ff e poi, all’arrivo del Load_new_data, la presentazione di dati validi come nuova finestra temporale per il Timer.

Valid clear_valid_bit=0 data_en=0 load_new_data=0 Valid 3 clear_valid_bit=0 data_en=0 load_new_data=0 Enable_Data clear_valid_bit=1 data_en=1 load_new_data=0

Load New Data clear_valid_bit=0 data_en=0 load_new_data=1 Valid 2 clear_valid_bit=0 data_en=0 load_new_data=0 Valid_bit=0 Valid_bit=0

Valid_bit=1 Valid_bit=1 Valid_bit=1

Valid_bit=0

others

(14)

4.3.3.3. Timer.

Il modulo Timer quando abilitato carica la nuova finestra temporale dell’esperimento FTI in un apposito registro a 14 bit, tramite il segnale Period [0-13]. Questo valore deve poter essere variabile, secondo specifiche, in un range compreso tra 10 µs e 100 ms con 12 bit di risoluzione.

Figura 4.10: Struttura interna del modulo Timer.

Lo scopo di questo modulo è quello di generare in uscita un singolo impulso di durata di un clock per ogni finestra temporale trascorsa. Quanto detto viene realizzato trasmettendo come parametro di configurazione il numero N ottenuto dividendo la finestra temporale in N finestre minime da 10 µs; un modulo chiamato Timer_base genera un impulso di un ciclo di clock ogni 10 µs (pari alla finestra temporale minima) e infine un contatore scandisce l’intera finestra temporale contando N impulsi del Timer_base per poi mandare il singolo impulso Tmr_pulse_O, generato per mezzo di una macchina a stati, in uscita.

(15)

Nel modulo Timer_base la finestra temporale minima è ottenuta con un contatore che conta da zero tanti cicli di clock di sistema quanti ne servono per ottenere 10 µs, quindi genera un l’impulso e resetta il contatore. Nel nostro caso il clock di sistema è di 90 Mhz per cui il numero di conteggi da zero è N=899.

Figura 4.11: Struttura interna del modulo Timer_Base.

La macchina a stati ha il compito di generare un impulso di uscita di 1 solo ciclo di clock una volta che è trascorsa una finestra temporale e si comporta secondo il diagramma di stato mostrato sotto.

WF1 pulse_short=0 WF 0 pulse_short=0 Pulse_Generator pulse_short=1 Pulse_long=0 Pulse_long=1 Pulse_long=0 Others pulse_short=0 Pulse_long=1

(16)

4.3.3.4. Gate Interlock.

Questo modulo riceve in ingresso un segnale che indica se deve essere attivata la modalità “safety” e in tal caso genera i segnali di Gate ed Interlock hardware e l’invio di un messaggio di errore al computer remoto.

Figura 4.13: A sinistra il blocco logico Gate Interlock coi segnali di ingresso e uscita; a destra struttura interna dello stesso modulo.

Nel caso di “safety mode” si deve generare un impulso quando si ha un evento di interlock software o una saturazione su uno qualsiasi dei contatori, come definito nelle specifiche preliminari. La struttura interna di questo modulo è mostrata nella figura sotto.

(17)

Figura 4.14:Struttura interna del modulo di GateInterlock.

Data la sovrabbondanza delle risorse dello FPGA la soluzione è ottimizzata a livello temporale infatti si hanno solo due banchi di porte in cascata. Si poteva ottimizzare come numero porte utilizzandone solo tre in cascata (OR tra i saturation, AND con il safety e OR con interlock_I) ma introducendo un ritardo maggiore.

4.3.3.5. Registri.

Per quanto riguarda l’indirizzamento del modulo SDPM esso è stato fatto nello spazio di memoria CE2 (di indirizzo 0xA0000000) a partire dall’offset

(18)

0x00200000. I registri utilizzati in questo modulo contengono ciò che si trova nell’indirizzo esadecimale descritto nella tabella sottostante:

Nome Indirizzo (hex) Accessibilità

SDPM_FRAME_INFO_REG 0xA0200000

SDPM_SPADA_SENSOR_1_REG 0xA0200004 R

e così via a incrementi di 4 fino al ... … SDPM_SPADA_SENSOR_30_REG 0xA0200078 R

SDPM_CFG_REG 0xA020007C R/W

SDPM_VALID_REG 0xA0200080 W

Per quanto riguarda il Valid_Reg il suo bit_0 indica la presenza di un dato valido nel registro CFG_REG, gli altri bit sono riservati.

La descrizione dettagliata dei bit del registro CFG_REG è riportata nella tabella sottostante:

Bit Funzione Descrizione

0-13 Period Multiplo della finestra di integrazione dei sensori Spada. Multipli di 10 µs fino a un valore massimo di 0x2710 (hex) pari a 100 ms.

14 Red led control Se a 1 accende il led rosso dello FPGA. 15 Green led control Se a 1 accende il led verde dello FPGA.

16 Gate Se a 1 viene generato un segnale di Gate sul connettore D17 della micro-line

17 Interlock Se a 1 viene generato un segnale di Interlock indipendentemente dalla saturazione dei contatori. 18 Safety Mode Se a 1 in caso di saturazione di uno dei contatori viene

generato un segnale di Interlock sul connettore D16. 19-31 RESERVED

Per ulteriori approfondimenti relativi al funzionamento del modulo SDPM si rimanda alla consultazione del codice in appendice A.

(19)

4.3.4. Data Mover Port (DM_PORT)

Il modulo DM_PORT, per mezzo della “data mover port”, collegata alla porta Data Mover del Link Layer Controller, permette l’utilizzo della connessione firewire sia tramite la “micro-controller interface”, collegata al DSP, sia tramite la “streaming port” collegata ai connettori Micro-line. Per utilizzare il data streaming della IEEE1394 abbiamo preso come riferimento una IP core fornita dalla Orsys chiamata dmport.

Questo modulo ha le seguenti caratteristiche:

• Accesso alla data mover port del TSB12LV32 Link Layer Controller. • Streaming port separata per eventuale connessione diretta a un hardware

esterno tramite i pin della micro-line.

• Possibilità di utilizzo del registro di dati per il software streaming tramite DSP.

• Generazione di interruzione possibile in caso di riempimento della pila o di altre condizioni di errore.

• Possibilità di una configurazione flessibile per mezzo di registri di controllo e di stato.

(20)

Figura 4.15: Struttura a blocchi del DM_Port IP core.

Come interfaccia CPU viene utilizzata la nota EMIF. Per generare le corrette abilitazioni e trasferimenti di lettura e scrittura viene usata una opportuna glue logic con gli stessi chip select e strobe line visti per il modulo SDPM e descritti nel seguito. In questo modulo vi sono a livello FPGA una serie di registri di stato e controllo da configurare opportunamente a livello DSP per ottenere vari tipi di configurazioni. La tabella a pagina seguente mostra una panoramica di questi registri con i relativi indirizzi di selezione mappati all’inizio dello spazio di memoria CE2, per una dettagliata descrizione si rimanda alla bibliografia [61] e [62].

(21)

L’interruzione generata dal modulo DM_Port viene portata sulla linea EXT_INT4 verso il DSP, ma non viene utilizzata ai fini del nostro progetto.

Il reset è lo stesso del modulo SDPM ed è il reset globale dello FPGA. Il clock invece viene ricevuto dal LLC ed è pari a 24,576 MHz.

Nel nostro progetto viene utilizzata la connessione firewire tramite la “micro-controller interface” per effettuare il “software streaming” cioè tramite il DSP i dati vengono trasferiti al registro STR_DATA e da qui passano nella pila di 8KByte da cui vengono prelevati dal LLC e spediti sul bus IEEE1394. In questo caso la streaming port non viene utilizzata per cui i suoi segnali di uscita rimangono non connessi e i suoi ingressi collegati agli I/O Buffer.

(22)

Figura 4.16: Struttura a blocchi della “micro-controller interface”.

I segnali della data mover interface sono direttamente collegati al LLC. Questa interfaccia contiene tutta la logica necessaria a effettuare trasferimenti sia asincroni che isocroni attraverso la relativa porta data mover del LLC e può operare in parallelo agli accessi via software ai registri del LLC, dunque i dati possono essere trasferiti indipendentemente dal software DSP. Gli accessi allo spazio di memoria CE2 avvengono per default a 32 bit, mentre quelli allo spazio di memoria CE3 sono a 16 bit.

La descrizione dei segnali del modulo DM_Port è mostrata nella figura seguente e per una più dettagliata descrizione di ogni segnale si rimanda alla bibliografia [51], [52] e [53].

(23)

Figura 4.17: Segnali di ingresso e uscita della DM_Port IP core.

4.3.5. Glue logic.

La glue logic serve a definire lo spazio di memoria destinato ai due moduli e se il DSP comunica con lo FPGA per operazioni di scrittura o di lettura.

(24)

SDPM_CS_RD SDPM_CS_WR Sdmp_Data_O S1 S2 D C ENB Multiplexer 32 32 DM_CS_RD DM_CS_WR Dsp Data 32 ENB CPU_D_PAD CPU_AOen_PAD Tristate CPU_CE2n_PAD CPU_A_PAD_21 CPU_CE3n_PAD CPU_A_PAD_20 CPU_A_PAD_19 CPU_A_PAD_18 Sdpm_Rd_I Sdpm_Wr_I DM_REG_DATA_O SDPM_REG_DATA_O Dmport_Rd_I Dmport_Wr_I Dmport_Data_O SDPM DM_PORT CPU_AREn_PAD Sdpm_Rdstrb_n_I

Figura 4.18: Schema della logica aggiuntiva del progetto.

Con la prima serie di porte and si assegna al modulo SDPM uno spazio di memoria di dimensione di 2MByte nello spazio CE2 a partire dall’offset 0x00200000 ed al modulo DM_PORT una locazione di memoria nello spazio CE3. L’uscita di queste due porte and stabilisce a quale dei due moduli si è richiesto un accesso; se il DSP effettua una lettura, cioè lo FPGA scrive in memoria, questi segnali pilotano, tramite la porta tristate, il bus a ricevere dati in uscita dalle linee del modulo selezionato.

La seconda barriera di quattro porte and, a partire dai due segnali suddetti e dal segnale CPU_AOen_PAD (settato dal DSP quando ad esempio si vuole scrivere una nuova configurazione della finestra temporale), generano le abilitazioni di lettura o scrittura nei due moduli.

4.4. Sviluppo DSP.

Lo sviluppo della programmazione su DSP, vista la grande complessità del processore TMS320C6713 della Texas Instruments, è passato attraverso diverse

(25)

fasi successive in cui affrontare l’utilizzo di una singola interfaccia o periferica necessaria al progetto.

In una prima fase ci siamo preoccupati di comprendere le fasi di inizializzazioni necessarie per la configurazione della scheda. Successivamente, con lo studio dei meccanismi di interruzione del DSP, della tecnica degli Interrupt Handler e dell’accesso alla memoria SDRAM tramite l’interfaccia EMIF, si è realizzata una prima versione di programma che salvava alcuni conteggi in memoria.

Nella seconda versione operativa del programma oltre a quanto sopra ci siamo preoccupati di comprendere il meccanismo di EDMA e l’utilizzo della porta UART per la trasmissione e ricezione dei dati.

Nella terza ed attuale versione del programma, funzionante per trasferimenti in tempo reale, ci siamo preoccupati di comprendere la connessione IEEE1394 per la trasmissione dati isocrona e la ricetrasmissione dei dati asincrona a mezzo firewire e lo studio del QDMA per effettuare un trasferimento continuo di dati.

4.4.1. Inizializzazione del sistema.

La fase di inizializzazione del sistema viene fatta tramite la funzione di libreria C6xCptInit che inizializza i parametri per l’intero hardware dividendolo in tre parti: board level, specific CPU level e CPU core level.

Il board level va ad inizializzare i registri di configurazione del PLD:

• Frame Set Register (FSR), per il caricamento dei boot loader nella memoria Flash.

• Fpga control register (FCR) usato dalle applicazioni per caricare il codice FPGA.

• LED control register. • Module control register. • I2C bus register.

(26)

• I/O flags register. • UART clock control.

• DSP EXT_INT6 e EXT_INT7 enable/status register. Lo specific CPU level va ad inizializzare i registri EMIF :

• Global control register che configura i parametri comuni a tutti gli spazi di memoria CE .

• I quattro registri CE space control register (CECTL). Ognuno corrisponde al relativo spazio di memoria CE supportato dalla EMIF.

• Lo SDRAM control register (SDCTL) che controlla i parametri SDRAM per tutti gli spazi CE e ne specifica il tipo e la quantità di memoria. Nella tabella sotto la dimensione e l’indirizzo dei quattro spazi EMIF di memoria:

• Lo SDRAM timing register (SDTIM) che controlla il periodo di refresh in termini di cicli dell’EMIF clock.

Il CPU core level va ad inizializzare i due registri core:

• Control Status Register (CSR) che permette il settaggio globale o meno delle interruzioni.

• Interrupt Service Table Pointer Register (ISTP) necessario per trovare gli indirizzi delle routine di servizio collegate alle interruzioni di programma.

Per maggiori dettagli sul significato dei singoli registri si faccia riferimento alla bibliografia [43], [44] e [45].

(27)

4.4.2. Interruzione di programma.

Nella prima versione del programma l’operazione che compie il DSP in reazione all’interruzione 5 proveniente dallo FPGA, per indicare la fine di un conteggio e la trasmissione del dato, è quella di leggere il dato contato e salvarne 10 conteggi successivi in un vettore nello spazio di memoria della SDRAM. Questo ha significato lo studio dei meccanismi di interruzione del DSP e della tecnica degli Interrupt Handler, cioè l’aggancio di una funzione da mandare in esecuzione al verificarsi di una interruzione sul canale prescelto.

Il DSP presenta un set di registri per la gestione del meccanismo di interruzione di cui faremo una sintetica panoramica e descrizione:

• Control Status Register (CSR). I suoi due bit meno significativi bit0, bit1 sono rispettivamente il GIE e il PGIE. Il Global Interrupt Enable abilita o disabilita tutte le interruzioni mascherabili; l’abilitazione si effettua con la funzione di libreria C6xGlobalIntEnable, mentre la funzione C6xGlobalIntDisable resetta a 0 il GIE e disabilita le interruzioni mascherabili. Il Previous GIE salva il valore del GIE. Quando arriva una interruzione si innesca un meccanismo per cui il PGIE salva il GIE, quindi il GIE viene resettato per evitare ulteriori interruzioni e ripristinato una volta servita l’istanza.

Figura 4.19: Bit del registro Interrupt Enable Register.

• Interrupt Enable Register (IER). Questo registro serve per abilitare o disabilitare i singoli interrupt. Una interruzione infatti può dare l’avvio alla routine di servizio solo se il corrispondente bit nel IER è settato. Questo si

(28)

effettua con la funzione di libreria C6xIntEnable, mentre la funzione C6xIntDisable disabilita l’esecuzione dell’interruzione ponendo a 0 il rispettivo bit.

• Interrupt Flag Register (IFR). Questo registro contiene lo stato delle richieste di interrupt.

• Interrupt Clear and Set Register (ICR e ISR). Servono per settare e resettare via sorfware i flag del registro IFR. Questo può essere eseguito con le funzioni di libreria C6xIntClear e C6xIntSet.

• Interrupt Return Pointer. Questo registro viene utilizzato in caso di annidamento di interruzioni.

Il DSP ha tre tipi di interruzioni che descriviamo in ordine di priorità: • Di reset (attivo basso).

• Non mascherabile (NMI). L’unica disponibile nel progetto è collegata allo FPGA ma non è utilizzata.

• Mascherabili. Il DSP ha 12 interruzioni di questo tipo; nel nostro progetto in particolare ne sono disponibili quattro esterne di cui due, INT6 e INT 7, per le periferiche esterne tramite PLD e le altre due, INT4 e INT5, filate direttamente tra FPGA e DSP come mostrato sotto.

(29)

Si osserva che di default, quando un’interruzione mascherabile va in esecuzione, solo un’interruzione NMI può interromperla. Tuttavia c’è la possibilità di annidare più interruzioni mascherabili settando opportunamente i bit dei registri IER, CSR, ISR, dopo aver salvato in registri o in memoria i valori attuali dei registri IER e IRP.

Affinché una interruzione mascherabile abbia effetto devono essere verificate le seguenti condizioni:

• Il Global Interrupt Enable bit settato a 1.

• Il NMIE bit nel registro IER è settato a 1 (è così per default).

• Il corrispondente interrupt enable (IE) bit del registro IER è settato a 1. In questo caso l’arrivo di una interruzione, comporta il settaggio a 1 del corrispondente bit flag nel registro IFR e la sua esecuzione a patto che non ci siano altri flag settati a 1 a priorità più alta.

Quando la CPU inizia a processare una interruzione fa riferimento alla Interrupt Service Table, una tabella di 16 pacchetti consecutivi, ciascuno di 32 byte e ognuno contenente il codice della routine che serve l’interrupt. Ogni routine, detta Interrupt Fetch Service Packet (ISFP), contiene 8 istruzioni di 32 bit.

(30)

Figura 4.21: Struttura della tabella IST del TMS320C6713.

L’esempio nella figura sopra, mostra il caso in cui tutte le istruzioni da eseguire nella routine di interruzione stiano in 32 byte, se le istruzioni da eseguire nella routine sono più di 8 , si ricorre ad un salto ad un’ulteriore routine.

La locazione di memoria assegnata alla IST è determinata dal registro Interrupt Service Table Pointer Register (ISTP) che ha la seguente struttura:

Figura 4.22: Bit della Interrupt Service Tabler.

• Bit[4..0]: Rimangono sempre settati a 0, de facto poiché ogni ISFP è di 32 byte .

(31)

• Bit[9..5]: Highest Priority Enable Interrupt. Indirizzo “relativo” della routine di interruzione a più alta priorità. Il bit più significativo è sempre 0 (almeno nel nostro caso).

• Bit[31..10]: Interrupt Service Table Base. Indirizzo base della tabella IST.

Questo registro, inizializzato nel Cpu Core Level serve a trovare l’indirizzo delle routine di servizio collegata ad ogni interruzione.

La funzione di libreria C6xIntHook serve proprio a collegare a una interruzione una funzione da mandare in esecuzione copiando il suo indirizzo opportunamente nella tabella IST.

Riassumendo nel nostro progetto sono previste le interruzione del DSP EXT_INT_4, EXT_INT_5, EXT_INT_6, EXT_INT_7 e CPU_INT_8. Le prime due direttamente filate con lo FPGA e assegnate rispettivamente ai moduli DM_Port e SDPM, le seconde due collegate al PLD di cui la INT_7 gestita dalla seriale e la INT_6 dal LLC ed infine la INT_8 che è interna al DSP ed è funzionale al trasferimento EDMA. Alle interruzioni sette e otto vengono inoltre collegate delle specifiche funzioni di handler che vanno in esecuzione con il servizio dell’interruzione da parte del DSP.

4.4.3. Accesso alla memoria SDRAM.

Per il trasferimento dei dati è stato necessario lo studio di come avviene l’accesso alla memoria SDRAM tramite l’interfaccia EMIF del DSP. Oltre alle impostazioni che vengono effettuate in fase di inizializzazione, descritte nel paragrafo 4.4.1, è stato necessario capire come avviene la comunicazione tra EMIF e SDRAM e quali sono le temporizzazioni per i cicli di lettura e di scrittura.

(32)

Figura 4.23: Diagramma a blocchi dell’interfaccia tra EMIF e16MBit SDRAM. L’interfaccia mostrata sopra permette la programmazione tramite EMIF dell’indirizzamento della 16M-bit SDRAM incluso il numero di bit di indirizzo per le righe (dimensione delle pagine) e per le colonne (pagine del banco). Il numero dei registri di indirizzo EMIF limita il numero massimo di pagine aperte simultaneamente che possono essere quindi quattro. Le pagine possono trovarsi in banchi differenti di un unico spazio CE o distribuite in diversi spazi, ma può essere aperta solo una pagina per banco allo stesso momento.

(33)

Figura 4.24: Esempio di temporizzazioni di lettura e scrittura di tre parole in SDRAM.

L’EMIF utilizza una sequenza di lunghezza quattro sia in lettura che in scrittura. Per la lettura si ha una latenza della CAS programmabile in due o tre cicli, mentre per la scrittura non c’è latenza quindi i dati sono pronti allo stesso ciclo degli indirizzi delle colonne. Se gli accessi avvengono a byte o halfword c’è la possibilità di mascherare i rimanenti accessi con i segnali di abilitazione. Per ulteriori dettagli si consulti la bibliografia [49].

4.4.4. Trasferimenti via EDMA.

Nella seconda versione operativa del programma, oltre a quanto sopra, ci siamo preoccupati di comprendere il meccanismo di EDMA per trasferire i dati in modo più rapido e senza impegnare il DSP.

Il controllore enhanced direct memory access (EDMA) effettua velocemente tutti i trasferimenti tra la memoria a due livelli di cache e tutti gli spazi di memoria indirizzabili comprese le periferiche del DSP e le memorie esterne; inoltre prevede 16 canali a priorità programmabile e la possibilità di collegamento e concatenamento dei dati.

(34)

Figura 4.25: Schema a blocchi del controllore EDMA.

L’architettura del controllore EDMA è SRAM based; esiste una porzione di memoria, detta PaRAM (Parametric Ram), di 2 Kbytes dedicata al controllore in cui il programmatore inserisce i parametri relativi ad ogni canale del controllore stesso. Ogni canale dispone all’interno della PaRAM di un blocco, ossia 6 parole da 32 bit, ciascuna contenente un parametro diverso richiesto dal controllore per il corretto trasferimento dei dati.

(35)

Di seguito è riportato sinteticamente il significato dei vari parametri del blocco: • OPT : configurazione del trasferimento.

• SRC : indirizzo del primo array o frame da cui devono essere prelevati i dati da trasferire.

• DST : indirizzo del primo array o frame in cui devono essere trasferiti i dati. • AFRMCNT : numero di array o frames che devono essere trasferiti meno 1. • ELECNT : numero di elementi in un array o frame.

• FRMIDX : offset per calcolare l’indirizzo di partenza di ogni array o frame. • ELEIDX : differenza tra gli indirizzi di due elementi successivi in un frame. • ELERLD : valore da ricaricare per il numero di elementi in un frame (campo

valido solo per trasferimenti in modalità ELEMENT SYNCHRONIZED). • LINK : indirizzo della PaRAM da cui scaricare i nuovi parametri una volta

completato il trasferimento corrente.

Per capire meglio le possibilità del trasferimento EDMA è significativo la spiegazione del campo OPT che configura il tipo di trasferimento richiesto.

Figura 4.27: Bit del registro OPT del descrittore EDMA. • Bit 31-29 PRI :Livello di priorità per gli eventi EDMA

PRI=001b; Alta priorità. PRI=010b; Bassa priorità. • Bit 28–27 ESIZE : Dimensione dell’elemento

ESIZE=00b; 32-bit word ESIZE=01b; 16-bit half-word ESIZE=10b; 8-bit byte

(36)

• Bit 26 2DS : Dimensione della sorgente 2DS = 0; 1-dimensional source. 2DS = 1; 2-dimensional source.

• Bit 25–24 SUM : Metodo di aggiornamento dell’indirizzo sorgente SUM = 00b; Indirizzo fisso senza modifiche

SUM = 01b; Indirizzo incrementato dai campi 2DS e FS SUM = 10b; Indirizzo decrementato dai campi 2DS e FS SUM = 11b; Indirizzo modificato dall’indice index/frame a secondo dei valori dei bit 2DS e FS

• Bit 23 2DD : Dimensione del destinatario

2DD = 0; destinatario a 1-dimension 2DD = 1; destinatario a 2-dimensional

• Bit 22–21 DUM : Metodo di aggiornamento dell’indirizzo destinatario DUM = 00b; Indirizzo fisso senza modifiche

DUM = 01b; Indirizzo incrementato dai campi 2DS e FS DUM = 10b; Indirizzo decrementato dai campi 2DS e FS DUM = 11b; Indirizzo modificato dall’indice index/frame a secondo dei valori dei bit 2DS e FS

• Bit 20 TCINT : Interruzione che indica un trasferimento completato TCINT=0; Disabilitata.

TCINT=1; Abilitata. Il bit relative viene settato nel registro CIPR al completamento del trasferimento

• Bit 19–16 TCC : Codice di trasferimento, vengono usati quattro bit per settare il corrispettivo bit del registro CIPR.

• 1 LINK : Link

LINK=0; Collegamento disabilitato.

LINK=1; Collegamento abilitato di un nuovo set di parametri alla fine di un trasferimento

(37)

FS=0; Il canale è sincronizzato con element/array FS=1; Il canale è sincronizzato coi frame

Ogni canale del EDMA è sincronizzato con un particolare evento, inoltre alcuni canali possono essere sincronizzati con l’interruzione generata dalla fine trasmissione di un altro canale EDMA come mostrato nella figura sotto:

Figura 4.28: Tabella degli eventi di sincronizzazione per i 16 canali EDMA.

Infine per monitorare e abilitare il trasferimento dei dati si deve gestire opportunamente anche un nutrito numero dei registri di controllo elencati a pagina seguente.

(38)

Figura 4.29: Registri di controllo dei processi EDMA.

Se il TCINT bit nell’options entry è settato a ‘1’ in un canale significa che quando il trasferimento è stato completato l’EDMA controller setta il bit relativo al canale nel CIPR. A questo settaggio è collegato un codice interno la cui azione finale più significativa è la generazione di una interruzione EDMA_INT alla CPU (per defaults l’EDMA interrupt è collegato con il CPU_INT8).

In sostanza il CIPR è equivalente a un interrupt pending register la cui sorgente sono i fine trasferimento e il CIER è simile a un interrupt enable register.

E’importante notare che se un bit del CIER bit è disabilitato, il fine trasferimento viene comunque registrato nel CIPR così che quando quel bit viene riabilitato nel CIER, l’interruzione corrispondente al canale viene spedita alla CPU. Per finire quindi se le interruzioni della CPU sono abilitate la Interrupt Service Routine relativa alla EDMA_INT8 viene mandata in esecuzione; questa deve provvedere a resettare il bit in CIPR, abilitando quindi il canale a ricevere ulteriori interruzioni. I registri ER, EER e ECR sono simili al Flag, Set e Clear Register visti nel meccanismo di interruzione. I due registri EER e ECR offrono la possibilità di abilitare/disabilitare via software gli eventi dei singoli canali settando a 1/0 il corrispondente bit dei due registri. L’event register (ER), si setta quando avviene un evento di sincronizzazione del canale EDMA. Gli eventi occorsi vengono

(39)

comunque registrati nel ER anche se questi sono disabilitati, permettendo di non perdere alcun evento, infatti riabilitando un evento con una pendenza segnalata nel ER si forza l’EDMA a processarlo.

Per una più dettagliata descrizione dei parametri e dei registri di controllo si rimanda alla bibliografia [46] e [47].

Nel nostro progetto viene utilizzato il solo canale EDMA numero 5 che come visto è sincronizzato con il segnale INT_5, nel nostro caso generato dallo FPGA. Vengono però utilizzati tre descrittori per questo canale: il descrittore cinque, che viene eseguito la prima volta, e due ulteriori descrittori per effettuare il reload e generare il concatenamento desiderato nella trasmissione dei dati. Nella nostra applicazione i registri dei tre descrittori sono tutti uguali fatto salvo il registro .dst come spiegato sotto nel dettaglio con la descrizione dei registri:

.opt :

• Setta il trasferimento EDMA ad alta priorità • Setta la dimensione di ogni elemento a 32 bit • Si abilita il prelievo da una fonte 2-Dimension..

• Setta la modifica dell’indirizzo di origine per incremento inserendo gli elementi nell’array in posizioni contigue tra loro.

• Si abilita la trasmissione tramite una fonte 1-Dimension in cui il blocco trasferito è costituito da un certo numero di singoli elementi come richiesto dal software streaming verso il firewire.

• Setta la modifica dell’indirizzo di destinazione per incremento. Nel caso 1-D tutti gli elementi sono contigui tra loro.

• Setta la generazione di un bit di interruzione quando il canale ha completato il trasferimento.

• Setta sui quattro bit TCC il numero del canale 5 per settare così il registro CIPR[TCC].

(40)

• Abilita la connessione per il concatenamento. Per trasferire in modo continuo i dati sono necessari due descrittori di reload.

.scr

Specifica su 32 bit il byte iniziale dell’indirizzo della sorgente, nel nostro caso è SDPM_FRAME_INFO_REG_ADDR = 0xA0200000 nello spazio di memoria CE2 riservato allo FPGA.

.cnt

• Specifica, nel nostro caso 2-D source, sui 16 bit più significativi il numero di array meno uno che costituiscono il blocco (nel nostro caso 20), sui 16 bit meno significativi, il numero di elementi che costituiscono l’array (nel nostro caso 31, cioè una lettura completa dei contatori SPADA più il registro di informazione).

.dst

• Specifica su 32 bit il byte iniziale dell’indirizzo della destinazione; nel nostro caso i due descrittori di reload caricano rispettivamente gli indirizzi di due buffer di memoria distinti che chiameremo uno “ping” e l’altro “pong”.

.idx

• Nel nostro caso 0 perché si considerano sempre gli stessi spazi di memoria.

.rld

• Nel nostro caso i 16 bit meno significativi specificano l’indirizzo della PaRam di uno dei due descrittori di ricarica che si chiamano a vicenda.

Le tre azioni da compiere in fase di inizalizzazione sono :

• L’abilitazione dell’evento di sincronia sul canale 5 tramite il setting del bit 5 del registro EER ( EDMA_EER |= (0x01 << 5) );

(41)

• L’abilitazione dell’interruzione generata dal fine trasferimento del canale tramite il setting del bit 5 del registro CIER (EDMA_CIER |=(0x01 << 5) );

• L’azzeramento del registro CIPR delle pendenze tramite il setting del bit 5 ( EDMA_CIPR |= (0x01 << 5) ).

Questa ultima operazione deve essere fatta anche all’interno della routine di interruzione collegata all’EDMA che parte proprio quando si verifica una pendenza di questo bit.

4.4.5. Interfaccia UART.

In questa prima fase dello sviluppo si è scelto di trasferire i dati verso il computer remoto tramite interfaccia seriale, non in tempo reale, rimandando lo studio del trasferimento dati via Firewire. E’ stato quindi affrontato l’utilizzo della porta UART sia per la trasmissione dei conteggi che per la ricezione dei dati di configurazione.

Anche per la UART sono presenti un numero di registri da gestire correttamente per ottenere opportune trasmissioni e ricezioni e per settare il tipo di interruzione. Questi registri sono mappati in 64k dello spazio di memoria CE1 come mostrato sotto:

(42)

L’accesso ai registri avviene per mezzo delle funzioni di libreria che eseguono anche molte delle funzioni elementari di trasferimento.

La libreria Orsys infatti ha una interfaccia detta stdio che fa da tramite tra il compilatore e la UART della scheda bufferando localmente i dati.

Il modulo fornito detto scc3 fornisce inoltre le funzioni di trasmissione e ricezione dei dati in vari tipi di formati.

Particolarmente significativa è la funzione DebugInit che provvede alla inizializzazione della porta seriale impostandone:

• Baudrate – setta la velocità di trasmissione da usare in baud. • TxIntEnable – abilita l’interruzione in trasmissione.

• RxIntEnable - abilita l’interruzione in ricezione. • RTSEnable - abilita l’handshake RTS.

• CtsEnable -abilita l’handshake CTS.

Per quanto riguarda l’interruzione, la nostra scheda ha la ext_int7 disponibile tramite il PLD per la UART, ma in condivisione con l’LLC, lo FPGA e altre periferiche.

Per abilitare solo la UART sulla ext_int7 si scrive sull’opportuno bit del registro di controllo del PLD con la funzione C6713CPT_EINT7_EN = 0x80.

Poi si passa ad abilitare, tramite la chiamata della funzione di libreria Scc3EnableRxInt, il bit 0 del registro UART_IER con l’effetto di abilitare l’interruzione ext_int7 in ricezione, cioè quando è disponibile sul buffer di ricezione un dato.

Viene impostata l’interruzione in ricezione poiché la scheda riceve tramite seriale i dati che devono essere passati alla Detection Board, quindi appena vengono ricevuti si genera una interruzione che ne effettua il loro trasferimento.

Per una più dettagliata descrizione delle funzioni e dei registri di controllo si rimanda alla bibliografia [54].

(43)

4.4.6. Il collegamento Fire Wire.

Nella terza ed attuale versione del programma, funzionante per trasferimenti in tempo reale, oltre a quanto detto, ci siamo preoccupati di comprendere la connessione IEEE1394 per la trasmissione dati isocrona e lo scambio dei dati asincrono a mezzo firewire.

Il protocollo IEEE1394 del 1995 consente un facile utilizzo, basso costo, alta velocità di comunicazione, fino a 400 Mbps, ampia scalabilità e permette entrambe le comunicazioni sincrone e asincrone.

Figura 4.31: Stratificazione del protocollo 1394.

La gestione del bus richiede svariate responsabilità che possono essere distribuite tra più di un nodo. Alcuni nodi sul bus devono assumere il ruolo di Cycle Master, Isochronous Resource Manager e Bus Manager.

• Il Cycle Master avvia i cicli di trasferimento inviando un Cycle Start packet ogni 125 µs. Il Root Node deve essere anche Cycle Master.

(44)

• L’Isochronous Resource Manager è il gestore delle risorse isocrone e deve essere capace di effettuare transazioni isocrone. Inoltre tale gestore deve anche implementare numerosi registri opzionali. Questi registri includono il registro Bus Manager ID, il registro di allocazione della larghezza di banda del bus e il registro di allocazione del canale. I nodi che desiderano utilizzare larghezza di banda isocrona devono sottrarre la quantità di larghezza di banda loro necessaria dal Bandwidth Available Register.

• Il Bus Manager ha numerose funzioni inclusa la divulgazione di una mappa topologica e di una mappa delle velocità, la gestione dell’alimentazione e l’ottimizzazione del traffico sul bus. La mappa delle velocità è utilizzata dai nodi per determinare quale velocità possono utilizzare per comunicare con altri nodi. Il Bus Manager è anche responsabile della determinazione del Root Node.Non sempre potrebbe esserci sul bus un nodo capace di assumere il ruolo di Bus Manager, in questo caso almeno alcune delle funzioni di gestione del bus sono eseguite dall’Isochronous Resource Manager.

Il bus 1394 appare come un grande spazio di memoria mappato in cui ogni nodo occupa un certo intervallo di indirizzi. Lo spazio di memoria è regolato dall’architettura IEEE 1212 Control e Status Register (CSR). Ogni nodo supporta fino a 48 bit di spazio di indirizzamento (256 TeraBytes). Inoltre, ogni bus può supportare fino a 64 nodi e la specifica del bus seriale 1394 supporta fino a 1024 bus. Il risultato è un totale di 64 bit di indirizzo, per un totale di 16 ExaBytes di spazio di memoria.

(45)

Figura 4.32: Spazio di indirizzamento del bus 1394.

Il protocollo 1394 come detto supporta il trasferimento dati sia asincrono che isocrono. I trasferimenti asincroni sono indirizzati ad un nodo specifico con un esplicito indirizzo. Nella trasmissione asincrona è possibile il controllo degli errori e il meccanismo di ritrasmissione.

I trasferimenti isocroni avvengono sempre “one to one” o “one to many”e non è disponibile alcuna correzione degli errori di trasmissione o una ritrasmissione. Fino all'80% della larghezza di banda disponibile del bus può essere utilizzata per trasferimenti isocroni ciò rende il firewire un’interfaccia eccellente per applicazioni in tempo reale in cui il tempo è un fattore critico (come nel nostro caso di imaging). Per ulteriori dettagli si veda la bibliografia [19].

Per l’utilizzo del firewire nel nostro progetto abbiamo utilizzato una API (Application Programmers Interface) per il bus IEEE1394 implementata dalla Orsys e disegnata appositamente per la scheda C6713 Compact. Questa provvede una libreria di funzioni per l’inizializzazione, il set up ed il trasferimento di dati sia in modalità sincrona che asincrona. L’obiettivo è quello di svincolare il programmatore dalla conoscenza dettagliata dello standard IEEE1394 per concentrarsi sulle applicazioni, una volta capiti i concetti e le possibilità del bus 1394.

(46)

La IEEE 1394 embedded API provvede a tutte le funzioni necessarie alle operazioni sul bus per entrambi i trasferimenti che sono:

• Inizializzazione del bus : effettua l’inizializzazione dei dati richiesti dai più bassi livelli del software e determina quale nodo sia il Bus Manager e quale l’Isocronus Resource Manager.

• Reset ed enumerazione del bus : una volta effettuato il reset del bus parte il processo di enumerazione che crea un dispositivo per ogni nodo attualmente collegato al bus e ne raccoglie le informazioni come lo stato attuale, l’ID del nodo, la massima velocità, la massima dimensione del pacchetto asincrono ecc.

Fatto questo si attende la chiamata da parte dell’utente di funzioni da mandare in esecuzione secondo il metodo delle callbacks che permettono al programmatore un metodo di controllo del bus 1394 senza il polling.

Le funzioni di callback sono chiamate dall’API quando deve essere fatta una specifica azione indicata dal Lynk Layer Controller, queste quindi devono essere incluse nel software dell’applicazione e oltre ad alcune presenti in libreria altre sono state scritte per effettuare le operazioni specifiche richieste all’applicazione. Per ulteriori dettagli sull’API si veda la bibliografia [62].

Le trasmissioni sia asincrone che isocrone necessitano di una specifica sequenza di operazioni che devono essere eseguite con successo.

La trasmissione isocrona per avere successo deve eseguire le seguenti operazioni: • L’inizializzazione hardware del LLC, dei driver dei dispositivi e della API

per il software del bus; questo viene effettuato tramite la funzione sbiInitialize.

• Ottenere la banda necessaria, se disponibile sul bus 1394 per il trasferimento che deve essere eseguito; ciò si può fare tramite la funzione sbiAllocateBandwith.

(47)

• Ottenere il canale isocrono per la trasmissione; si realizza con la funzione sbiAllocateChannel.

• Realizzare l’operazione di trasmissione e si può fare con la funzione sbiIsoTalk; il chiamante deve controllare le routine di callback per conoscere lo stato dell’operazione.

• Liberare la banda e il canale utilizzati quando è finita la trasmissione; questo si realizza con le due funzioni sbiFreeBandwith e sbiFreeChannel. • Chiudere l’interfaccia 1394 se non si intende fare ulteriori trasferimenti e

si effettua con la funzione sbiTerminate.

Per quanto riguarda la trasmissione asincrona le operazioni da compiere in sequenza sono:

• L’inizializzazione hardware del LLC, dei driver dei dispositivi e della API; questo viene effettuato tramite la funzione sbiInitialize.

• Allocare e ottenere un handle al device a cui si deve trasmettere o da cui si deve ricevere, e lo si fa con la funzione sbiGetDeviceHandle.

Queste due operazioni devono essere fatte una sola volta e poi si possono utilizzare le funzioni sbiAsyncWrite e sbiAsyncRead per leggere da e scrivere verso qualsiasi spazio di indirizzamento del bus1394 che sia stato reso disponibile dal device selezionato. La funzione termina immediatamente e sono le callback a informare l’applicazione circa lo stato della transizione. La solita funzione sbiTerminate viene chiamata per chiudere l’interfaccia 1394 se non si intendono operare ulteriori operazioni.

Se invece la transizione asincrona è di ingresso, cioè avviene in risposta a una richiesta di un altro nodo si deve seguire una ulteriore diversa serie di operazioni:

(48)

• L’inizializzazione hardware del LLC, dei driver dei dispositivi e della API; questo viene effettuato tramite la funzione sbiInitialize.

• La creazione di un buffer di memoria per supportare il traffico asincrono, l’associazione di questo buffer con il range di indirizzi sul bus 1394 del dispositivo chiamante e il permesso per altri dispositivi abilitati dal chiamante ad accedere a questi indirizzi. Tutto questo viene fatto chiamando la funzione sbiAllocateAddressRange.

• Dopo che lo spazio di memoria è stato acceduto viene chiamata una funzione di callback detta appNotificationCallback che può essere usata per modificare i dati tipo riempire il buffer dopo una lettura con nuovi dati o decodificare i messaggi che sono stati scritti nel range di indirizzi e far partire su questi nuove elaborazioni.

• Terminati gli accessi al buffer viene libero il range di indirizzi sul bus 1394 tramite la funzione sbiFreeAddressRange.

• La chiusura dell’interfaccia 1394 se non si intende fare ulteriori trasferimenti viene effettuata con la funzione sbiTerminate.

Nelle trasmissioni vengono spediti dei pacchetti di informazioni con le seguenti caratteristiche:

• Un pacchetto asincrono è una sequenza di quadlet (1 quadlet = 4 bytes). Tutti i pacchetti asincroni contengono un packet header seguito da un blocco dati.

• Un pacchetto isocrono consiste di un packet header e di un campo dati. Il Packet Header è composto da:

o Destination_ID – Un campo di 16 bit che specifica il nodo ricevente.

(49)

o Destination Offset – Questo campo contiene l’indirizzo del nodo destinazione (48 bit).

o Source_ID – Un campo di 16 bit che specifica il nodo sorgente. o Transaction Label – Un campo di 6 bit che specifica una

particolare etichetta per ogni transazione del nodo.

o Retry Code – Sono 2 bit che specificano se si sta tentando di trasmettere nuovamente il pacchetto.

o Transaction Code – Un campo di 4 bit che specifica il formato del pacchetto e il tipo di transazione da eseguire.

o Priority – Un campo di 4 bit che specifica le priorità di arbitrato. o Data Length – Stabilisce il numero di byte che devono essere

trasferiti.

o Header CRC – Questo campo di 32 bit contiene il carattere CRC.

Ogni dispositivo attivo sul bus 1394 deve inoltre avere una configuration ROM che contiene tutte le informazioni riguardanti il nodo tipo la possibilità di diventare Isocronous Resource Manager (IRM) o Bus Manager, i parametri per i trasferimenti come le velocità, le informazioni del venditore sul modello del dispositivo e molte altre.

Per utilizzare nel nostro progetto la firewire è necessaria la versione della programmazione dello FPGA con il modulo DM_PORT per il corretto interfacciamento con il Link Layer e il Physical Layer.

4.4.7. QDMA e PING PONG Buffering.

Nella terza ed attuale versione del programma, oltre al firewire ci siamo preoccupati di comprendere lo studio del QDMA per effettuare trasferimenti in

(50)

tempo reale. Ciò lo si è ottenuto applicando la concatenazione di trasferimenti in memoria secondo una modalità nota col nome di “ping-pong buffering”.

Il Quick DMA fornisce un modo più efficiente e veloce per spostare i dati rispetto al EDMA avendo comunque le stesse modalità di utilizzo. A differenza del EDMA questi trasferimenti avvengono sotto il diretto controllo del codice che gira sul DSP. Durante un trasferimento QDMA i registri di configurazione non possono essere modificati inoltre il QDMA non ha la possibilità del reload tramite link, ma può essere usato, come nel nostro caso, per trasferimenti di dati in modo concatenato.

Il Quick DMA consiste in due set di cinque parametri OPT, SRC, CNT, DST e IDX come quelli del EDMA a parte che sono di sola scrittura e manca il parametro RLD per il reload tramite linking. Il primo set mappa direttamente in memoria i cinque registri necessari a configurare il trasferimento. La particolarità è che scrivendo in questi registri si effettua la configurazione ma non si fa partire un trasferimento. Il secondo set, detto degli pseudo registri, è tale per cui una loro scrittura determina l’inoltro della richiesta di trasferimento. Il QDMA supporta l’interruzione alla fine del trasferimento attraverso l’uso dei campi TCINT e TCC e la notifica sui registri CIPR e CIER, come visto per l’EDMA, inoltre è possibile sincronizzare un canale EDMA con il segnale di fine trasferimento di un QDMA. Un tale trasferimento impiega da 1 a 5 cicli per essere portato a termine a seconda del numero di registri che è necessario configurare. Tipicamente un trasferimento QDMA viene realizzato scrivendo quattro dei cinque parametri nei registri e infine scrivendo il quinto parametro nel corrispondente pseudo registro per farne partire effettivamente il trasferimento. Tutti i registri dopo il trasferimento mantengono il loro valore per cui per realizzare un secondo trasferimento è sufficiente la appropriata scrittura solo di uno pseudo registro ottenendo l’esecuzione del trasferimento in un solo ciclo.

Un’importante caratteristica sia dell’EDMA che del QDMA è quella di poter trasferire dati in background alle operazioni della CPU e, nel solo caso

(51)

I canali possono essere configurati per servire in modo continuo una periferica tramite il linking che permette di caricare continuamente i nuovi set dei parametri. Una tecnica per implementare il trasferimento continuo che permetta di distanziare l’attività della CPU da quella dell’EDMA è il ping pong buffering. Con questo metodo si utilizzano due (o più) buffer di dati distinti (detti ping buffer e pong buffer) per lo stream di ingresso e quello di uscita. Mentre l’EDMA sta trasferendo i dati nel ping buffer la CPU accede ai dati nel pong buffer. Quando entrambe le attività sono completate i buffer si scambiano tra loro, così che l’EDMA sovrascrive sui vecchi dati in pong e la CPU accede ai nuovi dati su ping e così via. Per realizzare questa struttura ogni canale deve avere due set di parametri identici dove cambia solo l’indirizzo di destinazione dei dati in memoria. Per ulteriori dettagli consultare la bibliografia [48].

Figura 4.33: Schema di esempio del ping pong buffering con i rispettivi parametri per due canali EDMA.

Nel nostro progetto utilizziamo un canale EDMA per il trasferimento dallo FPGA alla SDRAM e il QDMA per il trasferimento “software streaming” verso la

(52)

firewire. Questo ultimo trasferimento sposta i dati dal buffer di memoria al registro STR_DATA del modulo DM_PORT che provvede a spostare nella pila di streaming del LLC il dato inserito.

Il punto critico è la sincronizzazione tra QDMA ed EDMA. Quando il QDMA, abilitato dal processore, ha finito di inviare i dati di ping al firewire deve aspettare che l’EDMA abbia completato il trasferimento su pong prima di poter cambiare il buffer di elaborazione. Per far questo si sfrutta la possibilità dell’EDMA di generare una interruzione alla fine di un trasferimento, questa viene controllata dal DSP che può quindi sincronizzare il QDMA. La sincronizzazione inversa, dell’EDMA con il QDMA, avviene sfruttando la stessa possibilità di generare l’interruzione da parte del QDMA, ciò comporta il setting del bit corrispondente al canale nel registro CIPR. Il DSP rimane in polling fino al verificarsi dell’evento e provvede alla sincronizzazione e ad azzerare manualmente questo bit per permettere i successivi trasferimenti.

4.4.8. Descrizione del programma su DSP.

Riassumiamo adesso come tutte le funzioni studiate e descritte nei paragrafi precedenti sono state utilizzate nel realizzare la terza versione del programma, che effettua correttamente la trasmissione dati in tempo reale.

Il programma dopo aver effettuato tutte le inizializzazioni ed enumerazioni del bus firewire aspetta i parametri di configurazione dall’esterno (via trasferimento firewire asincrono), una volta arrivati, sfruttando il trasferimento firewire isocrono ed il ping pong buffering, inizia a trasmettere i dati in tempo reale. Il programma prevede anche dei registri di accumulo per la visualizzazione periodica degli eventi occorsi in un dato tempo sul software del computer remoto.

(53)

In fase di precompilazione avviene l’inclusione di tutte le direttive e delle macro necessarie ad una maggiore leggibilità del codice e ad una semplice modificabilità del programma. Il flusso del programma a livello funzionale è il seguente:

• Dichiarazione delle variabili esterne e globali e delle funzioni utilizzate. • Dichiarazione e inizializzazione delle variabili locali al main.

• Inizializzazione del DSP, caricamento del driver API 1394, inizializzazione e caricamento del codice della struttura FPGA vista nel paragrafo 4.3, inizializzazione della EEPROM e configurazione delle interruzioni del PLD. Tutto ciò viene fatto con una funzione chiamata InitSystem che risiede in un file apposito per le inizializzazioni.

• Inizializzazione ed enumerazione del bus IEEE1394 come descritto nel paragrafo 4.4.6

• Inizializzazione della trasmissione isocrona con l’allocazione delle risorse e la scelta del software streaming verso l’LLC.

• Set up delle interruzioni numero 6 (LLC), 7 (UART) e 8 (EDMA) e aggancio delle relative funzioni di handler (descritte in uno specifico file .c collegato al progetto).

• Set up della UART per la velocità di trasmissione e la generazione di interruzione in ricezione.

• Inizializzazione del EDMA, tramite la funzione SpadaDmaInit che risiede nel solito file initialization.c ; questa setta i registri CIER e CIPR e il descrittore EDMA del canale 5 per il concatenamento e l’implementazione della trasmissione continua di dati come descritto nel paragrafo 4.4.7 . • Attesa di un trasferimento asincrono via firewire dal computer remoto

contenente i parametri di configurazione. Questo significa l’inizio dell’esperimento grazie al caricamento, tramite gli opportuni registri, del config_reg al modulo SDPM dello FPGA e del segnale di validazione del dato di configurazione.

(54)

• Ricevuta la configurazione viene inviato per verifica al computer remoto, sempre via trasferimento asincrono, lo stato attuale di configurazione. • Iniziato l’esperimento: si entra in un ciclo continuo di trasmissione in

modalità di ping pong buffering in cui il canale EDMA carica in memoria SDRAM nel buffer ping i conteggi che arrivano dallo FPGA, infatti il canale è sincronizzato con il segnale int_5 generato dallo FPGA per segnalare la disponibilità di un dato di conteggio valido su una finestra temporale. Una volta finito il trasferimento parte l’interruzione EDMA int_8 la cui routine segnala la fine trasferimento dati e su quale buffer sono stati salvati. A questo punto il DSP fa partire la trasmissione dei dati da quel buffer verso il firewire con il QDMA; nel frattempo automaticamente il descrittore EDMA ha aggiornato il proprio set di parametri per il salvataggio dei dati questa volta sul buffer pong. Prima di riiniziare questo ciclo si verifica che il QDMA abbia esaurito il trasferimento, così da ottenere una corretta sincronizzazione e dei dati sempre validi. Durante il trasferimento QDMA i conteggi vengono anche accumulati in un apposito array e spediti al computer remoto trascorso un tempo fissato.

• Alla fine di ogni ciclo descritto, prima di potervi accedere di nuovo, vengono fatti dei controlli. Il primo serve a verificare che il trasferimento QDMA sia terminato prima del completamento del successivo trasferimento EDMA per garantire un flusso di dati validi in tempo reale. Inoltre vengono fatti anche dei controlli sulla pila del LLC per accertarsi che i dati vengano spediti con regolarità sul firewire senza overflow o underflow.

• E’ attiva inoltre l’interruzione in ricezione della UART, ciò significa che appena viene ricevuto un dato si verifica una interruzione int_7 la cui funzione collegata effettuerà il trasferimento dei dati provenienti dalla detection board verso il computer remoto.

(55)

• Una volta terminato l’esperimento vengono disallocate le risorse sul bus IEEE1394.

Per ulteriori approfondimenti relativi al funzionamento del programma si rimanda alla consultazione del codice in appendice B.

Figura

Figura 4.1: Diagramma a blocchi dei collegamenti tra FPGA con struttura BSP  ed esterno
Figura 4.2: Connessioni tra FPGA e l’interfaccia EMIF del DSP.
Figura 4.3: Diagramma a blocchi delle linee di Interruzioni tra FPGA e DSP.  Lo FPGA ha accesso diretto alla data mover port del LLC usata per il  trasferimento di dati sia in modo asincrono che isocrono attraverso la firewire
Figura 4.4: Diagramma a blocchi delle linee di stato e controllo tra FPGA eLLC.  La struttura progettata utilizza un modulo principale per l’elaborazione dei dati  detto SDPM (Spada Data Processing Module), un secondo modulo per la gestione  dei trasferime
+7

Riferimenti

Documenti correlati

La proprietà non è responsabile per quanto pubblicato dai lettori nei commenti ad ogni post. Verranno cancellati i commenti ritenuti offensivi o lesivi

Lo studio proposto riguarda l’analisi delle caratteristiche tecniche degli impianti di produzione dei conglomerati bituminosi tradizionali e modificati con polverino

Mettiamo il caso che un medico, non contento della sua professione, voglia laurearsi in giurisprudenza e poi iscriversi all’albo degli avvocati, senza

se il cittadino ha dato il proprio consenso, nel Fascicolo sanitario elettronico vengono automaticamente inseriti i documenti presenti nella rete Sole, relativi quindi

Per fortuna l’informatore decide di aiutare ancora l’ispettore fornendogli indizi proprio attraverso il computer. Il numero

Finalmente arrivano informazioni sul complice della Signora Violet, l’abilissima ladra arrestata da Numerik.. Gli indizi sono contenuti in una busta chiusa: l’ispettore Numerik la

I E possibile utilizzare costanti di tipo stringa (stringhe letterali) scritte ` tra doppio apice e senza scrivere esplicitamente il carattere di fine stringa... Lettura

6: Il medico fonda l’esercizio delle proprie compe- tenze tecnico-professionali sui principi di efficacia e di appropria- tezza; il 13: le prescrizioni medi- che, oltre ad