• Keine Ergebnisse gefunden

Sicheres Fenster = 5

Kapitel 5 - Hardware für die Simulation pulsverarbeitender neuronaler Netze

6.1. Aufbau der Evaluierungsplattform (PLD 53 -Karte)

6.1.3. Programmierumgebung

betragen. Die erforderliche Datenmenge für eine Konfiguration des Bausteins beträgt 2.740.000 Bits. Daraus ergibt sich eine Konfigurationsdauer von 164,4 ms für diesen Baustein. Im Vergleich dazu benötigt die Konfiguration des zurzeit größten von der Firma Altera verfügbaren Bausteins 360,33 ms, mit 12.011.000 Bits und einer Taktrate von 33 MHz. Die Rekonfiguration eines Moduls während des Betriebs lohnt sich daher nur, wenn die zwischen zwei Konfigurationsvorgängen stattfindenden Berechungen ein Vielfaches der angegebenen Konfigurationszeiten in Anspruch nehmen, es sei denn, be-schränkte Ressourcen erfordern ohnehin eine Rekonfiguration.

zurückgeliefert wird. Der Parameter Size enthält, nachdem die Methode zurückgekehrt ist, die tatsächlich in den Buffer übertragene Datenmenge.

Da weder die Sende- noch die Empfangsmethode blockierend ist, kann mit dieser Anwenderschnittstelle eine maximale Nebenläufigkeit realisiert werden.

Statusinformationen über die Konfiguration und den aktuellen Zustand der Karte wer-den dem Anwendungsprogrammierer durch eine entsprechende Klasse RacerControl angeboten. Diese Klasse unterstützt explizit nicht die Methoden SendData() und Recei-veData(), da die Kommunikation mit dem Controller lediglich über die Mailboxen des PCI-Kontollers abgewickelt wird und eine entsprechende Aufbereitung der Daten von-nöten ist. Es steht vielmehr ein beschränkter, aber erweiterbarer Satz von Befehlen (Tabelle 10) zur Verfügung, die vom Controller akzeptiert und verarbeitet werden.

Methodenname Funktion

CODE_INIT_RING Durch diesen Befehl wird die Hardware initialisiert. Im Zuge dieser Initialisierung werden auch die physikalischen Adressen der zusammenhängenden none-paged-Buffer durch Mailbox 2-4 übertragen, die durch den Treiber für jedes Modul angelegt werden müssen.

CODE_INIT_MID Durch diesen Befehl wird die physikalische Adresse des zu-sammenhängenden none-paged-Buffer für die Statusinformatio-nen der Hardware in Mailbox 2 übertragen.

CODE_MID_REQ Durch diesen Befehl wird der Mastertransfer der Statusinforma-tionen in den dafür vorgesehenen Buffer angestoßen.

CODE_INT_MASK Durch diesen Befehl wird die Interrupt-Maske der Add-On Hardware übertragen. Es soll dadurch möglich werden, die Hardware an spezielle Anforderungen anpassen zu können.

CODE_FIFO_TRIGGER Durch diesen Befehl werden die FIFO-Trigger gesetzt. Dies geschieht global, deshalb entfallen auch die Regions- und In/Out- Parameter.

CODE_SET_FIFO_OFFSET Der Befehl setzt die FIFO-Offsets. Aufgrund der zusätzlichen Parameter lässt sich jede FIFO einzeln ansprechen.

CODE_CLUSTER Durch diesen Befehl werden die Module geclustert. Der Region-Parameter wird folgendermaßen ausgewertet:

00 – kein Clustern

01 – Modul 1 und Modul 2 werden geclustert 10 – Modul 2 und Modul 3 werden geclustert 11 - alle 3 Module werde geclustert

CODE_READ_BUFFER Hiermit wird der Hardware mitgeteilt, dass aus dem DMA-Buffer gelesen wurde. Als Parameter werden die Region und der aktuelle Adress-Pointer übergeben.

CODE_READ_REG Der Befehl stellt eine Leseanforderung an die internen Register der Add-On Hardware dar. Der Parameter bezeichnet das zu lesende Register. Der Befehl ist primär für die interne Fehler-suche vorgesehen.

CODE_WRITE_BUFFER Hiermit wird dem Host mitgeteilt, dass Daten in den DMA-Buffer geschrieben wurden. Die Anzahl der geschriebenen Bytes wird durch einen zusätzlichen Parameter übergeben.

CODE_FIFO_READY Hierdurch wird dem Host mitgeteilt, dass die eingangsseitigen

FIFOs bereit sind, neue Daten aufzunehmen. Je nach Konfigu-ration haben die FIFOs dann einen bestimmten Füllstand unter-schritten oder sind leer. Als Parameter wird die entsprechende Region übergeben.

