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.
Antworten:
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.
quelle
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.
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.
quelle
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:
quelle