Site Tools


de:projects:closed_area:fpga_soc

Fpga Soc

Baustelle

Diese Seite soll primär als Ideensammlung und Merkzettel dienen.

Die Grundidee des Projekts ist, eine CPU-Karte für einen Amiga 4000 oder 3000 mit einer Kombination aus FPGA und ARM-Prozessor zu entwickeln. Solche FPGA-unterstützten Emulatoren sind bereits aus der Literatur bekannt (z.B. Acher Jiffy).

Warum ?
- Direkte Nachbildung der 68k CPU im FPGA ist möglich, scheint aber momentan auf kleine 68k (68000, 68020) beschränkt zu sein.
- Softwareemulation ist möglich. Eine Anbindung an den Amiga-Bus erfordert aber in jedem Fall eine programmierbare Logik. Dann kann diese auch zur Beschleunigung der Emulation eingesetzt werden.

Wie ?
- Das FPGA soll den 68k Maschinencode in ARM-Maschinencode umsetzen
- Der ARM-Prozessor führt den nativen Code mit voller Geschwindigkeit aus.

Höhrt sich in der Theorie doch ganz gut an, oder ? Die Praxis wird wohl um einiges komplizierter und langsamer.
Damit so eine Lösung sinnvoll ist, muss mindestens die Geschwindigkeit der schnellsten 68k-Turbokarten erreicht werden. Ziel ist natürlich eine höhere Geschwindigkeit.

Befehlsumsetzer

Der Befehlsumsetzer erzeugt aus einer 68k-Anweisung eine oder mehrere ARM-Anweisungen. Herausforderung ist, die Unterschiede der Architekturen zu überbrücken.

Load/Store Architektur

Der ARM-Prozessor kann z.B. im Gegensatz zum 68k-Prozessor auf den Speicher nur mit Load/Store-Befehlen zugreifen. Deshalb wird z.B. aus einem einzigen 68k-Befehl, der den Wert an Speicheradresse $4 zum Register D0 addiert, im ARM-Code eine Abfolge von einem Load-Befehl, der den Wert von $4 in ein Scratch-Register schreibt, und einem ADD-Befehl der das Scratch-Register zu D0 addiert. Ist das Ziel der Addition nicht D0 sondern die Adresse $4 muss das Ergebnis noch mit einem Store-Befehl in den Speicher bei $4 geschrieben werden.
Aus einem einzigen 68k-Befehl werden also schnell 2,3 oder mehr ARM-Befehle.

Behandlung von Byte und 16bit-Word

Der 68k kann bei vielen Operationen auch mit Byte und 16-bit Wörtern arbeiten. Die oberen Bits bleiben dabei unberührt. Der ARM hat nur Operationen, die alle 32 Bits umfassen.
Aus einem einfachen add.b d0,d1 wird:
- d1 um 24 Bits nach links verschieben und in ein Scratch-Register kopieren
- d0 um 24 Bits nach links verschieben und zum Scratch-Register addieren
- in d0 die untersten 8 Bit löschen
- Scratch-Register um 24 Bit nach rechts verschieben und mit d0 ver-odern
Die Verschiebung um 24 Bits dient dazu, dass die Überlaufflags, etc. richtig gesetzt werden.

Aus einem einfachen Befehl werden also in diesem Beispiel 4 Befehle.

Liegt das Ziel im Arbeitsspeicher kann ein Befehl eingespart werden, da die ARM-Architektur bei den Load und Store-Befehlen Bytezugriffe und 16bit-Zugriffe unterstützt.

Zu wenige Register

In der ARM-Architektur stehen nur 13 Register zur freien Verfügung, der 68k hat deren 15. Außerdem werden noch mindestens ein oder zwei Register als Scratch-Register benötigt.
Ein Teil der Register muss also in den Arbeitsspeicher ausgelagert werden. Solange sie im L1-Cache gehalten werden, benötigt ein Zugriff vier Takte. Eventuell werden die durch ein Prefetch versteckt.

Muss sich zeigen.

Eine Möglichkeit ist, die Register nicht fest zu zu ordnen, sondern dynamisch zu vergeben. Vorteil ist dass fast immer ausreichend Register zur Verfügung stehen. Nachteil ist, dass man die Register vor einem Sprung gesichert werden müssen.

Eine feste Zuordnung hätte den Vorteil, dass man sich das sichern sparen kann. Aber es werden häufig Register ungenutzt verschwendet.

Interrupts

Da 68k-Operationen in mehrere ARM-Befehle zerteilt werden und diese von Registern gebrauch machen, die auf der 68k-Seite nicht sichtbar, muss verhindert werden, dass eine Abfolge von ARM-Befehlen, die einer 68k-Operation entspricht, durch einen Interrupt unterbrochen wird.
Die einfachste Lösung wäre Interrupts nur zwischen jeweils zwei solchen Befehlsfolgen zuzulassen. das würde natürlich einen sehr großen Aufwand bedeuten. Deshalb ist der Ansatz, Interrupts nur alle x Befehle zuzulassen. Die Länge von x muss noch bestimmt werden.

Tagebuch

Wie bootet das Ding ?
Auf dem SocKit kann der ARM-Teil (HPS) direkt von einer Micro-SD-Karte starten. Es gibt auch noch einen Flashspeicher, von dem auch gestartet werden kann. Die SD-Karte erscheint als bessere Variante. Linux wird z.B. mit dem uBoot Bootloader gestartet. Der besteht aus einem kleinen Preloader, der das SDRAM initialisiert und dann den eigentlichen Bootloader nachlädt.

Wie kann man den Code debuggen ?
Die Web-Version von Quartus unterstützt keine Entwicklung und kein Debugging von Code, der ohne Linux-Betriebssystem ausgeführt werden soll. Dazu darf man die Vollversion kaufen. Code kann man sich mit dem GCC backen. OpenOCD kann das SocKit unterstützen. Dmit kann der Prozessor angehalten werden, Speicher gelesen und beschrieben werden, der Zustand ausgelsen werden. Ob Breakpoints u.ä. funktionieren wird sich zeigen …

Preloader verstehen
In den Beipielen, die man auf rocketboards.org herunter laden kann, ist ein angepasster uBoot Sourcecode vorhanden. Leider ist der Buildprozess sehr kompliziert, so dass man sich mühsam durchhangeln muss.

Los geht's in der Datei arch/arm/cpu/armv7/start.S.


www.amigawiki.org

Links

de/projects/closed_area/fpga_soc.txt · Last modified: 2014/08/20 20:54 by chrisrot