CODE_ERROR Dieser Code dient zur Fehlerkontrolle und liefert einen Error-code.

CODE_WRITE_REG Dieser Code ist die Reaktion der Hardware auf eine CODE_READ_REG Anforderung. Sie liefert zusätzlich die Register-Identifikation und den Inhalt des Registers.

CODE_PT_TIMEOUT CODE_AMBEF_TIMEOUT

CODE_AMBEF_GIVEUP_TIMEOUT

Diese Befehle stellen Time-outs für den Zugriff auf verschie-dene Register der Hardware ein, damit im Betrieb eine Blockade vermieden werden kann.

Tabelle 10: Liste der RACER-Befehle

Der Anwendungsprogrammierer kann sich mit Hilfe des Befehlssatzes sowohl über den Füllstand der FIFOs eines jeden Moduls in dem durch die Hardware gesteckten Rahmen informieren als auch über die aktuelle Modulkonfiguration (clustering) und die Art der installierten Module. Darüber hinaus können Leistungsdaten ausgewertet werden, die von der Hardware bereitgestellt werden.

6.1.3.2. Die Softwareschichten des Gerätetreibers

Der Gerätetreiber besteht aus zwei Teilen. Ein Teil läuft im so genannten Kernelmodus ab: der Kernel-mode-Treiber. Den zweiten Teil bildet die Anwenderschnittstelle, welche in Form einer dynamisch gebundenen Bibliothek (DLL) vorliegt. Sie bietet einem Anwendungsprogrammierer den Zugriff auf die RACER-Hardware über C++

Objekte.

6.1.3.2.1. Kernel-mode-Treiber

Der Kernel-mode-Treiber beinhaltet Routinen, die beim Systemstart, oder wenn das System zurückgesetzt wird, den PCI-Bus nach einer RACER-Karte absuchen. Sofern die RACER-Hardware aufgefunden wird, initialisiert sie der Kernel-mode-Treiber.

Diese Initialisierung beinhaltet das Mapping der gerätespezifischen Register, Interrupts und Speicherbereiche. Ferner werden durch den Kernel-mode-Treiber zusammen-hängende, nicht virtuelle Speicherbereiche für die Ringpuffer der einzelnen Module angelegt. Der Hardware werden die Startadressen und Größen dieser Ringpuffer über-mittelt. In der Hardware werden damit die Register für den DMA-Controller initialisiert. Die Größe der Ringpuffer ist so gewählt, dass sie den Inhalt eines ganzen FIFOs aufnehmen können (512kB). Abschließend wird ein Name in den Win32-Namensraum exportiert, unter welchem das Gerät RACER angesprochen werden kann.

Ist die Initialisierung erfolgreich abgeschlossen, stellt der Kernel-mode-Treiber die grundlegenden Routinen zur Ansteuerung der RACER-Karte zur Verfügung. Auf dieser für Geräte üblichen Schnittstelle setzt die Anwenderbibliothek auf.

6.1.3.2.2. Anwenderbibliothek

Die Bibliothek, welche die eingangs beschriebene Anwenderschnittstelle implementiert, stellt den blockadefreien Datenstrom zur und von der RACER-Hardware sicher. Hierfür ist es insbesondere notwendig, große Datenpakete, die der Anwender auf die Karte übertragen möchte, in kleinere Pakete zu zerlegen, da unter allen Umständen die

Be-schickung eines bereits vollen Modul-FIFOs vermieden werden muss. Andernfalls würde der Kernel-mode-Treiber in dem geforderten Transfer blockieren, bis wieder aus-reichend Platz im betreffenden FIFO verfügbar ist. Eine Ausführung paralleler Transfers in andere Module, bei denen noch eine entsprechende Kapazität vorhanden ist, wäre so nicht möglich.

Es werden daher immer nur Datenpakete transferiert, die maximal halb so groß wie ein Modul-FIFO sind. Die Hardware übermittelt dem Treiber jeweils einen Interrupt, wenn nach einem Transfer der Füllstand kleiner oder gleich der halben FIFO-Größe ist. Sie signalisiert damit die Bereitschaft, ein weiteres Datenpaket aufnehmen zu können. Vor jedem Transfer eines Datenpakets wird von der Anwenderbibliothek überprüft, ob der FIFO in der Lage ist, die Daten aufzunehmen, indem die entsprechende Information aus dem Treiber gelesen wird.

