So implementieren Sie Memory Mapped IO

Ich beschreibe ein System in VHDL. Dieses System enthält bereits einen Prozessor, einen DDR-SDRAM-Controller und einen VGA-Controller. VGA liest Pixel aus SDRAM (bereits validiert und in FPGA bewährt).

Obwohl VGA und SDRAM bereits miteinander kommunizieren, muss ich noch die Verbindung zwischen Prozessor und SDRAM implementieren. Am Ende möchte ich einen Prozessor haben, der den im SDRAM gespeicherten Framebuffer einzieht. Dann erfolgt ein Seitenwechsel und VGA beginnt, das neue Bild abzurufen, das vom Prozessor gezeichnet wurde.

Um den VGA anzuweisen, vom neuen Speicherort abzurufen, möchte ich dem VGA-Controller (unter Verwendung von Memory Mapped io) die neue Adresse des neuen Bildes mitteilen. Eine einfache Strategie, die ich dachte, war, einen Mux zu setzen und zu überprüfen, ob der Adressbereich in die Register des VGA-Controllers oder in den Adressbereich des Cache fällt. Müsste ich mich auch um verschiedene Taktdomänen kümmern? Wenn ja, um welche möglichen Probleme sollte ich mich kümmern?

Zum Beispiel habe ich irgendwann in der Vergangenheit Code von x86 gesehen, der schreibt (mit outb-Befehl), und der nächste Befehl war ein inb an denselben und/oder einen verwandten Ort. Müsste ich in diesem Fall die Prozessorlogik ändern, um bei solchen Operationen anzuhalten? Wenn ja, wie viele Fälle sind zu implementieren? Wie viele Schnittstellen sind zu beachten?

Wie wird der Cache beim Booten verwendet, wenn alle Einträge ungültig sind? Ich glaube, es gibt ein ROM-Image mit dem Startcode. Könnte es auch einen temporären lokalen RAM für Schreibvorgänge geben, die durch im ROM gespeicherten Code (sw-Anweisungen) erstellt werden?

Zusammenfassung: Ich benötige Informationen zur Implementierung von Speicherhierarchieschaltungen: Caches, Memory Mapped IO, TLBs, virtueller Speicher usw. Und wie all dies miteinander kommuniziert. Ich weiß zum Beispiel, wie man Caches und TLBs implementiert. Aber ich bin mir nicht sicher, wie ich sie miteinander verbinden soll. Ich könnte einfach etwas verwenden, das funktioniert (wie die Mux-Idee). Aber ich möchte Designs folgen, die in der Industrie etabliert sind.

Was ich bereits gelernt habe: - wie man mips ausführt - Computerarchitektur (Patterson) - MIPS-Handbücher - ARM-Handbücher - Intel-Handbücher

Aber keiner erklärt es im Detail.

Wenn es viele Möglichkeiten zur Implementierung gibt, zeigen Sie mir bitte nur eine, die Sie kennen. Auch wenn es sich um Quellcode oder ein Blockdiagramm handelt. Auch hier brauche ich keine Erklärung, wie es intern funktioniert. Ich muss nur die Schnittstellen zwischen den Modulen kennen.

Danke euch allen

Schade, dass diese Frage keine Aufmerksamkeit bekommen hat. Könnten Sie etwas näher darauf eingehen? Teile deinen Code? Konkrete Schnittstellen?
Sicher! Hier ist die SDRAM-Schnittstelle: link . Es ist eine einfache Schnittstelle mit Unterstützung für drei Clients. Der erste Client (client0) hat Vorrang vor den anderen. Die anderen werden per Round Robin ausgewählt. Clients müssen nur die Anfangsadresse angeben, wie viele Bytes gelesen oder geschrieben werden sollen, und einen Puffer, in den der SDRAM-Controller ruft oder schreibt.
@Dzarda, hier ist die VGA-Schnittstelle: vga . Es ist als client0 in sdram angehängt, daher haben Lesevorgänge auf VGA Priorität.
Hier ist die Schnittstelle des Prozessors: Prozessor . Der Prozessor ist ein 2 Issue VLIW (ein Projekt von mir, mit benutzerdefiniertem Befehlssatz). Obwohl die Namen als dcache und icache erscheinen, ist es nur mit einigen Block-RAMs verbunden, die zur Verifizierung im FPGA angeschlossen sind.
Sehr interessant. Möchten Sie Ihre eigene Frage beantworten, seit es 11 Monate her ist?

