Wie kann ich einen sehr einfachen asynchronen DRAM-Controller implementieren?

9

Ich möchte wissen, wie man einen asynchronen Bare-Bones-DRAM-Controller erstellt. Ich habe einige 30-polige 1MB SIMM 70ns DRAM-Module (1Mx9 mit Parität), die ich in einem Homebrew-Retro-Computerprojekt verwenden möchte. Leider gibt es kein Datenblatt für sie, daher habe ich mich für den Siemens HYM 91000S-70 und "Understanding DRAM Operation" von IBM entschieden.

Die grundlegende Oberfläche, mit der ich am Ende enden möchte, ist

  • / CS: in, Chipauswahl
  • R / W: in, lesen / nicht schreiben
  • RDY: out, HIGH, wenn die Daten bereit sind
  • D: In / Out, 8-Bit-Datenbus
  • A: In, 20-Bit-Adressbus

Das Aktualisieren scheint ziemlich einfach zu sein und bietet verschiedene Möglichkeiten, um es richtig zu machen. Ich sollte in der Lage sein, eine verteilte (verschachtelte) Nur-RAS-Aktualisierung (ROR) während des CPU-Takts LOW (wo in diesem bestimmten Chip kein Speicherzugriff erfolgt) unter Verwendung eines alten Zählers für die Zeilenadressenverfolgung durchzuführen. Ich glaube, dass alle Zeilen gemäß JEDEC mindestens alle 64 ms aktualisiert werden müssen (512 pro 8 ms gemäß dem Seimens-Datenblatt, dh Standardaktualisierung von Zyklus / 15.6us), daher sollte dies gut funktionieren, und wenn ich nicht weiterkomme, werde ich einfach posten eine andere Frage. Ich bin mehr daran interessiert, einfach und korrekt zu lesen und zu schreiben und zu bestimmen, was ich in Bezug auf die Geschwindigkeit erwarten sollte.

Ich werde zunächst kurz beschreiben, wie es meiner Meinung nach funktioniert und welche möglichen Lösungen ich bisher gefunden habe.

Grundsätzlich teilen Sie eine 20-Bit-Adresse in zwei Hälften, wobei eine Hälfte für die Spalte und die andere für die Zeile verwendet wird. Sie streichen die Zeilenadresse und dann die Spaltenadresse. Wenn / W HIGH ist, wenn / CAS auf LOW geht, ist es ein Lesevorgang, andernfalls ein Schreibvorgang. Wenn es sich um einen Schreibvorgang handelt, müssen sich die Daten zu diesem Zeitpunkt bereits auf dem Datenbus befinden. Wenn es sich nach einer gewissen Zeit um einen Lesevorgang handelt, sind die Daten verfügbar, oder wenn es sich um einen Schreibvorgang handelt, sind die Daten mit Sicherheit geschrieben worden. Dann müssen / RAS und / CAS in der kontraintuitiv als "Vorladezeit" bezeichneten Periode wieder auf HIGH gebracht werden. Damit ist der Zyklus abgeschlossen.

Im Grunde ist es also ein Übergang durch mehrere Zustände mit ungleichmäßigen spezifischen Verzögerungen zwischen jedem Übergang. Ich habe es als "Tabelle" aufgeführt, die nach der Dauer jeder Phase der Transaktion in der folgenden Reihenfolge indiziert ist:

  1. t (ASR) = 0 ns
    • / RAS: H.
    • / CAS: H.
    • A0-9: RA
    • / W: H.
  2. t (RAH) = 10 ns
    • / RAS: L.
    • / CAS: H.
    • A0-9: RA
    • / W: H.
  3. t (ASC) = 0 ns
    • / RAS: L.
    • / CAS: H.
    • A0-9: CA.
    • / W: H.
  4. t (CAH) = 15 ns
    • / RAS: L.
    • / CAS: L.
    • A0-9: CA.
    • / W: H.
  5. t (CAC) - t (CAH) = & dgr;
    • / RAS: L.
    • / CAS: L.
    • A0-9: X.
    • / B: H (Daten verfügbar)
  6. t (RP) = 40 ns
    • / RAS: H.
    • / CAS: L.
    • A0-9: X.
    • / W: X.
  7. t (CP) = 10 ns
    • / RAS: H.
    • / CAS: H.
    • A0-9: X.
    • / W: X.

