Ich baue eine Homebrew-CPU und bin jetzt an dem Punkt angelangt, an dem ich den SRAM-Teil entwerfen kann. Ich plane die Verwendung eines einfachen statischen RAM mit 32 KB x 8 Bit (wie dem Cyprus CY62256N). Meine Sorge ist, dass das Teil asynchron ist, aber ich möchte, dass es sich wie ein synchrones Teil verhält.
Im Rest meines Designs werden die Register an der steigenden Flanke des Takts mit dem erforderlichen neuen Wert bereits auf den Datenleitungen geschrieben. Während der restlichen Taktperiode wird der neue Befehl verarbeitet und ein neuer Wert könnte auf die Datenleitungen gelegt werden. Dies ist in Ordnung, da das Register nur bei der steigenden Flanke aktualisiert wird und nicht später, obwohl die Uhr zufällig immer noch hoch ist.
Ich gehe davon aus, dass dieser Ansatz mit asynchronem SRAM nicht funktioniert. Ich mache mir Sorgen, dass die steigende Flanke des Takts den SRAM aktualisiert, aber wenn der Takt immer noch hoch ist, wenn der Wert der Datenleitungen für den nächsten Befehl aktualisiert wird, führt dies zu einer weiteren Aktualisierung, die nicht erwünscht ist.
Gibt es eine gemeinsame Technik, um das zu erreichen, was ich brauche?
Im Allgemeinen hat jeder reale Teil etwas, das als a angesehen werden kann, contamination delay
das propagation delay
zwischen einer Änderung an der Adresse oder dem Steuereingang ist, bis die alten Werte der Ausgänge nicht mehr gültig sind und beginnen, zu einem neuen Wert überzugehen, ziemlich wahrscheinlich durch verschiedene ungültige Zwischenprodukte.
Wenn Sie sicherstellen können, dass das Ansteuern der Adress- und Steuerausgänge des Prozessors zu einem eng verwandten Zeitpunkt (oder sogar nach) dem Latchen von Eingängen aus dem Speicher erfolgt, stellt eine endliche Kontaminationsverzögerung wahrscheinlich sicher, dass Sie gültige Werte erhalten.
Beachten Sie jedoch, dass ein typischer synchroner Speicher eine Pipeline-Verzögerung eines zusätzlichen Takts auferlegt, während ein asynchroner Speicher nur Ausbreitungsverzögerungen aufweist. Das Hinzufügen eines zusätzlichen Pipeline-Registers zu den Adressleitungen würde dazu führen, dass sich ein asynchroner Speicher eher wie ein synchroner verhält – zumindest solange er das Timing durchführt.
SRAM ist wie ein transparenter Latch. Wenn ein Schreibzyklus im Gange ist (CE und WR sind niedrig), werden die Daten auf dem Bus im RAM an der aktuellen Adresse gespeichert. Während dieser Zeit müssen die Adressleitungen stabil sein, sonst könnten mehrere Speicherplätze beschrieben werden. Am Ende des Schreibzyklus (wenn WR und/oder CE hoch gehen) hält der RAM weiterhin alle darin gespeicherten Daten.
Genau wie bei einem getakteten Register müssen Sie die Adress- und Datenaufbauzeiten des RAMs einhalten. SRAM ist jedoch viel langsamer als ein typisches Register, sodass sich seine Zugriffszeit wahrscheinlich bis weit in den „Rest der Taktperiode“ erstrecken wird. Wenn Ihre Adress- und/oder Datenleitungen nur kurz vor der steigenden Flanke der Uhr gültig sind, können Sie sie verriegeln und den Schreibzyklus an der steigenden Flanke starten und den Schreibzyklus dann zu einem späteren Zeitpunkt beenden (z. B. wenn die Uhr niedrig wird). . Natürlich können Sie erst wieder auf den RAM zugreifen, wenn der aktuelle Schreibzyklus abgeschlossen ist.
Ich versuche, dieses Problem zu lösen, indem ich / wr nur herunterziehe, wenn die Uhr niedrig ist.
_______ _______ __
clock _/ \_______/ \_______/
/fetch ___ _______________
enables \_______________/ \
/instr. _________ __________________
latch \_______/
/execute _______________
enables ___/ \_______________/
/execute _________________________ __
latches \_______/
(inc. /wr)
Ich mache das, indem ich die Uhr als hohes Bit auf einem BCD-Decoder verwende und nur die Ausgänge 0-7 verwende. Ich erhalte eine 3-Bit-Befehlsdecodierung und kurze Latch-Perioden von einem IC.
Die Freigabesignale werden durch einen Zähler und Logikgatter verzögert.
Phil Wright
Chris Stratton
Chris Stratton