Wie kann der Opcode für eine CPU effizient gestaltet werden?


12

Ich baue eine einfache 16-Bit-CPU in Logisim und habe die ALU bereit und die Opcodes, die ich haben möchte. Jetzt finde ich es wirklich schwierig, die richtige Codierung für die Befehle zu finden, damit die verschiedenen Teilschaltungen (z. B. Logik, Arithmetik) nicht alle Steuerleitungen (die die Codierung aufbauen) als Eingang benötigen, sondern so wenig wie möglich. Gibt es Strategien oder Methoden, die bei einem effizienten Opcode-Design helfen?

Danke im Voraus


1
Bauen Sie zuerst Ihre ALU und sehen Sie, welche Steuerkabel benötigt werden. Verbinden Sie diese dann direkt mit dem Register "Aktuelle Anweisung". Gleiches gilt für die Speicherzugriffssteuerungslogik und andere wichtige Klassen von Opcodes. Verwenden Sie dann die verbleibenden Bits, um die aktivierte Unterschaltung auszuwählen.
user253751

1
Es gibt auch die Originalarbeit von Ken Chapman über seine 8-Bit-programmierbare Statemachine KCPSM aka PicoBlaze. Es beschreibt, wie er Anweisungen auswählt und die ISA entwirft. dc.uba.ar/materias/disfpga/2010/c2/descargas/…
Paebbels

Antworten:


9

Ich denke, es ist ein guter Ansatz, einige andere Befehlssätze zu studieren.

Ein kleines wäre der MSP430 von TI, es ist ein 16-Bit-Prozessor mit ca. 22 Anweisungen.

http://www.physics.mcmaster.ca/phys3b06/MSP430/MSP430_Instruction_Set_Summary.pdf

Sie könnten auch in die Atmel AVRs schauen, sie haben auch einen ziemlich kleinen Befehlssatz.

In einem kleinen Projekt habe ich versucht, einen einfachen 32-Bit-Prozessor in VHDL mit einem kleinen Befehlssatz (14 Befehle) zu entwickeln:

http://www.blog-tm.de/?p=80

Aufgrund meiner momentanen Freizeit ist es nicht ganz fertig. Die Anweisungen sind implementiert, aber zwei sind nicht getestet und möglicherweise fehlen einige Statusflags.


Aber ich habe nichts gefunden, bei dem ich sehen konnte, wie die eigentliche Kodierung aussieht und warum sie so gewählt wurde.
Benjoyo

Die aktuelle Kodierung finden Sie im Repo: github.com/TM90/MISC_Processor/raw/master/Documentation/… . Der Grund, warum ich diese Codierungen so auswähle, dass die Logik im Befehlsdecoder minimal wird.
TM90,

7

Studieren (aber nicht replizieren) Sie den ARM-Ansatz zur Befehlskodierung. Es ist stark Präfix-orientiert (wie der von Dzarda empfohlene Huffman-Baum-Ansatz) und in Bezug darauf, wo das Register einen Teil des Befehls auswählt, sehr einheitlich.

Der einfallslose, aber zuverlässige Ansatz besteht darin, alle Steuersignale aufzulisten, die Sie haben (wahrscheinlich mehr als 16 Bit), und dann zu versuchen, die Logik im Karnaugh-Map-Stil zu minimieren.


Ich verstehe nicht wirklich, was Sie mit Steuersignalen meinen.
Benjoyo

Was ich am ARM gefunden habe und mag, ist das Bedingungsfeld, das werde ich einschließen.
Benjoyo

Steuersignale sind die Eingänge zu den verschiedenen Multiplexern und ermöglichen das direkte Datenaustausch zwischen den Teilen der CPU.
pjc50

Für eine 16-Bit-Architektur halte ich die ARM-Befehlskodierung nicht für angemessen. Mayby thumb2 ist besser. Aber ich mag die MIPS-Codierung, einfach und leicht zu verstehen, wenn auch etwas verschwenderisch
phuclv

4

Einmal habe ich versucht, in Logisim eine 4-Bit-CPU mit 8-Bit-Befehlslängenkern zu erstellen. Endete mit einer einfachen Zustandsmaschine, eigentlich mehr als einer CPU.

Zufällige Dinge zu suchen

  • Huffman-Bäume
  • Feste Länge oder variable Kodierung?
  • Handelt es sich um ein von Neumann-Design mit einem Adressraum oder um ein Harvard-Design mit separaten Daten / Programmen?

Ausgezeichnetes Video auf Computerphile über Huffman-Bäume:

https://www.youtube.com/watch?v=umTbivyJoiI


Huffman-Codierung funktioniert bei einer Codierung mit fester Länge nicht, oder?
Benjoyo

@Benjoyo Ich kann mir ein Szenario vorstellen, in dem die Ersatzbits für Variationen der am häufigsten verwendeten Anweisungen verwendet werden, um mehr Funktionalität bereitzustellen.
Dzarda

Aber ich verstehe nicht, welche Art von Optimierung dies bringt. Es hilft mir nicht beim Schaltungsdesign. Was ist das Ziel bei der Verwendung von Huffman-Codierung für Opcode?
Benjoyo

4

Die ISA, die ich einmal für die Klasse geschrieben habe, hatte einen 4-Bit-Op-Code wie folgt: 1XXX ALU instructions 01XX jump, jump register, call etc 001X branch not equal, branch equal zero 000X 0 - load, 1 - store

