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:
- t (ASR) = 0 ns
- / RAS: H.
- / CAS: H.
- A0-9: RA
- / W: H.
- t (RAH) = 10 ns
- / RAS: L.
- / CAS: H.
- A0-9: RA
- / W: H.
- t (ASC) = 0 ns
- / RAS: L.
- / CAS: H.
- A0-9: CA.
- / W: H.
- t (CAH) = 15 ns
- / RAS: L.
- / CAS: L.
- A0-9: CA.
- / W: H.
- t (CAC) - t (CAH) = & dgr;
- / RAS: L.
- / CAS: L.
- A0-9: X.
- / B: H (Daten verfügbar)
- t (RP) = 40 ns
- / RAS: H.
- / CAS: L.
- A0-9: X.
- / W: X.
- 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.
(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.