Studio e realizzazione di comunicazioni informative
Transcript
Studio e realizzazione di comunicazioni informative
UNIVERSITA’ DEGLI STUDI DI ROMA “LA SAPIENZA” FACOLTA’ DI SCIENZE MATEMATICHE, FISICHE E NATURALI TESI DI LAUREA IN FISICA Studio e realizzazione di comunicazioni informative mediante reti ad autoinstradamento di pacchetto nell’ambito del trigger di 2° livello dell’esperimento ATLAS. Relatore interno: Prof. Lucia Zanello Relatore esterno: Dr. Speranza Falciano Laureando: Alfredo Babusci Matr.11081595 Anno Accademico 1996-1997 TESINE Calcolatori quantistici. Relatore: Prof. G. Diambrini-Palazzi Crescita di cristalli superconduttori. Relatore: Prof. A. Scacco Ringraziamenti: Desidero ringraziare il Dr. Franco Marzano ed il Dr. Matteo Mascagni per la professionalità e la disponibilità mostrate durante tutto lo svolgimento del mio lavoro di tesi. Ringrazio inoltre K. H. Sulanke dell’Università di Zeuthen (Desy - Germania), B. Martin del CERN (Ginevra) e J. Legrand (Desy - Germania) per i componenti hardware forniti, ed il Dr. A. Nisati per la preziosa consulenza privata. Ringrazio infine con affetto la persona che in questi anni di studio ha avuto molta pazienza e fiducia in me. Alla mia Famiglia. INDICE Introduzione. 1 Il Large Hadron Collider (LHC) e l’esperimento ATLAS. 5 1.1 Il Large Hadron Collider (LHC). 5 1.2 Atlas. 6 1.2.1 Inner Detector. 8 1.2.2 Calorimetri. 11 1.2.3 Spettrometro dei muoni. 14 Il sistema di trigger. 19 1.3.1 Generalità. 19 1.3.2 Architettura del sistema di trigger. 22 Il trigger di 2° livello. 24 1.4.1 Dimensionamento del sistema di trigger di 2° livello. 28 1.3 1.4 2 1 Il protocollo IEEE 1355 e la sua realizzazione hardware. 33 2.1 Il protocollo IEEE 1355 DS-DE. 34 2.1.1 Descrizione generale. 34 2.1.2 Performance del protocollo IEEE 1355 DS-DE. 42 2.1.2.1 Comunicazioni unidirezionali. 44 2.1.2.2 Comunicazioni bidirezionali. 2.2 45 Lo switch STC104. 49 2.2.1 Il wormhole routing. 54 2.2.2 Interval labelling. 55 2.2.3 Universal routing. 57 2.2.4 Grouped adaptive routing. 58 2.2.5 59 Il “contention model”. 2.3 3 4 60 L’interfaccia STC101. 63 Topologia delle reti locali e globale di ATLAS. 69 3.1 Generalità. 69 3.2 Le reti locali e globale di ATLAS. 72 Descrizione dello hardware e del software sviluppato. 77 4.1 Lo hardware. 77 4.1.1 Le schede VME con lo switch STC104. 77 4.1.2 Le schede IMS B108. 78 4.1.3 Le schede “PCI-DSLink Zeuthen”. 79 4.1.4 Le schede “PCI-DSLink INFN”. 81 4.1.5 I personal computer. 82 4.2 5 2.2.6 Latenza teorica dello switch STC104. Il Software. 84 4.2.1 Software di configurazione e monitoring. 84 4.2.2 Software di comunicazione. 90 4.2.2.1 Misura dei tempi e calcolo delle velocità. 95 Risultati Sperimentali. 99 5.1 Misura della velocità delle schede di interfaccia. 100 5.1.1 Misure in assenza di controlli software. 100 5.1.2 Misure con controlli software attivi. 107 5.1.3 Misura della latenza delle istruzioni di I/O. 110 5.1.4 Misure con “molti” processi attivi su PC. 113 5.2 5.3 5.4 Misure inerenti la latenza dello switch STC104. 115 5.2.1 Misura della latenza del C104. 117 5.2.2 Misura dei tempi di instradamento dei pacchetti. 118 Misure inerenti il contest switch. 119 5.3.1 Contesa con quattro schede PCI-DSLink. 120 5.3.2 Contesa con due schede PCI-DSLink. 123 5.3.3 Distribuzione statistica delle misure temporali. 128 5.3.4 Considerazioni conclusive sul contest switch. 132 Test di affidabilità del protocollo IEEE 1355. 133 Conclusioni. 135 APPENDICE A: Sistema operativo e compilatori. 137 APPENDICE B: Caratteristiche del PCI Local Bus. 143 APPENDICE C: Listato dei programmi “sorgente”. 151 APPENDICE D: Esempio di programmazione di un registro dello switch STC101. BIBLIOGRAFIA. 195 197 INTRODUZIONE. Il lavoro descritto in questa tesi riguarda lo studio e la misura delle caratteristiche di un insieme di dispositivi hardware che possono costituire gli elementi base di un “event builder” per il sistema di trigger dell’esperimento ATLAS a LHC (Large Hadron Collider, Cern, Ginevra). LHC è il nuovo collider per protoni in corso di realizzazione al Cern, in grado di raggiungere un’energia nel centro di massa di 14 TeV. Lo scopo primario di questa macchina è la verifica sperimentale dell’esistenza del bosone di Higgs; questa è prevista dal Modello Standard (con una massa inferiore o dell’ordine del TeV) ed è connessa al meccanismo della rottura spontanea di simmetria. Dopo la scoperta dei bosoni W e Z 0 (e più recentemente del top), e dopo la verifica di numerose previsioni del M.S. effettuate al Lep, la scoperta del bosone di Higgs costituirebbe l’ultimo tassello mancante alla completa verifica del Modello. Altre possibilità offerte da LHC sono: lo studio della violazione di CP nel decadimento del beauty (a tutt’oggi le sole informazioni su questo soggetto sono state ottenute dal sistema K0 – K 0 ) e la possibilità di scoprire i partner supersimmetrici delle particelle oggi note. Una tale scoperta porterebbe anzi ad andare “oltre il Modello Standard”. ATLAS è uno dei principali esperimenti approvati per la fisica ad LHC. L’apparato, suddiviso in un Inner Detector, un sistema calorimetrico ed un rivelatore di muoni, è in grado di rivelare elettroni, fotoni, muoni, jet e di eseguire misure di energia trasversa mancante. Gli eventi interessanti prodotti nelle collisioni protone-protone vengono selezionati per mezzo di un sistema di trigger che ricostruisce le tracce e analizza i depositi di energia nei calorimetri per prendere una decisione sull’evento. Tale selezione ha lo scopo di ridurre il rate di collisioni anelastiche (≅ 108 eventi/s ad alta luminosità) a quello che è ragionevolmente possibile memorizzare su supporto permanente per l’analisi successiva (10-100 Hz). Il trigger è suddiviso in tre livelli gerarchici, ad ognuno dei quali corrisponde una certa quantità di dati da elaborare, una complessità degli algoritmi di ricostruzione da applicare agli stessi, ed una latenza massima entro la quale i risultati debbono essere resi disponibili in uscita al livello successivo. La realizzazione di questo complesso sistema di selezione “in-linea” richiede l’uso di elevato parallelismo: non solo i dati provenienti dai diversi rivelatori fluiscono simultaneamente dall’elettronica di front-end alle memorie, ma anche i dati dello stesso rivelatore sono suddivisi in sottoblocchi che vengono trasmessi in parallelo. A fronte di ciò, per gli algoritmi di selezione del secondo e terzo livello è necessario che i processori che li eseguono dispongano di dati contenuti in diverse memorie. Poichè le latenze fissate non permettono l’uso di procedure software per la raccolta dei dati dai diversi buffer, è indispensabile che tale processo sia realizzato con sistemi hardware molto veloci, dotati di controllo automatico dell’instradamento dei frammenti di evento verso le rispettive destinazioni. Dispositivi in grado di compiere questa funzione vengono denominati “event builder” (termine che evidenzia l’aspetto di raccolta dei blocchi di dati) o anche “switch” (termine che sottolinea la funzione di comunicazione tra “sorgenti” (le memorie) e “destinazioni” (i processori) ). E’ possibile utilizzare per questo scopo switch commerciali progettati, ad esempio, per sistemi di comunicazione telefonica; non è tuttavia certo che questi rappresentino la soluzione ottimale in termini di costo, prestazioni e flessibilità. Una alternativa consiste nel realizzare gli switch utilizzando elementi di base commerciali ma mantenendo il controllo dell’architettura di interconnessione. Il presente lavoro di tesi, in linea con il secondo approccio, riguarda lo studio delle switching network del trigger di ATLAS, la realizzazione del software di comunicazione tra nodi basato sul protocollo IEEE 1355 (DSLink) e misure di parametri caratteristici del protocollo e della rete. Nel primo capitolo viene riportata una descrizione generale dell’esperimento, ma soprattutto viene fornita una stima delle dimensioni delle switching network di ATLAS. Il protocollo di comunicazione utilizzato per le reti locali e globale, i componenti elettronici atti a realizzarlo, e la topologia interconnettiva ipotizzata, vengono analizzati invece nei capitoli 2 e 3. Una particolare attenzione è riservata alla tecnica di gestione delle informazioni da trasferire (pacchettizzazione) ed agli algoritmi che permettono l’instradamento dei dati attraverso gli switch. L’importanza di questi ultimi deriva del fatto che in sistemi complessi quali ATLAS, in cui il traffico dei dati è intenso, per ottenere una bassa latenza è necessario ottimizzare le comunicazioni tra i dispositivi. Per quanto riguarda la parte prettamente sperimentale del lavoro (capitoli 4 e 5), è stata realizzata in laboratorio una rete costituita da tre switch elettronici commerciali, e gestita mediante dei personal computer provvisti di alcune schede di interfaccia tra il bus di I/O PCI ed il protocollo di comunicazione IEEE 1355. Il controllo della switching network avviene grazie allo sviluppo di un software di configurazione e monitoring, mentre la gestione del trasferimento dati viene affidata a dei programmi che permettono di trasmettere e ricevere dei messaggi attraverso essa. Mediante questo software di comunicazione è stato possibile eseguire delle misure di alcuni dei parametri fondamentali del protocollo utilizzato e della rete di switch. Ciò al fine di comprendere entro quali limiti lo IEEE 1355 ed i componenti elettronici che lo realizzano possono essere un valido supporto per la gestione del traffico presente nel sistema di trigger, e per fornire indicazioni riguardanti gli obiettivi da raggiungere nel prossimo futuro. Capitolo 1 Il Large Hadron Collider (LHC) e l’esperimento ATLAS. Nel seguente capitolo si vuole fornire una descrizione sommaria del nuovo acceleratore di particelle Large Hadron Collider (LHC) e del suo apparato di rivelazione ATLAS. Quest’ultimo ha il compito di rivelare le particelle prodotte nelle collisioni dei fasci di LHC e di ricostruire gli eventi interessanti avendone calcolato i parametri fondamentali quali posizione, impulso ed energia. 1.1 Il Large Hadron Collider (LHC). Attualmente è in funzione al CERN (Ginevra) l’acceleratore di particelle LEP, il quale terminerà la sua attività probabilmente nell’anno 2000/2001. Nella sua cavità verrà costruito LHC, il nuovo collider protone-protone in grado di fornire ai fasci una energia di 7 TeV ciascuno. LHC sarà costituito da due anelli con raggio medio di 4,2 Km (circa 26 Km di circonferenza) nei quali verranno accelerate le particelle nelle due direzioni opposte. La sua luminosità1 inizialmente sarà di 10 33 cm-2 s -1 (bassa luminosità) mentre a regime, dopo un anno di funzionamento, arriverà a 1034 cm-2 s-1. Le particelle saranno raggruppate in pacchetti cilindrici lunghi ~7.5 cm, contenenti ognuno ~1011 di esse, mentre 3600 saranno i pacchetti circolanti contemporaneamente negli anelli. Considerando che la frequenza di tali pacchetti sarà di 11 KHz, si avrà una collisione ogni 25 ns (quest’ultimo dato verrà utilizzato in seguito nella descrizione del trigger). Per raggiungere l’energia finale del centro di massa di 14 TeV, i pacchetti verranno prima accelerati dal ProtoSincrotrone (PS) e N b ? f ?k L= 4 ?π ?σ x ?σ y 2 1 La luminosità di un acceleratore di particelle vale: Nb: numero di protoni per pacchetto; k: numero di pacchetti circolanti simultaneamente; σy: semidispersione lungo l’asse y; con f: frequenza dei pacchetti; σx: semidispersione lungo l’asse x; dal SuperProtoSincrotrone (SPS), quindi immessi nell’anello di LHC ed ulteriormente accelerati dalle cavità a radiofrequenza dello stesso. La fisica che si vuole studiare alle energie di LHC ha delle sezioni d’urto di produzione molto basse (dell’ordine di pochi nbarn). Dal momento che la produzione di particelle nell’unità di tempo è proporzionale alla sezione d’urto di quel processo moltiplicata per la luminosità della macchina (dn/dt = σL), avere una luminosità elevata in LHC è fondamentale. In tal senso un ordine di grandezza di differenza nella luminosità può significare un numero di particelle prodotte molto inferiore. 1.2 ATLAS. ATLAS è uno dei due apparati sperimentali approvati per la fisica all’acceleratore LHC; attualmente è in fase di progetto e coinvolge 144 istituti di ricerca in tutto il mondo. Dal momento che molti dei processi fisici che saranno investigati da ATLAS sono ancora poco conosciuti, il rivelatore deve avere un enorme potenziale investigativo. Per questo motivo è dotato di una serie di tecniche di rivelazione di natura diversa in grado di riconoscere elettroni, fotoni, muoni, jet e di effettuare misure di energia trasversa mancante ( ETmiss ). La figura 1.1 mostra il rivelatore nel suo insieme: Figura 1.1: Vista tridimensionale di ATLAS. ATLAS ha una forma cilindrica, coassiale con l’anello di LHC, di lunghezza e raggio complessivi pari rispettivamente a ~40 m e ~11 m. Le coordinate che vengono utilizzate nelle specifiche sono quelle sferiche (φ, θ, z) con z coincidente con l’asse del fascio, φ angolo azimutale e θ angolo polare, anche se si preferisce sostituire θ con la pseudorapidità η definita nel seguente modo: η = − ln tg θ . 2 Osservando il rivelatore lungo una sezione longitudinale, le zone al suo interno vengono identificate da un angolo θ (misurato a partire dall’asse z) al quale corrisponde un determinato valore di η; il range nel quale vengono rivelate le particelle vale |η|<3.2. Αl di fuori di questo intervallo si è nel cono identificato da angoli piccoli rispetto ai fasci (<5°), dove non si riescono ad ottenere dei risultati soddisfacenti per il troppo fondo. Per deflettere le particelle cariche all’interno dei rivelatori, ATLAS è dotato di un sistema magnetico composto da un solenoide superconduttore, il quale genera un campo assiale (lungo la direzione del fascio) pari a 2 Tesla, e da un sistema magnetico toroidale con anima in aria. Per evitare di modificare i parametri delle particelle prodotte negli urti, prima che queste arrivino nel calorimetro elettromagnetico, si devono minimizzare i percorsi che le stesse compiono all’interno della materia; per questo motivo il solenoide viene posto proprio all’interno del calorimetro e.m. ed il suo raggio è limitato a 1.22 m. La sua lunghezza è invece di 5.3 m. Il magnete toroidale, situato esternamente rispetto al solenoide, è composto da un “barrel” di lunghezza di 26 m, diametro interno di 9.5 m ed esterno pari a 19.5 m, e due “end-cap” lunghi 5.6 m e con diametro interno di 1.26 m. Come detto ATLAS è in grado di effettuare misure di diversa natura su particelle differenti; perciò è composto da 3 rivelatori principali, ognuno con particolari caratteristiche. Inoltre ognuno di essi utilizza diverse tecniche di rivelazione in quanto il flusso di particelle varia da una zona all’altra. Seguirà ora una descrizione sommaria di questi tre apparati denominati inner detector, calorimetro e spettrometro dei muoni. 1.2.1 Inner Detector. La parte più vicina alla regione del vertice di interazione è costituita da un rivelatore di tracce interno (Inner Detector ), posto in un solenoide il quale genera un campo magnetico assiale di 2 Tesla. Il rivelatore interno ha una copertura in pseudorapidità compresa nel range |η|<2.5, ed ha una elevata risoluzione di impulso (~22% per un momento trasverso pt pari a 500 GeV nel range |η|<1.5). La identificazione e ricostruzione delle tracce viene effettuata utilizzando due diversi rivelatori: il Semi-Conductor Tracking (SCT) [3] ed il Transition Radiation Tracker (TRT) [3]. Nella figura 1.2 si riporta una sezione dello inner detector: Figura 1.2 : Sezione longitudinale dello inner detector. La regione centrale, denominata barrel, è strutturata in cilindri concentrici ed è delimitata da due pareti identiche poste ai suoi lati, ortogonalmente alla direzione del fascio. Nella zona del barrel più vicina al fascio vi sono gli SCT 2, dei rivelatori a semiconduttore progettati con granularità sottile al fine di aumentarne la risoluzione. Questi sono in grado di effettuare una misura di precisione dell’impulso associato alle tracce. I sei piani SCT vengono integrati dal TRT (posto anch’esso su un cilindro coassiale alla direzione del fascio), il quale è un rivelatore a gas a deriva (drift detector) che consente una buona identificazione delle traiettorie che le particelle compiono. In particolare il tracciatore è in grado di identificare gli elettroni, senza utilizzare le informazioni del calorimetro e.m. sulla loro energia. Come si può notare dalla figura 1.2, anche nelle due zone terminali sono presenti sia gli SCT posti, questa volta, su dischi ortogonali all’asse z, sia il TRT, costituito da più camere di misura. Nella identificazione della traiettoria di una particella, i rivelatori SCT forniscono 6 punti con precisione elevata ed il TRT un minimo di 36 punti con una precisione minore. I dati del TRT consentono di discriminare le tracce relative alle 2 I rivelatori al silicio sono di 2 tipi: a pixel ed a striscie. I primi vengono posti nella zona più interna ed hanno una risoluzione maggiore rispetto ai secondi, ma il loro numero deve essere limitato per la elevata dissipazione in potenza ed il loro costo. traiettorie vere e proprie da quelle generate da punti scorrelati tra loro, non appartenenti ad un’unica particella. Una volta che la traiettoria della particella è stata identificata dal tracciatore, si utilizzano i dati degli SCT per ricavare il valore del suo impulso trasverso. La presenza del TRT è necessaria in quanto nelle zone del rivelatore vicine al vertice di interazione vi è una enorme produzione di particelle (fondo elevato), e risulta molto difficile, in alcuni casi impossibile, discriminare le traiettorie di interesse utilizzando soltanto i 6 punti delle strisce SCT. Nella figura 1.3 si può osservare come la risoluzione del momento trasverso nel rivelatore interno diminuisca rapidamente al crescere della pseudorapidità. Figura 1.3: Andamento della risoluzione del momento trasverso nello inner detector in funzione della pseudorapidità, per muoni con momento trasverso pari a 500 GeV. Questo andamento è giustificato dalla geometria del rivelatore e dalla forma del campo magnetico presente al suo interno. Infatti l’ingente perdita in risoluzione che si ha per η>1.5÷1.8, corrisponde al passaggio delle tracce dalla zona del barrel a quella delle terminazioni laterali, nelle quali vi è una riduzione della lunghezza radiale delle tracce stesse [3], ed il campo magnetico è meno intenso di 2 Tesla. Aumentando la lunghezza del barrel si potrebbe ottenere per il momento trasverso una buona risoluzione anche per valori di |η| maggiori di 1.8, ma aumenterebbero inevitabilmente anche le dimensioni dell’apparato (già notevoli), nonchè il suo costo. 1.2.2 Calorimetri. Il sistema calorimetrico di ATLAS è situato esternamente rispetto allo inner detector ed ha delle dimensioni molto maggiori di esso. E’ composto principalmente da un calorimetro elettromagnetico ed un calorimetro adronico, ed il suo scopo è quello di fornire delle misure energetiche su fotoni, elettroni e getti adronici che lo attraversano, nonchè delle ETmiss . Nella figura 1.4 viene riportato il suo schema generale: Figura 1.4: Sezione longitudinale del sistema calorimetrico. La zona centrale del calorimetro elettromagnetico viene denominata barrel e contiene, come detto, il solenoide superconduttore, mentre quella del calorimetro adronico è suddivisa in un barrel più due extended barrel. Le terminazioni laterali vengono denominate end-cap per entrambi i calorimetri, e sono racchiuse in un unico criostato. La copertura totale è compresa nel range |η|<3.2. Nella maggior parte del suo volume, la risoluzione in energia del calorimetro e.m. può essere vista come la somma di tre contributi: due termini pari a σ( E ) 10% = + 01% . , più un termine costante compreso tra 300 MeV e 500 MeV E E (rumore). Il materiale sensibile del calorimetro e.m. è costituito da Argon Liquido (LAr) per la sua caratteristica intrinseca di resistenza alle radiazioni. Per quanto riguarda il calorimetro adronico, la sua parte centrale è formata da piastre assorbenti di ferro poste ortogonalmente al fascio e intervallate da piatti di materiale scintillante in grado di rivelare gli adroni. Le uniche misure della risoluzione in energia per il calorimetro adronico sono state effettuate con dei prototipi “isolati”, ovvero non includenti il calorimetro e.m., ed hanno fornito, per i σ( E ) 50% = + 3% . L’end-cap del rivelatore pioni carichi (π+ e π -) il valore E E adronico, il quale viene sottoposto a maggiori radiazioni rispetto al barrel, è invece formato da piastre assorbenti di rame, intervallate da LAr. In questo caso la σ( E ) 100% = + 10% , ma risulta comunque adeguata risoluzione in energia scende a E E ai risultati che si vogliono ottenere. In generale le risoluzioni dipendono dalle segmentazioni spaziali delle varie parti del calorimetro; queste ultime vengono misurate in ∆η x ∆φ e, maggiore è la segmentazione, maggiore è la risoluzione ottenibile ma superiori sono anche i costi e la dissipazione in potenza del sistema. Nei calorimetri appena descritti le segmentazioni variano in funzione della distanza dal vertice. Il calorimetro e.m. ha una segmentazione pari a ∆η × ∆φ ≅ 0.003 x 0.1 nella parte più vicina al fascio, e ∆η × ∆φ ≅ 0.025 × 0.025 nelle zone rimanenti, mentre per quello adronico si passa dal valore ∆η × ∆φ ≅ 0.1 × 0.1 dei barrel ed extended barrel a ∆η × ∆φ ≅ 0.2 × 0.2 degli end-cap. Nella tabella 1.1 vengono riportati i valori della segmentazione e della risoluzione in energia per le varie regioni dei calorimetri: Calorimetro Regione Segmentazione (∆η x ∆φ) Risoluzione σ(E)/E 0.003 × 0.100 E.M. Barrel 0.025 × 0.025 0.025 × 0.050 10% + 01% . E 0.003 × 0.100 E.M. End-cap 0.025 × 0.025 0.025 × 0.050 10% + 01% . E 0.050 × 0.050 Adronico Adronico Barrel End-cap 0.1 × 0.1 0.2 × 0.2 50% E 100% E + 3% + 10% Tabella 1.1: Segmentazioni spaziali e risoluzioni energetiche dei calorimetri e.m. ed adronico. 1.2.3 Spettrometro dei muoni. Lo spettrometro dei muoni è stato progettato per effettuare delle misure di precisione delle traiettorie e dell’impulso trasverso 1 dei µ + e µ−, in maniera indipendente dal rivelatore interno e dai calorimetri. E’ uno dei punti di forza di ATLAS in quanto ha una buona risoluzione spaziale intrinseca (60 µm) su un range del momento trasverso che va da 5 GeV a più di 1 TeV. Le sezioni trasversali e longitudinali dello spettrometro vengono riportate rispettivamente nelle figure 1.5a e 1.5b: Figura 1.5a: Sezione trasversale dello spettrometro dei muoni. 1 Data l’enorme produzione di particelle lungo la direzione dell’asse del fascio, non possono essere effettuate delle misure del momento lungo tale direzione. Figura 1.5b :Sezione longitudinale dello spettrometro dei muoni. Il sistema magnetico toroidale descritto precedentemente effettua una copertura in pseudorapidità compresa nel range |η|<3, ed è suddiviso in tre zone: la regione del barrel (|η|<1.1), la regione di transizione (1.1<|η|<1.4) e la regione dell’end-cap (1.4<|η|<3). Ognuno dei tre magneti toroidali (un barrel e due end-cap) è provvisto di 8 bobine le quali creano un campo magnetico in aria 2, all’interno dello spettrometro. Dal momento che il numero di bobine che costituiscono il sistema magnetico è finito, il campo magnetico risultante non è perfettamente toroidale. La figura 1.6 mostra le linee di flusso del campo magnetico all’interno della regione di transizione: 2 Non è stato scelto un materiale ferromagnetico per limitare lo scattering multiplo dei muoni nel ferro. Figura 1.6: Andamento delle linee di flusso del campo magnetico nella regione di transizione. La componente assiale del campo magnetico, che aumenta in prossimità delle bobine, causa la non uniformità del campo magnetico risultante e di conseguenza una diminuzione della risoluzione del momento trasverso. Il rivelatore dei muoni è suddiviso in “camere”, grazie alle quali vengono individuate delle tracce per ricostruire la traiettoria ed il momento trasverso dei µ. Nel loro complesso le camere debbono assicurare la copertura nell’intervallo |η|<3; e 0<φ<2π, e devono permettere l’identificazione delle cosiddette Regioni di Interesse 3 (RoI) utilizzate dal sistema di trigger. Le camere presenti nella barrel region sono poste in tre stazioni cilindriche, coassiali con l’asse del fascio. Nell’end-cap invece la loro disposizione è verticale, formano una sezione ottagonale, e sono parzialmente sovrapposte (figura 1.5.b) per assicurare una buona copertura in tutto il range di η. Vi sono quattro differenti “tipi” di camere, due per effettuare le misure vere e proprie e altre due utilizzate dal sistema di trigger dei muoni: le Monitored Drift Tube (MDT), le Cathode Strip Chambers (CSC), le Resistive Plate Chambers (RPC) e le Thin Gap Chambers (TGC). In generale una RoI è una regione di un rivelatore, limitata in η e φ, alla quale corrispondono dei depositi significativi di energia trasversa (per il calorimetro e.m.) oppure la presenza di tracce (per lo spettrometro dei muoni). 3 Le camere MDT vengono utilizzate in un ampio intervallo di |η| (fino ad |η|<2.5) e sono costituite da 2 piani multistrato, ognuno contenente 3 o 4 tubi a deriva in alluminio, con un diametro di 30 mm. Sotto particolari condizioni si riesce ad ottenere con esse una risoluzione spaziale di circa 80 µm ed un tempo massimo di deriva di 500 ns4. Le camere CSC sono assemblate in modo analogo alle precedenti, vengono utilizzate per grandi valori di |η| (|η|>2.5) in quanto resistono maggiormente alle radiazioni, e permettono di ottenere buone risoluzioni spaziali (50 µm). Per quanto concerne invece il sistema di trigger, le camere RPC, utilizzate nella regione del barrel, sono costituite da rivelatori gassosi organizzati in piatti paralleli, con i quali si ottengono delle risoluzioni temporali pari a ~2 ns. Infine, mediante le TGCs, si riescono ad ottenere delle risoluzioni temporali di ~5 ns, ma migliori risposte alle alte frequenze. Le maggiori difficoltà che si incontrano nella identificazione degli eventi interessanti all’interno dei rivelatori, sono dovute alla enorme produzione di particelle “secondarie”: muoni di decadimento, elettroni ed adroni di punch-through, neutroni e fotoni, si aggiungono alle particelle da rivelare. Queste particelle secondarie possono avere bassa energia (elettroni e/o fotoni) nel qual caso eccitano singoli elementi del rivelatore e forniscono, nel complesso, dei punti random isolati, oppure possono avere una energia superiore a 10 MeV (particelle neutre e cariche) ed eccitare più rivelatori, fornendo dei punti correlati. Per questo motivo le particelle di fondo generate all’interno dei calorimetri influenzano, oltre alla risoluzione delle misure, anche il trigger dei muoni. Il flusso di particelle all’interno dello spettrometro è funzione sia del loro momento trasverso, sia della pseudorapidità. La produzione di muoni per pt<20 GeV è dominata dai decadimenti dei quark charm (c) e beauty (b), per pt>20 GeV dal decadimento del bosone Z mentre per pt>100 GeV dal decadimento del quark top (t). Nella regione del barrel, i flussi di muoni, elettroni e adroni valgono rispettivamente 1, 6 e 3 Hz/cm2; nella regione di transizione domina invece il flusso generato dagli elettroni di decadimento (5 Hz/cm 2) rispetto a quello dei muoni e degli adroni, che hanno lo stesso valore (3 Hz/cm2). 4 Il Tempo di Deriva è il tempo che intercorre tra l’attraversamento del tubo a deriva da parte della particella, e l’arrivo delle cariche prodotte dalla ionizzazione del gas sul conduttore centrale del tubo. Le frequenze dei conteggi stimate per i neutroni (n), i fotoni (γ) e le particelle cariche prodotte dal passaggio delle stesse all’interno dei calorimetri e degli altri elementi di ATLAS, vengono riassunte nella tabella 1.2: Particelle neutre (n) Fotoni (γ) Particelle cariche (Hz/cm2) (Hz/cm2) (Hz/cm2) Barrel 4 10 7 EI (inner end-cap) 1.4<|η|<2.2 60 50 70 2.2<|η|<3.0 380 500 800 EM (med. End-cap) 1.4<|η|<2.2 5 13 20 2.2<|η|<3.0 20 40 60 EM (outer end-cap) 1.4<|η|<2.2 1.5 7 12 2.2<|η|<3.0 1.5 9 30 Regione Tabella 1.2: Stima dei conteggi per la produzione di particelle all’interno delle camere di precisione (MDT) La stima è stata effettuata considerando i conteggi delle camere di precisione (MDT) per le regioni del barrel e dello end-cap5, e assumendo per la luminosità il valore massimo di 1034 cm-2 s-1. 5 Con la notazione EI, EM ed EO vengono indicate rispettivamente le zone interne, centrali, ed esterne della regione dello end-cap delle stazioni dei muoni. 1.3 Il sistema di trigger. 1.3.1 Generalità. Il sistema di trigger dell’esperimento ATLAS seleziona in tempo reale gli eventi prodotti dalle collisioni protone-protone nel rivelatore interno, nei calorimetri e nello spettrometro dei µ. Il trigger deve gestire una enorme quantità di dati provenienti dall’elettronica di front-end del rivelatore. Considerando infatti che, alla luminosità di 10 34 cm -2s-1, il volume dei dati per ogni bunch crossing è dell’ordine di 1 Mbyte, e che in LHC vi è una collisione ogni 25 ns, il flusso totale dei dati è pari a ~ 40 Tbyte/s ! Nella figura 1.7 viene riportato lo schema generale del sistema di trigger e acquisizione dati dell’esperimento. Figura 1.7: Schema del sistema di trigger dell’esperimento ATLAS. Data la grande quantità di informazioni da elaborare, il trigger viene suddiviso in tre livelli gerarchici, all’interno dei quali si cerca un compromesso tra la frequenza degli eventi da gestire e la complessità degli algoritmi che devono essere applicati ai dati stessi. Nel caso peggiore le decisioni sugli eventi debbono essere prese in pochi µs, ciò per non perdere i dati relativi al campionamento successivo. Inoltre la struttura che si cerca di utilizzare per il sistema di trigger è fortemente parallela, sia per evitare colli di bottiglia nei dispositivi di ricezione, sia per la natura stessa delle tecniche di rivelazione di ATLAS. Il primo livello è localizzabile immediatamente dopo l’elettronica di front-end e deve essere quindi in grado di accettare dati alla frequenza di 40 MHz (frequenza di collisione di LHC) ovvero ogni 25 ns. Questo livello ha come input tutte le informazioni provenienti dai calorimetri e dallo spettrometro dei µ, mentre non considera i dati forniti dal rivelatore interno (quest’ultimo è troppo lento). Il primo livello deve fornire, in maniera non ambigua, informazioni sull’evento selezionato e deve ridurre la frequenza dei dati in uscita a 100 KHz. La sua latenza è pari a ~2 µs: durante questo intervallo di tempo i segnali provenienti dai rivelatori vengono memorizzati in memorie pipeline. Grazie a questa prima selezione, vengono individuate le Regioni di Interesse (RoI), le quali hanno delle soglie programmabili e nelle quali sono contenute le informazioni da trasmettere al 2° livello. Anche se di complessità non elevata, gli algoritmi presenti nel livello uno sono estremamente selettivi e permettono una forte riduzione del flusso dei dati. Inoltre, dato il brevissimo tempo a disposizione per prendere una decisione (~2 µs), gli algoritmi del 1° livello sono implementati in modo hardware: in sostanza effettuano dei confronti tra le grandezze rivelate e le soglie programmate. Il secondo livello, che nel paragrafo 1.4 verrà descritto nel dettaglio, analizza soltanto i dati provenienti dalle RoI (con frequenza pari a 100 KHz) utilizzando però anche le informazioni provenienti dal rivelatore interno, relativamente alle RoI o di tutto il rivelatore, a seconda della luminosità alla quale si lavora. La sua latenza massima è pari a 10 ms, e la frequenza dei dati passa da 100 KHz ad 1 KHz. Questo livello, grazie ad una maggiore latenza, può applicare algoritmi più complessi rispetto a quelli del livello precedente, decidendo così se un evento è da rigettare, oppure deve essere passato al trigger di livello tre. Inoltre, i dati a disposizione sono quelli con la precisione e la granularità finali, ossia gli stessi dell’analisi offline. Una volta accettato, l’evento viene passato all’ultimo livello, il quale elabora tutti i dati dell’evento (non solo quelli delle RoI) e memorizza, con una frequenza massima di 100 eventi/s (la dimensione del singolo evento è di 1 Mbyte), le informazioni finali per le analisi offline. Quest’ultimo sottosistema, anche se presenta una complessità maggiore dei precedenti, permette di avere delle latenze di qualche secondo. In sostanza il primo livello accetta e registra in delle memorie pipeline tutti i dati provenienti dai calorimetri e dallo spettrometro dei muoni, fornisce al secondo livello le informazioni delle RoI ed alle memorie DAQ tutti i dati digitalizzati; il secondo livello elabora le RoI e decide se l’evento deve essere accettato o rigettato: in caso di risposta affermativa l’evento viene inviato al trigger di livello 3 (Event Filter), mentre in caso di risposta negativa i dati presenti nelle memorie del DAQ vengono “sovrascritti”. 1.3.2 Architettura del sistema di trigger. In questo paragrafo si vuole fornire una descrizione più dettagliata delle varie parti che compongono il sistema di trigger. Nella figura 1.8 viene riportato lo schema a blocchi dell’architettura nel suo complesso. Figura 1.8: Architettura del sistema di trigger. Dall’elettronica di front-end provengono dei link 1 dedicati denominati FEL (Front End Link) i quali, grazie a dei multiplexer ed ai Read Out Link (ROL), vengono connessi a ~2000 R/O Cards (Read Out Cards) o ROB (Read Out Buffer) 1 Questi link possono avere specifiche diverse per i vari rivelatori dai quali provengono anche se per la maggior parte si prevede di utilizzare link ottici da 1 Gbit/s. inserite nei crate (~200) denominati DAQ Crates; questi ultimi, allo stato attuale delle cose, possono in linea di principio essere identificati come crate VME. La frequenza degli eventi all’ingresso del trigger delle R/O Cards è, come detto in precedenza, di 100 KHz ed il volume dei dati di un singolo evento al loro ingresso è di ~1.3 Mbyte. Considerando le incertezze ancora presenti su quest’ultimo valore, una stima adeguata della banda passante aggregata in ingresso alle R/O Cards risulta essere di ~150 Gbyte/s (~1.5 Mbyte × 100 KHz). La capacità di acquisizione del singolo ROB è dell’ordine di 1 Gbit/s e quindi la stima iniziale di 2000 R/O Cards risulta essere ridondante (150 Gbyte/s ÷ 1 Gbit/s = 1200) . Ogni R/O Card è provvista di una memoria a molte porte [13], necessaria per memorizzare i dati durante la latenza di secondo livello, una CPU (Central Processing unit) per il preprocessamento e la formattazione dei dati, e delle interfacce di uscita per i livelli 2 e 3. Le memorie, che ricevono i dati dal primo livello e li spediscono al secondo ed eventualmente al terzo, debbono essere provviste di almeno due porte veloci (1 Gbit/s): una in ingresso ed una in uscita. Una ulteriore porta di I/O a bassa velocità (per esempio VME) è prevista per il monitoring della scheda. Ogni DAQ crate contiene invece, oltre alle R/O Cards, un DAQ Supervisor per la gestione del crate ed il monitoring del suo stato, ed una trigger interface (TRG) la quale colloquia con lo RoI builder del primo livello e col Supervisor del secondo; le coordinate del RoI builder vengono convertite in indirizzi che puntano ai buffer delle R/O Cards nei quali sono memorizzati i dati. In questo modo le informazioni relative ad una determinata RoI possono essere identificate e quindi trasferite (sotto la richiesta del Supervisor) al livello 2 per l’esecuzione degli algoritmi, al livello 3 se l’evento viene accettato, oppure ignorate se l’evento è da rigettare. I dati che arrivano al 3° livello sono quindi tutti relativi ad eventi accettati dal 2° livello. Il dimensionamento delle memorie presenti nelle R/O Cards e la latenza del secondo livello, dipendono l’una dall’altra: al crescere della latenza un maggior numero di eventi deve attendere la decisione del Supervisor, e quindi sono necessarie delle memorie più capienti per contenerli. Tutti i DAQ crates vengono connessi tra loro tramite una rete locale (al momento una LAN - Local Area Network) e gestiti da un sottosistema di controllo in grado di identificare ed isolare eventuali malfunzionamenti, senza interrompere le comunicazioni sugli altri DAQ crates2. La rete di controllo, oltre ad interconnettere tra loro i vari crate, è a sua volta collegata con il Detector Control System (DCS) il quale supervisiona tutte le componenti del rivelatore e le infrastrutture di ATLAS. 1.4 Il trigger di 2° livello. Il trigger di 2° livello ha lo scopo di ridurre la frequenza degli eventi di un fattore 100, ossia da 100 KHz ad 1 KHz. Tale riduzione è possibile grazie all’uso di algoritmi software più sofisticati rispetto a quelli utilizzati al 1° livello e soprattutto correlando tra loro le informazioni dei vari sottorivelatori. In questo punto sono disponibili agli algoritmi i dati con la precisione e granularità finali, che consentono di ricostruire meglio gli oggetti fisici (e±, µ±, h, jets, ecc…) indicati dal trigger di 1° livello, e di fare inoltre delle ipotesi su alcuni canali di decadimento. La riduzione della frequenza degli eventi si ottiene grazie alla definizione più netta della soglia di trigger, alla richiesta di criteri di correlazione (ad esempio criteri di isolamento applicati ai muoni, basati sulle informazioni dei calorimetri) ed a tagli in massa invariante per canali quali Z0 → µ+µ− ,e+e−, ecc… E’ altresì necessario progettare il sistema implementando un forte parallelismo ed introducendo il concetto di RoI, che permette di ridurre la quantità di informazioni sulle quali si deve applicare l’algoritmo di almeno un ordine di grandezza. In questo modo la realizzazione di un sistema che funzioni alle frequenze previste è possibile con tecnologie moderne. La latenza del 2° livello è variabile e compresa nel range 1 ÷ 10 ms. Lo schema generale di questo sottosistema, viene riportato nella figura 1.9. 2 Affinchè il tutto sia fault tolerant è necessario che il sottosistema di controllo ed il sistema di gestione del flusso dei dati siano tra loro indipendenti. Figura 1.9: Schema del trigger di 2° livello. I LVL2 Buffers sono le R/O Cards e contengono i dati provenienti dall’elettronica di front-end. Come già detto, il numero di questi buffer è stimato essere ~2000, per una rate totale di 150 Gbyte/s. Nel secondo livello, una prima elaborazione viene effettuata dai processori locali (processori general-purpose) i quali ricevono parte dei dati memorizzati nei buffer (quelli relativi alle RoI) sotto il controllo del LVL2 Supervisor. Questi processori sono organizzati in farm e dedicati ad uno specifico sotto-rivelatore. Una prima switching network (Local Switching Network) si rende in questo punto necessaria per la connessione globale tra i ROB ed i processori locali. Con questo tipo di interconnessione (a differenza delle Multiplexing Network) sono possibili dei collegamenti multipli tra più elementi; il flusso di dati provenienti da più buffer e destinati ad un processore locale non impedisce che nella rete vi siano, nello stesso istante, altre vie di comunicazione tra gli host. Un’altra rete (Global Switching Network) viene interposta tra i processori locali ed i processori globali (anch’essi processori general-purpose); questi ultimi sono in numero minore rispetto ai primi ed elaborano i dati relativi a tutte le RoI che appartengono ad un evento. Le unità di calcolo appena descritte (processori locali e globali) possono essere realizzate con dei processori veri e propri oppure con delle matrici a logica programmabile (Field Programmable Gate Array - FPGA3); queste ultime sono ugualmente veloci e meno costose dei processori; per contro sono però più complesse, ovvero la loro programmazione è (attualmente) più difficoltosa rispetto a quella delle CPU. Al momento non è stata presa nessuna decisione sulle unità di elaborazione in quanto le potenze di calcolo crescono notevolmente con gli anni, e non avrebbe senso decidere ora il processore finale dell’esperimento. Comunque una stima ragionevole per la potenza richiesta ai processori locali nel complesso risulta essere di ~5 × 10 5 MIPS (Mega Instructions Per Second) equivalenti: per soddisfare queste cifre, all’aumentare della potenza delle singole CPU, sarà sufficiente un numero sempre minore di esse. Il blocco denominato RoI Builder combina tra loro le informazioni sintetiche sull’evento, provenienti dai calorimetri e dallo spettrometro ed elaborate dal trigger di 1° livello, e le fornisce, sotto forma di RoI, al LVL2 Supervisor per l’identificazione dell’evento. Il LVL2 Supervisor controlla invece l’intero flusso di dati del 2° livello, selezionando dai ROB i dati da passare al trigger, eventualmente aggiungendo loro delle informazioni per l’instradamento attraverso la rete, assegnando, ove necessario, i processori delle farm locali e globali alle singole RoI e all’evento stesso, ed infine interagendo con il Supervisor del 3° livello. 3 Una FPGA è una logica programmabile (PLA, PLD ecc…) con una serie di funzionalità aggiuntive. In particolare ha una capienza maggiore delle PLD, è molto più flessibile e molto spesso è un dispositivo SRAM (Static RAM) ovvero ha bisogno di essere riconfigurata ogni volta che viene alimentata. La sua programmazione avviene mediante un apposito linguaggio nel quale sono presenti delle librerie contenenti i componenti elettronici da riprodurre al suo interno. Le sue caratteristiche fondamentali sono la velocità con la quale fornisce i risultati in uscita e la capacità, espressa in gateequivalente. Mediante le FPGA è possibile riprodurre innumerevoli componenti tra cui memorie, logiche di controllo, interfacce (tipo PCI-DSLink) e CPU. Una logica programmabile è invece un dispositivo elettronico costituito da una matrice di porte logiche fondamentali (AND e OR), in grado di realizzare delle funzioni booleane delle variabili presenti al suo ingresso. Come si può intuire dalla figura 1.9 e dai paragrafi precedenti, l’elaborazione dell’evento al livello due viene suddivisa in diversi passi fondamentali, ad ognuno dei quali corrisponde una diminuzione dell’ammontare dei dati. Il primo passo, effettuato dai processori locali, converte le informazioni provenienti dai vari subdetector (raw data) in quantità fisiche; il secondo passo, effettuato ancora dai processori locali, associa queste quantità fisiche (energia, impulso, ecc…) relative ad una singola RoI, ad oggetti ben definiti (e, µ, h, jet, ecc…). L’ultimo passo infine (processori globali), per ciascuna RoI, correla i vari subdetector ed elabora tutti gli oggetti delle RoI di uno stesso evento per la decisione finale. Data la necessità di combinare tra loro informazioni provenienti da subdetector differenti, l’uso delle switching network come reti di collegamento tra le vari parti, rende più duttile il sistema, in quanto in linea di principio (se la rete viene configurata in tal senso) ogni sorgente può inviare dati ad una qualsiasi delle destinazioni. I particolari delle switching network verranno discussi nei capitoli successivi. I dati memorizzati nei ROB sono suddivisi in base al tipo di rivelatore dal quale provengono: le informazioni relative allo spettrometro occuperanno un certo numero di memorie, così quelle dei calorimetri e del rivelatore interno. Questa suddivisione rimane tale nei processori locali, e così la rete locale può essere suddivisa in tre sottoreti indipendenti. Un processore globale invece, combinando informazioni provenienti da più rivelatori differenti, deve poter ricevere dati da più processori locali. Di conseguenza la rete globale deve essere unificata, ovvero deve connettere ogni processore locale ad ognuno dei processori globali. Data l’enorme quantità di componenti presenti nel trigger di 2° livello (processori, memorie, switch…) e la loro complessità, caratteristiche fondamentali del sistema sono la tolleranza ai guasti e la riconfigurabilità, in modo tale che un errore su un singolo componente non comporti il blocco totale dell’algoritmo e quindi della presa dati. Ancora una volta l’uso delle switching network soddisfa tali richieste; in particolare vedremo come le reti basate sullo switch elettronico SGS Thomson C104 siano in buon accordo con le specifiche appena descritte. 1.4.1 Dimensionamento del sistema di trigger di 2° livello. Dimensionare in modo preciso tutte le componenti del sistema di trigger non è al momento un compito agevole, in quanto non sono ancora state effettuate tutte le simulazioni necessarie sia della fisica, sia dei fondi previsti nella caverna e quindi dell’apparato sperimentale. Da ciò si dovrebbero ricavare le frequenze ed i volumi dei dati in gioco. Anche i dettagli sulla elettronica di lettura dei rivelatori sono importanti al fine di dimensionare il sistema, ma tale elettronica è ancora in via di definizione. Al momento è solo possibile effettuare una stima di massima del numero dei componenti che costituiscono le reti locali e globale, e calcolare delle dimensioni che sono un estremo superiore per quelle dell’esperimento finale. Eventuali espansioni future vengono considerate contemplando reti scalabili. E’ necessario considerare tutti i rivelatori, non solo lo spettrometro dei muoni, sia perchè gli switch hanno un utilizzo generale, sia per dimensionare correttamente la rete globale. Come detto gli switch locali appartengono al rivelatore dal quale provengono i dati al loro ingresso. I calorimetri (e.m. + adronico) distribuiscono le informazioni a ~800 ROB contenuti in ~50 DAQ, il TRT a ~512 ROB (in 32 crate), mentre lo spettrometro a muoni ~256 ROB (in ~16 crate). Figura 1.10: Dimensioni delle reti locali e globale. Questi dati vengono poi distribuiti dai tre switch locali rispettivamente a 256 (calorimetri), 256 (TRT) e 128 (spettrometro) processori locali, i quali, dopo aver applicato gli algoritmi di ricostruzione, li instradano verso i 128 processori globali mediante il global switch. Ogni evento è costituito in media da ~3 RoIs, ognuna delle quali ha delle dimensioni che dipendono dal rivelatore dal quale provengono. Per i processori locali esistono delle stime, sia per quanto riguarda queste dimensioni, sia per i tempi di esecuzione degli algoritmi del 2° livello. Nella tabella 1.3 vengono riportate le due serie di valori, ricavate considerando dei processori locali aventi una potenza di calcolo di 500 MIPS equivalenti4. 4 In realtà la simulazione per il calcolo delle latenze degli algoritmi dei processori locali è stata effettuata considerando dei processori da 100 MIPS equivalenti. I valori della tabella relativi a processori locali da 500 MIPS equivalenti sono stati ottenuti estrapolando i risultati di tale simulazione. Rivelatore Tempi di esecuzione degli algoritmi Dimensioni evento Spettrometro dei µ <100 µs @ 500 MIPS Calorimetri <100 µs @ 500 MIPS TRT (Inner Detector) SCT (Inner Detector) ~600 µs @ 500 MIPS <1 ms @ 500 MIPS ~1 Kbyte per RoI ~2.5 Kbyte per e/γ ~16 Kbyte per i jet ~0.3 Kbyte @ L=1034cm-2s-1 ~1 Kbyte @ L=1034cm-2s-1 Tabella 1.3: Stima dei tempi di esecuzione degli algoritmi dei processori locali e dimensioni degli eventi. Per la stima della latenza introdotta dai processori globali non è stata effettuata invece nessuna simulazione. Quindi non si conoscono ancora i tempi caratteristici dell’ultima parte degli algoritmi di ricostruzione, ma si suppone che essi siano sensibilmente inferiori a quelli esposti nella tabella 1.3. Ricapitolando si hanno dunque tre switch locali ed uno globale, con le dimensioni riportate nella figura 1.10 e rispondenti alle seguenti caratteristiche: • relativamente ad una stessa rete, tutte le sorgenti devono poter dialogare con tutte le destinazioni in modo bidirezionale; • non sono previste connessioni “orizzontali” del tipo ROB-ROB, processore locale - processore locale, processore globale - processore globale (almeno non tramite gli switch); • le reti devono avere una latenza dipendente soltanto dalla lunghezza del pacchetto che le attraversa e non dal nodo di ingresso; • le reti devono essere scalabili, per eventuali espansioni e/o modifiche; • il loro throughput deve essere dell’ordine di 1 Gbit/s per link. Nella distribuzione dei dati attraverso la rete di switch, è possibile implementare due differenti architetture: pull e push. Nella prima, i dati vengono inviati al destinatario sotto sua esplicita richiesta: la sorgente (ROB o processore locale) attende un segnale prima inviare le informazioni al processore locale o globale richiedente, che a sua volta effettua la richiesta soltanto quando necessita dei dati. Nella seconda i dati vengono instradati nello switch, anche se il processore che deve riceverli non è ancora pronto a processarli perchè occupato con un’altra RoI o evento: in questo caso le informazioni vengono memorizzate nella memoria locale del destinatario. Grazie alla bidirezionalità dei link, entrambe le architetture possono funzionare correttamente con la tecnica delle switching network: tutti gli host (sorgenti o destinazioni) hanno un loro indirizzo e possono così identificarsi univocamente, sia per richiedere dati che per inviarli. Nell’architettura pull, essendo il processore di destinazione a richiedere i dati, si ha un maggiore sfruttamento delle risorse di rete, le quali vengono impegnate soltanto quando l’algoritmo lo richiede e non ogniqualvolta nelle sorgenti vi è un pacchetto pronto per essere spedito. Per contro però il processore locale deve spendere del tempo per effettuare la richiesta. A favore della push vi è invece una maggiore semplicità di gestione del sistema in quanto le informazioni relative ad un evento vengono raccolte direttamente dalle sorgenti, a costo però di un maggior sfruttamento della switching network. Dopo aver mostrato quali sono le specifiche generali delle reti locali e globale del sistema di trigger, nei capitoli successivi verranno descritte nel dettaglio le caratteristiche dello switch STC104 della SGS Thomson, e verrà analizzata la topologia di interconnessione delle switching network dell’esperimento ATLAS. Capitolo 2 Il protocollo IEEE 1355 e la sua realizzazione hardware. I componenti hardware utilizzati, nonchè il software sviluppato per realizzare uno switching network con le caratteristiche richieste dal trigger di 2° livello di ATLAS, rispondono alle specifiche del protocollo di comunicazione IEEE 1355 [12]. Il presente capitolo vuole fornire una esauriente descrizione di questo protocollo e dei vari componenti elettronici mediante i quali esso viene realizzato. Vengono altresì studiate la prestazioni teoriche del protocollo di comunicazione ed alcune importanti tecniche di instradamento dei pacchetti attraverso gli switch STC104. Lo IEEE 1355 nasce come protocollo di interconnessione seriale tra dispositivi elettronici. Esso riguarda innumerevoli campi di applicazione nei quali è richiesta una connettività globale a bassa latenza, basso costo, di semplice implementazione, scalabile. Applicazioni tipiche sono la realizzazione di LAN, calcolo parallelo, server multimediali, networking e sistemi di acquisizione dati, quali appunto quello di ATLAS. La possibilità di applicazione dello IEEE 1355 in campo audio, video, e la compatibilità (ad alto livello) che esso ha nei confronti di altri protocolli (TCP/IP, ATM, ecc.), nascono fondamentalmente dalla libertà di poter scegliere la lunghezza dei pacchetti da trasmettere anche se, come vedremo, per raggiungere le migliori prestazioni è necessario imporre alcuni limiti sulle dimensioni degli stessi. Un’altra caratteristica fondamentale dello IEEE 1355, che permette comunicazioni asincrone, è la implementazione di memorie FIFO (First In First Out) tra i vari host interconnessi. In questo modo le differenti velocità dei dispositivi non limitano le comunicazioni tra essi. La realizzazione hardware dello IEEE 1355 viene effettuata da una serie di chip che saranno descritti nel seguito del capitolo e che rispondono al protocollo IEEE 1355 DS-DE (denominato anche DSLink). Come vedremo quest’ultimo completa lo IEEE 1355, mediante l’aggiunta di una serie di specifiche per il controllo del flusso di dati e per la gestione delle informazioni da trasferire. 2.1 Il Protocollo IEEE 1355 DS-DE. 2.1.1 Descrizione generale. Lo IEEE 1355 DS-DE (DSLink) è un protocollo che integra lo IEEE 1355 con alcune specifiche più dettagliate sui segnali utilizzati nelle comunicazioni. Viene utilizzato per collegamenti punto-punto e permette di effettuare trasmissioni bidirezionali asincrone, con controllo di flusso a vari livelli gerarchici. Il canale DSLink è costituito da 8 linee sulle quali viaggiano i segnali (differenziali) di Data e di Strobe, 4 per ogni direzione; è attualmente in grado di raggiunge velocità di trasmissione di 100 Mbit/s. Il protocollo DSLink prevede 5 livelli gerarchici: 1 elettrico; 2 a livello di bit; 3 a livello di token; 4 a livello di pacchetto; 5 a livello di messaggio. In generale la suddivisione in livelli è tipica di tutti i protocolli di comunicazione. Nello IEEE 1355 DS-DE i primi tre livelli vengono realizzati in modo automatico dai dispositivi hardware che vedremo nel seguito del capitolo (STC101 ed STC104). La pacchettizzazione ed il messaging non vengono invece eseguiti automaticamente, ma possono essere realizzati dall’utente mediante alcuni strumenti forniti dallo stesso hardware. Sostanzialmente i tre livelli inferiori permettono di realizzare sia un controllo sul flusso dei dati (rivelazione di errori sulla parità), sia uno handshake tra i dispositivi connessi, il tutto senza alcun intervento esterno. La capacità di gestire pacchetti e messaggi permette invece di aggiungere ai dati delle informazioni addizionali, dette di routing, quali l’indirizzo della destinazione ed un segnale indicante la loro terminazione. Mediante queste ultime è così possibile trasferire le informazioni tra più di due host, e attraversare delle switching network comunque complesse (come ad esempio quelle presenti nel trigger di 2° livello di ATLAS). Analizziamo nel dettaglio i 5 livelli del protocollo. Protocollo a livello elettrico. I segnali presenti all’interno dei dispositivi DSLink sono TTL compatibili. Quando devono essere propagati per distanze lunghe (alcuni metri), per eliminare le fluttuazioni del potenziale di “massa”, questi segnali vengono trasformati in livelli differenziali, generati tramite dei buffer della famiglia AT&T 41 [2]. Dal momento che i segnali DSLink sono, come vedremo, due per ogni direzione di percorrenza, ed ognuno di essi è differenziale, sono necessarie otto linee per il loro trasporto. I cavi DSLink a disposizione sono del tipo 2791 della Madison Cable Corporation, hanno una resistenza caratteristica di 100 Ω, e sono costituiti da 8 fili di rame, oltre ad uno per la massa ed uno riservato. Il collegamento di questi cavi alle schede elettroniche avviene tramite dei connettori, una coppia per ogni canale DSLink, i quali sono robusti e di piccole dimensioni (se comparati con componenti analoghi). I cavi ed i connettori sono completamente schermati. I cavi utilizzati per il prototipo allestito in laboratorio sono di due differenti lunghezze: ~20 cm e ~200 cm. Protocollo a livello di bit. Il controllo di flusso a livello di bit prevede che il segnale contenente l'informazione (Data) viaggi, su linee separate, con un segnale di Strobe, il quale ha la caratteristica di variare il suo stato ogniqualvolta il Data non varia (figura 2.1). Figura 2.1: Segnali data e strobe. Questi due segnali nel complesso trasportano un clock che può essere propagato tra i dispositivi DSLink connessi, rendendo la comunicazione asincrona. La sua ricostruzione viene fatta applicando ai segnali D e S l’operazione logica XOR (OR-Esclusivo). Protocollo a livello di token. A livello superiore il protocollo è organizzato in "token", delle stringhe di bit costituite da segnali di dato o di controllo. Questi vengono gestiti, in modo invisibile ai livelli superiori, dai singoli link, i quali sono provvisti di una apposita elettronica. I token possono essere di due tipi: data token e control token. I primi sono costituiti da 10 bit di cui 8 di dato, uno di parità dispari (P) ed uno di controllo del token stesso (C). I control token hanno invece 4 bit: i primi due indicano la codifica dell’informazione trasportata (secondo la legenda indicata nella tabella 2.1), mentre gli altri due sono gli stessi del caso precedente (C e P). In entrambi i token la funzione del bit C è quella di indicarne il tipo: se C=0 allora il token in esame è del tipo data, altrimenti (C=1) è un control token. I data token hanno quindi il bit C perennemente impostato al livello logico “0”, mentre i control token al livello “1”. Si noti che questa è l’unica caratteristica che li contraddistingue, oltre al diverso numero di bit in essi contenuti. Dal momento che la lunghezza dei due tipi di token è differente, il bit di parità viene impostato considerando lo stesso bit P, il bit di controllo C del token in esame e tutti i bit costituenti il “corpo” del token precedente, i quali sono 8 per i data token e 2 per i control token. In questo modo si riescono ad identificare errori singoli su tutti bit della stringa, incluso quello di controllo (figura 2.2). Infatti, se si effettuasse il controllo della parità sui data token ed i control token singolarmente, in presenza di un errore sul bit C verrebbe sfasata l’acquisizione di tutti i bit successivi, con conseguenze catastrofiche per il dato trasportato. La parità P assicura che il numero di “1” presenti nei bit considerati sia sempre dispari. Figura 2.2: Protocollo a livello di Token. Funzione del Token Codice Flow Control Token End Of Packet End Of Message ESCape token NULL token FCT EOP EOM ESC NUL valore dei bit del token di controllo (P + C + xx) P100 P101 P110 P111 ESC + P1001 Tabella 2.1: Codifica dei token di controllo. Il controllo di flusso a livello di token viene implementato dal protocollo DSLink per effettuare un handshake tra la sorgente ed il buffer di destinazione: quando quest'ultimo ha spazio a sufficienza per almeno 8 data token, invia un FCT alla sorgente la quale spedisce i dati, ed attende un altro FCT. In questo modo non avvengono perdite di informazione per "overrunning" ed inoltre, avendo i buffer in esame una capacità maggiore di 8 token, la banda passante dei link non viene limitata. I token di controllo non devono necessariamente essere inviati dopo ogni data token 1 Il NULL token è costituito da due comandi successivi. ma soltanto in caso di necessità. Ad esempio, se un dato è costituito da 32 bit e viene organizzato in un unico pacchetto avente un byte di testa, per trasmetterlo si devono inviare 5 data token successivi (uno per la testa e quattro per il dato), seguiti da un control token del tipo EOP. Protocollo a livello di pacchetto e di messaggio. A livello più elevato il protocollo DSLink prevede la pacchettizzazione dei dati ed il messaging degli stessi. Ciò consiste nel raggruppare le informazioni da spedire in pacchetti di lunghezza variabile (espressa in byte) aggiungendo ad essi una "testa" ed una "coda", con il duplice scopo di rendere possibile l'instradamento attraverso gli switch STC104 e, come vedremo, di consentire delle comunicazioni più complesse. La testa, che è costituita da uno o più data token, può avere una lunghezza variabile e definisce la destinazione del pacchetto. La coda indica invece la sua terminazione. Quest'ultima, costituita da un unico control token, può essere un segnale del tipo EOP (End Of Packet) oppure EOM (End Of Message) ed indica se il pacchetto in esame è l'ultimo di un messaggio oppure no. Inoltre, un pacchetto costituito da una testa ed un "end of packet" (senza byte di dato) costituisce un acknowledge packet. La fig. 2.3 riassume quanto appena espresso: Figura 2.3: Protocollo DSLink a livello di pacchetto. La pacchettizzazione offre innumerevoli vantaggi, soprattutto laddove vi siano diversi dispositivi connessi tra loro attraverso una rete di switch elettronici, come nel caso del trigger di 2° livello di ATLAS. I vari host possono essere dei processori o delle memorie, ognuno con un suo indirizzo (unico) all'interno del sistema, mentre i dati, organizzati in pacchetti, con la loro testa ed il loro terminatore possono viaggiare tra i dispositivi in maniera asincrona, bidirezionale ed indipendente gli uni dagli altri. Vediamo ora come il protocollo DSLink viene ulteriormente arricchito da strumenti per il controllo dei messaggi. Come visto, questi ultimi sono semplicemente dei pacchetti con un terminatore del tipo EOM, ma con essi si indica in genere la totalità dei dati che si devono spedire. In questo modo, aggiungendo un terminatore di uno dei due tipi, è possibile specificare se il token che lo precede è l’ultimo di un pacchetto oppure di un intero messaggio, ovvero se le informazioni riguardanti il dato sono state parzialmente o totalmente inviate al destinatario. Così il dispositivo ricevente è in grado di separare tra loro i vari messaggi (nel caso di ATLAS ciò equivale ad esempio alla separazione di dati relativi ad eventi differenti). Il Virtual Channel Protocol (VCP). Alle volte, anche utilizzando tutti e 5 i livelli del protocollo DSLink, non si ottengono delle comunicazioni ottimizzate. Ciò avviene soprattutto quando non si considerano delle semplici connessioni punto-punto, ma molti dispositivi che si scambiano dei pacchetti di dimensioni elevate. In questo caso, peraltro molto comune, per raggiungere delle prestazioni soddisfacenti si devono utilizzare degli algoritmi più sofisticati per il trattamento delle informazioni. Supponiamo, ad esempio, di voler connettere tra loro 4 processori in modo che essi possano dialogare a coppie. Una tecnica per fare ciò potrebbe essere quella di connetterli fisicamente tra loro attraverso 4 canali DSLink indipendenti, come in figura 2.4. Figura 2.4: Quattro processori connessi mediante quattro canali DSLink. Una tecnica più intelligente è quella che si ottiene implementando il Virtual Channel Protocol (VCP). La caratteristica fondamentale della gestione del canale virtuale è quella di prevedere la condivisione di un unico canale fisico da parte di più link logici, i quali vengono appunto detti canali virtuali. Questo canale fisico connette tra loro due multiplexer ai quali sono collegati i 4 processori, che a loro volta sono identificati da un "indirizzo". I dati provenienti da uno dei due processori P1 e P2 possono essere inviati ad uno qualsiasi degli altri due formando semplicemente uno o più pacchetti aventi come testa l'indirizzo del processore di destinazione. Considerando che non tutti i link saranno occupati contemporaneamente e per tutto il tempo di lavoro del sistema, così facendo si ha un notevole risparmio di componenti hardware, ed una migliore gestione delle risorse. In ATLAS, se volessimo connettere le tre farm di processori locali con i processori globali utilizzando la tecnica della figura 2.4, avremmo bisogno di decine di migliaia di canali, uno per ogni coppia di host! Figura 2.5: Quattro processori connessi mediante un canale DSLink. Come vedremo nei capitoli successivi, oltre all’implementazione dei canali virtuali, la sostituzione dei multiplexer con uno switch STC104 permette l’interconnessione globale tra tutti i dispositivi, ovvero una situazione nella quale ogni host può dialogare indifferentemente con tutti gli altri. Un’altra peculiare caratteristica del VCP è la suddivisione dei messaggi in pacchetti di lunghezza massima pari a 32 byte. Messaggi di lunghezza inferiore vengono spediti immediatamente mentre quelli con lunghezze maggiori vengono spezzati in più pacchetti (figura 2.6). Figura 2.6: Suddivisione dei messaggi in pacchetti aventi lunghezza massima pari a 32 byte. Ciò al fine di evitare che i messaggi più lunghi monopolizzino il link fisico costringendo gli altri ad attese indeterminate. La latenza della rete è così indipendente dalla lunghezza dei pacchetti che viaggiano sugli altri canali virtuali, e dipende soltanto dal traffico globale della rete e dai ritardi dei dispositivi hardware. In questo modo inoltre i messaggi spediti dai vari host sono realmente concorrenti2. Un segnale di acknowledge deve essere inviato al mittente prima della trasmissione del pacchetto successivo; ciò non richiede comunque l'invio di un indirizzo di ritorno in quanto un link virtuale è bidirezionale e quindi costituito da una coppia di canali virtuali: il segnale di acknowledge viene spedito sul canale di ritorno dello stesso virtual link. Inoltre, per riconoscere errori di disconnessione e di parità (capitolo 4), il protocollo DSLink prevede una trasmissione continua di segnali: quando non vi è nessuna informazione da trasferire, vengono spediti sul link dei NUL token. 2 Senza la suddivisione in pacchetti, può avvenire ad esempio che un messaggio di pochi byte di lunghezza, prima di poter occupare il canale, debba attendere che un messaggio di lunghezza molto superiore sia stato completamente trasferito. In questo modo il tempo di instradamento del pacchetto corto viene a dipendere dalle dimensioni del pacchetto lungo che lo precede. I chip SGS Thomson STC101 ed STC104, utilizzati nello sviluppo di questo lavoro e descritti nel seguito, implementano in modo automatico il protocollo DSLink fino al 3° livello incluso. Per quanto riguarda i controlli di flusso a livello di pacchetto e di messaggio, questi dispositivi forniscono ottimi strumenti per la loro utilizzazione, mentre contemplano solo in parte la gestione del canale virtuale. Nel caso in cui si voglia implementare il VCP, si devono effettuare delle aggiunte software oppure hardware, in particolare sulle schede che includono lo STC101 (interfaccia parallelo - DSLink). Nel caso di una gestione software, si deve tener conto di uno overhead che potrebbe non essere tollerabile in un sistema di connessione complesso quale quello presente in ATLAS. Riservare ad un processore ulteriore, oppure a delle logiche programmabili, il compito di gestire il canale virtuale è, nella maggior parte dei casi, l’unico modo per non influire negativamente sulle velocità di comunicazione. Anche se nel corso di questo lavoro non si sfrutteranno tutte le possibilità offerte dal VCP, nel capitolo 5 verranno analizzate in modo più approfondito queste problematiche discutendo alcuni risultati sperimentali. 2.1.2 Performance del protocollo IEEE 1355 DS-DE. Il DSLink ha una velocità massima 100 Mbit/s ma, come descritto nei paragrafi precedenti, per ogni pacchetto il protocollo richiede l'invio di una testa, di una coda e di bit aggiuntivi per il controllo di flusso. I dati veri e propri vengono quindi integrati da ulteriori bit che non trasportano informazione, anche se sono fondamentali ai fini delle comunicazioni. Si vuole ora calcolare lo overhead del protocollo, ovvero in quale misura questi dati aggiuntivi limitano la banda passante, nel caso di trasmissioni unidirezionali e bidirezionali con il VCP. La figura 2.7 mostra come avviene il flusso dei pacchetti tra un sender ed un receiver. Figura 2.7: Flusso unidirezionale dei pacchetti tra due host. Per comprendere i paragrafi che seguono dobbiamo ricordare che il canale DSLink è costituito da 4 linee separate, due di input e due di output. Quando un pacchetto viene spedito lungo le linee di output, su quelle di input si riceve un segnale di acknowledge, mentre ogni 8 token ricevuti in ingresso, vi è in uscita un control token (FCT) per il controllo del flusso di dati. Quindi, nel computo totale di tutti i bit trasmessi, si devono distinguere le linee di ingresso e quelle di uscita, tenendo in considerazione, oltre al protocollo, la sequenza di handshake nei casi unidirezionale e bidirezionale. Nelle comunicazioni unidirezionali si sfruttano le linee nei due versi di percorrenza ma non contemporaneamente (connessione half duplex). In quelle bidirezionali i link trasportano i dati in entrambe le direzioni (connessione full duplex). In quest’ultimo caso lungo ogni direzione del singolo link viaggiano i dati relativi alle comunicazioni in un verso, ed i segnali di controllo relativi alle trasmissioni nella direzione opposta. La trattazione che segue è stata sviluppata per i canali di output ma la stessa cosa avviene per quelli di input. 2.1.2.1 Comunicazioni unidirezionali. Se vogliamo inviare un messaggio di m byte suddiviso in pacchetti lunghi 32 byte (VCP) abbiamo bisogno di un numero di pacchetti pari a: np = min . int m √ 32 ↵ in cui la funzione min.int dà il più piccolo intero maggiore o uguale alla frazione espressa in parentesi. Ricordo che i data token sono formati da 10 bit (8 data bit + 1 bit di parità + 1 bit di controllo) mentre il terminatore ha 4 bit (1 bit di parità + 1 bit di controllo + 2 bit di codice). Considerando che per ogni pacchetto deve essere inviata una testa ed una coda si ha che il numero di bit che costituiscono il messaggio di output è: bn = 10 ?m + (10 ?s + 4) ?np dove s è pari al numero di byte costituenti la testa dei pacchetti. Il protocollo DSLink prevede che per ogni pacchetto spedito debba essere restituito al mittente un segnale di acknowledge costituito da una testa di s byte più un byte di coda. Il numero di data token in ingresso per il segnale di acknowledge è quindi pari a: ndt = ( s + 1) ?np Nel VCP, per ogni 8 token sul link di ingresso vi è un token di controllo di flusso sul link di uscita; questi ultimi sono così in totale: nft = min . int ndt √ 8 ↵ Ricordando che ogni token di controllo è costituito da 4 bit, il numero totale di bit trasmessi sul canale di output è pari a: B = bn + 4 ?nft Considerando infine che il numero di bit che costituiscono il messaggio è pari a 8⋅m, la velocità di trasmissione dei dati è pari a: Vd = Vd = 8 ?m ?100 Mbit / s B 8 ?m ?100 Mbit / s 10 ?m + (10 ?s + 4) ?n p + 4n ft Se ad esempio consideriamo due messaggi, il primo di lunghezza pari a 32 byte (m = 32), il secondo di 1 Kbyte (m = 1024), inviati entrambi mediante pacchetti da 32 byte ciascuno e con 2 byte di testa (s = 2), le velocità di comunicazione teoriche sono: 32 byte: Vd ≅ 9.20 Mbyte/s. 1024 byte: Vd ≅ 9.29 Mbyte/s. 2.1.2.2 Comunicazioni bidirezionali. Nel caso di comunicazioni bidirezionali, le velocità di comunicazione dei dati sul singolo canale diminuiscono in quanto ora sui link di uscita viaggiano, oltre ai byte considerati precedentemente, dei token di controllo per i pacchetti in ingresso. Ancora una volta sia m la lunghezza del messaggio in byte (in questo caso si debbono considerare due messaggi, lunghi ognuno m byte, che viaggiano nelle due direzioni), s la lunghezza della testa dei pacchetti in byte, ed n p il numero di pacchetti da 32 byte (per np vale la stessa formula del caso precedente). Il numero di bit trasmessi in uscita per il messaggio è: bn = [10 ?m + (10 ?s + 4 )?np ]+ (10 ?s + 4 )np dove il termine tra parentesi quadrata ha lo stesso significato del caso precedente, mentre il secondo termine rappresenta il numero di bit del segnale di acknowledge relativo al messaggio in ingresso (bit trasportati sempre dalle linee di uscita). Per quanto riguarda il controllo di flusso, il numero di data token che viaggiano sul link di ingresso è dato dai data token costituenti il messaggio in ingresso, e dai control token relativi al messaggio in uscita: ndt = [m + (s + 1) ?np]+ (s + 1) ?np Come nel caso precedente per ogni 8 token in ingresso viene trasmesso un control token sul link di uscita: nft = min.int ndt √ 8↵ Il numero totale dei bit costituenti il messaggio sul link di uscita è pari a: B = bn + 4 ?nft e la velocità di comunicazione vale: Vd = Vd = 8 ?m ?100 Mbit / s B 8 ?m ?100 Mbit / s 10 ?m + ( 20 ?s + 8) ?n p + 4 ?n ft Se anche questa volta calcoliamo le velocità di comunicazione teoriche nei due casi particolari (m = 32, m = 1024 byte) otteniamo: 32 byte: Vd ≅ 8.25 Mbyte/s. 1024 byte: Vd ≅ 8.27 Mbyte/s. Come previsto questi valori sono inferiori rispetto a quelli ricavati nel caso precedente. Per quanto riguarda il link di ingresso i calcoli sono analoghi. Se suddividiamo il messaggio in pacchetti di dimensioni maggiori di 32 byte, la banda passante aumenta in quanto diminuiscono i token di controllo che vengono spediti. Viceversa se diminuiamo la lunghezza dei pacchetti, le velocità di trasmissione diminuiscono. Inoltre se inviamo un singolo pacchetto otteniamo la massima velocità raggiungibile con il protocollo DSLink, in quanto sono minime le informazioni addizionali da aggiungere ai dati. Al proposito, vediamo quanto valgono le due bande passanti (unidirezionale e bidirezionale) nel caso in cui il messaggio da inviare non venga suddiviso, ma venga spedito con un singolo pacchetto di lunghezza qualsiasi (senza VCP). In entrambi i casi si ha np = 1 ed effettuando questa sostituzione nelle formule precedenti si ottiene: unidirezionale Vd = 8 ?m ?100 Mbit / s ; 10 ?m + 10 ?s + 8 bidirezionale Vd = 8 ?m ?100 Mbit / s ; 10 ?m + 20 ?s + 8 + 4 ?n ft La massima velocità raggiungibile con il DSLink a 100 Mbit/s si ricava facendo il limite di Vd per m → ∞. In questa situazione si ottiene che: n ft ♦ m + 2 ?( s + 1) 8 ovvero diviene trascurabile l’eventuale token aggiuntivo da inviare nel caso in cui quest’ultima frazione fornisca un valore non intero. Sostituendo si ottiene: unidirezionale Vd(m→∞ ) = 10 Mbyte/s; bidirezionale Vd(m→∞ ) = 9.52 Mbyte/s. Queste rappresentano le velocità di comunicazione limite, nei casi monodirezionale e bidirezionale, del protocollo IEEE 1355. Riassumendo i valori limite ottenuti nella tabella 2.2, si può notare come lo overhead introdotto dal protocollo DSLink sia sufficientemente limitato: Velocità dei link Velocità assoluta Caso unidirezionale Caso bidirezionale 12.5 10 9.52 100 80 ~ 76 (Mbyte/s) Efficienza (%) Tabella 2.2: Overhead introdotto dal protocollo DSLink. L’efficienza è definita come il rapporto tra il valore in esame ed il valore massimo (12.5) moltiplicato per 100. Nel caso peggiore si perde poco più del 20% della banda passante originale. 2.2 Lo switch STC104. Lo STC104 è uno switch elettronico asincrono in tecnologia VLSI (Very Large Scale Integration) costituito da 32 DSLink (Data Link 0-31) in grado di interconnettere tra loro 32 dispositivi in modo indipendente. Il notevole numero di porte (rispetto a componenti analoghi) di cui è provvisto è dovuto fondamentalmente al fatto che la macrocella SGS Thomson per il protocollo IEEE 1355 DS-DE occupa un’area di silicio di soli 0.2 mm 2 . Nelle figura 2.8 viene riportato il suo diagramma a blocchi: Figura 2.8: Schema a blocchi del C104. Il C104 è l’elemento base delle switching network locali e globali che si vogliono realizzare per i prototipi di trigger di 2° livello di ATLAS. Come si può notare ogni link ha la sua elettronica di processamento dei pacchetti ed i collegamenti interni sono assicurati da un crossbar switch 32x32. Ciò rende i link indipendenti tra loro e 32 dispositivi (host) possono essere connessi tramite un unico STC104, raggiungendo una larghezza di banda totale di 300 Mbyte/s [29]. La programmazione di questo dispositivo avviene a livello firmware tramite due link separati denominati Clink0 (ingresso) e Clink1 (uscita) i quali utilizzano lo stesso protocollo dei link di dato. Il Clink0 permette l'accesso ad una serie di registri interni mediante i quali è possibile configurare delle reti di C104 in termini di parametri di comunicazione quali velocità di trasmissione e lunghezza della testa dei pacchetti: tramite questi parametri si implementa il protocollo DSLink a livello di pacchetto. Il Clink1 propaga il segnale precedente al dispositivo successivo. Avendo i link lo stesso protocollo, si possono realizzare delle connessioni tra data link e control link; in genere però è consigliabile separare fisicamente le reti di dato e di controllo, per evitare che problemi nella prima si ripercuotano negativamente sul controllo dei dispositivi, rendendo impossibile qualsiasi operazione di diagnosi. L’accesso ai registri del C104 avviene mediante l’invio di token, secondo un protocollo di handshake; i vari comandi sono codificati in questi pacchetti i quali, in generale, contengono il codice del comando, l’indirizzo del link di destinazione, il dato (nel caso di operazioni di scrittura) ed un terminatore (figura 2.9). Figura 2.9: Pacchetti di comando inviabili al C104. La presenza dell’indirizzo di destinazione rende possibile il raggiungimento, da parte dei comandi, di uno qualsiasi dei link della rete. Il primo comando che il controller invia ad uno dei link (o anche a tutti insieme) è uno start token, contenente tra le altre cose il suo indirizzo di ritorno (figura 2.9). Il C104 esegue il comando e risponde al sender con un pacchetto che dipende sia dal comando che ha ricevuto, sia dal suo stato attuale. Dal momento che queste operazioni vengono svolte dai programmi sviluppati nel corso del lavoro di tesi, la loro descrizione viene fatta nel capitolo 4, quello dedicato al software. Inoltre, essendo i pacchetti di risposta del C104 codificati in modo analogo, non vengono riportati in questa sede, ma sono comunque disponibili sullo Engineering Data del C104 [29]. Si vuole ora entrare nel merito della programmazione a basso livello del dispositivo, descrivendo alcune delle funzioni svolte dai suoi registri più significativi. I Link0-31Command sono 32 registri di sola scrittura, aventi ciascuno 4 bit programmabili singolarmente. I primi due bit di ognuno di essi permettono di effettuare il reset (ResetLink) e lo start (StartLink) del link corrispondente, due operazioni che, come vedremo nel capitolo 4, sono indispensabili per la trasmissione dati. Il terzo (ResetOutput), se posto ad “1”, effettua il reset dei due segnali Data e Strobe, mentre il quarto (WrongParity) permette di forzare una parità scorretta. Altri registri di lettura e scrittura molto importanti sono i Link0-31Mode. I primi 3 bit di questi ultimi permettono di impostare la velocità di trasmissione, mentre il quarto, se posto ad “1”, in caso di errore scarica il pacchetto in transito sul link corrispondente (ciò fa sì che il link non rimanga bloccato). I 32 registri di lettura e scrittura PacketMode0-31 hanno 5 bit accessibili. Tra le impostazioni che questi permettono di effettuare si ricorda la possibilità di variare la lunghezza della testa dei pacchetti attesi in ingresso (da 1 a 2 byte) e la capacità di cancellare il primo byte del pacchetto in uscita (Header Deletion). La cancellazione della testa è molto importante quando, all’interno delle reti, si vogliono raggiungere delle destinazioni intermedie (come nel caso dell’algoritmo universal routing, descritto nel paragrafo 2.2.3) oppure quando si debbono suddividere reti molto complesse in più stadi (multistage network – capitolo 3). Inoltre, se un modo di arrivo ha più destinazioni (ad esempio diversi processi in esecuzione su un singolo processore) la prima testa del pacchetto viene utilizzata per raggiungere il nodo, la seconda per far giungere i dati alla destinazione all’interno del nodo. Infine, nel caso della gestione del canale virtuale, la seconda testa viene utilizzata per selezionare il link virtuale nel dispositivo di destinazione (figura 2.10). Figura 2.10: Esempio del funzionamento dello header deletion. Per ottenere delle informazioni sullo stato dei 32 link si possono interrogare i registri Link0-31Status (di sola lettura). Per ogni link, i 6 bit accessibili indicano rispettivamente se: • è avvenuto un errore; • il link è partito correttamente; • il reset output è stato completato; • è avvenuto un errore di parità; • è avvenuto un errore di disconnessione; • è stato ricevuto un token (dopo l’ultimo reset link). In caso di errore, il registro ErrorCode contiene il numero del link sul quale esso è avvenuto ed un codice di identificazione dello stesso, con il significato riportato nella tabella 2.3: Codice di errore Tipo di errore #C0 #C1 #C2 #80 #04 #05 #06 Errore nel comando di controllo (comando sconosciuto). Errore nel protocollo di controllo (acknowledge non richiesto). Errore di parità o disconnessione sul control link 1. Errore di parità o disconnessione. Testa ricevuta non valida (non è all’interno dell’intervallo impostato). Pacchetto troppo corto (è arrivato il terminatore prima della testa). Pacchetto nullo (nessun pacchetto presente dopo la header deletion). Tabella 2.3: Codici di errore. Mediante il bit LocalizeError del registro LinkMode0-31 si può fare in modo che se avviene un errore su un pacchetto in transito, questo venga scaricato o troncato. Ciò risulta essere molto utile in fase di comunicazione in quanto, invece di interrompere la stessa, si può scaricare il pacchetto e chiedere alla sorgente la sua ritrasmissione. Gli ultimi tre gruppi di registri descritti sono indispensabili quando si vogliono effettuare delle ispezioni di reti di C104, non solo per le operazioni di debugging ma anche per capire se un link è connesso fisicamente tramite un canale DSLink. Per la descrizione completa di tutti i registri degli STC104 si rimanda il lettore alla bibliografia [29]. Gli STC104 possono essere collegati tra loro per formare delle reti più complesse secondo varie topologie interconnettive. Essendo asincroni, e grazie alle tecniche che nel corso del capitolo verranno descritte, non vi sono limiti alla interconnettibilità di questi dispositivi, anche se è necessario rispettare alcune regole per evitare malfunzionamenti in fase di comunicazione. Oltre alle problematiche dovute ad errori di “setting”, si possono avere dei blocchi per errori di tipo logico. Uno di questi è il deadlock (stallo) uno stato nel quale non si hanno progressi in quanto due nodi si scambiano perennemente lo stesso pacchetto. Il deadlock è una proprietà (negativa) che discende dalla topologia delle reti e dall’algoritmo di routing utilizzato. Nello sviluppo della tesi sono stati connessi tra loro fino a tre STC104 (tutti quelli a disposizione) secondo la topologia indirect multistage network (capitolo 3). Come vedremo nel capitolo 5, per effettuare alcune misure è stato variato il numero di link di interconnessione tra gli switch, la lunghezza dei pacchetti che li attraversano, nonchè il numero di dispositivi attraversati. 2.2.1 Il wormhole routing. Nel paragrafo seguente ed in quello successivo vengono descritti l’importante algoritmo di routing dei pacchetti del protocollo IEEE 1355 e la sua realizzazione a livello hardware. Come già detto, la testa dei pacchetti viene utilizzata per instradarli all'interno dello switch, mentre la coda permette loro di avere una lunghezza qualsiasi, in quanto è proprio essa che indica che il pacchetto è terminato. La coda ha comunque un'altra funzione molto importante: essa consente infatti di realizzare il wormhole routing. Quando un pacchetto viene inviato nello switch, al suo interno si crea un percorso fisico che scompare quando è transitata la sua coda. La fig. 2.11 esemplifica questo comportamento: Figura 2.11: Wormhole routing all’interno di un STC104. In questo modo i link dello switch non vengono impegnati per tutto il tempo di transito dei pacchetti, e dati successivi possono essere inviati attraverso lo stesso percorso prima ancora che il dato precedente sia giunto a destinazione. Così vengono ridotti i tempi di latenza della rete, soprattutto nel caso in cui quest'ultima sia formata da diversi STC104 connessi in serie. Ogni link dello STC104 ha dei buffer in grado di memorizzare un certo numero di token in ingresso (> 20); ciò, integrato dal wormhole routing, rende disponibili i link per ulteriori comunicazioni prima ancora che il pacchetto sia transitato completamente. Con questa premessa può avvenire che un messaggio molto lungo arrivi dopo un messaggio più corto, anche se quest’ultimo è stato spedito successivamente; così l’attesa che i messaggi subiscono prima di essere instradati non dipende dalla lunghezza degli altri dati presenti. La caratteristica fondamentale del wormhole routing è quella di limitare la latenza dei pacchetti. 2.2.2 Interval labelling. Vedremo ora nel dettaglio come il routing dei pacchetti viene realizzato a livello hardware, ovvero come le loro teste vengono interpretate ed instradate all’interno del C104. Ogni link dello switch possiede 36 registri a 32 bit denominati Interval1-36, programmabili indipendentemente gli uni dagli altri. I primi 16 bit di questi registri sono detti Separator mentre i 5 bit dal 18° al 22° vengono denominati SelectLink. Nei campi Separator vengono memorizzati dei valori contigui crescenti (con intersezione nulla), mentre i SelectLink contengono i numeri dei link associati ai corrispondenti intervalli; lo Interval0 non è programmabile e contiene il valore 0. Quando un pacchetto arriva su un link, viene effettuato un confronto tra la sua testa ed i valori memorizzati nei Separator; a partire dal Separator1, il primo di questi registri che contiene un valore maggiore della testa in esame indica, tramite il registro SelectLink ad esso associato, la strada che il pacchetto deve seguire, ovvero il link di destinazione. La fig. 2.12 mostra la tecnica utilizzata per l’instradamento all’interno degli STC104. Figura 2.12: Registri mediante i quali viene effettuato il routing dei pacchetti. E' evidente la necessità di avere degli intervalli crescenti e senza intersezioni per evitare che vi siano dei pacchetti con delle destinazioni multiple o ambigue. Si noti inoltre che il pacchetto può essere inviato sullo stesso link di ingresso formando così un collegamento con se stesso (i link sono bidirezionali). Questa tecnica, nella quale ad ogni link di uscita è assegnato un intervallo mediante delle etichette, è denominata interval labelling. La programmazione indipendente dei singoli link permette, tra le altre cose, di creare delle reti asimmetriche nelle quali ad alcune destinazioni sono associati molti ingressi, mentre ad altre uno o nessuno3. La presenza di 36 registri per ogni link fa in modo che gli instradamenti su un nodo non dipendano dalla presenza o meno di pacchetti sugli altri link. Nei registri Interval1-36 sono inoltre presenti 2 bit denominati Discard ed Invalid mediante i quali si può riconoscere se la testa di un pacchetto non è nell’intervallo, ed eventualmente scaricarla insieme al pacchetto stesso. 2.2.3 Universal routing. Nella interconnessione di reti con carico pesante (heavy load) nelle quali molti host “attivi” sono collegati tramite più STC104, vi possono essere dei link troppo trafficati che costringono i pacchetti a delle attese elevate. Per switching network affette dalla presenza di tali punti, detti hot spot, la maggior parte delle volte non è possibile effettuare una stima della latenza, in quanto questa non dipende soltanto dal traffico globale della rete, bensì dal traffico sul punto caldo. Sotto queste condizioni le prestazioni delle reti possono diminuire drasticamente. Lo universal routing è un algoritmo che può essere utilizzato al fine di eliminare il problema degli hot spot; è anche detto routing a due fasi in quanto consiste nello spedire il pacchetto ad una destinazione intermedia (scelta in maniera pseudo-casuale tra gruppi di link predefiniti) dalla quale poi i dati vengono instradati verso il link finale. Con questo routing statistico, le percentuali di occupazione dei diversi percorsi tendono ad equivalersi. Inoltre, la probabilità che il tempo di attraversamento della rete superi una soglia stabilita, può essere minimizzata a piacere, aumentando ad esempio il numero di destinazioni intermedie. Al notevole incremento della banda passante totale, fortunatamente non corrisponde un aumento drastico della latenza attraverso la rete: nel caso peggiore (topologia binary n-cube) se n è il numero di nodi, la latenza cresce, con buona probabilità, come log(n) [15]. Per contro, a parità di nodi, aumenta 3 Non è comunque questo il caso delle reti di ATLAS. notevolmente il numero di switch necessari per realizzare la rete; per la binary n-cube si arriva addirittura al doppio. Scegliere delle destinazioni in modo pseudo-casuale con la tecnologia descritta è possibile grazie ai registri PacketMode0-31, RandomBase0-31 e RandomRange0-31 dello STC104. Nel primo è presente un bit, denominato “Randomize” che, se posto ad “1”, aggiunge una testa al pacchetto che lo attraversa, in base alle modalità impostate negli altri 2 registri. In particolare la generazione pseudo-casuale delle teste avviene nel range RandomBase ÷ (RandomBase + RandomRange –1). Infine, se nella implementazione dell’algoritmo universal routing si realizzano due reti distinte, una per le destinazioni pseudo-random, l’altra per quelle finali, si ottengono switching network esenti da deadlock. 2.2.4 Grouped adaptive routing. Il grouped adaptive routing è una ulteriore implementazione del protocollo IEEE 1355 realizzabile tramite lo STC104. Consiste nel formare dei gruppi di link di uscita consecutivi tali che, fornendo alla testa di un pacchetto l'indirizzo del primo link del gruppo, si ottiene il suo instradamento sul primo canale libero del gruppo stesso. Supponiamo di voler connettere tra loro due STC104 come in fig. 2.13: Figura 2.13: Esempio di 4 link appartenenti ad un gruppo. Per accedere al gruppo si deve fornire ai pacchetti la testa 10. Invece di specificare i singoli percorsi tra i due dispositivi, si configura un gruppo formato dai link 10, 11, 12 e 13 (figura 2.13) e, ai vari pacchetti che debbono passare da uno switch all'altro, si fornisce l'indirizzo del link 10. Considerando che non tutti i canali DSLink saranno sempre occupati contemporaneamente, con questa implementazione si possono ridurre i collegamenti tra i due STC104 (in funzione del traffico) con un maggior sfruttamento dei link fisici stessi, conseguente diminuzione della latenza ed aumento della banda passante. Dal momento che i pacchetti non sono costretti a passare su link prestabiliti, se opportunamente programmato e sotto alcune condizioni, il raggruppamento dei link è un efficace rimedio agli hot spot. L’impostazione di tale funzione avviene tramite il bit ContinueGroup del registro PacketMode che ogni link possiede. Se questo bit viene posto a “0”, il link corrispondente è il primo di un gruppo, altrimenti è uno qualsiasi del gruppo. Se sono posti tutti a “0” il grouping è disabilitato. Una volta effettuate tutte le impostazioni, per utilizzare questo algoritmo di instradamento si deve agire sull’unico bit del registro ConfigComplete. Uno dei difetti del grouped adaptive routing è che esso non è fault tolerant al 100%: se c’è un errore su uno dei link compresi nel gruppo, tutto il gruppo diviene inutilizzabile. Quanto detto verrà ripreso ed approfondito nella parte del lavoro dedicata alle misure (capitolo 5). 2.2.5 Il “Contention model”. Dopo aver descritto le principali funzionalità dello switch elettronico, si vuole affrontare un aspetto ricorrente nella trasmissione dei dati attraverso gli STC104: il contest switch. Quando due o più pacchetti seguono una strada che li costringe a passare sullo stesso link fisico, c’è una “contesa” del link in quanto soltanto uno alla volta lo può attraversare. Ciò avviene sia nel caso in cui questi pacchetti abbiano la stessa destinazione all’interno di un singolo switch, sia nella analoga situazione nella quale debbano usufruire dello stesso collegamento tra due diversi STC104 (figura 2.14): Figura 2.14: Esempio di contesa di un link tra 2 pacchetti. In questo caso la latenza non è più data soltanto dal tempo di routing dei dati nello switch, ma dipende anche dal numero di pacchetti che si contendono il link. Inoltre, se i messaggi da instradare non vengono suddivisi in pacchetti da 32 byte massimo (ovvero se non si implementa il VCP) la latenza dipenderà sensibilmente anche dalla lunghezza degli altri messaggi in trasmissione. Non è quindi più possibile predire quanto i pacchetti debbano attendere prima di poter transitare su un link, anche se il dispositivo assicura che verranno tutti instradati verso la propria destinazione. Nel capitolo 5 verranno effettuate alcune misure al proposito, e si dimostrerà inoltre come il VCP sia un deterrente ai problemi causati dal contest switch. 2.2.6 Latenza teorica dello switch STC104. Ricordando i risultati ottenuti nel paragrafo 2.1.2, riguardanti le prestazioni del protocollo DSLink, calcoliamo ora il time slot (S), definito come il tempo necessario per instradare un pacchetto attraverso lo STC104, in assenza di contesa. Come vedremo S dipende dai parametri dello switch, dalla lunghezza del pacchetto in esame e dal numero di byte che costituiscono la testa del pacchetto. Il routing del primo byte della testa richiede un tempo maggiore rispetto ai bit che seguono in quanto deve essere interpretato dai registri Interval e Select. Se chiamiamo h questo tempo e bn la latenza dei singoli bit successivi, si ha che il time slot S per un pacchetto costituito da k byte di dato ed s byte di testa vale: S = h + [10 ?k + 10 ?(s − 1)+ 4]?bn Se impostiamo le velocità dei link al loro valore massimo (100 Mbit/s): i valori teorici dei parametri h e bn valgono [15]: per s = 1: h ≅ 500 ns; bn ≅ 10 ns per s = 2: h ≅ 670 ns; bn ≅ 10 ns così il valore del time slot è dato da: per s = 1: S ≅ 500ns + [10⋅k + 4] ⋅10ns per s = 2: S ≅ 670ns + [10⋅k + 14] ⋅10ns Come si evince dalle espressioni precedenti, il peso che il tempo di instradamento della testa ha rispetto all’intero pacchetto, decresce all’aumentare del numero di byte da spedire. Ad esempio se consideriamo dei pacchetti lunghi 4096 byte con 2 byte di testa, h vale sempre ~670 ns mentre S ≅ 410 µs: in questo caso la testa, per essere instradata, impiega un tempo notevolmente minore rispetto a quanto non faccia il pacchetto. Ma se consideriamo pacchetti da 32 byte si ottiene che S ≅ 4 µs: in presenza del VCP il routing della testa introduce una latenza non trascurabile rispetto a quella introdotta dai dati (~17 %), e le comunicazioni perdono parte della loro efficienza. L’andamento del routing delay in funzione della lunghezza dei pacchetti, riportato nel grafico della figura 2.15, è stato calcolato considerando teste di 2 byte. Time slot (ns) 4.5E+05 4.0E+05 3.5E+05 3.0E+05 2.5E+05 2.0E+05 1.5E+05 1.0E+05 5.0E+04 0.0E+00 Andamento del tempo di routing attraverso lo STC104 0 500 1000 1500 2000 2500 3000 3500 4000 Dimensioni pacchetto (byte) Figura 2.15: Andamento del time slot per uno switch STC104 in funzione della lunghezza dei pacchetti. In assenza di contest switch , il tempo di routing di un pacchetto all’interno del C104 è pari al time slot, e nel caso in cui esso attraversi un numero maggiore di dispositivi, per ricavare la latenza è sufficiente moltiplicare questo numero per S. Se invece consideriamo un link conteso, l’instradamento dei pacchetti richiederà, in media, un tempo maggiore. Supponiamo ad esempio che due pacchetti della stessa lunghezza si presentino contemporaneamente su un singolo link. In questa situazione il primo dei due che vince la contesa riesce ad attraversare il C104 entro un singolo time slot S, mentre il secondo sarà instradato in un tempo pari a 2⋅S. Chiaramente all’aumentare dei pacchetti che sono in competizione tra loro si allungano i tempi medi di routing attraverso lo switch. Ciò causa quindi una diminuzione della banda passante totale di una rete e, come vedremo nel capitolo successivo, la contesa non deve essere trascurata soprattutto quando si progettano delle switching network a più stadi. Nel 5° capitolo verrà effettuato un confronto tra i valori teorici della figura 2.15 ed alcuni risultati sperimentali. 2.3 L’interfaccia STC101. Per inviare e ricevere pacchetti nella rete di STC104, vengono utilizzati dei personal computer (paragrafo 4.1.5) provvisti di un bus di I/O parallelo sincrono denominato PCI (appendice B). Come visto lo IEEE 1355 è invece un protocollo seriale asincrono: l’interfaccia tra il formato parallelo dei dati ed il protocollo DSLink è costituita dallo STC101. Il suo diagramma a blocchi è mostrato nella figura 2.16: Figura 2.16: Diagramma a blocchi del C101. Questo dispositivo VLSI, che gestisce in modo hardware il controllo di flusso fino al 3° livello (token) e converte i dati dal formato parallelo a seriale DSLink e viceversa, ha le seguenti caratteristiche fondamentali: • può operare in modo seriale bidirezionale con una banda passante totale di 19 Mbyte/s; • il bus parallelo è accessibile sia a 16 che a 32 bit; • è in grado di raggruppare i dati in pacchetti di diverse lunghezze e di aggiungere e rimuovere la testa agli stessi: fornisce cioè gli strumenti per la gestione dei pacchetti e dei messaggi (4° e 5° livello del protocollo DSLink); • in accordo con il protocollo IEEE 1355 contiene delle memorie FIFO (First In First Out) al suo interno (64 byte in ingresso e 64 byte in uscita); • ha una interfaccia parallela opzionale denominata Token Interface con la quale si possono gestire in multiplexing le porte di ingresso e di uscita, con conseguente aumento delle prestazioni. La porta denominata Tx data fornisce i dati da spedire alla FIFO di trasmissione, mentre la porta Tx framing invia le informazioni di contorno (header e terminator). Operazioni analoghe svolgono le porte Rx data ed Rx framing. Le informazioni per il routing ed i dati vengono combinate e separate dai blocchi trapezoidali della figura 2.16. La porta configuration/status permette di leggere e scrivere i registri di configurazione. Il parallel interface adaptor effettua invece il multiplexing delle porte logiche (quelle interne al dispositivo) nelle porte fisiche. Come per lo STC104, la programmazione dello STC101 avviene tramite dei registri interni i quali possono essere di sola lettura, sola scrittura o di lettura/scrittura. Molti dei registri sono simili a quelli presenti nel C104, pertanto non vengono descritti in questo paragrafo, rimandando il lettore alla bibliografia per ulteriori specifiche [28]. Come detto, questo dispositivo è in grado di lavorare in trasparent mode (con la pacchettizzazione disabilitata) ed in packetized mode (con la pacchettizzazione attiva). Queste differenti modalità vengono selezionate mediante il 5º bit del registro DeviceConfig (lettura/scrittura): quando questo viene posto ad “1” la pacchettizzazione è abilitata, e nei primi 3 bit dello stesso registro si deve impostare la lunghezza della testa dei pacchetti in ricezione, da 1 a 4 byte. Tramite il registro TxSendPacket (lettura/scrittura) vengono poi impostate le lunghezze dei pacchetti, l’eventuale aggiunta di una testa ed una coda agli stessi, ed il tipo di terminatore. Nel registro TxPacketHeader (lettura/scrittura) viene scritto il valore della testa dei pacchetti in trasmissione, e nel registro TxHeaderLength (lettura/scrittura) la lunghezza della stessa. Un ruolo molto importante lo hanno i registri di gestione delle interruzioni. Queste ultime, se opportunamente abilitate, possono fornire delle indicazioni sui pacchetti che si stanno ricevendo o trasmettendo. Il registro RxInterruptStatus (sola lettura) ha i primi 8 bit riservati ai seguenti controlli sui pacchetti in ricezione: esatta lunghezza della testa, validità della testa, tipo di terminatore ricevuto, riconoscimento di pacchetti vuoti, contatore della lunghezza del pacchetto in overflow, stato della FIFO di ricezione ed errore sul link. Il registro TxInterruptStatus (sola lettura) contiene invece soltanto informazioni sulla coda di trasmissione (1º bit). Mediante questo bit si possono effettuare dei controlli molto utili: se ad esempio la quantità di dati da spedire presenti nella coda di trasmissione supera la soglia programmata all’interno del registro TxLevel, TxInterruptStatus viene automaticamente asserito dall’elettronica del dispositivo. Ciò può indicare che il destinatario non sta leggendo i dati oppure lo sta facendo troppo lentamente (rispetto al trasmettitore). Una volta che tutte le impostazioni sulle modalità di trasmissione o ricezione sono state eseguite, si scrivono o leggono i dati sui registri di trasmissione (TxData) o ricezione (RxData) ai quali si può accedere ad 8, 16, 24 e 32 bit. Nel caso in cui si stiano effettuando delle trasmissioni, lo STC101 provvede quindi a convertire i dati dal formato parallelo a seriale DSLink (blocco DSLink della figura 2.16) a formare i vari pacchetti, ad inviare le informazioni di contorno ed i dati precedentemente memorizzati nella TxFIFO. Nel caso della ricezione il C101 effettua invece le operazioni opposte (conversione serie-parallelo, interpretazione delle informazioni di contorno, lettura dei dati). Contemporaneamente vengono aggiornati i registri interni del dispositivo interessati dalle comunicazioni in corso. I dati scritti sul registro TxData sono inviati nella coda di trasmissione mentre i dati in ingresso arrivano sulla coda di ricezione e successivamente nel registro RxData. Le due memorie FIFO di 64+64 byte si rendono necessarie in quanto la comunicazione è di tipo asincrono. In modalità trasparente, senza l’interfaccia token, i dati non vengono raggruppati in pacchetti ma vengono spediti immediatamente, senza informazioni addizionali (testa e terminatore). Una cosa analoga avviene in fase di ricezione. In questo modo non viene aggiunto un indirizzo di destinazione ai dati, che possono così viaggiare soltanto tra due punti fissi (connessione point-to-point). Quindi, se si vogliono effettuare delle comunicazioni tra diversi host (interfacciati tramite gli STC101) attraverso gli switch elettronici STC104, l’unica possibilità è quella di attivare la pacchettizzazione. Il trasparent mode è stato utilizzato nel corso del lavoro soltanto per effettuare i primi test dello hardware. Come detto, l’interfaccia parallela, oltre alle modalità di funzionamento a 16 e 32 bit, può funzionare con l’interfaccia token abilitata. In questa configurazione, i registri di lettura e scrittura RxData e TxData non sono accessibili direttamente, ed i dati vengono letti e scritti mediante le due porte TxToken ed RxToken. Altri registri (esterni al C101) vengono utilizzati al posto dei precedenti, ed i loro indirizzi dipendono dal modo con il quale le schede che li contengono vengono configurate (questo aspetto verrà chiarito in seguito). In questa modalità vi è inoltre la possibilità di aggiungere delle FIFO opzionali: la loro enorme utilità varrà evidenziata nel capitolo 4. Per particolari applicazioni è possibile lavorare in trasparent mode con la token interface attiva, facendo costruire i pacchetti ad un hardware addizionale posto tra il bus parallelo e l’interfaccia, senza utilizzare quello presente nel C101, se non per la parte di interfaccia denominata DSLink nella figura 2.16 Lo STC101 è una interfaccia fondamentale nelle comunicazioni secondo il protocollo IEEE 1355 DS-DE, e pertanto la sua implementazione deve essere prevista in ognuno dei processori locali e globali di ATLAS. A queste unità di elaborazione non sono quindi richieste soltanto delle grosse capacità di calcolo, ma anche una efficace gestione delle operazioni di I/O. A tal proposito il compito degli STC101 potrebbe essere demandato a delle FPGA. Se le velocità di queste ultime raggiungeranno, come si prevede, dei valori confrontabili con quelli ottenuti con l’uso di hardware dedicato, la loro duttilità potrebbe giocare un ruolo importante nella realizzazione del 2° livello di trigger dell’esperimento, in quanto permetterebbe di implementare il protocollo DSLink dal livello hardware fino al livello di messaggio, e di gestire “on-chip” i canali virtuali (VCP). Tutto ciò assume un interesse ancora maggiore se si considera il fatto che anche i processori di trigger di potrebbero essere realizzati mediante delle FPGA. ATLAS Capitolo 3 3.1 Topologia delle reti locali e globale di ATLAS. Generalità. Dopo aver descritto le specifiche delle reti locali e globale di ATLAS, nonchè le caratteristiche dei componenti utilizzati per realizzarle, si vuole ora mostrare la topologia con la quale gli switch STC104 vengono interconnessi tra loro: la indirect multistage network, detta anche clos network. La sua caratteristica fondamentale è quella di permettere una connessione globale tra tutti i suoi nodi, mantenendo costante il numero di C104 da attraversare per andare tra due host qualsiasi. La denominazione multistadio deriva invece dal fatto che tra ingresso ed uscita si debbono attraversare almeno due diversi “stadi” di switch (STC104). Due semplici esempi di clos network sono riportati nella figura 3.1: Figura 3.1: Clos network costituite da tre (a) e cinque (b) switch STC104. Il numero di nodi di ingresso/uscita che le reti della figura hanno dipende dal numero di link utilizzati per connettere tra loro gli switch, ed inoltre, all’aumentare delle connessioni link-link, aumenta la banda passante del singolo terminale di I/O [15]. Se confrontata con la binary n-cube o la two dimensional grid [15], la clos è una connessione a basso costo , ovvero ha un buon rapporto banda passante / numero di switch. Inoltre questa topologia ha una struttura molto semplice e lineare, è facilmente espandibile, ed al suo interno non presenta dei percorsi privilegiati, a differenza, ad esempio, delle connessioni ad albero. Per banda passante totale di una rete si intende il numero di byte che possono essere trasferiti dai suoi ingressi alle sue uscite nell’unità di tempo. In generale questo valore può essere incrementato aumentando il numero di connessioni tra gli switch che compongono la rete, a costo però di un aumento del numero dei dispositivi stessi e, in genere, della latenza della rete. Ciò è evidente in quanto, essendo i link per ogni switch in numero limitato, per aumentare le connessioni del tipo link-link, si devono sottrarre alcuni dei canali disponibili per gli ingressi e le uscite. Se questi ultimi non sono più sufficienti, necessariamente devono essere aggiunti nuovi C104. Come vedremo nel corso del capitolo, aumentare il numero di switch può comportare alle volte un aumento degli stadi della rete. Un esempio di una clos network più complessa delle precedenti, costituita da 64 nodi viene riportato nella figura 3.2: Figura 3.2: Clos network con 64 nodi. Come detto, un altro vantaggio di questa topologia è dato dal fatto che i pacchetti attraversano un numero di switch che non dipende dal percorso ma è fisso: si parla in questo caso di diametro1 costante. In questo modo, se la rete viene configurata correttamente, la sua latenza può essere determinata con buona precisione, a differenza delle reti con diametro variabile, quali quelle con topologia ad albero. Per realizzare reti secondo la topologia clos network , possono essere utilizzati degli switch con caratteristiche differenti. Una di queste, molto importante, è data dal numero di porte che il singolo dispositivo possiede. Come si può osservare nella tabella 3.1, nella realizzazione di reti complesse questo parametro ha una influenza notevole. n = numero di switch necessari per realizzare la rete d = diametro della rete Dimensioni della rete (nodi) Switch con 8 porte 8 n=1 d=1 n=6 d=3 n = 12 d=3 n = 40 d=5 n = 80 d=5 n = 224 d=7 n = 448 d=7 16 32 64 128 256 512 Switch con 16 Switch con 32 porte porte n=1 d=1 n=1 d=1 n=6 d=3 n = 12 d=3 n = 24 d=3 n = 80 d=5 n = 160 d=5 n=1 d=1 n=1 d=1 n=1 d=1 n=6 d=3 n = 12 d=3 n = 24 d=3 n = 48 d=3 Tabella 3.1: Numero di switch necessari per la realizzazione di clos network, in funzione del numero di porte per dispositivo. Utilizzando lo STC104, il quale possiede 32 porte, si ha un enorme vantaggio in termini di costo rispetto ad altri switch commerciali, tipo ATM [15] il quale, fino ad un anno fa, era provvisto di sole 16 porte. Ciò avviene per un duplice motivo: in 1 Con diametro si indica il numero dei dispositivi elettronici che i dati debbono attraversare per andare dalla sorgente alla destinazione. primo luogo all’aumentare del numero di porte del singolo switch, diminuisce il numero di dispositivi necessari per realizzare la rete con il numero di nodi prestabiliti, poi gli switch C104 sono più economici di quelli ATM2. Reti costituite da dispositivi con un numero di porte superiore, oltre ad essere meno costose, hanno una latenza inferiore, in quanto diminuisce il loro diametro. Infatti, a parità di tecnologia utilizzata, di nodi totali della rete, della topologia interconnettiva, e del numero di connessioni, nelle reti realizzate con meno dispositivi i pacchetti attraversano un numero minore di questi ultimi, e conseguentemente subiscono un ritardo inferiore. Con lo hardware disponibile attualmente (3 STC104 e 4 interfacce PCIDSLink) è possibile misurare latenza e banda passante per alcune particolari configurazioni (descritte nel 5° capitolo). Estrapolazione a topologie più complesse richiederebbero un elevato numero di componenti hardware. 3.2 Le reti locali e globale di ATLAS. Vediamo ora come molte delle caratteristiche generali che debbono avere le tre reti locali e la rete globale di ATLAS (capitolo 1) potrebbero essere soddisfatte da reti formate da STC104 connessi secondo la topologia indirect multistage. La connettività globale e la bidirezionalità sono garantite in quanto tutti i nodi sono connessi tra loro e i canali possono lavorare in full duplex. Come detto in precedenza, nelle clos network la latenza è indipendente dai nodi di ingresso e di uscita, quindi è un parametro costante e ben definibile. In genere si stabilisce una soglia massima per il suo valore, e si progetta la rete in modo che questo non venga superato. E’ evidente che la possibilità di prevedere con esattezza il contributo delle switching network alla latenza totale del trigger di livello 2 è un fattore importante nella progettazione di tale sistema. La topologia descritta soddisfa inoltre al criterio della scalabilità anche se, ad un aumento degli switch, può corrispondere un incremento del diametro della rete, con conseguente variazione dei suoi tempi caratteristici. Infatti, nelle reti con un 2 Uno switch STC104 ha un costo inferiore a 100 $, mentre un analogo dispositivo ATM, provvisto però di sole 16 porte, costa migliaia di dollari. numero di nodi che va da 64 a 512, ad un aumento degli switch che le compongono non corrisponde un aumento del diametro, il quale è costante e pari a 3 (tabella 3.1). Passando invece alla clos network con 1024 nodi, riportata nella figura 3.3 della pagina successiva, il diametro sale a 5. La velocità dei singoli link non soddisfa ancora le specifiche dell’esperimento. Infatti il trigger di 2° livello necessita di rate dell’ordine di 1 Gbit/s mentre i due dispositivi DSLink garantiscono 100 Mbit/s. Comunque è già stato realizzato un canale DSLink a 400 Mbit/s, denominato HSLink e completamente compatibile con quello esaminato nella tesi, ed è in fase avanzata di progettazione lo stesso canale ad 1 Gbit/s. Molto presumibilmente, quando ATLAS diverrà operativo, l’evoluzione della tecnologia DSLink sarà in grado di raggiungere le velocità richieste dall’esperimento. Tutte le prestazioni elencate fino ad ora subiranno perciò un incremento notevole. Un altro punto a favore della topologia clos è dato dal fatto che tutti i nodi sono trattati identicamente: non vi è suddivisione tra sorgenti e destinazioni quindi le prime possono essere aumentate a scapito delle seconde e viceversa. Se nell’eseguire questa operazione non si disconnettono fisicamente i link della rete, allora non è necessario neanche riconfigurarla (capitoli 4 e 5). Per il trigger di ATLAS tale prerogativa, oltre a poter essere utilizzata per effettuare dei test, rende possibile la eventuale sostituzione di nodi malfunzionanti senza interruzione della presa dati. Nel trigger di 2° livello di ATLAS, lo switch locale relativo ai muoni può essere realizzato con una delle configurazioni riassunte nella tabella 3.1. Le reti locali relative ai calorimetri ed al TRT, nonchè la rete globale, avendo un numero di link maggiore di 512 necessitano di una switching network con 1024 nodi. Quest’ultima è differente da quelle già viste in quanto per realizzarla serve un numero maggiore di link di collegamento tra i due stadi di C104: il suo aspetto viene mostrato nella figura 3.3. Figura 3.3: Clos network con 1024 nodi. Il numero di STC104 necessari per realizzare questa rete è pari a 160 (64+16×6) con un diametro pari a 5. Si noti che, mentre nel caso della figura 3.2 vi sono 8 link di connessione tra ogni switch interno ed ognuno di quelli esterni (8 canali DSLink), ora ce n’è soltanto uno. Ciò può comportare dei problemi di contest switch (paragrafo 2.2.5) maggiori rispetto al caso precedente, in quanto c’è una maggiore condivisione delle connessioni link-link da parte dei messaggi. Per evitare un degrado delle prestazioni in questo particolare caso, si devono disporre gli host lungo i nodi in modo che più sorgenti, per raggiungere le loro destinazioni, non debbano percorrere lo stesso link di connessione tra i C104. Comunque questo è un problema che, per essere affrontato dal punto di vista sperimentale, necessita di un numero di componenti hardware elevato. Si vuole ora fare una analisi dell’ultima topologia vista, al fine di calcolare l’ordine di grandezza del routing delay attraverso essa, in assenza di contest switch. Nel trigger di ATLAS la bidirezionalità dei link è richiesta sia per effettuare dei controlli sul flusso delle informazioni, sia per poter implementare correttamente le due architetture push e pull (capitolo 1). La maggior parte delle comunicazioni avvengono tra una o più sorgenti (processore locale o RoB) ed una destinazione (processore locale o globale). Nel caso dell’architettura push i dati vengono inviati dai RoB ai processori locali e da questi ultimi ai processori globali, senza una richiesta esplicita. Nell’architettura pull, anche se c’è una richiesta dei dati da parte dei processori globali e locali rispettivamente a questi ultimi e ai RoB, il flusso maggiore delle informazioni è equivalente a quello di tipo push, in quanto le richieste, se confrontate con i dati, vengono fatte mediante messaggi brevi (possono essere ad esempio dei pacchetti di acknowledge - capitolo 2). Con questa premessa le considerazioni che seguono vengono fatte soltanto per comunicazioni unidirezionali. Consideriamo pacchetti da 32, 128, 512, 1024, 2048 e 4096 byte di lunghezza, provvisti di 2 byte di testa: sotto queste condizioni abbiamo visto che (paragrafo 2.2.6) il routing attraverso un singolo C104 impiega un tempo pari a: S ≅ 670ns + [10⋅k + 14]⋅10ns con k = lunghezza pacchetto in byte. Moltiplicando S per 5 (numero di switch da attraversare) si ottengono i tempi necessari per attraversare la rete nei 6 casi proposti, in assenza di contest switch: Dimensioni pacchetto (byte) Latenza (µs) 32 ~20 128 ~66 512 ~254 1024 ~504 2048 ~1004 4096 ~2004 Tabella 3.2: Tempi necessari per attraversare una clos network con diametro pari a 5, in funzione della lunghezza dei pacchetti, in assenza di contest switch. Utilizzando i valori calcolati, vediamo ora qual’è l’ordine di grandezza delle latenze per le reti di ATLAS, quando queste vengono realizzate con gli switch STC104. Prendiamo in considerazione una RoI di dimensioni pari a 2.5 Kbyte (capitolo 1), e una rete locale con 1024 nodi, ovvero con diametro d = 5. In questo caso i pacchetti, per attraversare lo switch, impiegano un tempo medio pari a ~1.3 ms. Considerando che in media le RoI hanno delle dimensioni inferiori di 2.5 Kbyte, questo valore della latenza attraverso la rete rappresenta una stima per eccesso. Il calcolo appena eseguito sul tempo di attraversamento dei messaggi lungo la rete viene ora ripetuto per pacchetti lunghi 4096 byte nel caso in cui essi attraversino 1, 2 oppure 3 STC104. I risultati ottenuti, che verranno confrontati nel capitolo 5 con i corrispondenti valori sperimentali, sono riportati nella tabella 3.3: Numero di STC104 Latenza (µs) 1 ~ 410 2 ~ 820 3 ~ 1230 Tabella 3.3: Tempi di routing per pacchetti di lunghezza pari a 4096 byte, in funzione del numero di switch attraversati, in assenza di contest switch. Nel computo totale della latenza del trigger di 2° livello debbono essere aggiunti, al ritardo massimo introdotto delle reti locali e globale, fondamentalmente altri tre contributi. Il primo è dato dal tempo di calcolo dell’algoritmo dei processori locali, stimato essere, nel caso peggiore, inferiore ad 1 ms (paragrafo 1.4.1). Il secondo contributo è dato dal tempo di esecuzione dell’algoritmo dei processori globali per il quale però non esiste ancora nessuna stima. Inoltre si deve aggiungere il tempo necessario ai processori locali e globali per completare le operazioni di I/O. Quest’ultima latenza, oltre a dipendere dalla potenza dei processori e dal sistema di I/O, è funzione dell’algoritmo che si utilizza per formare i pacchetti. Infine nelle considerazioni appena fatte non è stato preso in esame il ritardo causato dalla gestione della rete locale (anch’essa effettuata dai processori del trigger) che connette tutti i processori con il supervisor del 2° livello3. Come verrà descritto nei prossimi due capitoli, vi sono diversi modi per raggruppare i dati ed innumerevoli controlli che possono (in alcuni casi devono) essere effettuati sui pacchetti prima che essi vengano spediti o appena sono ricevuti. Inoltre verrà mostrato quanto sia importante non appesantire troppo il lavoro di queste CPU con istruzioni di I/O relative a comunicazioni DSLink. 3 I processori delle farm locali e globale del 2° livello possono essere connessi al Supervisor sia tramite una rete LAN (Local Area Network), sia mediante alcuni DSLink delle switching network. Capitolo 4 4.1 Descrizione dello hardware e del software sviluppato. Lo hardware. Nello sviluppo del lavoro di tesi, sono state utilizzate le seguenti componenti hardware: • tre schede basate su VMEbus (Versa Module Eurocard bus) sviluppate al CERN (Ginevra), ognuna provvista di un STC104 con 32 link disponibili in uscita; • due schede PCI-DSLink sviluppate all’Università di Zeuthen, denominate nel seguito “PCI-DSLink Zeuthen”; • due schede PCI-DSLink sviluppate dall’INFN di Roma (“PCI-DSLink INFN”); • due schede IMS B108 della SGS Thomson e vari personal computer. Tutte le componenti sono state utilizzate in varie configurazioni, le quali vengono specificate ogniqualvolta il contesto lo renda necessario. Nei successivi cinque paragrafi viene data una breve descrizione delle singole componenti hardware, mettendo in evidenza la loro specifica funzione nell’ambito del lavoro svolto; informazioni più dettagliate possono essere reperite nei rispettivi “data book” menzionati in bibliografia. 4.1.1 Le schede VME con lo switch STC104. I tre switch elettronici STC104 a disposizione sono alloggiati all’interno di altrettante schede VME. Come precedentemente descritto, ogni scheda dispone di 32 DSLink bidirezionali dedicati ai dati, più due DSLink di controllo, uno di ingresso C0, l’altro di uscita C1, interfacciati con l’esterno grazie a 34 buffer differenziali AT&T 1041ML [2]. Tutti i link di due delle tre schede sono presenti sul pannello frontale e sono quindi disponibili per effettuare dei collegamenti tramite i cavi DSLink, mentre la terza presenta sul pannello frontale 24 dei 32 data link che possiede1. I tre STC104 vengono connessi tra loro per realizzare delle semplici configurazioni di switching network attraverso le quali transitano i pacchetti contenenti i dati scambiati dai PC. Come vedremo in seguito queste configurazioni permettono di effettuare delle misure di alcuni dei parametri caratteristici del protocollo DSLink, e di simulare, anche se in minima parte, il traffico presente nel trigger di 2° livello di ATLAS. 4.1.2 Le schede “IMS B108”. Le IMS B108 sono due schede di interfaccia ISABus-DSLink prodotte dalla SGS Thomson, contenenti ognuna due DSLink (ovvero due STC101). La configurazione fornita prevede l’utilizzo della token interface dei C101, selezionata permanentemente in modo hardware. Uno dei due link è adibito alla configurazione ed al controllo della rete (queste funzioni verranno analizzate nella parte relativa al software) mentre tramite il secondo vengono effettuate delle comunicazioni attraverso gli switch. Il bus ISA, nel quale vengono alloggiate le B108, è un bus di I/O utilizzato per i personal computer. Non ha più un grande interesse informatico in quanto è stato ormai sostituito dal PCIbus (appendice B), il quale ha una banda passante molto maggiore del primo ed è indipendente dalla piattaforma hardware sulla quale si trova (viene accoppiato indifferentemente a processori di tipo Pentium Intel, PowerPC, Alpha ed altri). Di queste due schede verrà quindi fatto un uso limitato, soprattutto nei casi in cui esse debbano effettuare delle comunicazioni ad elevate prestazioni. Altre loro caratteristiche verranno fornite, quando necessario, durante la descrizione del software, ma per maggiori informazioni si rimanda il lettore alla bibliografia [27]. 1 Ciò non costituisce comunque un problema al fine di realizzare le configurazioni che ci interessano. 4.1.3 Le schede “PCI-DSLink Zeuthen”. Le due schede di interfaccia “PCI-DSLink Zeuthen” sono provviste ognuna di un STC101 ovvero di un unico canale DSLink. A differenza delle altre schede, queste sono perfettamente controllabili in fase di programmazione in quanto sono state fornite con la completa descrizione della loro architettura interna. Tra le caratteristiche fondamentali ricordo la possibilità di selezionare, via software, l’utilizzo o meno della token interface, oltre chiaramente a tutte le altre funzioni realizzabili dallo STC101, e la presenza di ulteriori memorie FIFO da aggiungere a quelle presenti nello STC101. In particolare il PCI Controller S5933 contiene 32 byte di memoria FIFO in trasmissione e 32 byte in ricezione, mentre altri 2x16 Kbyte di memoria (TxFIFO ed RxFIFO) sono presenti sulla scheda all’interno di un ulteriore chip, capace di trasferimenti alla banda passante del PCIbus. La presenza di una NVRAM (Non Volatile RAM) e di una PLD (Programmable Logic Device) AMD MACH445-12 [14], opportunamente programmate dal costruttore, assicurano la identificazione di tutti i registri dello STC101 (appendice B) e di numerosi altri registri di controllo e di stato presenti sulle schede; questi ultimi possono essere suddivisi in 4 categorie: PCI Configuration Registers (r/w): sono dei registri di configurazione comuni a tutte le schede elettroniche connesse sul bus PCI. La loro principale funzione è quella di memorizzare gli indirizzi base dei vari dispositivi presenti sulla interfaccia PCI-DSLink. PCI Bus Operation Registers (r/w): a questi registri è demandata la funzione di controllo dall’interfaccia PCI. Ne viene utilizzato uno soltanto al fine di programmare la scheda come master oppure slave. Nel nostro sistema prototipo le schede vengono utilizzate nella configurazione MASTER, in quanto soltanto in questa modalità è possibile sfruttare tutte le sue FIFO interne. C101 Registers (r/w): sono i registri del C101 presente sulla scheda. Interface Control/Status Registers (r/w): sono tre registri molto importanti ai fini della gestione delle comunicazioni, in quanto permettono di effettuare controlli sul flusso dei dati. Dal momento che vengono utilizzati frequentemente nel software sviluppato, nella tabella 4.1 si riporta la descrizione delle funzioni che i singoli bit di questi registri svolgono. REGISTRO Bit Segnale Descrizione Interface Control Register (ICR) 0 1 C101_Reset Fifo_Reset Reset del C101. 2 TokenEnable 3 MasterMode 4 0 1 2 IntEnable RxFifoLevel RxFullFlag TxEmptyFlag 3 PacketReceived 4 PacketSent 5 HeaderValid 6 AckReceived 0 1 2 3 4 5 6 IntOnRxFifoLevel IntOnRxFullFlag IntOnTxEmptyFlag IntOnPacketReceived IntOnPacketSent IntOnHeaderValid IntOnAckReceived Interface Status Register (ISR) Interrupt Enable Register (IER) Reset delle memorie FIFO presenti sulla scheda. Abilita la connessione tra le FIFO e le porte di dato del C101. Abilita il bridge S5933 alle funzioni di Master. Deve essere abilitato quando si vogliono utilizzare le FIFO presenti su questo chip. Abilitazione interrupt. Stato della FIFO di ricezione. Flag FIFO di ricezione piena. Flag FIFO e S5933-FIFO entrambe vuote. Avvisa dell’arrivo di un pacchetto o messaggio non nullo. Indica che un pacchetto o messaggio è stato inviato correttamente. Indica che è stata ricevuta una testa corretta. Indica che è stato ricevuto un pacchetto vuoto. Abilitazione interrupt Rx FIFO Level. Abilitazione interrupt Rx Full. Abilitazione interrupt Tx Empty. Abilitazione interrupt Packet Received. Abilitazione interrupt Packet Sent. Abilitazione interrupt Header Valid. Abilitazione interrupt Ack Received. Tabella 4.1: Descrizione dei registri Control/Status presenti sulle schede “PCIDSLink Zeuthen”. I controlli riguardanti lo stato delle comunicazioni possono essere effettuati sia sui registri del C101, sia sugli analoghi registri appena descritti. Ad esempio, se si vuole effettuare un test per sapere se un pacchetto è giunto correttamente a destinazione, ma quest’ultimo ha una lunghezza maggiore della RxFIFO del C101 (64 byte), allora il controllo deve riguardare i registri della scheda e non quelli del C101. Questi registri aggiuntivi hanno una importanza notevole per la ottimizzazione delle comunicazioni; in particolare nel paragrafo 4.2.2 verrà evidenziata l’utilità delle FIFO di trasmissione/ricezione addizionali presenti sulle schede. Le due interfacce vengono utilizzate prevalentemente con tutte le FIFO di cui dispongono e la token interface attiva, per inviare e ricevere pacchetti da e per la rete di switch STC104: con le condizioni al contorno che verranno specificate in seguito, nel migliore dei casi si riescono ad ottenere delle velocità di comunicazione superiori a 9 Mbyte/s. I risultati inerenti queste misure vengono riportati nel capitolo 5. 4.1.4 Le schede “PCI-DSLink INFN”. Le schede di interfaccia PCI-DSLink sviluppate all’INFN sono provviste di due DSLink ognuna (quindi due STC101) indirizzabili singolarmente. Sebbene queste interfacce prevedano molte più modalità di funzionamento rispetto alle precedenti (mediante la programmazione di una FPGA ALTERA), nella revisione sviluppata (è in sostanza la prima realizzazione del progetto) è consentito “soltanto” l’uso dei due STC101, senza interfaccia token, e con formato parallelo dei dati limitato a 16 bit. Pertanto, gli unici accessi consentiti sono quelli da/per i registri degli STC101, quindi senza aggiunta di FIFO opzionali, oppure di registri di controllo ulteriori. Nelle configurazioni di switching network che analizzerò nel capitolo 5, anche le schede “PCI-DSLink INFN” avranno la funzione di interfaccia tra gli host (PC) ed i canali DSLink, e quindi serviranno per inviare e/o ricevere pacchetti attraverso la rete di switch. Le velocità di trasmissione ottenibili con i PC a disposizione e le schede configurate come descritto, sono dell’ordine di 2 Mbyte/s per ogni link fisico. Questo limite è dovuto principalmente a tre cause. In primo luogo non è possibile accedere alle porte dati dei C101 con parole a 32 bit ma al massimo fino a 16 bit. Inoltre la limitata capacità delle FIFO dei C101 influisce negativamente sulla banda passante (paragrafo 4.2.2). Infine le schede “INFN” non hanno a disposizione tutti i registri di controllo presenti sulle analoghe schede prodotte a Zeuthen, e per questo motivo le operazioni risultano essere più artificiose rispetto a queste ultime. Comunque, nello sviluppo futuro di interfacce PCI-DSLink per il trigger di 2° livello dell’esperimento ATLAS 2, la presenza di una FPGA ALTERA rende le schede “PCI-DSLink INFN” molto interessanti. Infatti i processori locali e globali di ATLAS, oltre ad eseguire gli algoritmi di livello 2, devono gestire anche tutte le operazioni di I/O che in alcuni casi richiedono un tempo macchina non indifferente. Per questo motivo la presenza di una FPGA ALTERA opportunamente programmata, potrebbe sostituire il processore nella gestione delle operazioni di I/O, con notevole aumento delle prestazioni globali del sistema. Nel prossimo capitolo verrà evidenziato come la gestione dei canali virtuali, per essere veramente efficiente, necessiti di alcuni accorgimenti hardware. 4.1.5 I personal computer. Le schede di interfaccia descritte vengono alloggiate nei bus PCI di 4 personal computer dotati di processori Pentium e AMD. Ognuno di essi ha una specifica configurazione hardware la quale interagisce con le schede PCI-DSLink e dalla quale dipendono, in parte, le prestazioni del sistema. Infatti vi sono innumerevoli parametri che condizionano le misure effettuate: tra i principali ricordo le velocità dei clock di sistema e del bus PCI, le dimensioni della memoria cache, i chip di bridge tra processore e bus PCI (appendice B). Per questo motivo nella tabella 4.2 vengono riportate le principali caratteristiche dei PC utilizzati: 2 Attualmente è in fase di realizzazione la revisione 2 delle schede “PCI-DSLink INFN”. Nella nuova serie saranno disponibili tutte le funzionalità con le quali l’interfaccia è stata progettata, compreso l’uso della logica programmabile ALTERA. Nome identificativo PC MainBoard CPU Memoria RAM Memoria cache Chipset Clock Sistema Clock bus PCI Bus PCI Sistema Operativo Versione Kernel JAVA PCAPE PCMRZ1 PCATL2 P/I-P55T2P4 Intel 48 Mbyte 512 Kbyte Intel TRITON PCISet 166 MHz 33 MHz 32 bit Linux RedHat 4.1 2.0.27 P/I-P55TP4XE Intel 64 Mbyte 512 Kbyte Intel TRITON PCISet 100 MHz 33 MHz 32 bit Linux RedHat 4.2 2.0.30 Pentium SI2 Intel 48 Mbyte 256 Kbyte Triton AMD K5-S 40 Mbyte 256 Kbyte Intel TRITON PCISet 75 MHz 25 MHz 32 bit Linux RedHat 4.2 2.0.30 SIS 85C503 90 MHz 33 MHz 32 bit Linux RedHat 4.2 2.0.30 Tabella 4.2: Caratteristiche dei PC utilizzati per effettuare le misure. La tabella non include tutti i parametri presenti nel sistema di comunicazione per il semplice fatto che molti di essi non possono essere controllati. Come verrà evidenziato nel 5° capitolo, variando i PC nei quali vengono alloggiate le schede di interfaccia, si ha una variazione delle velocità di comunicazione dei pacchetti. Questo è un sintomo evidente che le configurazioni che verranno analizzate non permettono, nella maggior parte dei casi, di raggiungere la velocità del protocollo DSLink. Di conseguenza soltanto alcuni dei parametri caratteristici dello IEEE 1355 possono essere misurati con gli strumenti hardware descritti. I PC hanno la funzione di generare e ricevere i pacchetti che viaggiano all’interno dello switch tramite le schede di interfaccia, ovvero svolgono le funzioni di I/O dei processori locali e globali dell’esperimento. La parte relativa agli algoritmi di trigger non verrà analizzata in questo lavoro. Nel caso specifico quindi i PC sono impegnati dalle sole operazioni di I/O e si limitano a salvare nella memoria dei calcolatori i dati ricevuti, senza eseguire alcuna operazione su di essi. 4.2 Il Software. Le misure sperimentali riportate nel capitolo successivo sono state effettuate mediante del software interamente sviluppato in linguaggio C, con il Sistema Operativo Linux (appendice A). Si ritiene necessaria una descrizione generale di questi programmi al fine di comprendere: • i problemi inerenti l’uso di un S.O. multiutente e multitasking; • le operazioni da eseguire per la configurazione dello switch e la trasmissione dei dati attraverso esso; • le condizioni sotto le quali vengono effettuate le misure dei tempi e delle velocità di comunicazione; • le problematiche riguardanti le varie componenti del sistema. Come riassunto nel capitolo precedente, vi sono diverse schede hardware, ognuna delle quali, per funzionare correttamente, ha bisogno del suo driver software. Alcune di queste schede sono state utilizzate per configurare la rete di switch, ovvero per inizializzare tutti i registri degli STC104 e per “prepararli” alle operazioni di trasmissione e ricezione. Altre invece sono state programmate per realizzare le comunicazioni vere e proprie. In entrambi i casi il primo, fondamentale passo, consiste nella inizializzazione degli STC101 inclusi in tutte le schede, ovvero il “setting” dei loro registri interni. 4.2.1 Software di configurazione e monitoring. La configurazione delle switching network è una operazione che viene fatta per effettuare il set dei registri presenti nel C104. Questa è necessaria all’inizio delle comunicazioni, ogni volta che si vogliono aggiungere dei dispositivi alla rete, quando si effettuano modifiche sulle modalità di trasferimento dati, ed infine in caso di errore su uno o più link. Se confrontata con le operazioni di trasmissione e ricezione, non deve essere eseguita frequentemente e quindi la velocità con la quale deve completare le sue funzioni, entro certi limiti, non è un parametro critico. Per questo motivo la configurazione viene realizzata tramite le schede B108 (con interfaccia ISA Bus) ovvero le meno performanti che si hanno a disposizione. In realtà, essendo queste interfacce provviste di due STC101 programmabili singolarmente, vengono utilizzate anche per effettuare delle comunicazioni a bassa velocità, quando si vogliono impegnare ulteriormente gli switch elettronici (soprattutto durante le prove di affidabilità). La rete è fisicamente e logicamente suddivisa in una control network ed una data network. In questo modo la parte di controllo è in grado di gestire le comunicazioni senza essere condizionata da eventuali errori sulla rete di dati. Anche il programma di configurazione, denominato IEEE1355_conf, segue questa specifica: tramite due link differenti tratta separatamente le due reti ed ha le seguenti caratteristiche: • inizializza il primo STC101 presente sulla B108 alle operazioni di configurazione della rete di STC104 ed il secondo a quelle di comunicazione. Questa operazione viene effettuata automaticamente (una sola volta) senza intervento dell’utente, all’avvio del programma; • interpreta i file di descrizione dello hardware (NDL – appendice A) e configura switching network costituite da un qualsiasi numero di STC104; • permette di effettuare il reset dei singoli link degli STC104 precedentemente configurati; • esegue delle ispezioni dei link degli STC104 che costituiscono la rete (precedentemente configurata), al fine di riconoscere eventuali malfunzionamenti; • esegue delle ispezioni sia dei singoli registri dei due STC101 presenti sulla B108, sia di tutti i registri degli STC104 che costituiscono la rete (precedentemente configurata); • permette di trasmettere pacchetti tra due host (mediante il 2° STC101 presente sulla B108) attarverso la rete di switch (precedentemente configurata). L’operazione di configurazione deve essere effettuata da un solo host (MASTER) il quale ha il controllo totale della control network ed è connesso fisicamente, tramite il control link0 (Clink0) ad essa. I dispositivi di comunicazione sono invece collegati agli switch (o tra loro) mediante i data link. La descrizione delle connessioni fisiche della rete, utilizzata nella operazione di configurazione, viene realizzata mediante un pacchetto software denominato Network Description Language (NDL) descritto in appendice A. Il file di descrizione (.ndl) viene prima convertito in un file binario dal Compilatore NDL, quindi in formato esadecimale mediante un programma da me realizzato (converti – appendice C). La scelta di lavorare con file di tipo esadecimale piuttosto che binario è dovuta alla semplicità di interpretazione degli stessi in fase di sviluppo del software. Il menù principale del programma IEEE1355_conf si presenta come in figura 4.1: ************************************************************** * STC104's NETWORK CONFIGURATION AND MONITORING PROGRAM * ************************************************************** ************************************************************** * * * Menu' : * * * ************************************************************** * * * 1-> STC104's Network configuration (Master) * * 2-> Reset whole STC104's Network * * 3-> Reset single STC104 link * * 4-> Monitor state of STC104 link * * 5-> Read STC104 registers * * 6-> Read STC101 registers * * 7-> Communication section * * 8-> Bye * * * ************************************************************** Select a number : Figura 4.1: Menù principale del programma di configurazione e monitoring delle reti di STC104. IEEE1355_conf utilizza alcune procedure 3 presenti in delle librerie incluse nel ToolSet D7394A dalla INMOS [26]. Nella tabella 4.3 ne vengono riportate alcune tra le più importanti, con la descrizione delle funzioni che svolgono: 3 Si parla indifferentemente di procedure e funzioni in quanto nel linguaggio C la loro dichiarazione è uguale. Nome della procedura Funzione svolta Configure Inizializza i registri di entrambi i C101 presenti sulla scheda. Non effettua però lo start dei DSLink. Configura la rete interpretando il file esadecimale creato a partire dal file ndl. ResetLink Effettua il reset del link del C101 specificato. ResetC104Link Effettua il reset del link del C104 specificato. StartLink Effettua lo start del link del C101 specificato. InitializeDeviceNoStart ReadFromLink Specificati un C104 ed un registro, ne legge il contenuto. Attende che arrivino dei dati sul data link del C101 e pone il risultato nella variabile specificata. WriteToLink Pone dei dati sul link del C101 specificato Select_link Seleziona uno dei due link presenti sulla B108. Cpeek Tabella 4.3: Procedure del programma di configurazione e relative funzioni svolte. Alcune delle azioni che vengono eseguite sullo STC101 e sullo STC104 sono analoghe in quanto, utilizzando lo stesso protocollo, parte dei loro registri hanno funzioni simili (LinkStatus, DeviceConfig…). Le operazioni ResetLink e ResetC104Link vengono effettuate al fine di marcare i buffer contenuti nei due chip (C101 e C104) come vuoti e azzerare lo stato dei bit di parità e di token. Il comando StartLink agisce sul registro LinkCommand dello STC101 specificato, ed è necessario ogniqualvolta si vogliono trasmettere dei dati attraverso un link. Una cosa analoga avviene per lo STC104. Sulla B108, prima di effettuare qualsiasi impostazione, si deve selezionare, tramite la procedura select_link, il link fisico (C101) sul quale si andrà ad agire. Per il link di controllo, il set effettuato sui registri è tale che: • la velocità di trasmissione è pari a 50 Mbit/s; • la pacchettizzazione è abilitata; • gli interrupt del C101 sono disabilitati in quanto vengono utilizzati quelli aggiuntivi presenti sulle schede B108. La possibilità di effettuare delle semplici ispezioni dei registri presenti sullo hardware, rende possibile dei controlli immediati in caso di malfunzionamento di uno o più link dei due dispositivi. Supponiamo ad esempio che un host debba ricevere dei dati e che questi non arrivino correttamente o non arrivano affatto. Ispezionando il registro LinkStatus sia dello STC101 che dello STC104, si può comprendere se: 1. è avvenuto un errore sul link; 2. il link non è partito correttamente (start_link non effettuato); 3. è avvenuto un errore di parità; 4. il link è disconnesso. Gli errori del primo caso possono avere varie motivazioni. Può accadere infatti che l’errore sia dovuto a problemi di natura temporanea (ad esempio un link è stato fisicamente disconnesso e reinserito senza aver effettuato le operazioni di reset link e start link) oppure permanente (rottura di un buffer differenziale o di uno dei connettori). In caso di guasto temporaneo è in genere sufficiente scaricare i dati che sono arrivati a destinazione, effettuare le operazioni dei reset link e start link, e ripetere la comunicazione. La stessa procedura cura errori del 2° e 3° tipo, i quali sono causati rispettivamente dalla mancata esecuzione dello start link e da un errore di parità avvenuto su un token. Nel caso in cui l’indicazione sia disconnect error (4° punto) si debbono invece fare dei controlli sulle connessioni fisiche del link: analogamente al primo caso potrebbero esserci dei problemi hardware, di soluzione non immediata. Questi controlli sono effettuabili sui singoli link di entrambi i dispositivi della SGS Thomson. Nel software di configurazione sviluppato è possibile leggere lo stato di tutti i registri accessibili all’utente, inserendo direttamente il loro indirizzo [28, 29]. Un esempio della stampa dello stato dei bit appartenenti a tre registri di controllo del link 1 del C104 viene riportato nella figura 4.2: *** LINK 1 *** * Mode Register: Randomize 0 GroupContinue 0 HeaderDeletion 1 DiscardOnError0 Header_Length 0 * Link Mode: SpeedDivide 1 LocalizeError 0 * Link Status: ParityError 0 SpeedSelect 1 Error 0 Start 1 Disconnect 0 ResetOutput 0 TokenReceived 0 Figura 4.2: Lettura dei registri PacketMode, LinkMode e LinkStatus del link 1 dello STC104. In questo caso si ricavano le seguenti informazioni sul link in esame: il primo byte della testa in uscita viene cancellato (HeaderDeletion = 1), la velocità è impostata a 50 Mbit/s, lo start è avvenuto correttamente (Start = 1) ma nessun token è stato ricevuto (TokenReceived = 0). Uno dei grossi vantaggi della tecnologia DSLink è dato dal fatto che se il dialogo tra una coppia di dispositivi viene interrotto a causa di uno qualsiasi degli errori descritti, gli altri link non ne risentono affatto. E’ sufficiente in questo caso ripristinare il corretto stato dei link con errore, effettuare nuovamente la configurazione della rete, e rimetterli in comunicazione. Essendo, nel C104, i link di controllo separati dai link di dato, le operazioni di reset dei singoli link della rete e di configurazione della stessa non interrompono le altre trasmissioni. Il reset totale della rete arresta invece le comunicazioni in corso, in quanto effettua l’azzeramento dei registri di tutti i link del C104, mentre la rottura del link di controllo rende impossibile qualsiasi operazione sulla rete. Il secondo link presente sulla scheda B108 viene utilizzato per comunicazioni a pacchetti. E’ utile quando si vogliono impegnare ulteriormante i link dello switch ma, data la bassa velocità di trasmissione (dell’ordine di 0.5 Mbyte/s) non ha una enorme utilità pratica. Il programma IEEE1355_conf prevede comunque la possibilità di trasmettere attraverso essi un qualsiasi numero di pacchetti con lunghezza desiderata, e di misurare i tempi di comunicazione. La tecnica di misura dei tempi verrà descritta in dettaglio nel paragrafo successivo. 4.2.2 Software di comunicazione. I programmi mediante i quali vengono trasmessi e ricevuti dei messaggi attraverso gli switch sono stati sviluppati indipendentemente per le schede “PCIDSLink Zeuthen” e “PCI-DSLink INFN”, anche se le funzioni che svolgono sono analoghe. In particolare tra le due interfacce cambiano il numero di C101, gli indirizzi base dei componenti nel loro interno, e alcune modalità di funzionamento (nella prima vengono utilizzate delle memorie FIFO aggiuntive e la token interface): di conseguenza i controlli sulle comunicazioni vengono fatti su registri diversi. Infatti, come descritto nel paragrafo 4.1.3, le schede progettate a Zeuthen hanno una serie di flag aggiuntivi (es. Interface Control/Status register) accessibili all’utente. Le funzionalità aggiuntive delle schede “PCI-DSLink INFN”, potenzialmente enormi, non sono invece state ancora programmate, e pertanto gli accessi vengono fatti esclusivamente sui registri degli STC101. A differenza del programma di configurazione, nello sviluppo del software di comunicazione non è stato possibile (ne si è voluto) utilizzare le librerie con le procedure descritte nel paragrafo precedente. Ciò, sia perchè tali funzioni hanno validità solo per le schede B108, sia perchè prevedono molti controlli che nel caso specifico non sono necessari, ed anzi introducono degli overhead notevoli che riducono drasticamente le velocità di comunicazione. Tutte le operazioni vengono quindi svolte da funzioni create ad hoc, costruite a partire dalle librerie standard del compilatore C, e da una libreria (libpcidev.a) contenente alcune procedure per la gestione del bus PCI (appendice B). Queste ultime consentono di accedere nello spazio di configurazione dei dispositivi PCI all’interno del microcontrollore del bus (AMCC S5933 [1]). Tra le più importanti ricordo: pcibios_present: determina se è presente il set di funzioni per l’interfaccia con il bus PCI. pcibios_find_device: se il dispositivo specificato in input dal numero del venditore, dal numero identificativo e dal numero indice viene trovato, la funzione ritorna il numero del bus su cui è inserito ed il numero del device all’interno del sistema. pcibios_read_config_dword: permette di leggere delle double word (32 bit) nello spazio di configurazione del device specificato. Mediante questa funzione vengono letti gli indirizzi base dei dispositivi presenti sulle schede connesse al bus PCI. pcibios_write_config_dword: permette di scrivere delle double word (32 bit) nello spazio di configurazione del device specificato. Il software di trasmissione è stato sviluppato con lo scopo di effettuare delle comunicazioni attraverso la rete di switch. Ciò al fine di misurare sia alcuni dei parametri caratteristici degli STC104, sia le latenze di attivazione dei processi necessari alla trasmissione e ricezione di pacchetti. Anche se queste ultime misure dipendono fortemente dalla macchina sulle quali vengono effettuate, forniscono indicazioni sulle velocità relative delle chiamate software rispetto alle rate di comunicazione (capitolo 5). I principali programmi realizzati e le relative funzionalità sono: Zboard, INFNboard: consentono di effettuare comunicazioni bidirezionali a pacchetti tra due schede PCI-DSLink dei due tipi analizzati, attraverso una rete di switch STC104 comunque complessa; Z_misure, INFN_misure: realizzano trasmissioni di messaggi tra due schede PCIDSLink del tipo “Zeuthen” ed “INFN” attraverso una rete di C104 comunque complessa, per effettuare misure dei tempi di comunicazione, mediante il Round Trip Time. Questa tecnica prevede che i pacchetti vengano inviati dalla sorgente alla destinazione che, a sua volta, li rispedisce al mittente. Il tempo di comunicazione viene chiaramente diviso per due. In questo modo non vi è la necessità di sincronizzare i due host per effettuare le misure4. Figura 4.3: Tecnica di misura “Round Trip Time”. 4 La sincronizzazione tra due host prevede che vi sia un segnale ulteriore (oltre ai dati) che viaggi tra loro, ad esempio attraverso la rete locale Ethernet. Come vedremo però, per effettuare le misure di velocità, vengono inibiti tutti i servizi non necessari che il S.O. Linux offre (tra cui quelli di rete). Questo per far si che la misura non venga alterata in modo rilevante dalla schedulazione [13] di questi processi. ZloopC104, INFNloopC104: effettuano trasmissioni e ricezioni di pacchetti mediante un’unica scheda PCI-DSLink attraverso une rete comunque complessa di C104. Z_misure_dati: permette di fare delle misure e di salvare su file i risultati. INFNlinklink: trasmissione e ricezione di pacchetti mediante i due link delle schede “PCI-DSLink INFN”, attraverso una rete comunque complessa di C104. Le istruzioni che si utilizzano per leggere e scrivere all’interno dei registri degli STC101 sono le istruzioni di input/output (presenti nella libreria io del linguaggio C) le quali permettono operazioni di lettura e scrittura ad 8, 16 e 32 bit. Queste accedono direttamente nello spazio di I/O del sistema (PC) all’indirizzo specificato da un parametro di input, e vengono utilizzate sia per inizializzare gli STC101 sia per leggere e scrivere i dati sulle FIFO delle schede. Ciò che segue è un esempio della programmazione del registro LinkCommand nel quale si impone il reset del C101: outw(RESET_LINK, c101_or_pld|LINK_COMMAND) Il primo valore rappresenta il dato da scrivere all’interno del registro, mentre il secondo campo dell’istruzione contiene l’indirizzo del registro. Quest’ultimo è costituito dalla somma di due termini: il primo (c101_or_pld) è l’indirizzo base dei dispositivi contenuti all’interno della scheda, il secondo (LINK_COMMAND) è lo sfasamento (offset) che deve essere aggiunto all’indirizzo base per identificare il registro in esame. Si noti che le costanti vengono sempre scritte con lettere maiuscole, ed i loro valori sono riportati in un file di testo denominato dslink.h. Come detto precedentemente, gli STC101 hanno dei registri per controllare, tra le altre cose, lo stato di occupazione delle Rx e Tx FIFO. Le operazioni di I/O possono così essere eseguite senza effettuare i controlli su queste memorie oppure effettuando gli stessi. Chiaramente nel primo caso non si ha il ritardo dovuto alle istruzioni di lettura dei registri di controllo, e le comunicazioni sono più rapide. Per contro però, se avvengono degli errori sui link e dei pacchetti vengono scaricati (DiscardOnError) le istruzioni di read rimangono indefinitamente in attesa di un dato in ingresso, bloccando il sistema. E’ questa una situazione non accettabile, soprattutto in un sistema complesso quale quello dell’esperimento finale. Inoltre è chiaro che le latenze introdotte dai controlli dipendono, oltre che dal tipo di test, anche dalla macchina che si utilizza. Nel capitolo successivo verranno effettuate delle misure “con controlli” e “senza controlli”. Le memorie FIFO in ricezione, oltre a permettere delle comunicazioni asincrone, sono utili per conoscere la lunghezza dei pacchetti in input. Infatti, nel registro RxPacketLength del C101, la lunghezza del pacchetto/messaggio in arrivo viene memorizzata soltanto quando nella FIFO è presente un token EOP/EOM. Avere una memoria FIFO profonda almeno quanto le dimensioni dei pacchetti al suo ingresso permette di conoscere la lunghezza di questi ultimi prima di quanto non sia possibile in assenza delle memorie. Questo avviene perchè i terminatori EOP/EOM hanno spazio a sufficienza per essere ricevuti ancor prima di iniziare a leggere i dati. Per mostrare la sostanziale differenza degli algoritmi di ricezione nel caso in cui i pacchetti abbiano una lunghezza maggiore e minore della RxFIFO, nella figura 4.4 vengono riportati i diagrammi di flusso relativi alle due situazioni: Figura 4.4: Differenze nell’algoritmo di ricezione pacchetti al variare delle lunghezza delle memorie FIFO presenti sulle schede PCI-DSLink. Nel primo caso (RxFIFO insufficiente) si deve eseguire un test sulla presenza della lunghezza del pacchetto ad ogni data byte ricevuto, nel secondo invece le sue dimensioni vengono lette immediatamente, prima di acquisire il primo byte di dato. Per questo motivo nel caso in cui si utilizzino le memorie FIFO addizionali, le comunicazioni risultano più veloci. Un altro vantaggio delle memorie opzionali (presenti sulle schede “PCI-DSLink Zeuthen”) è costituito dal fatto che un unico dispositivo di ingresso può leggere un pacchetto e contemporaneamente memorizzarne degli altri nelle FIFO, liberando così in anticipo i link della rete interessati dalla comunicazione. Tutti questi fattori, uniti all’accesso limitato a 16 bit del bus PCI, sono responsabili delle limitate prestazioni delle schede “PCI-DSLink INFN” rispetto alle analoghe schede prodotte a Zeuthen. La lettura della lunghezza del pacchetto in arrivo viene eseguita sul registro del C101 denominato RxPacketLength, attraverso l’istruzione della figura 4.5: /* Lunghezza del pacchetto in ricezione */ numbyte = inw(c101_or_pld|RX_PACKET_LENGTH); Figura 4.5: Lettura della lunghezza del pacchetto in arrivo. Il menù principale del programma che effettua le misure con la tecnica del round trip time si presenta come in figura 4.6: ************************************** * IEEE 1355 PACKET SENDER - RECEIVER * ************************************** PERSONAL COMPUTER NAME : java DESTINATION LINK NUMBER: 16 <1> Change destination link <2> Transmit --> Receive <3> Receive --> Transmit <4> Exit program Select a number <1...4> Figura 4.6: Menù principale del programma per la misura delle velocità di comunicazione tramite schede PCI-DSLink. Mediante la scelta <1> si può modificare il link di destinazione (testa dei pacchetti in partenza), mentre con le altre due opzioni si entra nelle procedure di trasmissione/ricezione (trasmric) e ricezione/trasmissione (rictrasm). Dopo aver eseguito la prima delle due, viene chiamata automaticamente la subroutine rate di calcolo dei tempi e delle velocità di comunicazione (appendice C). 4.2.2.1 Misura dei tempi e calcolo delle velocità. Linux, essendo un S.O. multitasking, permette l’attivazione contemporanea di più processi (task). Inoltre, essendo anche multiutente, è in grado di gestire più “accessi” contemporanei. La configurazione standard da me installata prevede l’attivazione, per default, di alcuni processi aggiuntivi (oltre a quelli fondamentali) quali ad esempio il gestore della rete LAN oppure lo httpd ovvero il gestore della rete Word Wide Web (WWW). Questi processi vengono eseguiti dal S.O. tramite lo scheduler [13] ad ogni prefissato intervallo di tempo macchina. Per non far condizionare le misure temporali dalle interruzioni dello scheduler di sistema, i tempi sono stati calcolati disattivando tutti i processi non strettamente necessari alle comunicazioni DSLink, ed effettuando il caricamento del S.O. in modalità “singolo utente”. Gli unici task lasciati attivi sono: il kerneld, “cuore” del S.O., in assenza del quale non si può effettuare alcuna operazione; il processo di inizializzazione del sistema (init), padre di tutti i processi; il processo di gestione dell’area di swap (kswapd); la shell (sh) per impartire i comandi da tastiera e visualizzare i risultati. In questo modo, mentre vengono eseguite le misure, non si hanno a disposizione i servizi della rete locale Ethernet; ma, grazie alla tecnica del Round Trip Time, questi non sono necessari. Con questa premessa le interruzioni che intervengono durante le comunicazioni sono ridotte al minimo. Nei sistemi dotati di processore Pentium e PentiumPro Intel si hanno a disposizione due strumenti di misura differenti. Il primo utilizza delle funzioni incluse in una libreria (time.h), ha una precisione dell’ordine del µs, e viene utilizzato soltanto per generare dei cicli di ritardo. Il secondo sfrutta invece il Time Stamp Counter (TSC [25]). Quest’ultimo è un registro a 64 bit dei processori Pentium il cui contenuto viene incrementato di una unità ad ogni ciclo del clock di sistema, a partire dall’ultimo reset di sistema. La precisione raggiungibile con quest’ultima tecnica di misura dipende dalla frequenza del clock, e nei PC a mia disposizione è dell’ordine di 10 ns (∆t = 10 ns @ frequenza_clock = 100 MHz). La lettura del TSC avviene tramite una chiamata assembler, e la latenza di questa lettura impegna un certo numero di impulsi di clock, dipendenti anch’essi dalla macchina. Le misure effettuate tramite il TSC offrono, oltre ad una precisione maggiore, una migliore affidabilità. Infatti l’incremento del registro TSC avviene indipendentemente dal software che si sta scrivendo; se ad esempio con una istruzione sprovvista di controllo in ricezione si legge una porta di I/O nella quale non ci sono dati, il sistema rimane bloccato fino all’arrivo del byte successivo, e nel frattempo non è possibile effettuare nessuna ulteriore operazione. In questa situazione tutti i processi sono fermi, compresi quelli relativi alla misura del tempo. Il TSC invece, essendo un componente hardware, continua a contare. I valori che si considerano per le misure temporali vengono calcolati effettuando una media su un elevato numero di campioni (n = 5000) mentre per l’indeterminazione si considera la stima della deviazione standard: (t − t ) 2 t= ti ∆t = i n i i n −1 E’ stato assegnato alle misure un errore statistico (e non massimo) perchè la precisione del TSC è tale che ripetendo molte volte le misure si ottengono risultati differenti. Il calcolo della velocità viene effettuato dividendo il numero di byte trasferiti per il tempo medio, mentre per l’incertezza su di essa viene utilizzata la formula di propagazione degli errori statistici: N V= b t 2 ( )= ƒV 2 ƒV ∆V = √ ?( ∆N b) + √ ? ∆t √ ƒN b ↵ ƒt ↵ 2 2 ( )=N ƒV √ ? ∆t ƒt ↵ 2 2 t b 2 ?∆t con Nb pari al numero di byte costituenti i pacchetti. Nel paragrafo precedente è stato specificato come i PC utilizzati non operino alcun algoritmo sui dati, eccetto quelli strettamente inerenti le operazioni di I/O su DS-Link. Anche se il lavoro svolto non riguarda la valutazione delle prestazioni delle unità di calcolo, nel capitolo successivo verranno eseguite delle misure con i processi di gestione della rete Ethernet attivi. Questo per valutare in che modo, nel caso particolare del S.O. Linux, la gestione concorrente delle risorse del sistema influisce sulle velocità di comunicazione del protocollo IEEE 1355. Capitolo 5 Risultati Sperimentali. Nel seguente capitolo vengono riportati i risultati sperimentali che sono stati ottenuti effettuando delle misure mediante lo hardware descritto ed il software sviluppato. Le caratteristiche dei PC utilizzati sono state precedentemente riassunte nel paragrafo 4.1.5, così come quelle delle schede PCI-DSLink. Lo strumento di misura è il TSC (paragrafo 4.2.2.1) ed tempi di trasmissione vengono calcolati inviando 5000 pacchetti tra due PC e facendo la media dei tempi che si ottengono. Viene inoltre utilizzata la tecnica Round Trip Time (paragrafo 4.2.2): quando un pacchetto arriva a destinazione viene salvato in un vettore e rispedito al mittente, senza operare su esso ulteriori elaborazioni. Dal momento che le variabili che intervengono nel sistema di misura complessivo sono svariate (diverse schede di interfaccia, diversi PC, presenza o meno dei C104 ecc…), le condizioni nelle quali vengono calcolati i tempi sono specificate di volta in volta. Le misure effettuate si suddividono in: • Misura della velocità delle schede di interfaccia (calcolo sperimentale delle loro prestazioni). Sono effettuate senza interporre tra le schede PCI-DSLink dei due tipi nessuno switch STC104, e vengono ripetute sia attivando i controlli software sui pacchetti che si trasmettono e ricevono, sia inibendo gli stessi (paragrafi 5.1.1 e 5.1.2). • Misura dei tempi necessari per completare alcune istruzioni di I/O (paragrafo 5.1.3). • Misura dei tempi di comunicazione quando sui PC utilizzati sono attivi altri processi del S.O. oltre a quelli di I/O, come ad esempio il processo che gestisce la rete locale Ethernet (paragrafo 5.1.4). • Misura della latenza dello switch STC104 (paragrafo 5.2). In particolare vengono calcolati i tempi necessari a pacchetti di varia lunghezza per attraversare lo switch (tempi di routing). 99 • Misure inerenti sia il contest switch (paragrafo 5.3), sia gli altri algoritmi di instradamento descritti nel capitolo 2. Molti dei risultati quantitativi che si ottengono nei paragrafi che seguono, vengono utilizzati per fare delle considerazioni qualitative sul protocollo IEEE 1355, sulle modalità di interconnessione degli switch, su alcuni degli algoritmi di instradamento dei pacchetti e sul trigger di 2° livello di ATLAS. Sarebbero infatti necessarie delle risorse hardware più consistenti per ottenere dei valori paragonabili a quelli che si hanno nel corso della presa dati. Si deve inoltre tener conto che, in tutte le misure fatte non viene mai considerato il ritardo che introducono i cavi DSLink utilizzati per connettere tra loro le schede di interfaccia e lo switch. Ciò in quanto questo ritardo non può essere apprezzato dallo strumento di misura a disposizione (TSC). La prova di questa affermazione è data dal fatto che, lasciando inalterate tutte le altre variabili del sistema, sono state eseguite delle misure temporali variando la lunghezza dei cavi da ~20 cm a ~200 cm, senza rilevare alcuna variazione sui tempi. 5.1 Misura della velocità delle schede di interfaccia. 5.1.1 Misure in assenza di controlli software. La prima misura eseguita riguarda le velocità di comunicazione che si possono raggiungere mediante le schede “PCI-DSLink Zeuthen” e “PCI-DSLink INFN” collocate all’interno dei PC a disposizione. I valori teorici delle prestazioni del protocollo DSLink calcolati nel capitolo 2, sono da ritenersi dei valori limite. Nel caso pratico infatti, come vedremo nei paragrafi successivi, sulle velocità di comunicazione influiscono negativamente sia gli accoppiamenti che vi sono tra le interfacce PCI-DSLink ed il bus PCI dei PC (appendice B), sia la latenza delle istruzioni di I/O. Per calcolare la banda passante delle schede PCI-DSLink, sono stati inviati dei pacchetti tra due host rispettando le seguenti condizioni: 100 • i due PC nei quali sono installate le interfacce sono JAVA e PCAPE, con le caratteristiche riportate nel paragrafo 4.1.5. I tempi vengono presi sul primo di essi (JAVA); • lo header dei pacchetti è lungo 2 byte, mentre la lunghezza dei pacchetti varia da 4 byte a 4 Kbyte; • tra le due schede PCI-DSLink non è stato interposto alcun C104; • le comunicazioni avvengono soltanto tra schede PCI-DSLink dello stesso tipo (Zeuthen o INFN); • i risultati sono stati ricavati non aggiungendo nessun controllo software, ma soltanto le istruzioni strettamente necessarie alle comunicazioni. In questo modo sono state ottenute le velocità massime raggiungibili mediante queste schede, con le condizioni al contorno specificate; • le potenzialità delle schede “PCI-DSLink INFN”, come ripetutamente detto, non vengono sfruttate se non in minima parte: per questa misura particolare viene utilizzato uno soltanto dei suoi due link. Come specificato nel paragrafo 4.1.4, la configurazione impostata su esse è limitante. Per questo motivo le velocità raggiunte sono inferiori a quelle ottenute con le schede “PCI-DSLink Zeuthen”; I risultati delle velocità di comunicazione in funzione della lunghezza dei pacchetti trasferiti, per le interfacce PCI-DSLink “Zeuthen” e “INFN”, vengono riportati nelle seguenti quattro figure: 101 Velocità (Mbyte/s) Schede "PCI-DSLink Zeuthen" percorso pacchetti: JAVA - PCAPE - JAVA 10 9 8 7 6 5 4 3 2 1 0 0 1000 2000 3000 4000 Lunghezza Pacchetti (byte) Figura 5.1a: Andamento della velocità di comunicazione tra due schede “PCI-DSLink Zeuthen” in funzione della lunghezza dei pacchetti trasferiti. Schede "PCI-DSLink Zeuthen" (ZOOM) percorso pacchetti: JAVA - PCAPE - JAVA Velocità (Mbyte/s) 7 6 5 4 3 2 1 0 0 20 40 60 Lunghezza Pacchetti (byte) Figura 5.1b: Andamento della velocità di comunicazione tra due schede “PCIDSLink Zeuthen” in funzione della lunghezza dei pacchetti trasferiti (ZOOM). 102 Schede "PCI-DSLink INFN" percorso pacchetti: JAVA - PCAPE - JAVA Velocità (Mbyte/s) 2.5 2 1.5 1 0.5 0 0 1000 2000 3000 4000 Lunghezza pacchetti (byte) Figura 5.2a: Andamento della velocità di comunicazione tra due schede “PCIDSLink INFN” in funzione della lunghezza dei pacchetti trasferiti. Schede "PCI-DSLink INFN" (ZOOM) percorso pacchetti: JAVA - PCAPE - JAVA Velocità (Mbyte/s) 2 1.5 1 0.5 0 0 20 40 60 80 Lunghezza pacchetti (byte) Figura 5.2b: Andamento della velocità di comunicazione tra due schede “PCIDSLink INFN” in funzione della lunghezza dei pacchetti trasferiti (ZOOM). 103 Ricordo che le operazioni di I/O sulle schede INFN sono eseguite con istruzioni a 16 bit, e che su di esse sono accessibili soltanto i registri dei C101. Ciò comporta le minori velocità di queste ultime schede rispetto a quelle di Zeuthen; anche variando i PC che alloggiano le schede non si ottengono risultati migliori. Infatti si hanno circa le stesse velocità con e senza le istruzioni di controllo (paragrafo 5.1.2) e per pacchetti lunghi 256 byte si è già al limite raggiungibile (con questa configurazione) di ~2 Mbyte/s. Analizziamo i risultati relativi alle schede progettate a Zeuthen. I valori sperimentali delle velocità di comunicazione ottenuti per esse si discostano dai valori teorici riportati nei capitoli precedenti per diversi motivi. Primo fra tutti si deve considerare il fatto che c’è un accoppiamento tra le varie componenti hardware dei sistemi, in particolare tra i chip di bridge (appendice B) ed il C101. Poi, dopo ogni pacchetto ricevuto, tramite il registro RxAcknowledge si deve effettuare un reset dei flag del registro RxInterruptStatus, in modo che quest’ultimo sia utilizzabile nella ricezione successiva. In trasmissione invece, prima di inviare un pacchetto, si deve abilitare la comunicazione scrivendo nel registro TxSendPacket indicazioni riguardanti la sua testa ed il tipo di terminatore aggiunto (paragrafo 5.1.3 – appendice D). In sostanza le operazioni di I/O, unite allo hardware (PC + schede di interfaccia), non riescono a raggiungere la banda passante del canale DSLink, ovvero non sono in grado di presentare i dati sulle porte di uscita (e di prelevarli) ad una velocità di 100 Mbit/s. In tutte le curve tracciate nelle figure precedenti, si può notare che le velocità di comunicazione crescono all’aumentare delle dimensioni dei pacchetti. Questo avviene sia perchè al decrescere di queste ultime lo overhead del protocollo diviene più pesante (il rapporto tra i bit aggiunti dallo IEEE 1355 e i bit di dato aumenta al diminuire della lunghezza dei pacchetti), sia perchè l’istruzione di acknowledge in ricezione e l’impostazione del registro TxSendPacket in trasmissione hanno un peso maggiore (paragrafo 5.1.3). D’altro canto le dimensioni dei pacchetti non possono essere incrementate a piacere, altrimenti si finisce per ritardare eccessivamente l’instradamento degli altri messaggi in transito sugli stessi link fisici (problema del contest switch – paragrafo 5.3). 104 La teoria del VCP (paragrafo 2.1.1) ipotizza che, nelle comunicazioni con i dispositivi DSLink, una dimensione di 32 byte per i pacchetti è un buon compromesso tra velocità di comunicazione e contesa sui link. Ma dai calcoli teorici svolti nel capitolo 2 è stata ottenuta, nel caso unidirezionale e per pacchetti di lunghezza pari a 32 byte (in assenza di contesa), una velocità pari a ~9.20 Mbyte/s. Sperimentalmente, nella stessa situazione, si ottengono invece velocità dell’ordine di 5 Mbyte/s; solo con pacchetti lunghi più di 1 Kbyte si raggiungono i valori teorici. Questa discrepanza non è causata dallo overhead del protocollo, considerato anche nella parte teorica, ma dalle componenti del sistema (PC, interfacce, software…). E’ evidente quindi che, se si vuole implementare il VCP, ovvero se si vogliono inviare pacchetti lunghi al più 32 byte, per la gestione dei messaggi la soluzione software non fornisce risultati accettabili, almeno con le macchine attualmente a disposizione. Nell’esperimento ATLAS la soluzione migliore potrebbe essere quindi quella di far eseguire queste ultime da un hardware aggiuntivo, in grado di gestire i messaggi e preparare i dati per le elaborazioni del sistema di trigger. In teoria anche alcuni degli algoritmi di ricostruzione degli eventi potrebbero essere eseguiti utilizzando, ad esempio, delle logiche programmabili. Le schede “PCI-DSLink INFN”, essendo provviste di una FPGA, sono state progettate per soddisfare anche queste necessità. Se ora viene sostituito uno dei due PC (PCAPE) che contengono le schede “PCI-DSLink Zeuthen” con PCMRZ1 (paragrafo 4.1.5) e si ripetono le misure appena eseguite, si ha una stima della influenza che i due diversi sistemi (PCMRZ1 e PCAPE, il PC sostituito) hanno sulle velocità di comunicazione. Sia PCMRZ1 la sorgente dei pacchetti e JAVA il mirror (colui che riceve e rispedisce al mittente); i risultati che si ottengono lasciando inalterate tutte le altre condizioni del sistema di misura, vengono riportati nella figura 5.3: 105 Schede "PCI-DSLink Zeuthen" percorso pacchetti: PCMRZ1 - JAVA - PCMRZ1 Velocità (Mbyte/s) 7 6 5 4 3 2 1 0 0 1000 2000 3000 4000 Lunghezza pacchetti (byte) Figura 5.3: Andamento della velocità di comunicazione tra due schede “PCIDSLink Zeuthen” in funzione della lunghezza dei pacchetti trasferiti tra PCMRZ1 E JAVA. Si noti che, variando un solo PC, si passa da una velocità massima di ~9.18 Mbyte/s del caso precedente (figura 5.1a) a ~6.31 Mbyte/s. La perdita di quasi 3 Mbyte/s nella banda passante evidenzia quanto sia importante il sistema nel quale vengono alloggiate le schede di interfaccia. In particolare, oltre alla potenza di calcolo del processore ed alla quantità di memoria installata, ha un peso notevole l’efficienza della gestione del bus PCI. Infatti tra PCAPE e PCMRZ1 la differenza nei clock di sistema è del 10% (da 90 a 100 MHz) ed anche gli altri parametri sono paragonabili. Ciò che cambia è il chip di bridge del bus PCI [tabella 4.2 - appendice B]: PCMRZ1 è uno dei primi PC su cui è stato introdotto questo bus di I/O e la sua efficienza non è pari a quella del bus di PCAPE1. Rimanendo nell’ambito del bus dei PC, vediamo ora come variano le velocità di comunicazione quando gli accessi al PCI vengono fatti con scritture e letture a 8 e 16 bit. Nella tabella 5.1 si riportano i risultati ottenuti facendo comunicare tra loro i due link di una delle schede “PCI-DSLink INFN”, alloggiata su PCATL2 (paragrafo 4.1.5). La lunghezza dei pacchetti è di 64 byte in quanto le FIFO di trasmissione e ricezione presenti nella interfaccia (64+64 byte) non consentono di impostare valori superiori: 1 I chip di bridge della prima generazione presentano alcuni problemi. 106 Accesso al bus (n° bit) V ± ∆V (Mbyte/s) 8 0.83 ± 0.08 16 1.55 ± 0.15 Tabella 5.1: Differenze nella velocità di comunicazione per accessi al bus PCI ad 8 e 16 bit, con lunghezza dei pacchetti pari a 64 byte. Essendo identica la quantità di informazione scambiata, è evidente il miglioramento delle prestazioni che si ottiene aumentando il numero di bit delle istruzioni di I/O: per scrivere 2 byte su una porta di uscita nei due casi proposti sono necessarie rispettivamente due ed una istruzione di output. La stessa considerazione vale in fase di lettura. Salvo esplicito avvertimento, nel seguito le misure che richiedono soltanto due delle quattro schede di interfaccia verranno effettuate mediante le schede “PCIDSLink Zeuthen”, le più performanti, installate sui computer JAVA e PCAPE. 5.1.2 Misure con controlli software attivi. Analizziamo ora come variano le velocità di comunicazione quando vengono aggiunti dei controlli software in ricezione e in trasmissione. Ricordo che si parla di controllo in ricezione quando, prima di leggere un pacchetto, si effettua un test sui registri della scheda per accertarsi che esso sia effettivamente presente nella FIFO di ricezione (figura 5.4a): /* Controllo in ricezione */ do { } while(!inw(c101_or_pld|ISR)&HEADER_VALID); Figura 5.4a: Istruzioni per il controllo in ricezione per le schede “PCI-DSLink Zeuthen”. Il controllo in trasmissione consiste invece nello scrivere un pacchetto soltanto se la TxFIFO non è piena (figura 5.4b); 107 /* Controllo in trasmissione */ do { } while(inw(c101_or_pld|TX_INTERRUPT_STATUS)&TX_FIFO); Figura 5.4b: Istruzioni per il controllo in trasmissione per le schede “PCI-DSLink Zeuthen”. Se, in assenza di controlli, si scrivono dei dati quando la TxFIFO è piena o si leggono quando la RxFIFO è vuota, ovvero se si eseguono delle istruzioni di I/O nelle FIFO quando queste non sono disponibili per ricevere o fornire dati, il sistema rimane bloccato rispettivamente fino alla trasmissione o all’arrivo di una double word (4 byte)2. L’unico modo per uscire da una situazione del genere è quello di fare un reset del sistema. Diversamente, quando si introducono i controlli, la lettura (o scrittura) sulle FIFO avviene soltanto nel caso in cui vi sia un dato (o spazio per un dato). In questo modo si può stabilire un tempo limite oltre il quale l’istruzione di I/O non deve essere più eseguita3. Nel caso in cui vengano attivati entrambi i controlli, per le velocità di comunicazione si ottengono i risultati della figura 5.5: 2 3 Questo perchè gli accessi al bus vengono fatti a 32 bit. Una attesa indeterminata dei dati non ha senso in quanto, in caso di errore, un pacchetto potrebbe essere scaricato lungo il percorso perchè uno dei suoi link di transito è disconnesso (paragrafo 4.2.1). 108 Velocità (Mbyte/s) Schede "PCI-DSLink Zeuthen" percorso pacchetti: JAVA - PCAPE - JAVA 10 9 8 7 6 5 4 3 2 1 0 0 1000 2000 3000 4000 Lunghezza Pacchetti (byte) Figura 5.5: Andamento della velocità di comunicazione tra due schede “PCI-DSLink Zeuthen” in funzione della lunghezza dei pacchetti, con controlli in trasmissione e ricezione attivi. Confrontando la curva dell’ultimo grafico con quella analoga ottenuta in assenza di controlli e riportata nella figura 5.1a, si nota come la diminuzione delle prestazioni causata dall’introduzione di questi ultimi sia minima. Si passa infatti da ~9.18 Mbyte/s a ~9.16 Mbyte/s (per pacchetti lunghi 4096 byte). Le istruzioni aggiunte non introducono dei ritardi rilevanti nelle comunicazioni in quanto vengono eseguite prima della trasmissione o ricezione di un intero pacchetto e non della singola parola a 32 bit. Queste istruzioni effettuano dei controlli minimali sui messaggi, ma esistono degli altri test che possono essere fatti utilizzando i registri presenti sul C101. Ad esempio prima di trasmettere o ricevere un dato si potrebbe effettuare un controllo sullo stato del link (bit LinkError del registro RxInterruptStatus), oppure prima di leggere un pacchetto si potrebbe vedere se la lunghezza della sua testa è corretta (bit ShortPkt dello stesso registro). Comunque l’eccellente affidabilità (paragrafo 5.4) fornita dai dispositivi DSLink mi ha consentito di fare tutte le misure senza la necessità di aggiungere ulteriori controlli, permettendomi così di far lavorare le schede alla massima velocità di comunicazione raggiungibile. 109 I test sulle comunicazioni che si eseguono nella presa dati dell’esperimento sono il risultato di un compromesso tra la latenza dei vari livelli di trigger ed il grado di affidabilità che si vuole raggiungere. L’entità di questi controlli nonchè il loro numero dipende inoltre dall’architettura finale del sistema di trigger, ma soprattutto dai dispositivi hardware utilizzati. Nel caso specifico tutte le misure successive vengono eseguite con l’aggiunta delle istruzioni delle figure 5.4a e 5.4b. 5.1.3 Misura della latenza delle istruzioni di I/O. In questo paragrafo si vogliono effettuare delle misure riguardanti le istruzioni di I/O al fine di identificare una delle cause della eccessiva diminuzione delle velocità di comunicazione che si riscontra al decrescere della lunghezza dei pacchetti. A tal fine analizziamo le istruzioni del linguaggio C di scrittura e lettura dei pacchetti su DSLink. Il protocollo IEEE 1355 richiede che, prima di scrivere un pacchetto sulla coda di uscita, si debba effettuare una scrittura sul registro TxSendPacket del C101 (appendice D). Con questa istruzione (figura 5.6a) l’interfaccia è configurata in modo che: • ad ogni pacchetto (o messaggio) viene aggiunto (TERMINATOR_ENABLE) ed una testa (HEADER_ENABLE); • il tipo di terminatore da mettere in coda ai dati è del tipo EOP (EOP_TERMINATOR); • il registro del C101 contenente la testa del pacchetto è TxHeaderLength_0 (HEADER_SELECT_0). un terminatore Con la variabile numbyte si imposta invece sul C101 la lunghezza, in byte, del pacchetto in trasmissione. Nella figura 5.6a vengono riportate le istruzioni necessarie per inviare un pacchetto nella TxFIFO di una scheda PCI-DSLink, in assenza di controlli: 110 /* Abilitazione TX SEND PACKET */ outw(TERMINATOR_ENABLE|EOP_TERMINATOR|HEADER_ENABLE| HEADER_SELECT_0|numbyte,c101_or_pld|TX_SEND_PACKET); /* Trasmissione pacchetto */ for (j=0; j<(numbyte/4); j++) outl(VettorePartenza[j], address); Figura 5.6a: Istruzioni di scrittura di un pacchetto sulla TxFIFO delle schede PCIDSLink. Dopo la ricezione di ogni pacchetto si deve invece effettuare una scrittura nel registro RxAcknowledge al fine di fare il reset dei bit del registro RxInterruptStatus (paragrafo 2.3). Questa operazione permette di preparare il C101 alla ricezione successiva: nel caso in cui questo non venga fatto, il pacchetto che segue non viene ricevuto correttamente. Ad esempio, facendo il reset del bit RX_FIFO_LEVEL si può sapere se i dati che si ricevono stanno saturando o meno la coda di ricezione, oppure, mediante il bit HdrValid si hanno indicazioni sulla corretta ricezione della testa di un pacchetto [28]. Le operazioni necessarie per ricevere un pacchetto sono le seguenti: /* Ricezione */ for (j=0; j<(numbyte/4); j++) VettoreArrivo[j] = inl(address); /* Acknowledge dopo la ricezione */ outw(ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID |RX_FIFO_LEVEL, c101_or_pld|RX_ACKNOWLEDGE); Figura 5.6b: Istruzioni di lettura di un pacchetto sulla RxFIFO delle schede PCIDSLink. Consideriamo ora l’operazione di scrittura dei pacchetti (figura 5.6a) su una delle schede “PCI-DSLink Zeuthen” installata sul PC JAVA. Il tempo necessario per effettuare le impostazioni sul registro TxSendPacket è di ~265 ns (prima istruzione della figura 5.6a), mentre la latenza di una istruzione di scrittura sulla FIFO di trasmissione, per un pacchetto di 4 byte è di ~566 ns4 (ciclo for della stessa figura). In 4 Ciò che si sta misurando in questo paragrafo sono i tempi necessari per completare le istruzioni di I/O e non la latenza della scrittura di un pacchetto sulla porta di uscita del C101. Infatti la lettura del 111 questa situazione, se si spedisce un pacchetto da 4 byte effettuando tutte le istruzioni della figura 5.6a, la banda passante dell’intera operazione di output, misurata sperimentalmente, vale ~4.2 Mbyte/s. Se nella stessa situazione si prendono i tempi immediatamente dopo l’istruzione di abilitazione del registro TxSendPacket, ovvero se si esclude dal calcolo della velocità la latenza introdotta da questa operazione, si arriva ad una banda passante di ~6.1 Mbyte/s. Dal momento che la prima delle due operazioni viene eseguita per ogni pacchetto inviato, e la sua latenza non dipende dalla dimensione dello stesso, all’aumentare delle dimensioni dei pacchetti essa ha meno influenza sulla banda passante totale. Calcolando infatti la velocità della scrittura per pacchetti di dimensioni pari a 1024 byte, ed includendo anche l’impostazione del registro TxSendPacket, il valore che si ottiene è ~13.5 Mbyte/s, ovvero si forniscono in uscita dei byte ad una velocità superiore a quella del DSLink (12.5 Mbyte/s). Quindi, quando i pacchetti sono molto piccoli, la latenza introdotta dalla istruzione per la corretta impostazione dei registri del C101 contribuisce alla diminuzione delle velocità di comunicazione. Per pacchetti di grandi dimensioni invece ciò non costituisce un limite. Delle considerazioni analoghe valgono nel caso delle operazioni di input (figura 5.6b). Nelle istruzioni di impostazione del C101 presenti nelle due figure precedenti, i dati vengono calcolati effettuando degli OR bit a bit di alcuni valori costanti (appendice D). Un miglioramento delle prestazioni per pacchetti di piccole dimensioni si può ottenere calcolando sia i dati da scrivere, sia gli indirizzi di destinazione, non all’interno della istruzione outw ma prima, in modo da fornire a quest’ultimo un valore costante. La banda passante che si ottiene per la scrittura di 4 byte è in questo caso pari a ~4.5 Mbyte/s (non si raggiunge ancora la velocità di 100 Mbit/s). Per contro però in questo modo non si possono modificare le informazioni di routing da un pacchetto ad un altro, e le comunicazioni sono meno flessibili (la lunghezza dei pacchetti è fissa, la testa ed il terminatore sono identici per tutti, ecc…). TSC avviene immediatamente prima e subito dopo le istruzioni esaminate nelle figure 5.6a e 5.6b, e non avvengono quindi comunicazioni DSLink. 112 5.1.4 Misure con “molti” processi attivi su PC. Nel seguente paragrafo si vuole misurare l’andamento della velocità delle schede di interfaccia progettate a Zeuthen, quando sul PC sono presenti altri processi di Linux. In particolare vengono attivati i servizi della rete locale Ethernet e WWW (ftpd, telnetd, inetd, httpd), la gestione della multiutenza (syslogd) ed altri servizi vari (tty, lpd…). Le velocità che si raggiungono per le schede “PCI-DSlink Zeuthen” in assenza dei processi elencati, sono quelle ottenute in precedenza in questo stesso paragrafo e riportate nella figura 5.5. Quando vengono aggiunti questi ulteriori task, le velocità di comunicazione diminuiscono leggermente poichè, oltre ad eseguire il programma di comunicazione su DSLink, lo scheduler [13] di Linux deve attivare, ad intervalli di tempo che dipendono dal singolo processo, anche gli altri processi di sistema. Chiaramente più grandi sono le dimensioni dei pacchetti, maggiore è la probabilità che la loro trasmissione venga momentaneamente interrotta a favore di altri task. Per osservare le differenze che si hanno quando vi sono molti processi attivi, nelle figure 5.7a e 5.7b si riportano le distribuzioni dei tempi di comunicazione ottenuti mediante le schede “PCI-DSLink Zeuthen”, in presenza dei soli processi definiti indispensabili per i PC (capitolo 4), ed in presenza di tutti gli altri processi menzionati. 113 Histogram (SI512.STA 1v*4917c) Frequenze dei tempi di comunicazione tra due schede "PCI-DSLink Zeuthen" in presenza dei soli processi indispensabili su PC lunghezza pacchetti: 512 byte 3888 3645 3402 3159 2916 2673 2430 2187 1944 1701 1458 1215 972 numero dei conteggi 729 486 243 0 18575 18585 18580 18595 18590 18605 18600 18615 18610 18625 18620 18635 18630 18645 18640 18655 18650 18665 18660 18675 18670 numero di cicli di clock da 166 MHz Figura 5.7a: Istogramma relativo ai tempi di comunicazione tra due schede “PCIDSLink Zeuthen” con la sola presenza dei processi “indispensabili” del S.O. Histogram (CONTR512.STA 1v*4916c) Frequenze dei tempi di comunicazione tra due schede "PCI-DSLink Zeuthen" in presenza di ulteriori processi attivi sui PC. lunghezza pacchetti: 512 byte 3495 3262 3029 2796 2563 2330 2097 1864 1631 1398 1165 932 numero dei conteggi 699 466 233 0 18576 18592 18609 18625 18642 18658 18674 18691 18707 18724 18740 18584 18601 18617 18633 18650 18666 18683 18699 18715 18732 numero di cicli di clock da 166 MHz Figura 5.7b: Istogramma relativo ai tempi di comunicazione tra due schede “PCIDSLink Zeuthen” con la presenza di “molti” processi del S.O. 114 Entrambe le figure si riferiscono a lunghezze dei pacchetti pari a 512 byte e dal loro confronto emerge che, quando vi sono più operazioni che il S.O. deve eseguire, il tempo di comunicazione medio cresce ed i valori delle singole misure (ti ) hanno una variabilità più elevata. Infatti si nota come in entrambe le figure sia presente la distribuzione, che chiamerò principale, costituita dalle colonne comprese nel range degli impulsi di clock fino a 18658. Questa corrisponde ai casi in cui i processi aggiuntivi non interrompono le comunicazioni in corso. Nella figura 5.7b si nota invece una “coda”, costituita da tempi di comunicazione superiori rispetto al valor medio della distribuzione principale. Anche se non sono molto pronunciate, le colonne formate da questi tempi mostrano chiaramente come la trasmissione di alcuni pacchetti sia in concorrenza con altre operazioni del S.O. Nel trigger di 2° livello di ATLAS è fondamentale conoscere entro quale tempo, in media, un pacchetto viene instradato attraverso lo switch. Oltre alle latenze dovute alla contesa dei link, e da tutte le altre variabili legate al protocollo di comunicazione, si deve quindi fare una stima del ritardo introdotto dalla rete tenendo in considerazione, oltre agli algoritmi di ricostruzione degli eventi, anche tutti gli altri processi attivi sui singoli processori locali e globali. Ciò potrebbe però non essere sufficiente in quanto, anche se il tempo medio di routing attraverso la rete ha un valore accettabile (come nel caso dell’esempio), alcune volte i pacchetti impiegano un tempo molto elevato per giungere a destinazione, e si potrebbe avere una perdita dei dati. Questo viene evidenziato, nella figura 5.7b, dalla presenza di ulteriori conteggi dei tempi di comunicazione, i quali in alcuni casi superano di molto il valor medio ottenuto (si arriva a tempi di ~400 ns superiori alla media). Per risolvere questo problema, nel progetto reti complesse è preferibile fare una stima della probabilità che un pacchetto impieghi più di un prefissato intervallo di tempo per essere instradato. Mediante i numerosi parametri a disposizione in questi sistemi, si può poi minimizzare questa probabilità imponendo che essa sia inferiore ad una soglia prestabilita. 5.2 Misure inerenti la latenza dello switch STC104. 115 Si vuole ora ricavare sperimentalmente la latenza introdotta dallo switch elettronico STC104, ed i tempi necessari per il routing dei pacchetti attraverso esso. La tecnica di misura utilizzata prevede la comunicazione di una serie di pacchetti (5000), aventi 5 lunghezze differenti (4, 32, 512, 2048 e 4096 byte), attraverso un numero di switch variabile da 0 a 3. Si ricorda che la lunghezza della testa dei pacchetti e pari a 2 byte e che è attivo lo header deletion (paragrafo 2.2) sulle uscite dell’ultimo STC104 attraversato. I risultati che si ottengono nei vari casi vengono riportati nella tabella 5.2 ed esprimono il tempo necessario ad un pacchetto per transitare tra JAVA e PCAPE quando tra questi ultimi vengono interposti 0, 1, 2 e 3 switch. Lunghezza pacchetti (byte) t ± ∆t (µs) 0 4 32 512 2048 4096 3.57 ± 0.18 6.58 ± 0.27 56.15 ± 0.67 (21.48 ± 0.12) ⋅10 (42.58 ± 0.16) ⋅10 1 4 32 512 2048 4096 4.49 ± 0.22 7.49 ± 0.25 57.07 ± 0.65 (21.57 ± 0.12) ⋅10 (42.67 ± 0.16) ⋅10 2 4 32 512 2048 4096 5.40 ± 0.20 8.41 ± 0.23 57.99 ± 0.66 (21.66 ± 0.12) ⋅10 (42.77 ± 0.15) ⋅10 3 4 32 512 2048 4096 6.31 ± 0.20 9.31 ± 0.22 58.91 ± 0.65 ( 21.76 ± 0.12) ⋅10 (42.86 ± 0.15) ⋅10 Numero di STC104 Attraversati 116 Tabella 5.2: Tempi di transito dei pacchetti in funzione della loro lunghezza e del numero di C104 attraversati. 5.2.1 Misura della latenza del C104. A partire dai dati della tabella, per calcolare il valore sperimentale della latenza attraverso il singolo C104, si riportano in un grafico bidimensionale i tempi di comunicazione relativi ai pacchetti di 4 byte di lunghezza, in funzione del numero di C104 attraversati (figura 5.8): Latenza attraverso 0, 1, 2, 3 STC104 lunghezza pacchetti: 4 byte 7 Latenza (µ s) 6.5 6 5.5 5 4.5 4 3.5 3 2.5 -1 0 1 2 3 4 numero di STC104 attraversati Figura 5.8: Fit lineare per il calcolo della latenza del singolo C104. Effettuando un fit lineare, si ricavano i valori della pendenza delle due curve (t1 e t2 ). A questi ultimi si applica la semplice formula: t ± ∆t = t2 + t1 t2 − t1 ± 2 2 117 e si ottiene che la latenza del C104 è pari a: t ± ∆t = (0.91 ± 0.12) µs. Questo valore indica il tempo necessario affinchè un pacchetto di lunghezza qualsiasi, con due byte di testa, sia instradato attraverso lo switch. Le specifiche tecniche dello STC104 [29] riportano per quest’ultimo un valore <1 µs. Nel calcolo appena eseguito non sono stati presi in considerazione i valori temporali della tabella 5.2 relativi a pacchetti di dimensioni superiori a 4 byte. Ciò perchè, essendo le incertezze associate alle misure della latenza di tipo statistico, all’aumentare dei tempi di comunicazione gli errori diventano sempre più grandi (non in percentuale ma in senso assoluto)5. Fare la stima di una grandezza dell’ordine dei microsecondi (risultato precedente) con delle misure affette da errori confrontabili con questo valore, non ha molto senso. Nel mio caso particolare se si ripete il fit lineare anche con gli altri valori della tabella, si ottiene per la latenza lo stesso risultato ma con una incertezza tanto maggiore quanto più elevata è la lunghezza dei pacchetti spediti. 5.2.2 Misura dei tempi di instradamento dei pacchetti. Nella parte teorica della tesi è stata ricavata la formula per il calcolo del tempo di attraversamento di un pacchetto con testa di 2 byte attraverso un C104 in funzione della sua lunghezza (k), espressa anch’essa in byte (paragrafo 2.2.6): S ≅ 670ns + [10⋅k + 14] ⋅10ns Facendo un confronto tra i valori teorici ed i risultati sperimentali della tabella precedente, si nota come tra essi vi sia un accordo tanto migliore quanto più la lunghezza di tali pacchetti è grande. Questo perchè, più questi ultimi sono lunghi, più le velocità di comunicazione ricavate sperimentalmente si avvicinano a quelle 5 La latenza si ottiene sostanzialmente mediante la sottrazione dei tempi di comunicazione relativi all’attraversamento di un certo numero di C104. Se questi tempi sono molto maggiori della latenza stessa, gli errori ad essi associati si avvicinano o addirittura superano i valori temporali misurati. Propagandosi nella sottrazione generano così un errore sulla latenza che è inaccettabile. 118 teoriche: quando ciò avviene, si è nella condizione migliore per la misura dei parametri che caratterizzano il protocollo IEEE 1355. Per pacchetti lunghi 512, 2048 e 4096 byte i risultati che si ottengono per i tempi di attraversamento del singolo switch sono i seguenti: 512 byte: valore teorico: S ≅ 52 µs valore sperimentale: S ± ∆S = (57.07 ± 0.65) µs 2048 byte: valore teorico: S ≅ 206 µs valore sperimentale: S ± ∆S = (21.57 ± 0.12) ⋅10 µs 4096 byte: valore teorico: S ≅ 410 µs valore sperimentale: S ± ∆S = (42.67 ± 0.16) ⋅10 µs Inoltre, lasciando inalterate le condizioni attuali, sono state fatte delle misure della latenza dei C104 configurando le connessioni tra due switch differenti come appartenenti ad un unico gruppo. Nessuna differenza nei tempi è stata rilevata: quindi l’implementazione dell’algoritmo grouped adaptive routing (paragrafo 2.2.4 – appendice A) non introduce ritardi ulteriori. 5.3 Misure inerenti il contest switch. Nel capitolo 2 è stato descritto il contest switch ovvero la contesa di un link fisico da parte di due o più messaggi. Nelle reti molto estese quali quelle locali e globali di ATLAS, nelle quali il traffico è intenso, questa è una situazione molto frequente: vediamo cosa avviene dal punto di vista sperimentale. E’ doveroso premettere che, avendo a disposizione un numero limitato di interfacce PCI-DSLink, 119 non è possibile simulare una situazione complessa e completa come quella che si verifica nella presa dati dell’esperimento: attraverso alcuni risultati sperimentali si possono comunque verificare le asserzioni fatte nella parte teorica della tesi. 5.3.1 Contesa con quattro schede PCI-DSLink. Per creare una contesa tra i pacchetti, si realizza una topologia interconnettiva tale che uno dei link di uscita di un C104 sia la comune destinazione di due dei suoi link di ingresso, ovvero si fa in modo che i pacchetti in ingresso su due diversi canali abbiano, come uscita, lo stesso link. Questa connessione comprende 5 PC6, una scheda B108 di configurazione, le quattro interfacce PCI-DSLink e due STC104, il tutto connesso come nella figura 5.9: Figura 5.9: Connessione per la realizzazione di comunicazioni con contest switch. Tramite le due schede “PCI-DSLink Zeuthen” installate su JAVA e su PCAPE si effettuano delle comunicazioni attraverso due C104, misurando i tempi di 6 PCAPE1 è un personal computer dotato di processore INTEL 80486, utilizzato per configurare le reti. La sua descrizione non è stata fornita in quanto mediante esso non vengono effettuate comunicazioni. 120 percorrenza al variare della lunghezza dei pacchetti. Successivamente si introduce una comunicazione ulteriore tra PCATL2 e PCMRZ1 (forniti delle schede “PCIDSLink INFN”) e si misurano le variazioni delle velocità sui primi due PC. Tutto ciò imponendo ai pacchetti, tramite un apposito file di configurazione NDL (appendice A) e ad una giusta impostazione dei registri dei C101, di transitare sull’unico canale DSLink presente tra i C104. Per maggior chiarezza, chiamerò nel seguito pacchetti principali quelli scambiati tra JAVA e PCAPE (le misure dei tempi vengono prese su JAVA) e pacchetti secondari quelli scambiati tra PCMRZ1 e PCATL2. PCAPE1, tramite una scheda B108, configura la rete. Dal punto di vista quantitativo, i risultati che si ottengono con questa misura non sono una fedele rappresentazione di ciò che in realtà avviene in caso di contesa in quanto, con le schede a disposizione, non si riescono a saturare in velocità i dispositivi DSLink, ed in particolare i C104. Infatti sarebbero necessarie delle sorgenti/destinazioni con una banda passante almeno uguale a 100 Mbit/s per misurare le perdite in velocità dovute esclusivamente alla contesa. Dal punto di vista qualitativo si giunge invece alle considerazioni che verranno fatte nel corso del paragrafo. Un altro problema che interviene nelle misure di questo tipo è causato dalle differenti caratteristiche delle schede utilizzate. Avendo queste delle velocità e delle memorie FIFO diverse tra loro, le comunicazioni non vengono influenzate soltanto dal contest switch ma anche da questi altri fattori. Se, ad esempio, si effettuano delle comunicazioni suddividendo i messaggi in pacchetti piccoli (minori di 128 byte) si ha, come visto, una efficienza minore rispetto alle analoghe trasmissioni effettuate con pacchetti grandi. Quando però si introduce una contesa, i pacchetti piccoli hanno il vantaggio di poter essere memorizzati anche nelle FIFO delle schede “PCI-DSLink INFN” (quelle meno capienti), con conseguente diminuzione dei tempi di attesa da parte dei C101 delle schede “Zeuthen” i quali trovano, in media, i canali DSLink più liberi. Inoltre la limitata velocità raggiungibile con le interfacce “INFN” condiziona notevolmente i risultati, non impegnando in maniera considerevole lo switch. Le misure che si ottengono sono date, di volta in volta, dalla concomitanza di tutti questi effetti. Per comprendere meglio il problema, analizziamo le figure 5.10a e 5.10b, le quali riportano gli andamenti della velocità di comunicazione tra JAVA e PCAPE 121 (provvisti delle schede “PCI-DSLink Zeuthen”) al variare sia della lunghezza dei pacchetti scambiati tra loro (pacchetti principali), sia delle dimensioni dei pacchetti scambiati tra PCMRZ1 e PCATL2 (pacchetti secondari), in presenza di contest switch: Velocità di comunicazione in presenza di contest switch 4096 bytes 5 2048 bytes Velocità (Mbyte/s) 1024 bytes 4 512 bytes 32 bytes 3 2 1 0 0 500 1000 1500 2000 2500 3000 3500 4000 Lunghezza pacchetti secondari (byte) Figura 5.10a: Andamento della velocità di comunicazione tra le schede “PCIDSLink Zeuthen” al variare della lunghezza dei pacchetti principali e secondari, in presenza di contest switch. 122 Velocità di comunicazione in presenza di contest switch (ZOOM) 6 4096 bytes 2048 bytes Velocità (Mbyte/s) 5 1024 bytes 4 512 bytes 32 bytes 3 2 1 0 0 50 100 150 200 250 300 Lunghezza pacchetti secondari (byte) Figura 5.10b: Andamento della velocità di comunicazione tra le schede “PCI-DSLink Zeuthen” al variare della lunghezza dei pacchetti pricipali e secondari, in presenza di contest switch (ZOOM). Le cinque curve sono relative a dimensioni dei pacchetti principali pari a 4096, 2048, 1024, 512 e 32 byte. Dai grafici si nota che, per lunghezze dei pacchetti secondari maggiori di 128 byte, si ha un andamento monotono decrescente della velocità di comunicazione dei pacchetti principali. Ciò è naturale in quanto l’unico link di collegamento tra i due C104 viene impegnato da entrambe le trasmissioni. Ma i valori che si ottengono per le velocità sono quantitativamente inferiori a quelli teorici in quanto, prima che dalla contesa, la banda passante viene limitata dalle schede PCI-DSLink meno performanti (“INFN”). Per questo motivo non possono essere fatti dei confronti numerici con i valori ricavati nella parte teorica. Qualitativamente invece la situazione è reale, e le curve mostrano chiaramente che, se su un link conteso avvengono delle comunicazioni a bassa velocità, queste condizionano tutte le altre presenti su di esso, in modo tanto più evidente quanto più la lunghezza dei pacchetti che creano contesa è grande. Se le dimensioni dei pacchetti secondari sono molto elevate (superiori a 1.5 Kbyte) allora si perde, in questa particolare situazione, più del 50% della velocità iniziale (curva “4096 byte” della figura 5.10a). 123 Inaspettatamente la zona delle curve vicino allo zero mostra un andamento abbastanza irregolare: appare una crescita iniziale delle velocità, poi un calo successivo. Questo comportamento è dovuto fondamentalmente alla concomitanza di due fattori: la limitatezza delle memorie FIFO in trasmissione e ricezione, la quale favorisce le comunicazioni con pacchetti piccoli e, per contro, la inefficienza delle comunicazioni con pacchetti piccoli, dimostrata precedentemente. 5.3.2 Contesa con due schede PCI-DSLink. Per eliminare gli effetti indesiderati dovuti alle FIFO e, in parte, quelli dovuti alla limitata velocità delle schede “INFN”, viene eseguita un’altra serie di misure, simile alla precedente, utilizzando soltanto le schede “PCI-DSLink Zeuthen”. Avendo queste ultime delle FIFO più grandi rispetto alle analoghe interfacce “INFN”, le velocità di comunicazione hanno un andamento più regolare rispetto alle misure precedenti, ovvero per esse non si riscontrano “anomalie” nello scambio di pacchetti piccoli. La configurazione per questa nuova misura è la seguente: entrambe le schede “PCI-DSLink Zeuthen” trasmettono indipendentemente dei pacchetti in una rete formata da un singolo switch, e li ricevono dopo che questi sono passati attraverso l’unica connessione del tipo link-link presente sul C104 (figura 5.11). 124 Figura 5.11: Schema della connessione realizzata mediante le due schede “PCI-DSLink Zeuthen” per la simulazione del contest switch sul link di uscita numero 15 del C104. A differenza del caso precedente ognuna delle due schede riceve i dati che ha trasmesso: non vi è scambio di informazioni tra le due. Tutti i pacchetti che entrano nello switch, sia dal link 8 che dal 30, vengono instradati sul link di uscita n° 15, il quale è quello conteso. Per far ciò viene fornita ad essi una testa di 3 byte: il primo ha il valore 15 per entrambe le schede DSLink, e viene cancellato quando lo header esce dal link 15. Il secondo byte assume nei due casi i valori 8 e 30 e viene cancellato, appunto, all’uscita dei link 8 e 30. Il terzo byte, non specificato (non è necessario), viene ricevuto in ingresso. La figura 5.12 mostra l’inizializzazione dei registri dei C101 interessati: /* Inizializzazione testa del pacchetto (2 byte) */ outl((0xf|(linknum<<8))&0xffff,c101_or_pld| TX_PACKET_HEADER_LOWER_0); /* Impostazione lunghezza testa pacchetti (3 byte) */ outl(0x3, c101_or_pld|TX_HEADER_LENGTH_0); Figura 5.12: Impostazione della testa dei pacchetti in trasmissione. 125 La prima istruzione di output scrive nel registro TxPacketHeaderLower (paragrafo 2.3) del C101 i due byte di testa necessari alle comunicazioni, mentre la seconda imposta sul C101 una lunghezza dei pacchetti trasmessi pari a 3 byte. Si noti che con questa configurazione ogni byte subisce due routing all’interno del C104. Le misure vengono prese sul PC JAVA variando gli stessi parametri (pacchetti principali e secondari) del caso precedente ed i risultati ottenuti sono quelli riportati nelle figure 5.13a e 5.13b. Le 5 curve mostrano l’andamento della velocità di comunicazione per pacchetti principali da 4096, 2048, 1024, 512 e 32 byte, spediti tramite le schede di “Zeuthen” alloggiate su JAVA, al variare della lunghezza dei pacchetti secondari trasmessi mediante PCAPE, in presenza di contest switch. 4096 bytes 2048 bytes 1024 bytes 512 bytes 32 bytes Velocità di comunicazione in presenza di contest switch Velocità pacchetti principali (Mbyte/s) 6.7 6.2 5.7 5.2 4.7 4.2 3.7 3.2 2.7 2.2 1.7 0 500 1000 1500 2000 2500 3000 3500 4000 Lunghezza pacchetti secondari (byte) Figura 5.13a: Andamento della velocità di comunicazione sulla 1a scheda “PCIDSLink Zeuthen”in funzione dei pacchetti spediti mediante la 2a scheda, in presenza di contest switch. 126 6.7 6.2 5.7 5.2 (Mbyte/s) Velocità pacchetti principali Velocità di comunicazione in presenza di contest switch (ZOOM) 4.7 4096 bytes 4.2 2048 bytes 3.7 1024 bytes 3.2 512 bytes 2.7 32 bytes 2.2 1.7 0 100 200 300 400 500 Lunghezza pacchetti secondari (byte) Figura 5.13b: Andamento della velocità di comunicazione sulla 1a scheda “PCIDSLink Zeuthen”in funzione dei pacchetti spediti mediante la 2a scheda, in presenza di contest switch (ZOOM). A differenza del caso precedente, le curve hanno tutte un andamento monotono decrescente. Ciò significa che, all’aumentare del numero di byte costituenti i pacchetti secondari (quelli che creano contesa sul link 15), le velocità di comunicazione dei pacchetti principali non crescono mai, ma diminuiscono, come è giusto che avvenga. Non si nota quindi più la dipendenza dalle FIFO di trasmissione e ricezione (ogni scheda “PCI-DSLink Zeuthen” ha due FIFO entrambe profonde 16 Kbyte). Con una singola scheda “PCI-DSLink Zeuthen”, utilizzando la configurazione della figura 5.11 ma in assenza di contesa del link, si arriva al massimo ad una velocità di ~6.30 Mbyte/s. Il valore massimo è inferiore ai 9.16 Mbyte/s raggiunti utilizzando due schede (figura 5.5) in quanto le operazioni di scrittura e lettura vengono ora effettuate sulla singola interfaccia e non avvengono quindi sequenzialmente7. Neanche in questo modo si riesce quindi a saturare la banda passante del canale DSLink, ed i risultati ottenuti non rappresentano, ancora una volta, una reale misura della contesa. Le 5 curve mostrano però come il contest switch limiti le velocità di comunicazione dei pacchetti principali, e conducono alle seguenti considerazioni qualitative. 7 Con due differenti PC, mentre uno trasmette dei dati l’altro può riceverli. 127 Rispetto alle misure precedenti (figure 5.10a e 5.10b) i valori limite delle velocità raggiunte in questo caso sono maggiori, a dimostrazione del fatto che queste ultime, quando avviene una contesa, sono influenzate dai dispositivi più lenti. Ciò è ancora più evidente quando le dimensioni dei pacchetti che creano contesa (quelli secondari) sono grandi. La zona iniziale di tutti i tracciati è a pendenza nulla; ovvero quando i pacchetti secondari sono piccoli, la contesa non influenza, nel caso specifico, le velocità di comunicazione dei pacchetti principali. Questa parte dei grafici è tanto più ampia quanto più le dimensioni dei pacchetti principali sono grandi, in quanto all’aumentare di quest’ultimo parametro, le dimensioni dei pacchetti secondari hanno su di essi una influenza minore. Ad esempio, se le dimensioni dei pacchetti principali sono di 4 Kbyte, la diminuzione della loro velocità si ha per pacchetti secondari di lunghezza superiore a 1.5 Kbyte, mentre nel caso di pacchetti principali lunghi 32 byte, la decrescita della velocità inizia per lunghezze dei pacchetti secondari pari a 32 byte. Tutto ciò avviene perchè si stanno misurando delle velocità medie, e perchè non si hanno sorgenti che possono saturare il canale DSLink. Se ai due messaggi si fa percorrere la connessione link-link nei due versi opposti (il primo dal link 15 al 14, il secondo dal 14 al 15)8, non si nota alcuna diminuzione della velocità di comunicazione: ogni canale DSLink è bidirezionale ed ha due linee separate, una in ingresso, l’altra in uscita. In questo caso non si ha quindi contesa. Tra le prime 4 curve della figura 5.13a e la quinta vi è un “salto” dovuto alla diversa efficienza delle comunicazioni al variare della lunghezza dei pacchetti. Questa dipendenza viene evidenziata nella figura 5.14, la quale mostra l’andamento della velocità di comunicazione in funzione della dimensione dei pacchetti spediti e ricevuti da una singola interfaccia “PCI-DSLink Zeuthen” attraverso un C104, in assenza di contest switch (in accordo con la topologia riportata nella figura 5.11): 8 A tale scopo è sufficiente, in una delle due interfacce, modificare il primo byte della testa spedita. 128 Velocità (Mbyte/s) Andamento della velocità di comunicazione sulla singola scheda "PCI-DSLink Zeuthen" 7 6 5 4 3 2 1 0 0 1000 2000 3000 4000 Lunghezza pacchetti (byte) Figura 5.14: Andamento della velocità di comunicazione della singola scheda “PCIDSLink Zeuthen” attraverso un unico C104, in assenza di contest switch. Per pacchetti lunghi 32 byte la velocità di comunicazione à pari a (3.73 ± 0.17) Mbyte/s, mentre se i pacchetti hanno dimensioni maggiori di 512 byte, le velocità superano 6.20 Mbyte/s, fino ad arrivare a (6.29 ± 0.28) Mbyte/s (4096 byte). 5.3.3 Distribuzione statistica delle misure temporali. Si vogliono ora fare alcune considerazioni sulla distribuzione delle misure dei tempi in caso di comunicazioni con contest switch. Nella parte teorica è stato mostrato come, in presenza della contesa di un link, i tempi di routing, in media, aumentano secondo una certa legge. Ciò è stato fino ad ora visto in modo sperimentale attraverso la diminuzione delle velocità di comunicazione: rivediamo ora il problema analizzando i tempi di comunicazione. In assenza di contest switch, tutti i pacchetti vengono instradati, in media, entro un tempo determinato, dipendente soltanto dai parametri del pacchetto stesso (lunghezza della testa, sue dimensioni ecc…) e da quelli dello switch. Diversamente, quando si è in presenza di contest switch “alcune volte” i pacchetti sono costretti ad attendere che il canale si sia liberato prima di poterlo occupare. Sulla latenza dei 129 pacchetti l’effetto di tutto ciò si manifesta con una duplice dipendenza; la prima, comune al caso dell’assenza di contesa, dai parametri del pacchetto su cui si effettuano le misure, l’altra dalla presenza o meno di altri pacchetti sullo stesso link. Quest’ultima dipendenza aggiunge dei ritardi ai tempi di comunicazione che, nel caso di pacchetti secondari di dimensioni notevoli, hanno in media dei valori molto maggiori dei tempi di comunicazione misurati in assenza di contest (lo dimostrano le ingenti diminuzioni in velocità per pacchetti secondari di grosse dimensioni). Per comprendere meglio quanto detto, nella figura 5.15a viene tracciato l’istogramma della distribuzione dei tempi di comunicazione quando si trasmettono e ricevono, con una singola scheda “PCI-DSLink INFN”, 5000 pacchetti da 32 byte attraverso un C104, in assenza di contest switch (in accordo con la topologia della figura 5.11): Histogram (L32.STA 1v*4995c) Frequenze relative dei tempi di comunicazione attraverso un C104 per pacchetti di lunghezza pari a 32 bytes 3645 3402 3159 2916 2673 2430 2187 1944 1701 1458 1215 numero di oggetti 972 729 486 243 0 1335 1341 1338 1347 1344 1353 1350 1359 1356 1365 1362 1371 1368 1377 1374 1383 1380 1389 1386 1395 1392 numero di cicli di clock da 166 MHz Figura 5.15a: Distribuzione dei tempi di attraversamento di un STC104 da parte di pacchetti lunghi 32 byte, trasmessi e ricevuti tramite una singola scheda “PCI-DSLink Zeuthen”, in assenza di contest switch. 130 La distribuzione è costituita da due componenti separate nettamente tra loro di una piccola quantità (~0.2 µs). Questo distacco è dovuto alla presenza dei controlli in trasmissione e ricezione. Nella figura 5.15a le due colonne principali sono a loro volta delle distribuzioni centrate intorno a dei valori medi che distano, appunto, di 0.2 µs. Se si aggiungono ora dei pacchetti secondari di lunghezza pari a 512 byte condividenti lo stesso link, l’istogramma che si ottiene è quello della figura 5.15b: Histogram (L32_512.STA 1v*4999c) Frequenze relative dei tempi di comunicazione attraverso un C104 per pacchetti di lunghezza pari a 32 bytes, in presenza di contest switch con pacchetti da 512 bytes 4380 4088 3796 3504 3212 2920 2628 2336 2044 1752 1460 numero di oggetti 1168 876 584 292 0 1335 2389 1862 3442 2916 4496 3969 5549 5023 6603 6076 7656 7130 8710 8183 9237 9763 10817 11870 10290 11344 numero di cicli di clock da 166 MHz Figura 5.15b: Distribuzione dei tempi di attraversamento di un STC104 da parte di pacchetti lunghi 32 byte, trasmessi e ricevuti tramite una singola scheda “PCI-DSLink Zeuthen”, in presenza di contest switch. Questo secondo grafico, tracciato in presenza di contest switch, mostra due componenti fondamentali per le frequenze relative dei tempi di comunicazione (anche queste sono delle distribuzioni). La prima, che ha un valor medio pari a ~1365 impulsi di clock (da 166 MHz), coincidente con la distribuzione dei tempi in assenza 131 di contesa, e contiene circa l’80% della distribuzione della figura precedente, ovvero entrambe le colonne della figura 5.15a. Infatti i valori riportati sull’asse delle ascisse, nell’intorno della prima colonna, sono molto simili a quelli della figura 5.15a: questi tempi corrispondono alla situazione nella quale i pacchetti principali non trovano occupato il link conteso. La seconda componente del grafico di figura 5.15b (le due colonne più piccole sulla destra), ha un valor medio di ~9970 impulsi di clock e rappresenta i casi nei quali i pacchetti principali trovano il link conteso impegnato dai pacchetti secondari. Il loro tempo medio di routing è infatti notevolmente maggiore. Calcolando i valori medi delle due distribuzioni della figura 5.15b, si trova che essi distano tra loro di ~52 µs: questa quantità corrisponde proprio al tempo necessario ad un pacchetto da 512 byte per attraversare un STC104 (paragrafo 5.2). Per avere una conferma del fatto che le due distribuzioni osservabili nella figura 5.15b distano tra loro di un valore pari al tempo medio di routing di un pacchetto da 512 byte, sono state ripetute delle misure anche per una contesa con pacchetti secondari da 1024 byte di lunghezza, ottenendo nuovamente un buon accordo tra il risultato teorico (~102 µs) e quello sperimentale (~103 µs). Osservando le “colonne” della figura in esame, si nota come l’altezza della prima sia molto maggiore della somma delle altre due, a dimostrazione del fatto che la maggior parte delle volte i pacchetti non incontrano contesa. Il motivo di questa sistematicità è il seguente: essendo i pacchetti secondari lunghi 512 byte mentre i principali 32 byte, prima che venga formato e trasmesso un pacchetto secondario, cioè prima che quest’ultimo impegni il link conteso, riescono ad essere instradati più pacchetti principali. In generale quindi, quando si parla di diminuzione della velocità di comunicazione, non si intende che tutti i pacchetti vengono instradati con un certo ritardo, ma che alcuni di essi devono attendere prima di ottenere il routing. 132 5.3.4 Considerazioni conclusive sul contest switch. Per quanto visto fino ad ora, la suddivisione dei messaggi in pacchetti di dimensioni limitate è indispensabile. Ma qual’è la lunghezza ottimale di questi pacchetti ? Per quanto premesso all’inizio del capitolo, dai grafici tracciati non è possibile ricavare questo valore; si può fare però una semplice considerazione. Abbiamo visto che, in generale, le velocità di comunicazione risentono in maniera considerevole della lunghezza delle memorie FIFO presenti nel sistema. D’altra parte, se ogni link dello switch ha la capacità di memorizzare un certo numero di token in ingresso (> 20), è ragionevole ritenere che, ottimizzando tutte le altre componenti del sistema, per non perdere efficienza, il numero di byte che compongono i pacchetti non deve superare di molto questo valore. Si deve a questo punto ricordare che in tutti i casi mostrati, le velocità di comunicazione decrescono al diminuire della lunghezza dei pacchetti in quanto, quando le loro dimensioni sono piccole, lo overhead introdotto dal software e gli accoppiamenti delle componenti il sistema divengono prevalenti. Per l’implementazione del VCP nell’esperimento ATLAS, la suddivisione dei messaggi in pacchetti di lunghezza pari a 32 byte deve quindi essere eseguita in modo più efficiente rispetto a quanto fatto fino ad ora, ovvero con una velocità almeno pari a quella del protocollo DSLink, in modo che si possa sfruttare tutta la banda passante di quest’ultimo. Le possibili soluzioni sono due. La prima è quella di utilizzare dei processori più potenti. La seconda scelta prevede invece l’uso di componenti aggiuntivi che svolgano non soltanto questo compito, ma anche gli ulteriori algoritmi di I/O (memorizzazione provvisoria dei pacchetti in arrivo, riconoscimento delle informazioni di routing per la gestione dei canali virtuali, ecc…). Le schede “PCI-DSLink INFN” sono state progettate anche per svolgere questo compito ma, come ripetutamente detto, nella revisione a mia disposizione tutto ciò non è ancora previsto. 133 5.4 Test di affidabilità del protocollo IEEE 1355. Le prove di affidabilità del sistema vengono realizzate per vedere con quale frequenza avvengono degli errori nelle comunicazione con la tecnologia DSLink. Il primo test effettuato riguarda la trasmissione, mediante il Round Trip Time (paragrafo 4.2.2), di messaggi attraverso un singolo STC104: 10 8 pacchetti da 2048 byte ciascuno vengono trasferiti da JAVA a PCAPE senza rilevare alcun errore. La stessa cosa viene ripetuta con due C104 configurati con il grouping dei link (utilizzando quindi le 4 schede PCI-DSLink a disposizione). Anche in questo caso non si ha nessun errore di comunicazione. Ma se in questa situazione si disconnette uno dei link del gruppo, tutto il gruppo diviene inutilizzabile. Questo è l’unico inconveniente di una certa rilevanza riscontrato sugli STC104. Invece, facendo comunicare per diverse ore le 4 interfacce interponendo tra esse un unico C104, configurato in modo che su uno dei suoi link avvenga una contesa, non è stato rilevato alcun errore. Anche nelle comunicazioni tra schede differenti (PCI-DSLink “Zeuthen” e “INFN”) non si rivela alcun errore nei dati trasmessi: chiaramente le velocità di comunicazione in questo caso si riducono a quelle ottenibili con le interfacce più lente. Altre prove di affidabilità sono state effettuate facendo comunicare per diverse ore le tre coppie di schede DSLink disponibili. In questa situazione si è verificato che, se si interrompe una o più comunicazioni in corso, si effettua la configurazione della rete e si ripristinano le trasmissioni interrotte, sugli altri link attivi non si hanno errori. Ovvero la “configurazione a caldo” non interrompe le comunicazioni in corso. Ciò è fondamentale ai fini della presa dati di ATLAS in quanto in caso di errore si possono ripristinare i link malfunzionanti, senza dover interrompere le comunicazioni sugli altri canali. Si ricorda infine che non è stato possibile fare dei test impegnando più di sei link contemporaneamente. Tutte le prove di affidabilità sono state eseguite con i controlli in trasmissione e ricezione attivi. Numerosi altri controlli possono essere aggiunti, sia per avere una maggiore sicurezza nello scambio dei dati, sia per il ripristino della corretta configurazione in caso di errore. Data l’enorme affidabilità che la tecnologia DSLink 134 ha mostrato nel corso dello svolgimento del lavoro, non vengono però eseguiti ulteriori test. 135 CONCLUSIONI. Anche se l’architettura del sistema di trigger di ATLAS è ormai nota con sufficiente precisione, essa necessita ancora di alcune specifiche inerenti l’elettronica da adottare. In modo particolare, per quanto riguarda il 2° livello, sia sui processori (locali e globali), sia sulle switching network, non è stata presa ancora nessuna decisione definitiva. Il lavoro svolto in questa tesi ha permesso di focalizzare l’attenzione su alcuni aspetti fondamentali, riguardanti prevalentemente le reti e, anche se in modo marginale, le farm di processori. Lo studio dello IEEE1355 DS-DE ha mostrato come esso sia molto duttile, permettendo di implementare (ad alto livello) numerosi altri protocolli di comunicazione. Oltre alle specifiche descritte, particolarmente interessanti sono gli algoritmi inerenti il VCP: la gestione dei canali virtuali, oltre ad incrementare la banda passante delle reti, permette di introdurre degli algoritmi di instradamento più sofisticati. Ad esempio i pacchetti provenienti da una sorgente potrebbero essere in grado di scegliere autonomamente, all’interno del processore di destinazione, qual’è l’algoritmo di ricostruzione al quale devono essere forniti. Questa è una prerogativa molto importante ai fini della gestione delle informazioni in ATLAS, sia che si utilizzi l’architettura pull sia la push. Per ciò che concerne la interfaccia PCI-DSLink ma soprattutto lo switch, si hanno delle caratteristiche notevoli. L’ottima affidabilità, la riconfigurabilità, la scalabilità, la bassa latenza e l’elevato numero di porte del singolo STC104, rendono quest’ultimo un buon dispositivo di instradamento dei dati, anche in previsione delle sue future espansioni (peraltro compatibili con la tecnologia attuale). Non si deve inoltre dimenticare che l’elevato numero di porte per switch, nonchè il basso costo rispetto a dispositivi analoghi (ATM, Ethernet), lo rendono molto competitivo. Unico neo rilevato è la attuale impossibilità di utilizzare in modo efficace il grouping dei link. Un secondo aspetto che emerge dallo studio delle switching network è quello che riguarda la gestione dello I/O. E’ stato puntualizzato più volte nel corso del 136 lavoro quanto sia importante, forse fondamentale, introdurre dello hardware aggiuntivo per la manipolazione dei pacchetti da trasmettere e ricevere. Per questo motivo si ritiene indispensabile indirizzare gli sforzi futuri verso lo sviluppo di interfacce PCI-DSLink includenti logiche programmabili o altri dispositivi analoghi (in linea con le schede “INFN”). In sostanza, anche se la banda passante dei componenti hardware che realizzano il protocollo IEEE 1355 non raggiunge ancora il valore di 1 Gbit/s, si ritiene che il DSLink possa fornire un valido strumento per l’event builder di trigger di 2° livello di ATLAS. In fase di sviluppo si sono rivelate molti importanti le caratteristiche del S.O. Linux e le possibilità offerte dal linguaggio C. Per quanto riguarda il S.O., sono state apprezzate fondamentalmente due delle sue caratteristiche. La prima è la sua “configurabilità”: esso permette di aggiungere e rimuovere in modo molto semplice i moduli software, anche quelli relativi al Kernel. Un esempio è dato dal controllo dei processi attivi, fatto nella esecuzione delle misure. Un secondo pregio di Linux è quello della disponibilità (gratuita) di tutte le librerie necessarie per lo sviluppo dei programmi (quella matematica, quella di I/O) trovate tramite WWW, nonchè di numerose informazioni, soprattutto nell’ambito di altri ambienti di ricerca. Il linguaggio C è risultato essere invece uno strumento molto potente per la gestione dei dispositivi di I/O e del bus PCI. Inoltre permette di effettuare delle chiamate in linguaggio macchina in modo semplice e con bassa latenza (un esempio è la lettura del registro TSC – appendice C). I risultati ottenuti necessitano di una verifica in ambito test-beam. Ciò al fine di vedere come si comportano lo hardware IEEE 1355 DS-DE ed il software sviluppato quando integrati in un sistema reale che comprenda il rivelatore e la sua elettronica di lettura, nonchè un vero sistema di acquisizione dati. Inoltre, la presenza di numerose sorgenti e destinazioni da connettere allo switch, permetterebbe di eseguire altri importanti test sulla bontà del protocollo e sugli algoritmi di instradamento. 137 APPENDICE A Sistema operativo e compilatori. Nello sviluppo della tesi sono stati realizzati dei programmi in linguaggio C per la gestione dello hardware precedentemente descritto. Le macchine a disposizione sono dei personal computer (PC) del tipo “IBM compatibile”, le cui caratteristiche sono riportate nel capitolo 4. Il Sistema Operativo (S.O.) utilizzato è il Linux Red Hat 4.x, un S.O. “Unix like” a 32 bit multitasking e multiutente, in grado di operare sui PC. I S.O. a 32 bit più diffusi ed installabili sui PC sono, oltre a Linux, Windows 95 e Windows NT della Microsoft. A differenza degli altri due, Linux è un sistema operativo denominato “freeware” ovvero la sua distribuzione è gratuita. Ciò implica che tutti i programmi sorgente di cui è costituito e le sue librerie sono disponibili a costo nullo. Questo, è stato un enorme vantaggio in quanto, nello sviluppo dei programmi di controllo delle interfacce PCI-DSLink, è stato possibile prelevare un elevato numero di librerie, come ad esempio quella contenente le funzioni per la gestione del bus PCI. Anche la maggior parte della documentazione è stata prelevata gratuitamente1. Un altro fondamentale punto a favore della scelta Linux è dato dal fatto che in ATLAS il S.O. utilizzato è Unix (o LynxOS). Le similitudini tra questi S.O. sono tali che, l’eventuale passaggio da Linux a Unix del software sviluppato, comporta delle problematiche sicuramente minori rispetto all’analoga conversione Windows-Unix. I programmi sono stati scritti tutti in linguaggio C, il cui compilatore è prodotto della GNU (Gnu’s Not Unix) anch’esso installato gratuitamente con il S.O., completo di tutte le librerie standard. Per quanto riguarda le librerie del programma di configurazione IEEE1355_conf, sono state utilizzate, con opportune modifiche, quelle incluse nel ToolSet D7394A della INMOS SGS-Thomson [26], originariamente disponibili per il S.O. DOS. 1 Le librerie e la documentazione sono state prelevate nella rete mondiale WWW (World Wide Web). Il compilatore NDL. Quando si devono realizzare delle switching network con molti componenti e con topologie complesse, la loro configurazione (inizializzazione di registri, network labelling ecc…) può risultare molto laboriosa; ad esempio si deve prestare attenzione al problema del deadlock. Al fine di rendere più semplice questa operazione, si utilizza un tool della INMOS comprendente un linguaggio di descrizione dello hardware, denominato NDL (Network Description Language) ed il relativo compilatore. La descrizione delle switching network viene così realizzata in un linguaggio ad alto livello, al quale vengono fornire tutte le indicazioni riguardanti la loro topologia, e mediante il quale si possono definire le impostazioni con cui configurare i registri interni di ogni C104 (ad esempio il setting delle velocità dei singoli link, le loro etichette, il grouping ecc…). In particolare, mediante semplici comandi è possibile scrivere nei numerosi registri Interval e Select dei C104 (capitolo 2), senza la preoccupazione di aver creato dei percorsi potenzialmente affetti da deadlock. Nelle figure A.1 ed A.2 viene riportata una semplice connessione tra due STC104 con il relativo file di descrizione NDL. Figura A.1: Schema di una connessione tra due STC104. -- File di configurazione per rete con due STC104. #INCLUDE "c:\tools\libs\stdndl.inc" CONTROLPORT host : NODE switch1 : NODE switch2 : [32]EDGE edge : NETWORK -- Impostazione velocità dei link DO SET DEFAULT (link.speed.multiply SET DEFAULT (link.speed.divide SET DEFAULT (control.speed.divide := 20) := [1]) := [2]) -- Impostazione tipo di switch SET switch1 (type SET switch1 (interval.separator[0] SET switch2 (type SET switch2 (interval.separator[0] := := := := "C104") 0) "C104") 0) -- Impostazione dei link 0..15 dello switch1 DO i = 0 FOR 16 DO SET switch1 (interval.separator[i+1] := i+1) SET switch1 (link.select[i] := i) SET switch1 (delete[i] := TRUE CONNECT switch1[link][i] TO edge[i] -- Impostazione dei link 16..31 dello switch2 DO i = 16 FOR 16 DO SET switch2 (interval.separator[i+1] := i+1) SET switch2 (link.select[i] := i) SET switch2 (delete[i] := TRUE) CONNECT switch2[link][i] TO edge[i] -- Impostazione dei link 16..31 switch1 e 0..15 switch2 DO i = 0 FOR 16 DO SET switch1 (interval.separator[i+17] := i+17) SET switch1 (link.select[i+16] := i+16) SET switch1 (delete[i+16] := FALSE) SET switch2 (interval.separator[i+1] := i+1) SET switch2 (link.select[i] := i) SET switch2 (delete[i] := FALSE) CONNECT switch1[link][i+16] TO switch2[link][i] -- Connessioni della control network CONNECT host[control] TO switch1[control.up] CONNECT switch1[control.down] TO switch2[control.up] : Figura A.2: File NDL relativo allo schema della figura A.1. Le variabili definite come edge rappresentano le connessioni del link con i dispositivi esterni; anche se vengono tutti configurati, questi ultimi non debbono essere necessariamente occupati. Le velocità delle reti di dato e di controllo sono state impostate rispettivamente a 100 Mbit/s e 50 Mbit/s, mediante la divisione della velocità massima del DSLink (100 Mbit/s) per uno e per due (prime righe del file di configurazione). La testa dei pacchetti è costituita da due byte, il primo dei quali viene cancellato ogni volta che un pacchetto esce da un C104 tramite una connessione di tipo edge (DELETE[] = TRUE). I link che uniscono i due switch non hanno invece la cancellazione della testa (DELETE[] = FALSE) in quanto questa serve per l’instradamento sul 2° dispositivo. In questo modo al C101 in ricezione giungono sempre pacchetti con una testa, sia che essi abbiano attraversato un singolo C104, sia che ne abbiano attraversati due o tre. La configurazione riportata nella figura A.2 permette delle comunicazioni bidirezionali tra qualsiasi coppia di host connessa sui terminali edge. E’ sufficiente impostare la testa dei pacchetti con il valore del link di uscita per instradarlo correttamente attraverso la rete. Se ad esempio tramite un PC connesso al link 0 del primo switch si inviano dei pacchetti con header = 18, questi giungono all’uscita del link 18 del secondo switch tramite la connessione link18 link2 realizzata tra i C104. Una cosa analoga avviene nalla direzione opposta. La descrizione della rete di controllo viene fatta nelle ultime due righe della figura A.2. La stessa configurazione può essere effettuata definendo i link di collegamento tra i due STC104 come appartenenti ad un unico gruppo (implementazione dell’algoritmo “link grouping”). In questo caso il file di configurazione NDL ha l’aspetto riportato nella figura A.3. --File di configurazione per rete con due STC104 con link group. #INCLUDE "c:\toolset\libs\stdndl.inc" CONTROLPORT host : NODE switch1 : NODE switch2 : [32]EDGE edge : NETWORK DO -- Impostazione velocita' dei link SET DEFAULT (link.speed.multiply := 20) SET DEFAULT (link.speed.divide := [1]) SET DEFAULT (control.speed.divide := [2]) -- Impostazione tipo di switch SET switch1 (type := "C104") SET switch1 (interval.separator[0] := 0) SET switch2 (type := "C104") SET switch2 (interval.separator[0] := 0) -- Impostazione dei link 0..15 dello switch1 DO i = 0 FOR 16 DO SET switch1 (interval.separator[i+1] := i+1) SET switch1 (link.select[i] := i) SET switch1 (delete[i] := TRUE) CONNECT switch1[link][i] TO edge[i] -- Impostazione del link 16 dello switch1 SET switch1 (interval.separator[16+1] := 16+1) SET switch1 (link.select[16] := 16) SET switch1 (delete[16] := FALSE) -- Impostazione del link 0 dello switch2 SET switch2 (interval.separator[0+1] := 0+1) SET switch2 (link.select[0] := 0) SET switch2 (delete[0] := FALSE) -- Impostazione dei link 16..31 dello switch2 DO i = 16 FOR 16 DO SET switch2 (interval.separator[i+1] := i+1) SET switch2 (link.select[i] := i) SET switch2 (delete[i] := TRUE) CONNECT switch2[link][i] TO edge[i] -- set del gruppo SET switch1 (link.groups := [[16,31]]) SET switch2 (link.groups := [[0,15]]) -- connessione link del gruppo DO i = 0 FOR 16 DO CONNECT switch1[link][i+16] TO switch2[link][i] -- Connessioni della control network CONNECT host[control] TO switch1[control.up] CONNECT switch1[control.down] TO switch2[control.up] : Figura A.3:File NDL relativo alla configurazione della figura A.1 con il grouping dei link di collegamento. Si noti che in questo caso vengono definiti soltanto i primi link del gruppo ovvero il link 16 dello switch 1 ed il link 0 del 2° C104: tutti gli altri seguono la stessa impostazione. I vantaggi (e gli svantaggi) che si ottengono con le due configurazioni sono stati descritti nel corso della tesi (paragrafo 2.2.4). La compilazione dei file NDL viene effettuata in due passi dal compilatore NDL mediante i programmi INDL ed INIF. Questi ultimi, oltre a fornire un file binario NIF (Network Initialization File), effettuano dei controlli sulla giusta connessione degli switch. In particolare riconoscono se la rete è potenzialmente esente da deadlock, se un link è stato connesso due o più volte, se sono state inizializzate tutte le variabili definite, ecc… Il file NIF generato dal compilatore può essere così interpretato dal programma di configurazione; nel mio caso è stata effettuata una ulteriore conversione da binario ad esadecimale (programma converti in appendice C) per una migliore lettura dei file in fase di sviluppo del software. La separazione della descrizione dello hardware dalla configurazione software ha una importanza fondamentale in quanto con un unico programma di configurazione della rete, realizzato in un qualsiasi linguaggio di programmazione (nel mio caso in C), si possono interpretare un numero illimitato di file NIF, corrispondenti ad altrettante configurazioni hardware. Inoltre la semplicità della sintassi NDL rende la descrizione della rete effettuabile anche da utenti che non conoscono i particolari dei linguaggi di programmazione più complessi quali il C. Nel caso del software sviluppato, se si vogliono configurare reti costituite da uno, due oppure tre C104, è sufficiente fornire al programma di configurazione il nome del file precedentemente prodotto, scegliendo tra CONF.one, CONF.two e CONF.three. Nel caso in cui si volesse modificare la topologia della rete , si dovrebbe creare un altro file di descrizione dello hardware (NDL), e poi utilizzarlo al posto dei precedenti nel programma IEEE1355_conf. APPENDICE B Caratteristiche del PCI Local Bus. Il PCI (Periferal Component Interconnect) è un bus parallelo locale utilizzato per la interconnessione tra i dispositivi presenti all’interno dei calcolatori elettronici. Il PCI è nato essenzialmente come soluzione alla necessità di ottenere alte prestazioni nei trasferimenti di I/O. E’ ormai presente all’interno di tutti i personal computer dotati di processori PowerPC, Penthium Intel e compatibili, Alpha. Uno dei punti di forza, che ne ha permesso una enorme diffusione è la non dipendenza del suo protocollo dal tipo di processore. Questa prerogativa è dovuta alla presenza di un chip ASIC (Application Specific Integrated Circuit), denominato bridge PCI-host, che realizza il collegamento tra i vari dispositivi di I/O ed il PCI. Il bridge dipende dal processore al quale è interfacciato e deve essere progettato in funzione della CPU cui è connesso, ma l’insieme processore-bridge è machine independent. Il bus PCI può essere a 32 o 64 bit ed avere un clock di 25 o 33 MHz. Le velocità di trasferimento dati, nel caso di clock a 33 MHz (frequenza attualmente più comune) e bus a 32 e 64 bit, sono rispettivamente di 132 e 264 Mbyte/s. I PC utilizzati nello sviluppo della tesi hanno un PCIbus a 32 bit con clock a 33 MHz. Il PCI è di tipo multi-master2, ovvero accetta più dispositivi di controllo sullo stesso bus. I vari master effettuano la richiesta del bus allo arbiter il quale decide, in base alla priorità stabilita, se fornire o meno l’accesso. Molti dei segnali che viaggiano sul bus PCI sono in multiplex tra loro: per questo motivo i cicli di accesso alle linee del bus sono suddivisi in due fasi, la Address phase e la Data phase. Durante la prima fase vengono inviati sul bus segnali di indirizzo e di comando, mentre nella seconda si inviano segnali di dato e di abilitazione delle linee. 2 Un master è un dispositivo che gestisce il bus nelle comunicazioni con altri host. Tutti i segnali possono essere raggruppati in alcune categorie logiche, dipendenti dalla funzione svolta. Nel caso del bus PCI a 32 bit, i principali gruppi sono costituiti da: • Segnali di sistema: sono quelli comuni a tutto il sistema di I/O come il clock ed il reset. • Segnali di Indirizzo/Dato: vi sono 32 linee contenenti, in multiplex, i segnali di indirizzo e di dato. Altre 4 linee (C/BE) sono utilizzate per la codifica dei comandi che vengono richiesti da un master ad uno slave, e per la abilitazione dei byte di dato (anch’essi in multiplex). Un’ultima linea è dedicata alla parità (pari) dei segnali precedenti. • Segnali di controllo dell’interfaccia: servono per il controllo dei dispositivi, come ad esempio la loro identificazione o la segnalazione dello stato di accesso al bus (segnala se un master ha il controllo del bus). • Segnali di arbitraggio: sono due linee punto-punto (due per ogni dispositivo) e vengono utilizzate dal master per richiedere l’arbitraggio del bus, e dallo arbiter per la conferma dell’accesso al PCI. Queste linee non sono presenti nei dispositivi slave. • Segnali di errore: sono due bit adibiti al controllo della parità nelle transizioni sul bus dei dati e degli indirizzi, e alla segnalazione di errori di sistema di una certa entità (potenzialmente catastrofici). • Segnali di interrupt: sono quattro segnali opzionali asincroni che permettono al dispositivo connesso di svolgere fino a 4 diverse funzioni. Ogni dispositivo di I/O connesso sul bus PCI ha una zona di 256 byte di memoria nella quale sono contenuti i suoi registri di configurazione. Questa zona di memoria, denominata Spazio di Configurazione del dispositivo, è suddivisa in due regioni, una detta di header (64 byte) simile per tutti i dispositivi, l’altra invece (192 byte) dipendente dallo specifico host. La header di configurazione ha un ruolo chiave nella gestione dei device, e contiene una serie di registri di lettura e scrittura. I suoi primi 16 byte (PCI Device Independent Region) sono uguali per tutti gli host e memorizzano delle informazioni fondamentali, come ad esempio il loro numero identificativo (Device ID – 16 bit), il produttore (Vendor ID – 16 bit) oppure la revisione (Revision ID – 8 bit). Gli altri permettono invece di aggiungere delle ulteriori funzionalità ai dispositivi PCI (es. memorie FIFO). Vediamo quali sono i registri più importanti della header region, e quali funzioni svolgono: • Vendor ID, Device ID, Revision ID (r): contengono delle informazioni per la identificazione del dispositivo. • Header Type (r): contiene informazioni sulla zona dello spazio di configurazione denominata Base Address. Viene interrogato dal sistema nella fase di inizializzazione del bus ed è indispensabile per l’uso del dispositivo. Mediante il suo 7° bit permette inoltre di distinguere se il dispositivo ha una unica funzione oppure è multifunzione. • Class Code (r): identifica la generica funzione di un dispositivo (se esso è una memoria di massa, un controller video ecc…). • Command (r/w): permette di controllare l’accesso al dispositivo. Se ad esempio contiene tutti “0”, si può accedere al device limitatamente alla sua zona di configurazione. In questo caso si dice che il dispositivo è logicamente disconnesso. • Status (r/w): registra gli eventi che avvengono sul bus PCI. Non viene utilizzato di frequente in quanto è relativo a particolari modalità di funzionamento. • Interrupt Line (r): indica quale linea di interrupt viene utilizzata da un determinato dispositivo. Ad esempio il valore 0x00 (esadecimale) corrisponde alla linea INTA, 0x01 alla linea INTB… • Base Address (r/w): sono 6 registri a 32 bit molto importanti ai fini dell’accesso al bus. Infatti, dal momento che alla sua accensione il sistema (PC) effettua una copia (mapping) in memoria (oppure nel suo spazio di I/O) di tutti i dispositivi connessi al bus PCI, nei registri base address devono essere memorizzate le informazioni riguardanti la zona di memoria occupata dai dispositivi, nonchè gli indirizzi di partenza della loro mappa. Sapendo quanti byte occupano i registri dei dispositivi, il sistema può assegnare loro parte delle sue risorse (memoria o spazio di I/O), con relativo indirizzo di partenza, senza generare conflitti tra essi. Così l’accesso avviene direttamente con operazioni di lettura/scrittura nella memoria (o nello spazio di I/O) del calcolatore. L’operazione di mapping avviene con modalità che dipendono dal sistema sul quale è connesso il dispositivo; o tramite il BIOS3, oppure tramite appositi device driver, dei programmi al livello di S.O. E’ comunque effettuata da un apposito algoritmo che individua tutte le informazioni necessarie nello spazio di header di ogni dispositivo. • Expansion ROM Base Address (r/w): contiene l’indirizzo di partenza e le dimensioni di eventuali ROM di espansione presenti sul dispositivo. Anche in questo caso viene utilizzato dal sistema per effettuare una mappa delle risorse esterne. Per accedere allo spazio di configurazione di un dispositivo vengono utilizzate le routines software PCI BIOS Functions [20] le quali, secondo le specifiche PCI, sono indipendenti dal S.O.: nel caso specifico sono state notate alcune lievi differenze tra quelle relative ai due S.O. DOS e Linux. In particolare non coincidono i nomi e l’ordine delle loro variabili di input ed output4. Per il linguaggio C di Linux tali procedure, incluse in una libreria denominata libpcidev, sono le seguenti: int pcibios_present(void): determina se è presente il set di funzioni per l’interfaccia con il bus PCI (PCI BIOS Functions). Se non la trova fornisce il valore 0. int pcibios_find_device(vendor, dev_id, index, &bus_num, &dev_fun): se il dispositivo specificato in input dal numero del venditore, dal numero identificativo e dal numero indice viene trovato, la funzione fornisce il numero del bus su cui è inserito ed il numero del device. In caso contrario fornisce una stringa di 32 “1”. I valori ricavati vengono utilizzati per accedere nell’area destinata al dispositivo. int pcibios_find_class(class_code, index, &bus_num, &dev_fun): fornisce la locazione dei dispositivi che hanno un determinato Class Code. Ha come ingresso il Class Code, ed un numero indice (N), mentre in uscita fornisce il numero del bus ed il numero del device con il Class Code e l’indice specificati. In caso di errore fornisce una stringa di 32 “1”. 3 In questi sistemi si parla di plug-and-play intendendo con ciò che le schede PCI sono utilizzabili non appena vengono inserite nel bus. Le risorse del sistema possono essere assegnate dinamicamente senza interverto da parte dell’utente e senza conflitti. 4 L’importanza che viene data sia ai nomi delle procedure, sia all’ordine dei suoi parametri di I/O è sempre maggiore. Ciò avviene perchè, essendo il PCI un bus multipiattaforma, si tende sempre più a scrivere del software che possa essere portato da un sistema ad un’altro. La situazione ideale è quella che prevede che un unico programma, scritto in un certo linguaggio, sia utilizzabile su sistemi dotati di processore qualsiasi: l’unica cosa che cambia sono le librerie che contengono le funzioni PCI, le quali sono necessariamente dipendenti dalla CPU. int pcibios_read_config_byte(bus_num, dev_fun, address, &data): permette di leggere un byte nello spazio di configurazione del dispositivo specificato. Ha come input il numero del bus, il numero del device e l’indirizzo del registro da leggere. In output fornisce valore letto. int pcibios_read_config_word(bus_num, dev_fun, address, &data): come la precedente ma per delle word (16 bit). int pcibios_read_config_dword(bus_num, dev_fun, address, &data): come la precedente ma per delle double word (32 bit). Mediante questa funzione vengono letti gli indirizzi base dei dispositivi presenti sulle schede di interfaccia PCIDSLink. int pcibios_write_config_byte(bus_num, dev_fun, address, data): permette di scrivere dei byte nello spazio di configurazione del device specificato. Ha come input il numero del bus, il numero del device, l’indirizzo del registro ed il dato da scrivere. int pcibios_write_config_word(bus_num, dev_fun, address, data): come la precedente ma per delle word. int pcibios_write_config_dword(bus_num, dev_fun, address, data): come la precedente ma per delle double word. La legenda dei termini utilizzati è riportata nella tabella B1: Vendor Device_id Index Bus_num Dev_fun Class_code Address Data Numero identificativo del produttore del device (16 bit). Numero identificativo del dispositivo (16 bit). Numero indice del dispositivo sul bus (8 bit). Numero del bus su cui il dispositivo è inserito (8 bit). Nel mio caso specifico vale 0 (c’è un solo bus in ogni PC). Numero identificativo del device all’interno del sistema nel quale è inserito (8 bit). Da questo valore si ricavano gli indirizzi base dei dispositivi. Numero identificativo della funzione all’interno di un dispositivo (32 bit). Indirizzo base del dispositivo o dei registri al suo interno (32 bit). Valori da leggere e/o scrivere. Tabella B1: Legenda dei termini utilizzati nelle routine PCI. Le specifiche del bus PCI non permettono la connessione diretta di più di un dispositivo su una unica scheda di espansione, a meno che non si fornisca a quest’ultima un ulteriore chip di bridge tra il bus ed i dispositivi presenti su di essa. Sulle interfacce PCI-DSLink utilizzate nel lavoro di tesi, le quali contengono diversi componenti, è infatti presente un chip denominato S5933 PCI Matchmaker Controller [1] il quale opera da “ponte” tra gli host connessi su di essa (FIFO opzionali, STC101…) ed il bus. Come esempio, nella figura B1 viene riportato lo schema a blocchi dell’interfacciamento tra la CPU ed una scheda “PCI-DSLink Zeuthen”. Figura B1: Schema della connessione tra la CPU e le interfacce PCI-DSLink. Grazie alle funzioni descritte si accede, tramite il bridge della CPU, allo S5933. Quest’ultimo dispositivo possiede dei registri di programmazione (simili a quelli presenti sul bridge CPU-bus) i quali permettono l’accesso ai dispositivi presenti sulle schede di interfaccia PCI-DSLink. In particolare è presente uno spazio di configurazione contenente gli indirizzi base dei registri dei due STC101, della memoria FIFO opzionale e di alcuni ulteriori registri di controllo della scheda. Nel momento in cui le schede vengono alimentate, una NVRAM (Non Volatile RAM) opportunamente programmata provvede alla inizializzazione di questi registri di configurazione dello S5933, e tutte le operazioni di I/O possono così essere eseguite. Si noti che in mancanza di una memoria non volatile, il chip S5933 deve essere inizializzato ogni volta che si effettua un reset del sistema. Per ottenere tutte le informazioni sul PCI, ovvero sulle ultime revisioni o aggiunte al protocollo del bus, oppure sulle sue specifiche, si può contattare il PCI SIG (PCI Special Interest Group) [21], una associazione di industrie di microcomputer con il compito di seguire gli sviluppi del PCI bus. APPENDICE C Listato dei programmi “sorgente”. Programma di configurazione e monitoring mediante le schede IMS B108: IEEE1355_conf.c /***************************************************************/ /* Nome File: IEEE1355_conf.c */ /* Programma che permette di configurare una switching network */ /* costituita da un qualsiasi numero di STC104 e di fare il */ /* 'monitoring' del suo stato. */ /* Consente di effettuare delle comunicazioni attraverso la */ /* rete precedentemente configurata. */ /* */ /* Autore: Alfredo Babusci */ /* [email protected] */ /* */ /* Revisione: 06/97 */ /***************************************************************/ /***********/ /* Include */ /***********/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <stdarg.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <asm/io.h> #include <sys/time.h> #include "c101.h" #include "txt9mixv.h" #include "inmos.h" #include "c104.h" #include "dstest.h" #include "control.h" /********************************/ /* Costanti e variabili globali */ /********************************/ #define MAX_HEADER_SIZE #define getch getchar 2 FILE *DBF; int DBFLAG = 0; FILE *CPOKE; int CPOKEFLAG = 0; int MDEBUG=1; PRIVATE BOOL Master; PRIVATE int WaitCount = 0; int RegisterAddress = 0x180; int cod; /*****************************/ /* Funzione 'premi un tasto' */ /*****************************/ void premi() { printf("\n"); printf("Press a key... "); getchar(); } /************************************/ /* Funzione di elevamento a potenza */ /************************************/ int potenza (int base, int espo) { int conta; int prodotto = 1; for (conta=0; conta<espo; conta++) prodotto = prodotto * base; return prodotto; } /*****************************************************/ /* Funzione di lettura numeri in formato esadecimale */ /*****************************************************/ int leggi_esad (char aiuto[11]) { int i, ii, ind; ind = 0; for (i=0; i<=3; i++) { ii=(int)aiuto[i] - 48; if ((ii>=0) && (ii<=9)) ind = ind + ii*potenza(16,(3-i)); else ind = ind +(ii-39)*potenza(16,(3-i)); } return ind; } /******************************************/ /* Funzione di lettura numero dell'STC104 */ /******************************************/ int lettura(unsigned long int c104num) { char aiuto[11]; cod = 0; do { printf("Insert STC104 device number (1-%d) : ", c104num); gets(aiuto); cod = atoi(aiuto); } while ((cod > c104num)|(cod<=0)); return cod; } /****************/ /* Main Program */ /****************/ int main (int argc, char *argv[]) { int i, j, ii, ind, Link, numbyte, numcicli; long int ss, uu, ss1, uu1; char buf[100]; int Result = OK ; int ACTIVE, act, MyId; Channel aiuto1; char CREG[64]; char String[4096]; char aiuto[11]; char leggicar[1]; char inserisci[10]; struct timeval tempo, tempo1; struct timezone zona; unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned int BYTE BYTE unsigned short* long int long int long int long int long int long int long int long int dato; Canale; LinkArrivo; *LinkPronto; LunghezzaPacchettoPartenza; LunghezzaPacchettoArrivo; Status; TipoPacchettoArrivo; TipoPacchettoPartenza; dimvettore = 2048; PacchettoPartenza[dimvettore]; PacchettoArrivo[dimvettore]; long int QualeLinkPronto; unsigned long int valore, Connection, Length; BYTE HeaderIn[MAX_HEADER_SIZE], HeaderOut[MAX_HEADER_SIZE]; Channel *FromDataLink, *ToDataLink; Channel *FromControlLink, *ToControlLink; unsigned long int ConfigurationStatus, NumberOfDevicesInControlNetwork ; VCPLINKBLOCK *ControlNetwork, *DataNetwork, TempVcplinkptr, ControlLink, DataLink ; VLCBBLOCK *Vlcb ; const VCPLINKBLOCK *VirtualLinks; VCPLINKBLOCK *VirtualLinksbis; FromDataLink ToDataLink FromControlLink ToControlLink = = = = (Channel (Channel (Channel (Channel *)DATA_LINK ; *)DATA_LINK ; *)CONTROL_LINK ; *)CONTROL_LINK ; ControlNetwork = NULL ; TempVcplinkptr.ToNetwork = ToControlLink ; /************************************************************/ /* Inizializzazione del C101: viene fatta immediatamente, */ /* sia per il master che per lo slave. */ /************************************************************/ iopl(3); InitializeDevicesNoStart(RegisterAddress); iopl(0); /* *** Sono il Master *** */ Master = TRUE; do { printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n"); printf("************************************************************ **\n"); printf("* STC104's NETWORK CONFIGURATION PROGRAM *\n"); printf("************************************************************ **\n"); printf("\n\n\n"); printf("************************************************************ **\n"); printf("* *\n"); printf("* Menu' : *\n"); printf("* *\n"); printf("************************************************************ **\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); printf("* *\n"); 1-> STC104's Network configuration (Master) 2-> Reset whole STC104's Network 3-> Reset of single STC104 link 4-> Read entire state of STC104 link 5-> Read STC104 registers 6-> Read STC101 registers 7-> Data Network initialization 9-> Bye printf("************************************************************ **\n"); printf("\n"); printf(" Select a number : "); gets(aiuto); j = atoi(aiuto); if ((j>0) && (j<=9)) { switch(j) { /*****************************************************/ /* Configurazione del C104 (lettura del file .NIF) */ /*****************************************************/ case 1: if (Master) { iopl(3); printf("Network initialization....\n"); StartLink(&TempVcplinkptr); ControlNetwork = Configure (FromControlLink, ToControlLink, buf, &NumberOfDevicesInControlNetwork, &ConfigurationStatus); iopl(0); if (ControlNetwork != NULL) { ControlNetwork->CurrentVirtualLink = 0 ; if(MDEBUG) printf ( "Network configuration OK \n"); printf("Number of STC104s in the network: %d\n", NumberOfDevicesInControlNetwork); } else printf("Network configuration NOT OK \a\n"); } else printf ("You cannot configure the network, you aren't Master. \n"); premi(); break; /******************/ /* Reset dei C104 */ /******************/ case 2: iopl(3); for(i=0; i<NumberOfDevicesInControlNetwork; i++) { ControlNetwork->CurrentVirtualLink = i; for (ii = 0; ii < 1; ii++) if (MDEBUG) ResetC104 (ControlNetwork); if (MDEBUG) printf ("Reset of %d^ C104 done \n", (i+1)); else printf ("Reset NOT OK \a\n"); } InitializeDevicesNoStart(RegisterAddress); iopl(0); premi(); break; /*************************************/ /* reset del singolo link di un C104 */ /*************************************/ case 3: iopl(3); if (NumberOfDevicesInControlNetwork >1) ControlNetwork->CurrentVirtualLink = lettura(NumberOfDevicesInControlNetwork)-1; printf("Insert the link number to reset :"); gets(aiuto); cod = atoi(aiuto); if ((cod>=0) && (cod<32)) { ResetC104link (cod, ControlNetwork); printf ("Reset link n~ %d done \n", cod); } else printf("The number is out of range.\a\n"); premi(); iopl(0); break; /*******************************************************/ /* Stampa il contenuto dello stato di un link del C104 */ /*******************************************************/ case 4: iopl(3); if (NumberOfDevicesInControlNetwork >1) ControlNetwork->CurrentVirtualLink = lettura(NumberOfDevicesInControlNetwork)-1; printf("Insert the link number of interest :"); gets(aiuto); cod = atoi(aiuto); if ((cod>=0) && (cod<36)) { ii = ServC104LinkRegisters (ControlNetwork, ControlNetwork>CurrentVirtualLink, cod, String); if (MDEBUG) { for (i=0; i<ii; i++) printf("%c", String[i]); printf("\n"); } } else printf("The number is out of range.\a\n"); premi(); iopl(0); break; /************************************************************** **********/ /* Lettura dei registri dei C104 (sono mappati in memoria 0x1000-0xffff)*/ /************************************************************** **********/ case 5: iopl(3); if (NumberOfDevicesInControlNetwork >1) ControlNetwork->CurrentVirtualLink = lettura(NumberOfDevicesInControlNetwork)-1; do { printf ("Insert the register address to read \n"); printf ("(standard exadecimal format -x----) : 0x"); gets(aiuto); ind = leggi_esad(aiuto); printf ("\n"); } while ((ind < 0x1000) | (ind > 0xffff)); valore = 0; CPeek(ind, &valore, ControlNetwork); printf ("The register n^ #%x of %d^ C104 has the value #%x (%d) \n", ind, cod, valore, valore); premi(); iopl(0); break; /*********************************/ /* Lettura dei registri del C101 */ /*********************************/ case 6: iopl(3); ControlLink.ToNetwork = (Channel *)CONTROL_LINK; DataLink.ToNetwork = (Channel *)DATA_LINK; do { printf ("Insert the register address to read \n"); printf ("(standard exadecimal format -x----) : 0x"); gets(aiuto); printf ("\n"); ind = leggi_esad(aiuto); } while ((ind < 0x0004) | (ind > 0x001c)); VirtualLinks = &ControlLink; select_device(VirtualLinks); ii = read_C101_register (ind); printf ("The register n^ #%x of 'control' C101 has the value #%x (%d) \n", ind, ii, ii); VirtualLinks = &DataLink; select_device(VirtualLinks); ii = read_C101_register (ind); printf ("The register n^ #%x of 'data' STC101 has the value #%x (%d) \n", ind, ii, ii); premi(); iopl(0); break; /*********************************/ /* Inizializzazione Data Network */ /*********************************/ case 7: iopl(3); DataNetwork = MallocVcpLinkBlock(); if (DataNetwork != NULL) { DataNetwork->ToNetwork = ToDataLink; DataNetwork->FromNetwork = FromDataLink; DataNetwork->HeaderInLength = DATA_HEADER_IN_SIZE; DataNetwork->NumberOfVirtualLinks = MAX_CHANNELS; DataNetwork->VirtualLinksOnThisLink = MallocArrayOfVlcbs (MAX_CHANNELS); for (ii=0; ii<MAX_CHANNELS; ii++) { Vlcb = GetVirtualLinkControlBlock (DataNetwork, ii); Vlcb->HeaderOutLength = DATA_HEADER_OUT_SIZE; HeaderOut[0] = ii; InstallVlcbHeaderOut(HeaderOut, DATA_HEADER_OUT_SIZE, Vlcb); HeaderIn[0] = ii; InstallVlcbHeaderIn(HeaderOut, DATA_HEADER_IN_SIZE, Vlcb); Vlcb->BufferPointerForUnsolicitedMessagesIn = MallocVlcbUnsolicitedtBuffer(Vlcb->VlcbMaxPacketSize); } DataNetwork->BaseOfOutputBuffer = MallocVlcbOutputBuffer(Vlcb->VlcbMaxPacketSize + DATA_HEADER_OUT_SIZE);; DataNetwork->OutputBuffer = DataNetwork>BaseOfOutputBuffer; DataNetwork->MinimumHeader = 0; DataNetwork->MaximumHeader = MAX_CHANNELS; } /* Trasmissione e ricezione pacchetti */ VirtualLinks = &DataLink; StartLink (VirtualLinks); printf("\n"); printf("You want transmit or receive (t/r)? ..."); gets(leggicar); printf ("%c\n", leggicar[0]); printf(" \n"); if (leggicar[0] == 't') { printf("Which link do You want to connect to ? "); gets(inserisci); Canale = atoi(inserisci); printf("\n"); printf("Insert the number of bytes that constituite the packet: "); gets(inserisci); numbyte = atoi(inserisci); } printf("\n"); printf("Insert the cycle number: "); gets(inserisci); numcicli = atoi(inserisci); HeaderOut[1] HeaderOut[0] HeaderIn[1] HeaderIn[0] = = = = Canale; Canale; Canale; Canale; /***********************/ /* Trasmissione Dati */ /***********************/ if (leggicar[0] == 't') { /* Azzeramento Pacchetto Partenza */ for (i = 0; i < dimvettore; i++) PacchettoPartenza[i] = 0; DataNetwork->TimeOutValue = MYUNDEFINEDVALUE; for (i=0; i<numbyte; i++) PacchettoPartenza[i]='b'; LunghezzaPacchettoPartenza = numbyte; printf("\n"); Vlcb->HeaderOut = HeaderOut; Vlcb->HeaderOutLength=2; for (i=0; i<numcicli; i++) { WriteToLinkOrTimeOutPointer(Vlcb, PacchettoPartenza, LunghezzaPacchettoPartenza, 1, 1000, DataNetwork); printf("DATO %s\n", PacchettoPartenza); } DataNetwork->TimeOutValue = 1000; printf ("I transmitted : %s\n", PacchettoPartenza); /* Azzeramento vettore ricezione */ for (j=0; j<dimvettore; j++) PacchettoArrivo[j] = 0; premi(); } /********************/ /* Ricezione Dati */ /********************/ if (leggicar[0] == 'r') { printf("\n"); printf("I'm waiting data...\n"); for (i=0; i<numcicli ; i++) { ReadFromLinkOrTimeOut(PacchettoArrivo, &LunghezzaPacchettoArrivo, &TipoPacchettoArrivo, MYUNDEFINEDVALUE, DataNetwork); printf("Cycle number : %d\n", (i+1)); printf("Packet length (byte) : %d\n", LunghezzaPacchettoArrivo); printf("\n"); printf ("I received : %s\n", PacchettoArrivo); printf("Packet type : %d\n",TipoPacchettoArrivo); printf("\n"); /* Azzeramento vettore ricezione for (j=0; j<dimvettore; j++) PacchettoArrivo[j] = 0; */ } premi(); } iopl(0); break; } /* Fine dello switch */ } /* Fine dell' if */ else printf("The number is out of range. \a\n"); } /* fine del do */ while (j != 9); } /* End Program */ Programma di comunicazione mediante le schede “PCI-DSLink Zeuthen” attraverso un numero qualsiasi di STC104: Zboard.c /***************************************************************/ /* Nome File : Zboard.c */ /* */ /* Programma per effettuare comunicazioni a pacchetti mediante */ /* le schede di Zeuthen (K.H. Sulanke) con interfaccia token */ /* abilitata, tramite la S5933-FIFO e la FIFO on-chip. */ /* */ /* Autore : Alfredo Babusci */ /* [email protected] */ /* */ /* Revisione : 01/98 */ /***************************************************************/ #include #include #include #include #include #include #include <stdio.h> <stdlib.h> <unistd.h> <asm/io.h> <sys/time.h> "amcc.h" "dslink.h" /*****************************/ /* Funzione 'premi un tasto' */ /*****************************/ void premi() { printf("\n"); printf("Press a key... "); getchar(); } /**********************/ /* Funzione 'delay' */ /**********************/ void delay(int milli) { int microsec1, microsec2, temp; struct timeval tempo1, tempo2; struct timezone zona; gettimeofday(&tempo1, &zona); microsec1 = tempo1.tv_usec; do { gettimeofday(&tempo2, &zona); microsec2 = tempo2.tv_usec; temp = microsec2-microsec1; if (temp < 0) temp = (1000000-microsec1) + microsec2; } while (temp < milli); } /**************************/ /* Procedura attesa token */ /**************************/ void token(word c101_or_pld) { int link_status; printf("WAIT FOR TOKEN...\n"); do { link_status=inw(c101_or_pld|LINK_STATUS); if(link_status & LINK_STATUS_ERROR) { outl(RESET_LINK, c101_or_pld|LINK_COMMAND); delay(1000); outl(START_LINK, c101_or_pld|LINK_COMMAND); delay(1000); } } while(link_status & LINK_STATUS_ERROR || !(link_status & TOKEN_RECEIVED)); } /**********************************/ /* Procedura link di destinazione */ /**********************************/ int destinazione(word c101_or_pld) { char inserisci[10]; int linknum; printf("Insert link number "); gets(inserisci); linknum = atoi(inserisci); /* Inizializzazione testa del pacchetto */ outl(linknum & 0xffffL, c101_or_pld|TX_PACKET_HEADER_LOWER_0); delay(1000); outl((linknum)>>16 & 0xffffL, c101_or_pld|TX_PACKET_HEADER_UPPER_0); delay(1000); return(linknum); } /****************************************/ /* Procedura di calcolo delle velocita' */ /****************************************/ void rate(double cnt[10000], int cicli, int numbyte) { int j; double massimo, minimo, media, velocita; media = 0; massimo = 0; minimo = 999999999; for (j=1; j<cicli; j++) { cnt[j]/=0.09; media = media + cnt[j]; if (cnt[j] > massimo) massimo = cnt[j]; if (cnt[j] < minimo) minimo = cnt[j]; } media = media / (cicli - 1); velocita = (numbyte * 953.6743164 *2 ) / media; printf("\n"); printf("TEMPO MEDIO TRA-RIC (ns) %f\n\n", media); printf("TEMPO MINIMO TRA-RIC (ns) %d\n\n", minimo); printf("TEMPO MASSIMO TRA-RIC (ns) %d\n\n", massimo); printf("SCARTO (ns) %d\n\n", massimo-minimo); printf("VELOCITA' (Mbytes/s) %f\n", velocita); printf("END.\n"); } /************************************/ /* Procedura di ricezione pacchetti */ /************************************/ void ricezione(word c101_or_pld, word address) { int i, j, cicli, numbyte; int dimvettore = 4096; dword VettoreArrivo[dimvettore]; char inserisci[10]; printf("\n\n"); printf("Ricezione pacchetti \n\n"); printf("\n\n"); printf("Insert cycles number "); gets(inserisci); cicli = atoi(inserisci); printf("\n\n"); /* Azzeramento Vettore Arrivo */ for (i=0; i<dimvettore; i++) VettoreArrivo[i] = 0; /* Acknowledge per azzeramento bits di interrupt */ outw(ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID, c101_or_pld|RX_ACKNOWLEDGE); delay(1000); numbyte = 0; for (i=0; i<cicli; i++) { /* Controllo in ricezione */ do { } while(!(inw(c101_or_pld|ISR)&PACK_RECEIVED)); /* Lunghezza del pacchetto in ricezione */ numbyte = inw(c101_or_pld|RX_PACKET_LENGTH); /* Ricezione */ for (j=0; j<(numbyte/4); j++) VettoreArrivo[j] = inl(address); /* Acknowledge dopo la ricezione */ outw(ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID, c101_or_pld|RX_ACKNOWLEDGE); printf("PACKET LENGTH %d\n", numbyte); printf("I RECEIVED %s\n", VettoreArrivo); printf("CYCLE NUMBER %d\n", i+1); } printf("END RECEPTION \n"); } /***************************************/ /* Procedura di trasmissione pacchetti */ /***************************************/ void trasmissione(word c101_or_pld, word address) { int i, j, cicli, numbyte; char inserisci[10]; int dimvettore = 4096; dword VettorePartenza[dimvettore]; unsigned int cnt1, cnt2, cnt3; double cnt[10000]; printf("\n\n"); printf("Insert cycles number "); gets(inserisci); cicli = atoi(inserisci); printf("\n"); printf("Insert packets length <2,8,16,32,64,128,256,512,1024,2048 bytes>"); gets(inserisci); numbyte = atoi(inserisci); printf("\n\n"); /* Azzeramento Vettore Partenza */ for (i=0; i<dimvettore; i++) VettorePartenza[i] = 0; /* Inizializzazione Vettore Partenza */ for (i=0; i<(numbyte/4); i++) VettorePartenza[i] = 'amoR'; for (i=0; i<cicli; i++) { __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt3)); /* Abilitazione TX SEND PACKET */ outw(TERMINATOR_ENABLE|EOP_TERMINATOR|HEADER_ENABLE| HEADER_SELECT_0|numbyte, c101_or_pld|TX_SEND_PACKET); /* Controllo in trasmissione */ do { /*printf("TX FIFO LEVEL %x\n", (inw(c101_or_pld|TX_INTERRUPT_STATUS))&0x1L);*/ } while(((inw(c101_or_pld|TX_INTERRUPT_STATUS))&0x1L)); /* Trasmissione */ for (j=0; j<(numbyte/4); j++) outl(VettorePartenza[j], address); printf("PACKET LENGTH %d\n", numbyte); printf("I TRANSMITTED %s\n", VettorePartenza); printf("CYCLE NUMBER %d\n", i+1); __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt3)); cnt[i] = (cnt2-cnt1-12); } printf("END TRASMISSION...\n"); } /********/ /* Main */ /********/ void main(void) { unsigned int classcode; unsigned short val, indice; unsigned char bus_num, dev_fun; dword base_adr0, base_adr1; word op_regs_base, c101_or_pld, address; int i, j, k, ii, liv, numpac, numbyte; int etichetta, cicli, linknum, temp, link_status, bandiera; char leggicar[1], inserisci[10]; struct timeval struct timespec struct timezone long int long tempo1, tempo2; tempo3, tempo4; zona; nanosec1, nanosec2; microsec1, microsec2; sec1, sec2; /* Funzione che inizializza le operazioni sul PCI */ pcidev_init(); if (pcibios_present()) printf ("PCIBIOS PRESENTE \n\n"); if (pcibios_find_device(0x1234, 0x5678, 0x00, &bus_num, &dev_fun) == 0) { printf ("DEVICE TROVATO\n"); printf ("BUS = %x\n", bus_num); printf ("DEVICE = %x\n", dev_fun); } else printf ("%x\n", pcibios_find_device(0x1234, 0x5678, 0x00, &bus_num, &dev_fun)); printf ("\n"); /* Lettura degli indirizzi base */ pcibios_read_config_dword(bus_num, dev_fun, PCI_CS_BASE_ADDRESS_0,&base_adr0); pcibios_read_config_dword(bus_num, dev_fun, PCI_CS_BASE_ADDRESS_1,&base_adr1); op_regs_base = (word)base_adr0 & 0xfffc; c101_or_pld = (word)base_adr1 & 0xfffc; address = op_regs_base|AMCC_OP_REG_FIFO; printf printf printf printf printf ("BASE ADR 0 = %x\n", base_adr0); ("BASE ADR 1 = %x\n", base_adr1); ("ADDRESS = %x\n", address); ("OP REG BASE = %x\n", op_regs_base); ("C101 REGS BASE = %x\n", c101_or_pld); iopl(3); printf ("DEVICE ID = %x\n", inw(c101_or_pld|DEVICE_ID)); printf ("DEVICE ID = %x\n", inw(c101_or_pld|DEVICE_REVISION)); /* Abilita accesso I/O */ pcibios_write_config_word(bus_num, dev_fun, PCI_CS_COMMAND, IO_ACCESS_ENABLE); /* S5933 - Reset */ outl(GLOBAL_RESET, op_regs_base|AMCC_OP_REG_MCSR); delay(1000); outl(0L, op_regs_base|AMCC_OP_REG_MCSR); /* Abilitazione Token interface */ outl(MASTER_MODE|TOKEN_ENABLE|FIFO_RESET, c101_or_pld|ICR); /* Abilitazione pacchettizzazione */ outw(SUPPRESS_RX_EOX|ENABLE_PACKETIZATION|RX_HEADER_LENGTH_1, c101_or_pld|DEVICE_CONFIG); /* Set 100 Mbit/s */ outw(WRITE_1|SPEED_SELECT|_100MBIT, c101_or_pld|LINK_MODE); /* Lunghezza testa pacchetti (bytes) */ outl(0x2L, c101_or_pld|TX_HEADER_LENGTH_0); /* Abilitazione master + token */ outl(MASTER_MODE|TOKEN_ENABLE, c101_or_pld|ICR); /* Set Tx FIFO LEVEL */ outw(TX_LEVEL_HIGH|TX_LEVEL_0, c101_or_pld|TX_LEVEL); /* Abilitazione interrupts */ outw(0x3L, c101_or_pld|TX_INTERRUPT_ENABLE); outw(0x1L, c101_or_pld|ENABLE_INTERRUPTS); /* Start Link */ outw(START_LINK, c101_or_pld|LINK_COMMAND); /* Attesa Token */ token(c101_or_pld); linknum = 0; do { printf("\n\n\n\n"); printf("DESTINATION LINK NUMBER: %d\n\n", linknum); printf("<1> Change destination link\n\n"); printf("<2> Transmit\n\n"); printf("<3> Receive\n\n"); printf("<4> Exit program\n\n\n"); printf("Select a number <1...4> "); gets(leggicar); switch(leggicar[0]) { case '1': linknum=destinazione(c101_or_pld); break; case '2': trasmissione(c101_or_pld, address); break; case '3': ricezione(c101_or_pld, address); break; default : break; } }while (leggicar[0] != '4'); iopl(0); } /******************/ /* FUNZIONI UTILI */ /******************/ /* gettimeofday(&tempo1, &zona); gettimeofday(&tempo2, &zona); microsec1 = tempo1.tv_usec; microsec2 = tempo2.tv_usec; sec1 = tempo1.tv_sec; sec2 = tempo2.tv_sec; printf("delay %d\n", (sec2-sec1)); printf("delay %d\n", (microsec2-microsec1)); */ Programma di comunicazione mediante le schede “PCI-DSLink INFN” attraverso un numero qualsiasi di STC104: INFNboard.c /*****************************************************************/ /* Nome File: INFNboard.c */ /* */ /* Programma per effettuare comunicazioni a pacchetti mediante */ /* le schede PCI-DSLink di Mascagni Matteo con interfaccia token */ /* disabilitata. */ /* */ /* Autore: Alfredo Babusci */ /* [email protected] */ /* Revisione 01/98 */ /*****************************************************************/ #include #include #include #include #include #include #include <stdio.h> <stdlib.h> <unistd.h> <asm/io.h> <sys/time.h> "amcc.h" "Mboard.h" /*****************************/ /* Funzione 'premi un tasto' */ /*****************************/ void premi() { printf("\n"); printf("Press a key... "); getchar(); } /**********************/ /* Funzione 'delay' */ /**********************/ void delay(int milli) { int microsec1, microsec2, temp; struct timeval tempo1, tempo2; struct timezone zona; gettimeofday(&tempo1, &zona); microsec1 = tempo1.tv_usec; do { gettimeofday(&tempo2, &zona); microsec2 = tempo2.tv_usec; temp = microsec2-microsec1; if (temp < 0) temp = (1000000-microsec1) + microsec2; } while (temp < milli); } /**************************/ /* Procedura attesa token */ /**************************/ void token(word link) { int link_status; printf("WAIT FOR TOKEN...\n"); do { link_status=inw(link|LINK_STATUS); if(link_status & LINK_STATUS_ERROR) { outl((RESET_LINK<<16)|0xffff, link|LINK_COMMAND); delay(1000); outl((START_LINK<<16)|0xffff, link|LINK_COMMAND); delay(1000); } } while(link_status & LINK_STATUS_ERROR || !(link_status & TOKEN_RECEIVED)); /* Start Link */ outl((START_LINK<<16)|0xffff, link|LINK_COMMAND); delay(1000); } /**********************************/ /* Procedura link di destinazione */ /**********************************/ int destinazione(word link) { char inserisci[10]; int linknum; printf("Insert link number "); gets(inserisci); linknum = atoi(inserisci); /* Inizializzazione testa del pacchetto */ outl((linknum<<16)|0xffff, link|TX_PACKET_HEADER_LOWER_0); delay(1000); outl((linknum<<16)|0xffff, link|TX_PACKET_HEADER_UPPER_0); delay(1000); return(linknum); } /****************************************/ /* Procedura di calcolo delle velocita' */ /****************************************/ void rate(double cnt[10000], int cicli, int numbyte) { int double j, clock; massimo, minimo, media, velocita; media = 0; massimo = 0; minimo = 999999999; clock = 90000000; /* Clock a 90 Mhz */ for (j=1; j<cicli; j++) { cnt[j] = (cnt[j] - 12); media = media + cnt[j]; if (cnt[j] > massimo) massimo = cnt[j]; if (cnt[j] < minimo) minimo = cnt[j]; } media = media / (cicli - 1); velocita = (numbyte * 953.6743164 ) / media; printf("\n"); printf("TEMPO MEDIO TRA-RIC (ns) %f\n\n", media); printf("TEMPO MINIMO TRA-RIC (ns) %d\n\n", minimo); printf("TEMPO MASSIMO TRA-RIC (ns) %d\n\n", massimo); printf("SCARTO (ns) %d\n\n", massimo-minimo); printf("VELOCITA' (Mbytes/s) %f\n", velocita); printf("END.\n"); } /************************************/ /* Procedura di ricezione pacchetti */ /************************************/ void ricezione(word link) { int i, j, cicli, numbyte; int dimvettore = 4096; word VettoreArrivo[dimvettore]; char inserisci[10]; printf("\n\n"); printf("Ricezione pacchetti \n\n"); printf("\n\n"); printf("Insert cycles number "); gets(inserisci); cicli = atoi(inserisci); printf("\n\n"); /* Azzeramento Vettore Arrivo */ for (i=0; i<dimvettore; i++) VettoreArrivo[i] = 0; /* Acknowledge per azzeramento bits di interrupt */ outl(((ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID)<<16|0xf fff),link|RX_ACKNOWLEDGE); delay(1000); for (i=0; i<cicli; i++) { /* Controllo in ricezione */ do { } while(!(inw(link|RX_INTERRUPT_STATUS)&HDR_VALID)); numbyte = 4096; /* Ricezione */ for (j=0; j<(numbyte/2); j++) { VettoreArrivo[j] = inw(link|RX_DATA_16_BIT); if ((inw(link|RX_INTERRUPT_STATUS)&0xc)!=0) numbyte = inw(link|RX_PACKET_LENGTH); } /* Acknowledge dopo la ricezione */ outl(((ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID)<<16|0xf fff),link|RX_ACKNOWLEDGE); printf("DATO RICEVUTO = %s\n", VettoreArrivo); printf("CICLO = %d\n", i+1); } printf("END RECEPTION \n"); } /***************************************/ /* Procedura di trasmissione pacchetti */ /***************************************/ void trasmetti(word link) { int i, j, cicli, numbyte; char inserisci[10]; int dimvettore = 4096; word VettorePartenza[dimvettore]; unsigned int cnt1, cnt2, cnt3; double cnt[10000]; printf("\n\n"); printf("Insert cycles number "); gets(inserisci); cicli = atoi(inserisci); printf("\n"); printf("Insert packets length <2,8,16,32,64,128,256,512,1024,2048 bytes>"); gets(inserisci); numbyte = atoi(inserisci); printf("\n\n"); /* Azzeramento Vettore Partenza */ for (i=0; i<dimvettore; i++) VettorePartenza[i] = 0; /* Inizializzazione Vettore Partenza */ for (i=0; i<(numbyte/2); i++) VettorePartenza[i] = 'aa'; for (i=0; i<cicli; i++) { __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt3)); /* Abilitazione TX SEND PACKET */ outl(((TERMINATOR_ENABLE|EOP_TERMINATOR|HEADER_ENABLE| HEADER_SELECT_0|numbyte)<<16|0xffff), link|TX_SEND_PACKET); /* Controllo in trasmissione */ do { } while((inw(link|TX_INTERRUPT_STATUS))&C101_TX_LEVEL); /* Trasmissione */ for (j=0; j<(numbyte/2); j++) outl((VettorePartenza[j]<<16)|0xffff, link|TX_DATA_16_BIT); printf("HO TRASMESSO %s\n", VettorePartenza); printf("CICLO = %d\n", i+1); __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt3)); cnt[i] = cnt2-cnt1; } printf("END TRANSMISSION \n"); rate(cnt, cicli, numbyte); } /********/ /* Main */ /********/ void main(void) { unsigned int classcode; unsigned short val, indice; unsigned char bus_num, dev_fun; dword base_adr1, base_adr2; word primo_C101, secondo_C101; int i, j, k, ii, liv, numpac, numbyte; int etichetta, cicli, linknum, temp, bandiera; char leggicar[1], inserisci[10]; struct timeval tempo1, tempo2; struct timespec tempo3, tempo4; struct timezone zona; long nanosec1, nanosec2; int microsec1, microsec2; long sec1, sec2; /* Funzione che inizializza le operazioni sul PCI */ pcidev_init(); if (pcibios_present()) printf ("PCIBIOS PRESENT \n\n"); if (pcibios_find_device(0x10e8, 0x811a, 0x00, &bus_num, &dev_fun) == 0) { printf ("DEVICE FOUND\n"); printf ("BUS NUMBER = %x\n", bus_num); printf ("DEVICE NUMBER = %x\n", dev_fun); } else printf ("%x\n", pcibios_find_device(0x10e8, 0x811a, 0x00, &bus_num, &dev_fun)); printf ("\n"); /* Lettura degli indirizzi base */ pcibios_read_config_dword(bus_num, dev_fun, PCI_CS_BASE_ADDRESS_1,&base_adr1); pcibios_read_config_dword(bus_num, dev_fun, PCI_CS_BASE_ADDRESS_2,&base_adr2); primo_C101 = (word)base_adr1 - 1; secondo_C101 = (word)base_adr2 - 1; printf ("FIRS C101 = %x\n", primo_C101); printf ("SECOND C101 = %x\n", secondo_C101); iopl(3); printf ("DEVICE ID FIRST C101= %x\n", inw(primo_C101|DEVICE_ID)); printf ("DEVICE REVISION FIRST C101= %x\n", inw(primo_C101|DEVICE_REVISION)); printf ("DEVICE ID SECOND C101= %x\n", inw(secondo_C101|DEVICE_ID)); printf ("DEVICE REVISION SECOND C101= %x\n", inw(secondo_C101|DEVICE_REVISION)); delay(2000); /* Reset Link */ outl((RESET_LINK<<16)|0xffff, primo_C101|LINK_COMMAND); delay(1000); outl((RESET_LINK<<16)|0xffff, secondo_C101|LINK_COMMAND); delay(1000); /* Abilitazione pacchettizzazione */ outl(((SUPPRESS_RX_EOX|ENABLE_PACKETIZATION|RX_HEADER_LENGTH_1)<<16) |0xffff, secondo_C101|DEVICE_CONFIG); delay(1000); outl(((SUPPRESS_RX_EOX|ENABLE_PACKETIZATION|RX_HEADER_LENGTH_1)<<16) |0xffff, primo_C101|DEVICE_CONFIG); delay(1000); /* Set 100 Mbit/s */ outl(((WRITE_1|SPEED_SELECT|_100MBIT)<<16)|0xffff, primo_C101|LINK_MODE); delay(1000); outl(((WRITE_1|SPEED_SELECT|_100MBIT)<<16)|0xffff, secondo_C101|LINK_MODE); delay(1000); /* Lunghezza testa pacchetti partenza (bytes) */ outl(0x2ffff, primo_C101|TX_HEADER_LENGTH_0); delay(1000); outl(0x2ffff, secondo_C101|TX_HEADER_LENGTH_0); delay(1000); /* Abilitazione interrupts */ outl(0x3ffff, primo_C101|TX_INTERRUPT_ENABLE); delay(1000); outl(0x3ffff, secondo_C101|TX_INTERRUPT_ENABLE); delay(1000); outl((INTERRUPTS_ENABLED<<16)|0xffff, primo_C101|ENABLE_INTERRUPTS); delay(1000); outl((INTERRUPTS_ENABLED<<16)|0xffff, secondo_C101|ENABLE_INTERRUPTS); delay(1000); /* Inizializzazione TxFIFO Level */ outl(((TX_LEVEL_0|TX_LEVEL_HIGH)<<16)|0xffff, primo_C101|TX_LEVEL); delay(1000); outl(((TX_LEVEL_0|TX_LEVEL_HIGH)<<16)|0xffff, secondo_C101|TX_LEVEL); delay(1000); /* Start Link */ outl((START_LINK<<16)|0xffff, primo_C101|LINK_COMMAND); delay(1000); outl((START_LINK<<16)|0xffff, secondo_C101|LINK_COMMAND); delay(1000); /* attesa token */ token(primo_C101); linknum = 0; do { printf("\n\n"); printf("DESTINATION LINK NUMBER: %d\n\n", linknum); printf("<1> Change destination link\n\n"); printf("<2> Transmit\n\n"); printf("<3> Receive\n\n"); printf("<4> Exit program\n\n\n"); printf("Select a number <1...4> "); gets(leggicar); switch(leggicar[0]) { case '1': linknum=destinazione(primo_C101); break; case '2': trasmetti(primo_C101); break; case '3': ricezione(primo_C101); break; default : break; } }while (leggicar[0] != '4'); iopl(0); } /******************/ /* FUNZIONI UTILI */ /******************/ /* gettimeofday(&tempo1, &zona); gettimeofday(&tempo2, &zona); microsec1 = tempo1.tv_usec; microsec2 = tempo2.tv_usec; sec1 = tempo1.tv_sec; sec2 = tempo2.tv_sec; printf("delay %d\n", (sec2-sec1)); printf("delay %d\n", (microsec2-microsec1)); */ Programma di comunicazione mediante le schede “PCI-DSLink Zeuthen” attraverso un numero qualsiasi di STC104. Permette di calcolare le velocità di comunicazione e di salvare i risultati su file: Z_misure_dati.c /***************************************************************/ /* Nome File : Z_misure_dati.c */ /* */ /* Programma per effettuare comunicazioni a pacchetti mediante */ /* le schede di Zeuthen (K.H. Sulanke) con interfaccia token */ /* abilitata, tramite la S5933-FIFO e la FIFO on-board. */ /* Permette di misurare le velocita' di comunicazione */ /* e di registrare i risultati su file. */ /* Autore : Alfredo Babusci */ /* [email protected] */ /* */ /* Revisione : 01/98 */ /***************************************************************/ #include #include #include #include #include #include #include #include <stdio.h> <stdlib.h> <unistd.h> <asm/io.h> <sys/time.h> <math.h> "amcc.h" "dslink.h" /*****************************/ /* Funzione 'premi un tasto' */ /*****************************/ void premi() { printf("\n"); printf("Press a key... "); getchar(); } /**********************/ /* Funzione 'delay' */ /**********************/ void delay(int milli) { int microsec1, microsec2, temp; struct timeval tempo1, tempo2; struct timezone zona; gettimeofday(&tempo1, &zona); microsec1 = tempo1.tv_usec; do { gettimeofday(&tempo2, &zona); microsec2 = tempo2.tv_usec; temp = microsec2-microsec1; if (temp < 0) temp = (1000000-microsec1) + microsec2; } while (temp < milli); } /**************************/ /* Procedura attesa token */ /**************************/ void token(word c101_or_pld) { int link_status; printf("WAIT FOR TOKEN...\n"); do { link_status=inw(c101_or_pld|LINK_STATUS); if(link_status & LINK_STATUS_ERROR) { outl(RESET_LINK, c101_or_pld|LINK_COMMAND); delay(1000); outl(START_LINK, c101_or_pld|LINK_COMMAND); delay(1000); } } while(link_status & LINK_STATUS_ERROR || !(link_status & TOKEN_RECEIVED)); } /**********************************/ /* Procedura link di destinazione */ /**********************************/ int destinazione(word c101_or_pld) { char inserisci[10]; int linknum; printf("Insert link number "); gets(inserisci); linknum = atoi(inserisci); /* Inizializzazione testa del pacchetto (2 teste - 2 bytes) */ outl((0xfL|(linknum<<8)) & 0xffffL, c101_or_pld|TX_PACKET_HEADER_LOWER_0); delay(1000); return(linknum); } /**************************************************/ /* Procedura di calcolo delle velocita' con errori*/ /**************************************************/ void rate(unsigned int cnt[10000], int cicli, int numbyte) { int j; unsigned int massimo, minimo, clock; double tempo[10000]; double tempom, tmax, tmin, velocita; double media, deltaT, deltaV; char inserisci[15]; FILE *dati; media = 0; massimo = 0; deltaT = 0; deltaV = 0; velocita = 0; minimo = 999999999; clock = 166000000; /* 166 MHz */ printf("\n"); printf("Inserisci il nome del file : "); gets(inserisci); printf("\n"); dati = fopen(inserisci, "w"); for (j=1; j<cicli; j++) { cnt[j] = (cnt[j]-13); tempo[j] = (double)cnt[j] / clock; fprintf(dati, "%d\n", cnt[j]); if (cnt[j] > massimo) massimo = cnt[j]; if (cnt[j] < minimo) minimo = cnt[j]; } fclose(dati); /* Calcolo del tempo medio con relativo errore */ for (j=1; j<cicli; j++) media = media + (double)cnt[j]/(cicli-1); tempom = media / clock; /* tempo medio */ for (j=1; j<cicli; j++) deltaT = deltaT + (double)(pow((tempom - tempo[j]), 2)); deltaT = sqrt(deltaT / (cicli-2)) ; /* Calcolo della velocita' e relativo errore */ velocita = ((double)numbyte /(1024*1024)) / tempom; deltaV = numbyte*deltaT/(pow(tempom, 2)*1024*1024); tmax = (double)massimo / clock; tmin = (double)minimo / clock; printf("\n"); printf("DeltaCNT %9.0f\n\n", media); printf("TEMPO MEDIO TRA-RIC (s) %.12f\n", tempom); printf("ERRORE SUL TEMPO MEDIO (s) %.12f\n", deltaT); printf("TEMPO MINIMO TRA-RIC (s) %.12f\n", tmin); printf("TEMPO MASSIMO TRA-RIC (s) %.12f\n", tmax); printf("SCARTO (s) %.12f\n\n", tmax-tmin); printf("VELOCITA' (Mbytes/s) %2.4f\n", velocita); printf("ERRORE SULLA VELOCITA' %2.4f\n\n", deltaV); printf("END.\n"); premi(); } /*****************************************************/ /* Procedura di ricezione --> trasmissione pacchetti */ /*****************************************************/ void ricezione(word c101_or_pld, word address) { int i, j, cicli, numbyte; int dimvettore = 4096; dword VettoreArrivo[dimvettore]; dword VettorePartenza[dimvettore]; char inserisci[10]; printf("\n\n"); printf("Receive/Transmit Packets \n\n"); printf("\n\n"); printf("Insert cycles number "); gets(inserisci); cicli = atoi(inserisci); printf("\n"); printf("Insert packets length <2,8,16,32,64,128,256,512,1024,2048 bytes>"); gets(inserisci); numbyte = atoi(inserisci); printf("\n\n"); /* Azzeramento Vettore Arrivo */ for (i=0; i<dimvettore; i++) VettoreArrivo[i] = 0; /* Azzeramento Vettore Partenza */ for (i=0; i<dimvettore; i++) VettorePartenza[i] = 0; /* Acknowledge per azzeramento bits di interrupt */ outw(ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID, c101_or_pld|RX_ACKNOWLEDGE); delay(1000); for (i=0; i<cicli; i++) { /*************/ /* RICEZIONE */ /*************/ /* Controllo in ricezione */ do { } while(!(inw(c101_or_pld|ISR)&HEADER_VALID)); /* Ricezione */ for (j=0; j<(numbyte/4); j++) VettoreArrivo[j] = inl(address); /* Acknowledge dopo la ricezione */ outw(ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID, c101_or_pld|RX_ACKNOWLEDGE); /****************/ /* TRASMISSIONE */ /****************/ /* Abilitazione TX SEND PACKET */ outw(TERMINATOR_ENABLE|EOP_TERMINATOR|HEADER_ENABLE| HEADER_SELECT_0|numbyte, c101_or_pld|TX_SEND_PACKET); /* Controllo in trasmissione */ do { } while(((inw(c101_or_pld|TX_INTERRUPT_STATUS))&0x1L)); /* Trasmissione */ for (j=0; j<(numbyte/4); j++) outl(VettoreArrivo[j], address); } printf("END.\n"); } /*****************************************************/ /* Procedura di trasmissione --> ricezione pacchetti */ /*****************************************************/ void trasmric(word c101_or_pld, word address) { int i, j, cicli, numbyte; char inserisci[10]; int dimvettore = 4096; dword VettorePartenza[dimvettore]; dword VettoreArrivo[dimvettore]; unsigned int cnt1, cnt2, cnt3; unsigned int cnt[10000]; printf("\n\n"); printf("Insert cycles number "); gets(inserisci); cicli = atoi(inserisci); printf("\n"); printf("Insert packets length <2,8,16,32,64,128,256,512,1024,2048 bytes>"); gets(inserisci); numbyte = atoi(inserisci); printf("\n\n"); /* Azzeramento Vettore Partenza */ for (i=0; i<dimvettore; i++) VettorePartenza[i] = 0; /* Inizializzazione Vettore Partenza */ for (i=0; i<(numbyte/4); i++) VettorePartenza[i] = 'amoR'; /* Azzeramento Vettore Arrivo */ for (i=0; i<dimvettore; i++) VettoreArrivo[i] = 0; /* Acknowledge per azzeramento bits di interrupt */ outw(ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID, c101_or_pld|RX_ACKNOWLEDGE); delay(1000); for (i=0; i<cicli; i++) { __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt3)); /****************/ /* TRASMISSIONE */ /****************/ /* Abilitazione TX SEND PACKET */ outw(TERMINATOR_ENABLE|EOP_TERMINATOR|HEADER_ENABLE| HEADER_SELECT_0|numbyte, c101_or_pld|TX_SEND_PACKET); /* Controllo in trasmissione */ do { } while(((inw(c101_or_pld|TX_INTERRUPT_STATUS))&0x1L)); /* Trasmissione */ for (j=0; j<(numbyte/4); j++) outl(VettorePartenza[j], address); /*************/ /* RICEZIONE */ /*************/ /* Controllo in ricezione */ do { } while(!(inw(c101_or_pld|ISR)&HEADER_VALID)); /* Ricezione */ for (j=0; j<(numbyte/4); j++) VettoreArrivo[j] = inl(address); /* Acknowledge dopo la ricezione */ outw(ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID, c101_or_pld|RX_ACKNOWLEDGE); __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt3)); cnt[i] = (cnt2-cnt1); } printf("END. \n"); rate(cnt, cicli, numbyte); } /********/ /* Main */ /********/ void main(void) { unsigned int classcode; unsigned short val, indice; unsigned char bus_num, dev_fun; dword base_adr0, base_adr1; word op_regs_base, c101_or_pld, address; int i, j, k, ii, liv, numpac, numbyte; int etichetta, cicli, linknum, temp, link_status, bandiera; char leggicar[1], inserisci[10]; struct timeval tempo1, tempo2; struct timespec tempo3, tempo4; struct timezone zona; long nanosec1, nanosec2; int microsec1, microsec2; long sec1, sec2; /* Funzione che inizializza le operazioni sul PCI */ pcidev_init(); if (pcibios_present()) printf ("PCIBIOS PRESENTE \n\n"); if (pcibios_find_device(0x1234, 0x5678, 0x00, &bus_num, &dev_fun) == 0) { printf ("DEVICE TROVATO\n"); printf ("BUS = %x\n", bus_num); printf ("DEVICE = %x\n", dev_fun); } else printf ("%x\n", pcibios_find_device(0x1234, 0x5678, 0x00, &bus_num, &dev_fun)); printf ("\n"); /* Lettura degli indirizzi base */ pcibios_read_config_dword(bus_num, dev_fun, PCI_CS_BASE_ADDRESS_0,&base_adr0); pcibios_read_config_dword(bus_num, dev_fun, PCI_CS_BASE_ADDRESS_1,&base_adr1); op_regs_base = (word)base_adr0 & 0xfffc; c101_or_pld = (word)base_adr1 & 0xfffc; address = op_regs_base|AMCC_OP_REG_FIFO; printf printf printf printf printf ("BASE ADR 0 = %x\n", base_adr0); ("BASE ADR 1 = %x\n", base_adr1); ("ADDRESS = %x\n", address); ("OP REG BASE = %x\n", op_regs_base); ("C101 REGS BASE = %x\n", c101_or_pld); iopl(3); printf ("DEVICE ID = %x\n", inw(c101_or_pld|DEVICE_ID)); printf ("DEVICE ID = %x\n", inw(c101_or_pld|DEVICE_REVISION)); /* Abilita accesso I/O */ pcibios_write_config_word(bus_num, dev_fun, PCI_CS_COMMAND, IO_ACCESS_ENABLE); /* S5933 - Reset */ outl(GLOBAL_RESET, op_regs_base|AMCC_OP_REG_MCSR); delay(1000); outl(0L, op_regs_base|AMCC_OP_REG_MCSR); /* Abilitazione Token interface */ outl(MASTER_MODE|TOKEN_ENABLE|FIFO_RESET, c101_or_pld|ICR); /* Abilitazione pacchettizzazione */ outw(SUPPRESS_RX_EOX|ENABLE_PACKETIZATION|RX_HEADER_LENGTH_1, c101_or_pld|DEVICE_CONFIG); /* Set 100 Mbit/s */ outw(WRITE_1|SPEED_SELECT|_100MBIT, c101_or_pld|LINK_MODE); /* Lunghezza testa pacchetti (bytes) */ outl(0x3L, c101_or_pld|TX_HEADER_LENGTH_0); /* Abilitazione master + token */ outl(MASTER_MODE|TOKEN_ENABLE, c101_or_pld|ICR); /* Set Tx FIFO LEVEL */ outw(TX_LEVEL_HIGH|TX_LEVEL_0, c101_or_pld|TX_LEVEL); /* Set Rx FIFO LEVEL */ outw(RX_LEVEL_HIGH|RX_LEVEL_0, c101_or_pld|RX_LEVEL); /* Abilitazione interrupts */ outw(0x3L, c101_or_pld|TX_INTERRUPT_ENABLE); outw(0x1L, c101_or_pld|ENABLE_INTERRUPTS); /* Start Link */ outw(START_LINK, c101_or_pld|LINK_COMMAND); /* Attesa Token */ token(c101_or_pld); linknum = 0; do { printf("\n\n"); printf("IEEE 1355 PACKET SENDER - RECEIVER \n\n"); printf("PERSONAL COMPUTER NAME : java \n"); printf("DESTINATION LINK NUMBER: %d\n\n", linknum); printf("<1> Change destination link \n\n"); printf("<2> Transmit --> Receive \n\n"); printf("<3> Receive --> Transmit \n\n"); printf("<4> Exit program \n\n\n"); printf("Select a number <1...4> "); gets(leggicar); switch(leggicar[0]) { case '1': linknum=destinazione(c101_or_pld); break; case '2': trasmric(c101_or_pld, address); break; case '3': ricezione(c101_or_pld, address); break; default : break; } }while (leggicar[0] != '4'); iopl(0); } /******************/ /* FUNZIONI UTILI */ /******************/ /* gettimeofday(&tempo1, &zona); gettimeofday(&tempo2, &zona); microsec1 = tempo1.tv_usec; microsec2 = tempo2.tv_usec; sec1 = tempo1.tv_sec; sec2 = tempo2.tv_sec; printf("delay %d\n", (sec2-sec1)); printf("delay %d\n", (microsec2-microsec1)); */ Programma di comunicazione mediante i due link di una unica scheda “PCIDSLink INFN” attraverso un numero qualsiasi di STC104: INFNlinklink.c /*****************************************************************/ /* Nome File: INFNlinklink.c */ /* */ /* Programma per effettuare comunicazioni a pacchetti mediante */ /* una unica scheda "PCI-DSLink INFN" (Dott. Mascagni Matteo) */ /* con interfaccia token disabilitata */ /* Permette inoltre di effettuare delle misure di velocita'. */ /* Autore: Alfredo Babusci */ /* [email protected] */ /* Revisione 01/98 */ /*****************************************************************/ #include #include #include #include #include #include #include <stdio.h> <stdlib.h> <unistd.h> <asm/io.h> <sys/time.h> "amcc.h" "Mboard.h" /*****************************/ /* Funzione 'premi un tasto' */ /*****************************/ void premi() { printf("\n"); printf("Press a key... "); getchar(); } /**********************/ /* Funzione 'delay' */ /**********************/ void delay(int milli) { int microsec1, microsec2, temp; struct timeval tempo1, tempo2; struct timezone zona; gettimeofday(&tempo1, &zona); microsec1 = tempo1.tv_usec; do { gettimeofday(&tempo2, &zona); microsec2 = tempo2.tv_usec; temp = microsec2-microsec1; if (temp < 0) temp = (1000000-microsec1) + microsec2; } while (temp < milli); } /********/ /* Main */ /********/ void main(void) { unsigned int classcode; unsigned short val, indice; unsigned char bus_num, dev_fun; int dimvettore = 4096; word VettorePartenza[dimvettore], VettoreArrivo[dimvettore]; dword base_adr1, base_adr2; word primo_C101, secondo_C101; int i, j, k, ii, liv, numpac, numbyte; int etichetta, cicli, linknum, temp, link_status, bandiera; char leggicar[1], inserisci[10]; struct timeval tempo1, tempo2; struct timespec tempo3, tempo4; struct timezone zona; long nanosec1, nanosec2; int microsec1, microsec2; long sec1, sec2; unsigned int cnt3, cnt2, cnt1; double cnt[100000], massimo, minimo; double media, velocita; /* Funzione che inizializza le operazioni sul PCI */ pcidev_init(); if (pcibios_present()) printf ("PCIBIOS PRESENTE \n\n"); if (pcibios_find_device(0x10e8, 0x811a, 0x00, &bus_num, &dev_fun) == 0) { printf ("DEVICE TROVATO\n"); printf ("BUS = %x\n", bus_num); printf ("DEVICE = %x\n", dev_fun); } else printf ("%x\n", pcibios_find_device(0x10e8, 0x811a, 0x00, &bus_num, &dev_fun)); printf ("\n"); /* Lettura degli indirizzi base */ pcibios_read_config_dword(bus_num, dev_fun, PCI_CS_BASE_ADDRESS_1,&base_adr1); pcibios_read_config_dword(bus_num, dev_fun, PCI_CS_BASE_ADDRESS_2,&base_adr2); primo_C101 = (word)base_adr1 - 1; secondo_C101 = (word)base_adr2 - 1; printf ("PRIMO C101 = %x\n", primo_C101); printf ("SECONDO C101 = %x\n", secondo_C101); iopl(3); printf ("DEVICE ID PRIMO C101= %x\n", inw(primo_C101|DEVICE_ID)); printf ("DEVICE REVISION PRIMO C101= %x\n", inw(primo_C101|DEVICE_REVISION)); printf ("DEVICE ID SECONDO C101= %x\n", inw(secondo_C101|DEVICE_ID)); printf ("DEVICE REVISION SECONDO C101= %x\n", inw(secondo_C101|DEVICE_REVISION)); delay(2000); /* Reset Link */ outl((RESET_LINK<<16)|0xffff, primo_C101|LINK_COMMAND); delay(1000); outl((RESET_LINK<<16)|0xffff, secondo_C101|LINK_COMMAND); delay(1000); /* Abilitazione pacchettizzazione */ outl(((SUPPRESS_RX_EOX|ENABLE_PACKETIZATION|RX_HEADER_LENGTH_1)<<16) |0xffff, secondo_C101|DEVICE_CONFIG); delay(1000); outl(((SUPPRESS_RX_EOX|ENABLE_PACKETIZATION|RX_HEADER_LENGTH_1)<<16) |0xffff, primo_C101|DEVICE_CONFIG); delay(1000); /* Set 100 Mbit/s */ outl(((WRITE_1|SPEED_SELECT|_100MBIT)<<16)|0xffff, primo_C101|LINK_MODE); delay(1000); outl(((WRITE_1|SPEED_SELECT|_100MBIT)<<16)|0xffff, secondo_C101|LINK_MODE); delay(1000); /* Lunghezza testa pacchetti partenza (bytes) */ outl(0x2ffff, primo_C101|TX_HEADER_LENGTH_0); delay(1000); outl(0x2ffff, secondo_C101|TX_HEADER_LENGTH_0); delay(1000); /* Abilitazione interrupts */ outl(0x3ffff, primo_C101|TX_INTERRUPT_ENABLE); delay(1000); outl(0x3ffff, secondo_C101|TX_INTERRUPT_ENABLE); delay(1000); outl((INTERRUPTS_ENABLED<<16)|0xffff, primo_C101|ENABLE_INTERRUPTS); delay(1000); outl((INTERRUPTS_ENABLED<<16)|0xffff, secondo_C101|ENABLE_INTERRUPTS); delay(1000); /* Start Link */ outl((START_LINK<<16)|0xffff, primo_C101|LINK_COMMAND); delay(1000); outl((START_LINK<<16)|0xffff, secondo_C101|LINK_COMMAND); delay(1000); /* Ciclo di attesa token */ printf("ATTESA TOKEN...\n"); do { link_status=inw(primo_C101|LINK_STATUS); if(link_status & LINK_STATUS_ERROR) { outl((RESET_LINK<<16)|0xffff, primo_C101|LINK_COMMAND); delay(1000); outl((START_LINK<<16)|0xffff, primo_C101|LINK_COMMAND); delay(1000); } } while(link_status & LINK_STATUS_ERROR || !(link_status & TOKEN_RECEIVED)); printf("\n\n"); printf("Trasmissione e Ricezione pacchetti \n\n"); printf("Insert link number "); gets(inserisci); linknum = atoi(inserisci); do { printf("\n\n"); printf("Insert cycles number "); gets(inserisci); cicli = atoi(inserisci); printf("\n"); printf("Insert packets length <1,8,16,32,64,128,256,512,1024,2048 bytes> "); gets(inserisci); numbyte = atoi(inserisci); printf("\n\n"); /* Inizializzazione Vettore Partenza */ for (i=0; i<(numbyte/2); i++) VettorePartenza[i] = 'aa'; /* Azzeramento Vettore Arrivo */ for (i=0; i<dimvettore; i++) VettoreArrivo[i] = 0; /* Inizializzazione testa del pacchetto */ outl((linknum<<16)|0xffff, primo_C101|TX_PACKET_HEADER_LOWER_0); delay(1000); outl((linknum<<16)|0xffff, secondo_C101|TX_PACKET_HEADER_LOWER_0); delay(1000); /* Acknowledge per azzeramento bits di interrupt */ outl(((ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID)<<16|0xf fff),primo_C101|RX_ACKNOWLEDGE); delay(1000); /*****************************/ /* Trasmissione -> Ricezione */ /*****************************/ for (i=0; i<cicli; i++) { __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt3)); /* Abilitazione TX SEND PACKET */ outl(((TERMINATOR_ENABLE|EOP_TERMINATOR|HEADER_ENABLE| HEADER_SELECT_0|numbyte)<<16|0xffff), secondo_C101|TX_SEND_PACKET); /* Trasmissione */ for (j=0; j<(numbyte/2); j++) outl((VettorePartenza[j]<<16)|0xffff, secondo_C101|TX_DATA_16_BIT); printf("TRASMISSIONE N. %d\n", i+1); /* Controllo in ricezione */ do { } while((inw(primo_C101|RX_INTERRUPT_STATUS)&0x2)==0); numbyte = 0; numbyte = inw(primo_C101|RX_PACKET_LENGTH); printf("NUMERO DI BYTES IN RICEZIONE %d\n", numbyte); /* Ricezione */ for (j=0; j<(numbyte/2); j++) VettoreArrivo[j] = inw(primo_C101|RX_DATA_16_BIT); printf("TERMINATORE %x\n", inw(primo_C101|RX_INTERRUPT_STATUS)); /* Acknowledge dopo la ricezione */ outl(((ACK_EOM_RXED|ACK_EOP_RXED|ACK_ACK_RXED|ACK_HDR_VALID)<<16|0xf fff),primo_C101|RX_ACKNOWLEDGE); printf("DATO RICEVUTO = %s\n", VettoreArrivo); printf("RICEZIONE N. %d\n", i+1); __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt3)); cnt[i] = (cnt2-cnt1-30); } printf("END RECEPTION \n"); media = 0; massimo = 0; minimo = 999999999; /* clock a 75 Mhz */ for (j=1; j<cicli; j++) { cnt[j]/=0.075; media = media + cnt[j]; if (cnt[j] > massimo) massimo = cnt[j]; if (cnt[j] < minimo) minimo = cnt[j]; } media = media / (cicli - 1); velocita = (numbyte * 953.6743164 *2) / media; printf("\n"); printf("TEMPO MEDIO TRA-RIC (ns) %f\n\n", media); printf("TEMPO MINIMO TRA-RIC (ns) %d\n\n", minimo); printf("TEMPO MASSIMO TRA-RIC (ns) %d\n\n", massimo); printf("SCARTO (ns) %d\n\n", massimo-minimo); printf("VELOCITA' (Mbytes/s) %f\n", velocita); printf("END.\n"); leggicar[0] = 'x'; printf("\n\n\n"); printf("Communication - Exit (c-e) ?\n"); gets(leggicar); }while (leggicar[0] !='e'); iopl(0); } /******************/ /* FUNZIONI UTILI */ /******************/ /* gettimeofday(&tempo1, &zona); gettimeofday(&tempo2, &zona); microsec1 = tempo1.tv_usec; microsec2 = tempo2.tv_usec; sec1 = tempo1.tv_sec; sec2 = tempo2.tv_sec; printf("delay %d\n", (sec2-sec1)); printf("delay %d\n", (microsec2-microsec1)); */ Programma per la conversione di file da binario ad esadecimale: converti.c /***********************************************/ /* Nome File : converti.c */ /* */ /* Programma per convertire dei file dal */ /* formato binario al formato esadecimale */ /* */ /* Autore : Alfredo Babusci */ /* [email protected] */ /* */ /* Revisione : 02/97 */ /***********************************************/ #include <stdio.h> #include <stdlib.h> void main(void) { FILE int int char *stringa; buffer[2000]; i, ii; inserisci[15]; printf("\n\n"); printf("Convertitore di file da binario ad esadecimale\n"); printf("\n\n"); printf("Inserisci il nome del file sorgente (binario) : "); gets(inserisci); stringa = fopen (inserisci,"rb"); i=0; while ((fread(&buffer[i], sizeof(int), 1, stringa)==1)) i++; fclose(stringa); printf("\n\n"); printf("Inserisci il nome del file di destinazione : "); gets(inserisci); printf("\n"); stringa = fopen (inserisci, "w"); for (ii=0; ii<i; ii++) fprintf(stringa, "%x\n", buffer[ii]); fclose(stringa); printf("Conversione effettuata.\n"); } APPENDICE D Esempio di programmazione di un registro dello switch STC101. In queste pagine si vuole fornire un esempio di programmazione del registro TxSendPacket del C101. La scrittura di questo registro è necessaria ogni volta che si vuole inviare un pacchetto (o un messaggio) in uscita, al fine di fornire le informazioni per l’instradamento (informazioni di routing). Il registro TxSendPacket contiene 5 campi con la denominazione e la lunghezza riportati nella tabella D.1: Registro TxSendPacket Bit Nome del campo 11:0 PacketLength 12 13 HeaderEnable HeaderSelect 14 TerminatorEnabl e TerminatorType 15 offset #4 – read/write Funzione Determina la lunghezza del pacchetto in trasmissione. Se posto ad “1” aggiunge una testa al pacchetto. Determina quali registri contengono la testa del pacchetto e la sua lunghezza: “0” → TxPacketHeader0 e TxHeaderLength0 “1” → TxPacketHeader1 e TxHeaderLength1 Se posto ad “1” aggiunge un terminatore al pacchetto. Determina il tipo di terminatore da aggiungere: “0” → EOM “1” → EOP Tabella D.1:Campi del registro TxSendPacket e loro funzioni. Supponiamo di voler inviare su un link di uscita un messaggio da 1 Kbyte; è allora necessario scrivere nei campi menzionati la seguente configurazione: outw(numero_byte|testa_abilitata|selezione_testa|terminatore_abilitato| tipo_terminatore, indirizzo_base|TX_SEND_PACKET); con: 1. numero_byte = 1024 (1 Kbyte); 2. testa_abilitata = 1; 3. selezione_testa = 0; 4. terminatore_abilitato = 1; 5. tipo_terminatore = 0. La impostazione n°1 riguarda il numero di byte di cui è costituito il pacchetto: la variabile corrispondente (numero_byte) è posta quindi a 1024 (1 Kbyte). La seconda abilita il C101 ad aggiungere una testa al pacchetto in uscita (testa_abilitata = 1); il valore della testa e la sua lunghezza in byte sono contenuti in due registri indicati dalla variabile selezione_testa (punto 3 e tabella D.1). Il punto 4 indica invece al C101 di aggiungere un terminatore ai pacchetti (terminatore_abilitato). Il tipo di terminatore viene infine deciso mediante l’ultimo set (tipo_terminatore = 0 ovvero terminatore del tipo EOM). Tutti questi valori vengono sommati tra loro dall’operatore “ | ” (OR bit a bit) e scritti in un indirizzo fornito nel secondo campo dell’istruzione. A sua volta quest’ultimo è costituito da un indirizzo base dello spazio di I/O del PC, a partire dal quale sono accessibili i registri della scheda PCI-DSLink (tra cui il C101), più uno sfasamento (offset - #4) che viene sommato allo indirizzo_base per raggiungere il registro specifico (in questo caso TxSendPacket). BIBLIOGRAFIA. [1] AMCC, “S5933 PCI Matchmaker Controller Data Book”, Applied Micro Circuit Corporation, 1996. [2] AT&T, “The 41 Series of High Performance Line Drivers, Receivers, Transceivers”. [3] ATLAS Collaboration, “ATLAS Technical Proposal for a General Purpose pp Experiment at the Large Hadrone Collider at CERN”, 1994. [4] ATLAS Collaboration, “Level-2 Trigger User Requirements Document.”, Level-2 Requirements group. [5] Andrew S. Tanenbaum, “Reti di computer”, gruppo Editoriale Jackson, 1995. [6] Barry M. Cook, “Data-strobe Links and Virtual Channel Processors”, IOS Press, 1997. [7] Brian W. Kernighan - Dennis M. Ritchie, “Linguaggio C”, Gruppo Editoriale Jackson, 1988. [8] Dimitri Bertsekas - Robert Gallager, “Data Networks”, Prentice Hall, 1992. [9] Donald H. Perkins, “Introduction to High Energy Physics”, third edition 1987. [10] E. Solari & G. Willse, “PCI Hardware and Software Architecture & Design”, 3a edizione. [11] Giacomo Cioffi - Vincenzo Falzone, “Manuale di Informatica”, Calderini, 1986. [12] IEEE 1355, “An Introduction to IEEE 1355”, http://www.1355- association.org/ [13] J.F. Wakerly, “Microcomputer Architecture and Programming”, J. Wiley, 1981. [14] K.H. Sulanke, “PCI to Data Strobe Link – Description”, Rev. 2.4. [15] M.D. May - P.W.Thompson - P.H. Welch, “Networks, Routers and Transputers”, SGS-Thomson, 1993. [16] Marco Severi, “Introduzione alla Esperimentazione Fisica”, Zanichelli, 1989. [17] Mascagni Matteo, “PCI Local Bus”, Maggio 1994. [18] Matt Welsh, “The Linux Bible”, Yggdrasil Computing Inc., 1995. [19] Naba Barkakati, “I segreti di Linux”, Apogeo, 1996. [20] PCI Special Interest Group, “PCI Bios Specification”, Agosto 1994. [21] PCI Special Interest Group, “PCI Local Bus”, http://www.pcisig.com/ [22] Rachel Morgan - Henry McGilton, “Unix System V”, McGraw-Hill, 1988. [23] Red Hat Development Team, “Red Hat Linux 4.2 Users Guide”, Red Hat Software Inc., 1996. [24] Ruggero Adinolfi, “Reti di computer”, Mc Graw-Hill Libri Italia srl, 1994. [25] Sandpile Organizzation, “Technical 80x86 processor informations”, http://www.sandpile.org [26] SGS-Thomson, “DS-Link Evaluation Kit Installation and User Guide”, 1995. [27] SGS-Thomson, “PC HTRAM Motherboard - IMS B108”, 1994. [28] SGS-Thomson, “STC101 Parallel DSLink Adaptor”, 1997. [29] SGS-Thomson, “STC104 Asynchronos Packet Switch – Engineering Data”, 1995. [30] SGS-Thomson, “T9000 ToolSet Hardware Configuration Manual”, 1994. [31] Prof. L. Zanello – Dr. S. Falciano – Dr. M. Mascagni - Dr. A. Nisati, comunicazione privata.