HaDesWWW logo
Startseite

Downloads
Geschichte(n)
 
Hardware
FPGA-Board
Prozessor
  Instruktionssatz
Peripherie
  XBus-Referenz
PS/2-Board
Soundboard
USB-MMC-Board
 
PC-Software
HaCom
HoAsm, HLink
Emulator
Connectivity
 
Embedded Software
HAL
Dateimanager
Tetris
PacMan
3D-Engine
Pong
PacMan 3D
 
Kontakt

Geschichte und Geschichten

Natürlich war die HaDes XP kein durchstrukturiertes Entwicklungsprojekt mit Projektplänen, Meilensteinen etc. Vielmehr ließen wir uns von unseren aktuellen Zielen und Interessen leiten, neue Features der Toolchain und des Prozessors kamen je nach Bedarf hinzu.

Kam uns beispielsweise ein Programmteil zu ineffizient vor, konnte es schon einmal passieren, dass wir einfach einen neuen Befehl in den Instruktionssatz des Prozessors aufnahmen. Die Implementierung in Compiler, Assembler, Emulator und natürlich im realen Prozessor dauerte dabei oft nur eine Stunde. Welcher PC-Programmierer hat sich diese Möglichkeit nicht schon einmal gewünscht?

Dennoch will ich mich einmal an einer zeitlichen Anordnung der einzelnen Entwicklungsabschnitte versuchen: 

Die Grundlagen

Die Geschichte der HaDes XP beginnt - wenn man nicht wirklich bei Adam und Eva anfangen will - während des USB-Praktikums im WS 03/04. Nachdem unsere eigentliche Aufgabe (einen USB-Controller für den Prozessor HaDes III zu entwerfen, der den Controller Philips ISP 1581 ansteuert und durch die Emulation einer seriellen Schnittstelle eine komfortable Hochgeschwindigkeitsverbindung zum PC aufbaut) halbwegs in trockenen Tüchern war, begannen wir an der HaDes III herumzuspielen. Der erste Ansatzpunkt war hier die lästige und unserer Meinung nach völlig unnötige Beschränkung auf einen nur 888 Instruktionen fassenden, separaten Programmspeicher im FPGA. Tja, und als das Praktikum dann abgeschlossen war, konnten wir nicht mehr aufhören und mussten uns einfach selbst so ein Board zulegen...

Shared Memory HaDesIIIe

Noch während des USB-Praktikums im WS 03/04 bauten wir die HaDes III (die wir ja eigentlich nur um einen USB-Port erweitern sollten) von einer Harvard-Architektur (mit getrenntem, winzigem Programmspeicher auf dem FPGA und Datenspeicher im SRAM) zu einer von-Neumann-Architektur (mit kombiniertem Programm- und Datenspeicher im SRAM) um. Das Ziel war, endlich mal etwas größere Programme schreiben zu können. Wir entwickelten auch bereits eine erste Version des icache, ein Datencache erschien uns allerdings unnötig (da auf den Digilab-Boards an der Uni der Speicher sehr schnell angebunden ist). Wir stellten allerdings schnell fest, dass der aus dem HaDes-Praktikum bekannte Assembler hassem3 der Aufgabe, Programme mit mehr als etwa 500 Instruktionen einzulesen, einfach nicht gewachsen war (ein echtes Schrottprogramm...)

Erste Version der Toolchain (HoAsm, HLink, HaCom)

Inzwischen hatten wir uns entschlossen, demnächst ein FPGA-Board anzuschaffen. Aber zunächst sollte ein Ersatz für den hassem3 her. Da wir bereits im Auge hatten, größere Programme zu entwickeln, sollte das System flexibel genug sein, um Code aus mehreren Programmiersprachen zu verbinden. Außerdem sollten zur Optimierung nicht benötigte Funktionen aus dem Programm entfernt werden. Der Assembler musste also (durch Florian) aufgeteilt werden in den eigentlichen Assembler HoAsm, der binäre Objektdateien, in denen jede Funktion als separates Codesymbol enthalten ist, erzeugt, und den Linker HLink, der nur die benötigten Symbole extrahiert und zu einem lauffähigen Programm verbindet.