Dieser Mechanismus kann bei Bedarf anders konfiguriert werden, da für bestimmte Ap-plikationen eine andere Strategie zu höheren Datendurchsätzen führen kann. So könnten zum Beispiel immer eine komplette FIFO-Größe oder nahezu beliebig große Datenpa-kete zur Karte transferiert werden, wenn das betreffende Modul mit jedem PCI-Takt ein Wort aus dem FIFO verarbeitet, also der FIFO im Grunde immer nur ein Wort für einen Takt zwischenspeichert. Die maximale Datenmenge hängt in einem solchen Fall von der Zahl der vom Modul generierten Ergebnisworte ab, da ein voller Ausgangs-FIFO zu einem Rückstau in den Eingangs-FIFO des Moduls führt. Generiert zum Beispiel das Modul für jedes eingehende Datenwort ein Ausgangswort, so kann die maximale Größe des Datenpakets der dreifachen FIFO-Größe entsprechen, da der Ausgangs-FIFO durch das weiter unten beschriebene Verfahren automatisch in den Ringpuffer des Treibers geleert wird, sofern dieser noch eine entsprechende Kapazität aufweist.

Damit mehrere Transfers sowohl für ein Modul als auch für verschiedene Module kurz nacheinander gestartet werden können, werden für jeden Methodenaufruf, der einen sol-chen Transfer auslöst (SendData, CopyData oder MoveData), die den Transfer beschrei-benden Parameter58 in eine Warteschlange eingereiht. Für jedes Modul existieren eine FIFO-Warteschlange und ein sie verwaltender Thread. Der verwaltende Thread ent-nimmt jeweils den ältesten Eintrag aus der Warteschlange und startet den eigentlichen Schreib-Thread, welcher den Transfer ausführt. Schreib-Threads für unterschiedliche Module laufen konkurrierend ab.

Der Rücktransfer der Daten läuft vollständig nebenläufig, da die RACER-Hardware nach zuvor einstellbaren Kriterien die Ausgangs-FIFOs der Module entleert. Es kann auf alle durch den FIFO bereitgestellten und programmierbaren FIFO-Flags reagiert werden. Erfüllen mehrere Ausgangs-FIFOs die Kriterien für einen Rücktransfer, so werden die Daten reihum aus den FIFOs entleert, wobei jeweils maximal eine komplette FIFO-Füllung transferiert wird. Ein Rücktransfer ist natürlich nur möglich, sofern der zugehörige Ringpuffer im Treiber noch eine hinreichende Kapazität aufweist. Ist ein Ringpuffer vollständig gefüllt und wird er nicht entleert, so führt dies zu einem Rückstau der Daten bis hin zum Eingangs-FIFO des betreffenden Moduls. Es obliegt dem Anwender, den Ringpuffer rechtzeitig zu entleeren, um einen solchen Rückstau zu vermeiden. In einer solchen Situation können durchaus weitere Datentransfers an das im Rückstau befindliche Modul initiiert werden. Jedoch werden vom Modul keine Daten mehr verarbeitet, solange der Ausgangs-FIFO nicht entleert wird.

58 Die Parameter sind das Zielmodul, die Startadresse der zu transferierenden Daten und die Größe des zu transferierenden Datenpakets.

Der Treiber wird nach jedem DMA-Transfer in einen Ringpuffer über die transferierte Datenmenge durch einen Interrupt von der Hardware in Kenntnis gesetzt. Im Treiber werden daraufhin die lokal geführten Schreib- und Lesezeiger auf den Ringpuffer aktu-alisiert. Ebenso wird die Hardware mit Hilfe eines Interrupts darüber informiert, sobald Daten durch den Anwender aus dem Ringpuffer gelesen wurden. Außerdem findet ein Abgleich der lokalen Zeiger in der Hardware statt.

Neben den Datentransferfunktionen bietet die Anwenderbibliothek außerdem Statusin-formationen über die Klasse RacerControl an. Diese geben Aufschluss über den aktuel-len Zustand der Karte. Zudem kann das Verhalten des Kartencontrollers über diese Klasse konfiguriert werden. Die wesentlichen Statusinformationen umfassen dabei:

- den Füllstand der Ein- und Ausgangs-FIFOs (FIFO-Flags) - die aktuellen Werte der Schreib- und Lesezeiger der Ringpuffer - die Basisadressen der Ringpuffer und des Konfigurationsdatenbuffers

- die gewählten Auslöseschwellen (FIFO-Flags) für den Rücktransfer der Daten - die Belegung der Modulsockel (Modul eingesteckt oder nicht)

- die Identifikationsdaten der Module (MID)

- die Einstellung der die Module verbindenden Switches (clustering)

Darüber hinaus stehen noch weitere Informationen zur Dauer, Größe und Anzahl der durchgeführten Transfers und zur Konfiguration von Abbruchkriterien (time outs), die vom Controller verwendet werden, zur Verfügung. Eine detaillierte Übersicht über diese Informationen und Konfigurationsmöglichkeiten findet sich im Anhang dieser Arbeit.