Die Zeiten, auf die ich mich beziehe, sind in der folgenden Abbildung dargestellt.

Zeitdiagramm

(CA = Spaltenadresse, RA = Zeilenadresse, X = egal)

Auch wenn es nicht genau das ist, ist es so etwas und ich denke, dass die gleiche Art von Lösung funktionieren wird. Ich habe mir bisher ein paar Ideen ausgedacht, aber ich denke, nur die letzten haben Potenzial und ich suche nach besseren Ideen. Ich ignoriere hier das Aktualisieren, schnelle Seiten- und Paritätsprüfen / Generieren.

Die einfachste Lösung besteht darin, nur einen Zähler und ein ROM zu verwenden, wobei der Zählerausgang der ROM-Adresseneingang ist und jedes Byte den entsprechenden Zustandsausgang für den Zeitraum hat, dem die Adresse entspricht. Dies funktioniert nicht, da ROMs langsam sind. Selbst ein vorinstallierter SRAM scheint viel zu langsam zu sein, um es wert zu sein.

Die zweite Idee war, einen GAL16V8 oder so zu verwenden, aber ich glaube nicht, dass ich sie gut genug verstehe. Programmierer sind sehr teuer und die Programmiersoftware ist, soweit ich weiß, nur Closed Source und Windows.

Meine letzte Idee ist die einzige, von der ich denke, dass sie tatsächlich funktioniert. Die 74ACT-Logikfamilie weist geringe Ausbreitungsverzögerungen auf und akzeptiert hohe Taktfrequenzen. Ich denke, Lesen und Schreiben könnten mit einem CD74ACT164E- Schieberegister und SN74ACT573N durchgeführt werden .

Grundsätzlich erhält jeder einzelne Zustand seine eigene statisch programmierte Verriegelung unter Verwendung von 5-V- und GND-Schienen. Jeder Schieberegisterausgang geht an den / OE-Pin eines Latch. Wenn ich die Datenblätter richtig verstehe, könnte die Verzögerung zwischen den einzelnen Zuständen nur 1 / SCLK betragen, aber das ist viel besser als bei einer PROM- oder 74HC-Lösung.

Ist es also wahrscheinlich, dass der letzte Ansatz funktioniert? Gibt es einen schnelleren, kleineren oder allgemein besseren Weg, dies zu tun? Ich glaube, ich habe gesehen, dass der IBM PC / XT 7400-Chips für DRAM verwendet hat, aber ich habe nur Top-Board-Fotos gesehen, daher bin ich mir nicht sicher, wie das funktioniert hat.

ps Ich möchte, dass dies in DIP machbar ist und nicht mit einem FPGA oder einem modernen uC "betrügt".

pps Vielleicht ist es besser, die Gate-Verzögerung direkt mit demselben Latch-Ansatz zu verwenden. Ich weiß, dass sowohl Schieberegister- als auch direkte Gate- / Ausbreitungsverzögerungsmethoden mit der Temperatur variieren, aber ich akzeptiere dies.

Für alle, die dies in Zukunft feststellen, werden in dieser Diskussion zwischen Bil Herd und André Fachat mehrere der in diesem Thread erwähnten Designs behandelt und andere Probleme einschließlich DRAM-Tests erörtert.

Anthony
quelle
1
Welche CPU wird Ihr Retro-Computer verwenden?
Anonym
6502 wird der Speicher offensichtlich bankiert.
Anthony
Ist es möglich, kein Fahrrad für Sie zu erfinden? Gibt es bereits verfügbare Designs mit DRAMs? Ich bin mit dieser Maschinenfamilie nicht vertraut, aber C64 muss gut zusammenpassen. Es verwendet jedoch ursprünglich einen 6567 "VIC" -Chip zur Steuerung des RAM. Aber auch hier bin ich mir sicher, dass es seitdem Projekte gab, die sich auf das beziehen, was Sie tun möchten.
Anonym
3
Ein leicht verzerrter Vorschlag: Der Z80 hatte genug DRAM-Controller eingebaut, um die Aktualisierungslogik zu verarbeiten. (Sie brauchten noch Adressmultiplexer)
Brian Drummond
2
@BrianDrummond Bitte empfehlen Sie nicht, auf die dunkle Seite zu gehen. Daraus kann nichts Gutes entstehen.
Pipe