Anstatt optimal zu sein, ist dies einer der einfacheren Stile zum Konstruieren / Entwerfen von Gattern, da das Eingangssignal eines einzelnen Bits vollständig steuern kann, welcher Logikpfad verwendet wird. Alternativ können Sie Ihre am häufigsten verwendeten Symbole mit einem Huffman-Code versehen und mit Nullen versehen, um einen Op-Code mit fester Länge zu erhalten.


Diese Art der Optimierung ist das, wonach ich im Moment suche. Aber ich habe einen 5-Bit-Opcode und habe Mühe, die Befehle so zu gruppieren, dass sie in der Schaltung Sinn machen.
Benjoyo

@Benjoyo du könntest ein paar mehr ALU-Befehle mit dem oberen Bit haben. Auch meine Sprungbedingungsabdeckung war ziemlich schwach und die meisten normalen Zweige würden zwei Anweisungen erfordern. Im Allgemeinen dachte ich an die Kategorien als: Math / Control / Memory

3

Eine Sache, die Sie berücksichtigen müssen, ist, ob Sie irgendeine Form von Mehrwortbefehlen zulassen oder alles, was sich wie ein Mehrwortbefehl "verhalten" kann. In diesem Fall möchten Sie möglicherweise überlegen, ob Sie nach der Hauptanweisung zusätzliche Anweisungswörter oder Präfixwörter verwenden möchten. Das Zulassen von Präfixen und Folgewörtern kann die Komplexität der Interrupt-Behandlung erhöhen, es kann jedoch vermieden werden, dass selten verwendete Anweisungen in denselben Opcode-Bereich wie häufig verwendete Anweisungen eingefügt werden müssen.

Wenn Befehle in dem Zyklus abgerufen werden, bevor sie ausgeführt werden, könnte man einen "bedingten Verzweigungs" -Befehl haben, der entweder bewirkt, dass das nächste Befehlswort übersprungen wird, oder dessen Inhalt direkt in den Programmzähler übertragen wird; Ein solches Design könnte die Unterbrechungssequenzierung etwas komplizierter machen, aber es könnte die Notwendigkeit erleichtern, einen großen Teil des Operationscode-Raums für "Verzweigungs" -, "Sprung" - und "Aufruf" -Anweisungen zu verwenden, während ein viel größerer Bereich von Verzweigungsbedingungen zugelassen wird als sonst möglich wäre. Da eine Verzweigung, die genommen wird, im Allgemeinen einen Totzyklus nach der Ausführung des Befehls selbst benötigt, unabhängig davon, woher die Adresse stammt, kostet es keinen Aufpreis, wenn die Adresse aus dem folgenden Wort stammt, das abgerufen, aber nicht ausgeführt wird Zeit.

Obwohl das Verschieben der Zieladresse aus den Verzweigungsbefehlen den Opcode-Speicherplatz, den sie verschlingen, verringert, ist ein 16-Bit-Opcode-Format immer noch recht eng. Die Verwendung von Präfixanweisungen kann dabei helfen. Wenn man zum Beispiel 32 Register haben möchte, damit jedes Register unabhängig als Quelle1, Quelle2 und Ziel angegeben werden kann, wären 15 Bits im Opcode erforderlich, was insgesamt zwei Befehle ermöglicht. Nicht sehr nützlich. Andererseits wäre es schön, 32 Register für jeden der drei Operanden verwenden zu können. Man könnte die beiden Ziele ausbalancieren, indem jede ALU-Operation, der kein Präfix vorausgeht, acht Bits verwendet, um zwei aus sechzehn Registern zu wählen, aber eine ALU-Operation, die unmittelbar auf ein Präfix folgt, einige Bits im Präfix verwendet mit acht aus der folgenden Anweisung, Anweisungen, die die oberen Register verwenden, benötigen zwei Wörter / Zyklen anstatt eines, aber in einigen Fällen kann sich ein solcher Kompromiss durchaus lohnen. Die größte Schwierigkeit bei der Verwendung von Präfixen besteht darin, dass entweder verhindert werden muss, dass ein Interrupt zwischen einem Präfix und dem nächsten Befehl auftritt, oder dass, falls dort ein Interrupt auftritt, der Befehl nach dem Präfix weiterhin die richtigen Register verwendet [z. B. indem er das Programm hat -counter save logic speichert die Adresse des zuletzt ausgeführten Nicht-Präfix-Befehls]. In einigen Fällen kann sich ein solcher Kompromiss jedoch durchaus lohnen. Die größte Schwierigkeit bei der Verwendung von Präfixen besteht darin, dass entweder verhindert werden muss, dass ein Interrupt zwischen einem Präfix und dem nächsten Befehl auftritt, oder dass, falls dort ein Interrupt auftritt, der Befehl nach dem Präfix weiterhin die richtigen Register verwendet [z. B. indem er das Programm hat] -counter save logic speichert die Adresse des zuletzt ausgeführten Nicht-Präfix-Befehls]. In einigen Fällen kann sich ein solcher Kompromiss jedoch durchaus lohnen. Die größte Schwierigkeit bei der Verwendung von Präfixen besteht darin, dass entweder verhindert werden muss, dass ein Interrupt zwischen einem Präfix und dem nächsten Befehl auftritt, oder dass, falls dort ein Interrupt auftritt, der Befehl nach dem Präfix weiterhin die richtigen Register verwendet [z. B. indem er das Programm hat -counter save logic speichert die Adresse des zuletzt ausgeführten Nicht-Präfix-Befehls].

Die Verwendung von Anweisungen mit mehreren Wörtern erschwert einige Aspekte des Entwurfs, verringert jedoch möglicherweise die Notwendigkeit, andere schwierige Entscheidungen zu treffen.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.