Implementierung
wie dies in einer Logikschaltung usw. implementiert wird.
Im normalen Ausführungsfluss wird eine Anweisung in die Anweisung abgerufen Register IR, wird dann von der Steuereinheit in ein großes Bündel einzelner Steuerdrähte decodiert, das dann den Datenpfad des Prozessors steuert.
Wenn ich Sie wäre, würde ich den Steuerpfad "rückwärts" von entwerfen Dieser Prozess:
Entwerfen Sie zuerst den Datenpfad.
Erstellen Sie dann eine Liste aller Steuersignale, die erforderlich sind, um anzugeben, wie Daten durch diesen Datenpfad fließen. Die ALU benötigt einige Steuersignale, um Geben Sie an, ob addiert, subtrahiert usw. werden soll. Der Programmzählerabschnitt benötigt Steuersignale, um anzugeben, ob der Programmzähler mit einer inkrementierten Version des vorherigen Werts oder mit einem völlig anderen Verzweigungswert usw. neu geladen wird.
Stellen Sie dann für jede Assembler-Befehls-Mnemonik fest, welche Impulsfolge auf jeder Steuersignalleitung erforderlich ist, um dies zu implementieren Befehl.
Wenn Sie Glück haben, können viele dieser Steuersignale direkt aus dem Befehlsregister "decodiert" werden. Die verbleibenden Steuersignale werden von der Steuereinheit erzeugt, die als Moore implementiert ist Maschine oder eine mehlige Maschine.
Wenn Sie eine Princeton-Architektur haben, bezieht Ihr Prozessor normalerweise Anweisungen aus demselben Speicher mit einem Port, der zum Lesen und Schreiben von Daten verwendet wird --dann müssen mindestens LOAD und STORE mehrere Zyklen ausführen.
Möglicherweise ist der konzeptionell einfachste und universellste Ansatz die Implementierung der Steuereinheit mit einem sehr breiten Steuerungsspeicher ROM hält das Mikroprogramm mit einem Pipeline-Register, das alle Ausgangsbits dieses ROM-Taktzyklus zwischenspeichert.
Jedes Mal, wenn ein neues erstellt wird Der Opcode wird aus dem Hauptspeicher abgerufen, typischerweise werden die hohen Bits des microPC mit dem Opcode geladen und die niedrigen Bits des microPC auf Null zurückgesetzt
Das "Mikroprozessor-Design: Entwurfsschritte" geht viel detaillierter.
ps: Bitte helfen Sie, den aktuellen Entwurf des "Mikroprozessor-Designs" Buch, um der nächsten Person das Entwerfen eines Prozessors zu erleichtern.
typische 8-Bit-CPUs
... unter Verwendung von 8-Bit-Anweisungen ...
Mit sehr seltenen Ausnahmen verwendet jeder Befehlssatz, den ich jemals vorgeschlagen habe (viel weniger sogar simuliert oder tatsächlich implementiert), mehr als 8 Bit für mindestens einige Befehle.
Alle "8-Bit-CPUs", die ich je gesehen habe (6800, 6502, Zilog Z80, 8080, 68HC11, Microchip PIC, Atmel AVR usw.; sowie einige einzigartige Homebrew-Prozessoren und eine Reihe von "Nur-Papier" -Ideen, die noch nicht implementiert wurden) enthalten mindestens einige Anweisungen, die länger als 8 Bit sind.
Für praktisch alle diese CPUs Das erste Byte des Befehls hat den vollständigen Opcode, und aus diesem Byte kann der Decoder in der CPU genau herausfinden, wie lange die Ins dauern Die Funktion ist. Oft sind NOP und RETURN Ein-Byte-Befehle. Oft ist BRANCH ein Mehrbyte-Befehl - ein Byte für den Opcode, gefolgt von der Anzahl der Bytes, die zum Füllen des Programmzähler-PCs erforderlich sind.
Ich halte es für unwahrscheinlich, dass die Person, die Ihnen diese Spezifikationen für eine 8-Bit-Maschine gegeben hat, wirklich beabsichtigte, dass Sie unter der zusätzlichen schweren Last arbeiten, auch die maximale Länge jeder Anweisung zu begrenzen, einschließlich der Nicht-Anweisungen Opcode-Bits auf 8 Bit.
Und so können Sie wahrscheinlich den nächsten Abschnitt überspringen.
Was wäre, wenn jeder Befehl genau 8 Bit breit wäre?
Ich denke Die maximale Befehlslänge auf 8 Bit (oder sogar noch kürzer!) zu beschränken, ist eine faszinierende Idee. Dies vereinfacht einige Teile des Prozessors und macht die Implementierung und das Testen anderer Dinge viel schwieriger.
... Anweisungen, und es werden 9 oder 10 davon sein. ...
Ein Prozessor mit mindestens 9 Befehlen benötigt mindestens 4 Bits, um diese Befehle vollständig zu unterscheiden - die Opcode-Bits.
Zum Laden / Speichern / Verzweigen, wenn Null / Verzweigung, wenn nicht Null, ich benötige ein Bit für das einzelne Register und 4 Bits für die Adresse
Plus mindestens 2 Bits, um zwischen diesen 4 verschiedenen Operationen unterscheiden zu können 1 weiteres Bit, um anzuzeigen, ob es sich um eine dieser 4 Anweisungen oder um eine andere Anweisung handelt.
Dies bedeutet, dass das Laden / Speichern / Verzweigen bei Null / Verzweigen bei Nicht-Null-Befehlen das folgende Format hat:
3-Bit-Opcode + 1-Bit-Quell- / Zielregisterauswahl + 4-Bit-Adresse = 8 Bit.
Das sind insgesamt 8 Bit, also passt es kaum.
Wenn Sie Wenn Sie wirklich 2 Bit Registerauswahl für andere Anweisungen benötigen (ich bin mir nicht sicher, ob Sie dies tun), müssen Sie für diese Anweisungen ein anderes Format verwenden, möglicherweise
3-Bit-Opcode + 1-Bit-Quelle / Ziel Registerauswahl + 1-Bit-Quellregister ter + 2 Funktionsbits + 1 nicht verwendetes Bit = 8 Bits. Typischerweise wird der gleiche maschinensprachliche Opcode für mehrere verschiedene ALU-Operationen verwendet. Die Funktionsbits wählen die bestimmte Operation aus - Addieren, Subtrahieren oder eine andere ALU-Operation.