Antworten:

6

Das technische Referenzhandbuch für IBM Personal Computer XT (Anhang D) enthält vollständige Schaltpläne für IBM PC / XT, die Sie möglicherweise online finden.

Das Problem hierbei ist, dass Sie bei einer Strobe-Leitung, die beim Lesen oder Schreiben des Speichers aktiviert wird, RAS, CAS und eine Steuerleitung (nennen Sie es MUX) für den Adressmultiplexer generieren möchten. Der Einfachheit halber gehe ich unrealistisch davon aus, dass Strobe, RAS und CAS alle aktiv hoch sind.

Wenn ich mir das PC / XT-Schema und die Schaltpläne einiger anderer Computer in dieser Zeit anschaue, sehe ich drei grundlegende Strategien, die ungefähr die folgenden sind:

  • Verwenden Sie den Blitz für RAS. Verwenden Sie eine Verzögerungsleitung (ein Teil, dessen Ausgabe eine zeitverzögerte Version seiner Eingabe ist) auf RAS, um MUX zu generieren, und verwenden Sie eine andere Verzögerungsleitung, um eine noch spätere Version von RAS zu generieren, die für CAS verwendet wird. Diese Strategie wird vom PC / XT und dem TRS-80 Model II verwendet.

    Ein beispielhafter (moderner) Verzögerungsleitungsteil ist der Maxim DS1100.

  • Verwenden Sie den Strobe für RAS und verzögern Sie ihn für MUX und CAS. Verwenden Sie dazu jedoch ein Hochgeschwindigkeits-Schieberegister anstelle einer Verzögerungsleitung. Diese Strategie wird vom TRS-80 Model I und dem Apple II verwendet.

  • Verwenden Sie benutzerdefinierte ICs. Dies ist die Strategie des Commodore 64.

David Moews
quelle
Anscheinend hatte ich gestern nur einen XT TR ohne Anhang D gefunden. Ich habe es jetzt, das ist großartig. Ich wusste nicht, dass diese Verzögerungsleitungs-ICs existieren, und fragte mich, wie sie mit der Temperatur umgehen. Vielen Dank, dass Sie das moderne Beispiel erwähnt haben. +1 auch für mehrere Lösungen.
Anthony
5

Ihre Frage ist so kompliziert, dass ich nicht einmal sicher bin, was Ihr eigentliches Problem ist, aber ich werde es versuchen!

Das "sauberste" 6502-basierte DRAM-Design, das ich finden konnte, stammt vom Commodore PET 2001-N . Es hat einen 6502, der mit 1 MHz läuft, aber die DRAM-Logik wird mit 16 MHz getaktet, wodurch wahrscheinlich alle Timings generiert werden.

Ich habe die Details nicht analysiert, aber die Hauptaktion scheint mit einem 4-Bit-Zähler 74191 zu geschehen, der an ein Schieberegister 74164 angeschlossen ist. Dies gibt 8 separate Leitungen aus, die in einen 74157 MUX gehen, der von der R / W-Leitung gesteuert wird. Der Ausgang des MUX geht in ein 7474-Flipflop und eine diskrete Logik, um die endgültigen RAS / CAS-Signale zu erzeugen. Hier ist ein Auszug, der auf die entsprechende Seite im Referenzschema verweist.

PET 2001-N Referenzseite 6

Die Aktualisierung wird mit einem separaten Zähler durchgeführt, und jede Adressleitung wird an einen Multiplexer angeschlossen, der entweder die "echte" Adresse oder die Aktualisierungsadresse auswählt.