Antworten (2)

Hier ist ein Link zu einer kurzen Erklärung, wie Memory Mapped I/O in einem älteren Computersystem funktioniert. Vielleicht kann das ein paar deiner Fragen beantworten:

http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/IO/mapped.html

Nach all der Zeit habe ich nichts Genaues zu diesem Thema gefunden. Ich beschloss, einfach etwas zu programmieren, das funktioniert, und zu vergessen, wie es die Industrie tut. Dies geschah nach dem Lesen einer Dokumentation zum Wishbone-Busprojekt, die besagt, dass sie in FPGA eine Reihe von Multiplexern verwenden, um die Routen zwischen den Modulen zu erstellen.

Mein Rat für diejenigen, die etwas Ähnliches in FPGA ausprobieren: Mach einfach etwas, das funktioniert. Ich kann mich irren, aber es gibt einfach keine detaillierten Informationen darüber, wie man so etwas macht.

Zunächst einmal habe ich meine Realität akzeptiert: Ich bin ein FPGA-Typ, der im Allgemeinen durch Takte von 50 MHz begrenzt ist. Ich projiziere auch kein System, das mit einem Motherboard oder PCI oder was auch immer verbunden werden soll. Es ist ein einfaches SoC und alle physischen Schnittstellen, die ich benötige (Tastatur, Maus, VGA, SDRAM usw.), sind vorhanden und können von mir durch Pinzuweisungen verwendet werden (natürlich muss ich die Logik noch in VHDL implementieren).

Mit anderen Worten: Ich muss mich nur um VHDL kümmern, weil die physischen Dinge bereits von den Jungs von Altera/Xilinx/YourVendorHere erledigt werden.

Ich erkläre kurz, wie ich vorgegangen bin:

  • Ich habe keinen Bus implementiert. Zuerst wollte ich einen Bus benutzen, weil es im Allgemeinen so gemacht wird. Aber die Wahrheit ist, dass ein Bus nur dann nützlich ist, wenn Sie Plug-and-Play-Module verwenden, und dies war nicht mein Fall (bitte korrigieren Sie mich, wenn ich falsch liege). Am Ende habe ich also nur ein paar Multiplexer verwendet, um die Adressen zuzuordnen.

  • Für Status-/Steuer-/Datenregister innerhalb von Modulen habe ich mich für ein einfaches „Protokoll“ entschieden, das man sich als Handshake/Polling vorstellen kann: In einer Schleife lese ich das Register so lange, bis es den erwarteten Wert liefert, dann führe ich die Operation aus Ich will.

  • Ich habe keine Ahnung, wie die ARM- und Intel-Jungs ihre Sachen machen, aber hier habe ich einfach ein ROM und RAM (beides Block-RAM) für Bootstrap-Code hinzugefügt. Es ist einfach und es funktioniert.

  • Die Schnittstelle zwischen dem Prozessor und cache/tlb/mmu ist die folgende: cache, tlb und mmu werden nicht von selbst aktiv. Wenn ein Fehler auftritt, muss der Prozessor sie anweisen, die erforderlichen Daten abzurufen.

Es gibt so viele Details, dass ich nicht weiß, was erklärt werden soll oder nicht. Wenn jemand von Ihnen detaillierte Informationen darüber benötigt, wie ich Dinge getan habe, senden Sie mir einfach eine E-Mail: hdhzero@gmail.com. Ich werde froh sein, alles hier auf Stapel oder in meiner E-Mail zu awnsen.

Ich lasse hier auch einige Links, die mir geholfen haben: http://www.st.ewi.tudelft.nl/~gemund/Publications/michel_bsc.pdf http://amir-shenodua.blogspot.com.br/2012/ 06/simple-memory-management-with-vhdl.html

Ich empfehle auch das folgende Buch, das einige Kapitel enthält, die beschreiben, wie man einen Prozessor mit IO-Modulen verbinden kann: http://www.amazon.com/FPGA-Prototyping-VHDL-Examples-Spartan-3/dp/0470185317