Emulation eines ROMs auf der DE-10 Nano mit BRAM/M10K

Dies ist Teil meiner Experimente mit dem DE-10 Nano Board. Diesmal emuliere ich ein ROM mit der Block RAM (BRAM) bzw. den M10K-Blöcken des Cyclone V.

In einem anderen Beitrag, in dem ich ein EverDrive V2 wiederherstelle, wird das ROM in den 29W640-Speicher geschrieben. Dieses ROM startet im Anfangssektor; die CPLD EPM240 übernimmt das Mapping, startet aus dem Spiel-ROM-Sektor und schreibt das ROM von der SD-Karte in den passenden Sektor des 29W640.

In diesem Fall wird der Speicher innerhalb des Cyclone V emuliert, und die Signale werden über den GPIO der DE-10 Nano abgegriffen.

Der interne Speicher ist sehr schnell, aber begrenzt. Das Maximum liegt wohl bei etwa 696 kB. Es gibt jedoch viele sehr kleine Homebrew- und Test-ROMs, die sich perfekt für diesen Versuch eignen. Beispiele findet man unter:

https://github.com/namalgo/genesis

Anpassung der Logikpegel

Ein weiterer wichtiger Punkt ist, dass die Mega Drive, wie fast alle alten Konsolen, mit 5-V-Signalen arbeitet, während die GPIOs der DE-10 Nano mit 3,3 V arbeiten.

Zur Lösung habe ich Level-Shifter SN74ALVC164245 verwendet. Sie sind tri-state-fähig und lassen sich über DIR und OE als Eingang oder Ausgang verwenden. Der Chip ist in zwei getrennte 8-Bit-Bänke aufgeteilt und besitzt daher zwei DIR- und zwei OE-Signale.

In diesem Fall benötige ich:

  • 16 Eingangsleitungen: A0-A13 und die Steuerleitungen MD_CE und MD_OE. Am Expansion Port entspricht CE dem Signal CART.
  • 16 Ausgangsleitungen: D0-D15.

Für die Eingänge verwende ich die Level-Shifter ohne Steuerung, mit DIR und OE auf GND. Bei den Ausgängen muss der Bus nur dann aktiviert werden, wenn die Mega Drive ihn anfordert; die Freigabe erfolgt daher direkt über GPIO-Signale.

DE-10 Nano · Emulación de ROM con BRAM/M10K

Implementierung in Quartus

Für die Implementierung des ROMs im FPGA gibt es zwei Wege: grafisch in Quartus oder direkt als Verilog-Modul.

Option 1: grafische Konfiguration

In Quartus wird ein ROM-Modul erzeugt und die .mif- oder .hex-Datei des ROMs geladen. Anschließend werden die Ein- und Ausgänge des Moduls erzeugt.

Danach werden zwei Steuerleitungen hinzugefügt: MD_ROM oder MD_CE, je nach Expansion Port oder Cartridge Port, sowie MD_OE, das CAS0 entspricht.

Wenn der Expansion Port als Cartridge verwendet wird, muss das Signal /CART auf HIGH gesetzt werden, also auf 5 V.

Abbildung 1. Konfiguration des ROMs in Quartus.

Abbildung 2. Konfiguration des ROMs in Quartus.

Abbildung 3. Konfiguration des ROMs in Quartus.

Abbildung 4. Konfiguration des ROMs in Quartus.

Zum Schluss werden die Pins des GPIO zugewiesen.

Abbildung 5. Pin-Zuweisung am GPIO der DE-10 Nano.

Erklärung der Eingangsleitungen

Abbildung 6. Für den Test verwendete Signale und Verbindungen.

Abbildung 7. Detail der Signale/Verbindung.

Wichtigste Signale

/CAS_0

Wird bei Lesezugriffen von 0x000000 bis 0x7FFFFF aktiviert. Es arbeitet als /OE (Output Enable) und zeigt dem Speicher an, dass er die Daten auf den Bus legen muss.

/ASEL

Wird bei Lese- und Schreibzugriffen im Bereich 0x000000 bis 0x7FFFFF aktiviert. Die Dauer beträgt etwa 220 ns; es dient als allgemeines Speicherzugriffssignal.

/CAS_2

Wird bei Lese- und Schreibzugriffen im selben Bereich aktiviert. Der Puls ist mit etwa 150 ns kürzer und dient als weiteres Steuersignal für das interne Timing.

/ROM

Wird im normalen Modus bei Zugriffen auf 0x000000 bis 0x1FFFFF aktiviert. Der Puls dauert etwa 330 ns und arbeitet als /CE (Chip Enable). Es ist das Schlüsselsignal für ROM-Zugriffe.

Wenn ein Cartridge eingesteckt ist

Wenn /CART_IN auf LOW liegt, ändert /ROM seinen Bereich und reagiert auf 0x400000 bis 0x5FFFFF. So remappt das System das ROM und priorisiert das Cartridge gegenüber dem Expansion Port.

Spezielle Signale: Bereich A12000

Diese Signale steuern Zugriffe auf den Bereich 0xA12000 bis 0xA120FF:

  • /FDWR: nur Schreiben.
  • /DISK und /FDC: Lesen und Schreiben.

Ausführung über den Expansion Port

Wenn Code ohne Cartridge über den Expansion Port läuft, bleibt /CART_IN auf HIGH. Dann wird /FDWR bei Zugriffen auf 0x000000 bis 0x3FFFFF aktiviert, jedoch nicht bei RAM-Zugriffen, sondern nur bei ROM-artigen Zugriffen.

Signale nur am Cartridge Port

Diese Signale sind am Expansion Port nicht verfügbar:

  • /CE_0: Lesen/Schreiben im Bereich 0x000000 bis 0x3FFFFF. Es ist das echte Chip Enable des Cartridges.
  • /TIME: Zugriffe auf den Bereich 0xA13000 bis 0xA130FF.

Signaldauer

SeñalDuración
/ROM330 ns
/ASEL220 ns
/CAS_2150 ns

Option 2: Implementierung in Verilog

Ich füge auch den Verilog-Code (.v) bei, falls man die Umsetzung direkt und nicht grafisch machen möchte.

Debugging mit Signal Tap

Zum Schluss hat mir Signal Tap Analysis von Quartus sehr gut gefallen. Es funktioniert wie ein Logikanalysator und ist sehr hilfreich, um Ein- und Ausgänge beim Debugging zu prüfen.

Abbildung 8. Verwendung von Signal Tap zur Fehlersuche an Signalen.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top