Gleichzeitig begann Markus bereits mit dem Entwurf einer Programmiersprache und der Entwicklung eines Lexers für diese. Einen Compiler für die HaDes zu schreiben, hatten wir uns als Übungsaufgabe für die Vorlesung Compilerbau vorgenommen, die wir im kommenden Sommersemester hören wollten. Mit diesem Ziel hatten wir uns deutlich unterschätzt: Die erste funktionsfähige Version (natürlich noch ohne Optimierung und record-Strukturen) war bereits vor dem Start des Semesters fertiggestellt, und als das HL-Funktions-Inlining hinzukam, langweilte uns der Professor immer noch mit der Definition von Stack-Automaten. 

Portierung des Prozessors der HaDes III auf das Xilinx-System

Aber ich will nicht vorgreifen. Einen wichtigen Schritt nahm das HaDes XP-Projekt im April 2004, denn wir bestellten endlich echte FPGA-Hardware. Als stolze Besitzer je eines TE-XC2S200 mussten wir natürlich zunächst einmal die zahlreichen, faszinierenden Funktionen des Boards kennenlernen, was uns durch die mitgelieferten VHDL-Beispielprojekte zur Ansteuerung der Buttons & Lights sowie des VGA-Adapters erheblich erleichtert wurde. So konnten wir uns auch schnell an die Xilinx-Software (ISE WebPack) gewöhnen (bisher hatten wir stets mit Altera FPGAs und Quartus gearbeitet). Wir stellten erfreut fest, dass die VHDL-Synthese den damals aktuellen Quartus-Versionen weit überlegen war, unter Anderem konnten Block-RAM-Bausteine direkt aus VHDL-Prozessen erzeugt werden. Die Aufgabe, die HaDes III CPU auf die Xilinx-Plattform zu portieren, ging daher flott von der Hand, und wir konnten fast alle der LPM (Library of Parametrized Modules)-Bausteine (deren Verwendung im HaDes-Praktikum unter Anderem für die Beschreibung von Oder-Gattern (!), Addition (!), für Register und BlockRAMs gefordert war) durch Standard-VHDL-Zuweisungen oder -Prozesse ersetzen und damit den Code deutlich vereinfachen. Die Xilinx-spezifischen Unisim-Komponenten verwendeten wir zunächst nahezu überhaupt nicht. 

HaDes Emulator

Mit der Implementierung eines Emulators für die HaDes III hatten wir bereits parallel zum Assembler und Linker begonnen. Dabei kümmerte sich Florian um die Benutzeroberfläche (mit wxWidgets, das damals noch wxWindows hieß) und Markus um die Emulation der CPU und der XBus-Komponenten. Bis zum Kauf des Boards war auch der Emulator einsatzbereit, aber damit natürlich sofort wieder veraltet. Da sich am Instruktionssatz durch die Portierung auf den Spartan zunächst kaum etwas änderte, musste er aber erst nach und nach angepasst werden, zum ersten Mal zur Emulation der durch das TE-BL Board verfügbaren Peripheriekomponenten.

Integrated Peripherals (Switches, LEDs und VGA-Textmodus)

Ende April war die CPU portiert und schien im Testbench zu laufen. Nun wurden dringend Peripheriekomponenten für den XBus benötigt, um auch etwas sehen zu können. Die Ansteuerung der Switches, LEDs und der 7-Segment-Anzeigen auf dem TE-BL Board war schnell erledigt, doch bevor wir Programme ausführen konnten, wurde noch ein Speicherinterface benötigt. Hier stießen wir auf ein unerträgliches Geschwindigkeitsproblem: der externe SRAM ist auf dem Trenz-Board nur mit einem 8-bit-Bus angebunden und hat zudem eine Leselatenz von 70 ns, was eine Gesamtverzögerung von 16 Takten pro gelesenem Wort ergibt. Ohne einen Instruktions- UND einen Datencache (mit Unterstützung von Write-Back?Through?) war das nicht zu ertragen ;-)

Schließlich war es aber so weit, die HaDes XP lief. Nun war es höchste Zeit, die Steuerung der VGA-Schnittstelle zu übernehmen! Einen Grafikmodus konnten wir uns nicht leisten, da dieser allein die gesamte Bandbreite zum SRAM aufgefressen hätte, aber für Tetris genügte ja ein Textmodus. Der Bildspeicher wurde ans obere Ende des SRAMs eingeblendet, der durch das Video Refresh auch nicht übermäßig belastet war. Wenn schon nur ein Textmodus, dann aber natürlich gleich richtig: Die Vorder- und Hintergrundfarbe jedes nur 8x8 Pixel großen Zeichens und der 256 Zeichen umfassende Zeichensatz (der in BlockRAMs im FPGA gespeichert wird) musste natürlich einstellbar sein. Das ließ genügend Freiheiten zum Zeichnen einfacher Grafiken (z.B. abgerundete Tetris-Steine), so dass dem Textmodus-VGA-Controller der Name XGfx verpasst wurde - nicht ahnend, was da noch alles kommen würde...