Teile dieser Logik scheinen auch Timings für das Video-Subsystem zu generieren. Ich bin sicher, dass es für Ihre speziellen Anforderungen vereinfacht werden kann, aber ich denke, dass etwas Ähnliches nützlich sein kann: Ein Hochfrequenzzähler, ein Schieberegister und Multiplexer.

Rohr
quelle
Dies ist, worüber ich nachdachte, aber ich war dumm genug, mehrere Latches anstelle von ein oder zwei MUXs zu erarbeiten. Der 16-MHz-Takt hat mich allerdings ausgeschaltet, weil a) er viel höher ist als der CPU-Takt, den ich gerade als merkwürdig empfunden habe, aber er macht Sinn und b) die Phasen können ein Minimum von ~ 62 ns plus Ausbreitungsverzögerungen sein, was ich für langsam hielt, aber jetzt ich siehe, das ist in der gleichen Reihenfolge wie der IBM PC / XT.
Anthony
Der Apple II ist sehr ähnlich und verwendet den 14,318-MHz-Videotakt zum Timing und zur gemeinsamen Nutzung des Speichers zwischen CPU und Video in abwechselnden Halbzyklen ohne Konflikte. Es wird nicht einmal ein separater Aktualisierungszähler benötigt, da die Videoaktualisierungsaktivität dazu dient, den Speicher ebenfalls zu aktualisieren.
Dave Tweed
-2

ps Ich möchte, dass dies in DIP machbar ist und nicht mit einem FPGA oder einem modernen uC "betrügt".

Obwohl ich den Geist Ihres Projekts und Ihren Wunsch, nicht ausgefallene Teile zu verwenden, vollständig verstehe, würde ich definitiv den FPGA-Weg gehen, wenn ich Sie wäre .

Mehrere Gründe:

  1. Es ist eine perfekte Lernmöglichkeit. Das Entwerfen eines DRAM-Controllers ist kein "Hallo-Welt" -Projekt, und danach können Sie sicher sagen, dass Sie FPGA "können".
  2. Sie könnten jede Leistung aus diesem Speicher herausholen, insbesondere wenn es sich um einen älteren DRAM-Chip handelt. Sie hätten nicht nur Ihren selbstgebauten 6502-basierten PC, sondern möglicherweise auch den schnellsten 6502-basierten PC.
  3. Es kann viel einfacher sein, Probleme zu debuggen oder Statistiken über die von Ihrer CPU ausgegebenen Speicheroperationen zu erstellen. Sie können Logikanalysatoren auf parallelen Bussen verwenden, aber es macht nie Spaß (ein Freund von mir macht etwas in dieser Richtung - er möchte eine zyklusgenaue Simulation von 8088 schreiben und muss aus diesem Grund diese Statistiken über Speicherzugriffe und Timing sammeln Muster. Er verwendet den Original-Chipsatz (8288, 8280, 8237) und einen Logikanalysator mit vielen Kanälen, aber aus seiner Erfahrung kann ich Ihnen sagen, dass es sich um einen Widerstand handelt.
anrieff
quelle
2
Ich bin mir nicht sicher, wie dies eine Antwort anstelle eines Kommentars ist. 1) Er sagt nicht, dass er FPGAs lernen möchte. 2) DRAMs aus den 80ern sind bereits langsam genug für diskrete Logik. 3) Das Debuggen kann schwierig sein. Warum nicht alles im FPGA oder auch nur in Software implementieren? Warum überhaupt den RAM benutzen ... :)
Pipe
1
@pipes: Ja genau. Ich möchte im Moment keine Zeit damit verbringen, FPGAs zu lernen. Ich habe bereits genug mit einem zweiten analogen Projekt auf meinem Teller. FPGAs und PLDs haben im Allgemeinen das Gefühl, dass sie an dieser Stelle nur im Weg sind, obwohl ich eines Tages lernen werde, wie man sie benutzt.
Anthony
1
@pipe: Das Umverdrahten von Boards ist oft schwierig, zeitaufwändig und frustrierend, insbesondere wenn man nicht besonders gut darin ist. Die Verwendung einiger ziemlich einfacher PLDs (z. B. 22V10) für einige Teile des Designs erleichtert das Optimieren.
Supercat