Auch eine Verbindung zum PC sollte hergestellt werden. Das erwies sich als schwerer als gedacht, denn der USB-Anschluss auf dem TE-BL Board war dafür nicht recht zu gebrauchen. Zwar war eine Demoversion eines USB-Cores beim Entwicklungsboard dabei, aber dabei handelte es sich wirklich um eine Demoversion - man konnte nämlich nur einmal pro Millisekunde 16 bit damit übertragen (2 kB/s). Überdies verschlang sie viel zu viele Logikzellen des FPGAs (ca. 30%), da auf dem Board nur ein Transceiver sitzt und somit die komplette USB-Funktionalität im FPGA implementiert werden musste. Einen genialen Ausweg bot ein Kabel, das bereits die ganze Zeit eine Verbindung zum PC herstellte: das Parallelkabel, über das per JTAG vom PC aus die FPGA-Konfiguration durchgeführt wird. Florian gelang es, den im Spartan eingebauten JTAG-Controller in den USR1-Modus zu schalten und damit Daten an den "internen Testport" des Spartans (Xilinx Komponente BSCAN_SPARTAN2) und wieder heraus zu senden. Das war die Geburtsstunde der XJtag-Komponente, die uns seither mit einer zuverlässigen Full-Duplex-Leitung mit 4 kB/s Kapazität dient. 

Währenddessen vertiefte sich Markus in die Geheimnisse der vorzeichenbehafteten Division und erweiterte die HaDes CPU damit nicht nur um einen Multiplizierer, sondern auch einen Dividierer. Er entwarf auch die Ansteuerung des Flash-Speichers inklusive Löschen von Sektoren mit dem Löschcode 0xDEAD, wobei die lange dauernden Schreibvorgänge parallel zum Zugriff auf den SRAM - der den gleichen Datenbus benutzt - durchgeführt werden können.

Anfänge der Basisbibliothek und Tetris

Mit der PC-Verbindung war das letzte Stück Hardware, das noch für Tetris benötigt wurde, geschafft, wir konnten endlich unseren Compiler anwerfen und mit der Entwicklung von Embedded Software beginnen. Doch auch hier benötigten wir zunächst Basisfunktionen zur Ansteuerung unserer Hardware - die HAL musste her. Wir orientierten uns dabei zunächst an einem Funktionssatz, den wir während des HaDes III Grundpraktikums entwickelt hatten (damals genannt HAdesLibrary16 nach unserer Gruppennummer während des Praktikums), stellten aber schnell fest, das es viel einfacher war, die Funktionen in HL komplett neu zu implementieren, als den vorhandenen Assemblercode auf unsere neue HaDes XP anzupassen. 

Screenshot von CSet

Das erste richtige Programm, das nicht nur irgendeine Hardwarekomponente testete, war der Zeichensatz-Editor CSet. Mit ihm lassen sich interaktiv die 256 Zeichen des Textmodus-Zeichensatzes umgestalten. Letzlich haben wir aber so wenig Gebrauch von dieser Möglichkeit gemacht, dass der Editor nicht einmal eine Funktion erhielt, um den geänderten Zeichensatz auf dem Flash zu speichern oder auch nur an den PC zurückzusenden. Stattdessen kümmerten wir uns lieber um

Screenshot der Urversion von TetrisTetris!

Und tatsächlich konnte man nach wenigen Tagen bereits spielen. Wenn auch diese erste Version (siehe links) weder einen Mehrspielermodus, noch Highscores, Animationen, eine Vorschau auf den nächsten Stein, ja noch nicht mal alle Steine besaß (es waren nur vier verschiedene Steine verfügbar), so hatten wir doch nach nur vier Monaten unser Ziel erreicht. Alles weitere war dann - wie ja eigentlich auch schon vorher - nur noch Spielerei :-) 


Fleißiges Entwickeln

Inzwischen hatten wir an so vielen Ecken gleichzeitig zu basteln begonnen, dass sich kaum noch eine eindeutige Reihenfolge festlegen lässt. Kleine und größere Änderungen am Prozessor zogen sofort einen Rattenschwanz von Anpassungen des Assemblers, Compilers, Emulators, und natürlich der Basisbibliothek und vielleicht sogar einzelner Anwendungsprogramme nach sich. Davon ließen wir uns aber nicht abhalten und warfen unter Anderem das Instruktionsformat noch einmal über den Haufen, um 16 statt 8 Register unterstützen zu können. Neben solchen Optimierungsmaßnahmen erblickten vor allem einige neue HaDes-Programme das Licht der Welt. 

Dateimanager

Nachdem die Ansteuerung des Flash-Bausteins funktionierte, wurde es Zeit, diese auch sinnvoll einzusetzen. Am wichtigsten war es zunächst, Programme darauf abzulegen und auch davon starten zu können, denn dies bedeutete nichts anderes als die völlige Unabhängigkeit der HaDes XP von einem PC. Dazu benötigten wir erst einmal ein Dateisystem, das einfach genug war, um es auch im Bootloader (der höchstens 256 Instruktionen lang sein darf!) auslesen zu können. Hinzu kamen Funktionen zum Zugriff auf Dateien und zur Übertragung von Dateien per JTAG (dies war auf PC-Seite deutlich aufwändiger als auf HaDes-Seite). Der Dateimanager als Anwenderschnittstelle war demgegenüber ein Klacks.

Erweiterungsboard "PS/2 & VRAM"

Endlich hatten wir (fast) alle Hardwarekomponenten des Trenz-Boards ausgenutzt - was nun? Es musste natürlich sofort neue Hardware her. Zwei Probleme brannten uns noch unter den Nägeln: 

  • Nun hatten wir zwar einen schönen VGA-Anschluss, konnten diesen aber nur im Textmodus verwenden, da der Hauptspeicher für einen Grafikmodus nicht ausreichte und vor allem nicht schnell genug war. Auf Dauer musste aber natürlich ein Grafikmodus her - schließlich sollte PacMan das nächste Spiel werden, und für eine flüssige Animation braucht man da einfach Grafik. Also musste das Board einen schnellen SRAM-Baustein zur Verwendung als Grafikspeicher enthalten.
  • Für eine komfortable Bedienung, insbesondere im Zweispielermodus, braucht es einfach mehr als acht Knöpfe - wie wär's stattdessen mit 104? Aber natürlich ist eine reine Tastaturbedienung dem 21. Jahrhundert nicht würdig, ein bisschen Mausgeschubse gehört schon auch dazu. Also sahen wir zwei PS/2-Anschlüsse vor. 

Die tatsächliche Herstellung des Boards dauerte leider insgesamt drei Monate. Wir hatten eine doppelseitige Platine vorgesehen, was unsere zum Ätzen hinzugezogenen Kommilitonen vor größere Probleme stellte. Das Ergebnis: Fehler in der Kupferschicht, fehlendes Rohmaterial... und endloses Warten...

Integrierte VGA-Grafik und PacMan

Wir hatten also genügend Zeit, schon einmal eine Grafikkarte zu entwickeln - schließlich ist das Verhalten eines schnellen SRAM-Chips kein großes Rätsel. Beim Design orientierten wir uns daran, was man wohl in 2D-Spielen - insbesondere PacMan - brauchen könnte: schnelles (wortweises) Zeichnen von Sprites (die über eine transparente Farbe verfügen können). 

Und während wir immer noch auf das Board warteten, konnten wir ja schon einmal den Emulator mit der Grafikfunktionalität versehen und uns ans PacMan-Schreiben machen. Das sollte diesmal aber kein einfacher Klon des Originals werden, denn das wird entweder schnell langweilig, oder man müsste viele zusätzliche Levels entwerfen... also lieber gleich ein Algorithmus zur zufälligen Erzeugung von Levels. Selbst wenn er den größten Teil des Programms ausmacht...

3D-Engine

HaDes Emulator: DCT (Direct Code Translation)

Netzwerkfunktionalität

Und immer langsam weiter...

Mini-Soundkarte

Pong

PacMan 3D

 
rrobek.de Hauptseite
 
Valid HTML 4.01!