Latch-Trigger: Reverse Engineering des Befehlsregisters in Intel 8086

Der Intel 8086-Mikroprozessor ist einer der einflussreichsten Chips überhaupt. Die von ihm hervorgebrachte x86-Architektur dominiert bis heute Desktop- und Servercomputer. Und doch ist dieser Chip so einfach, dass seine Schaltkreise unter einem Mikroskop untersucht und zerlegt werden können. In diesem Artikel werde ich die Implementierung eines dynamischen Latch [ einstufiges Flip-Flop ] erklären , einer Schaltung, die ein Bit enthält. Der 8086 hat über 80 Latches, die über den Chip verteilt sind und verschiedene wichtige Bits des Prozessorstatus enthalten, aber ich werde mich auf acht davon konzentrieren, die das Befehlsregister implementieren und den ausführenden Befehl halten.



Der 8086 hat über 80 Riegel. Einige von ihnen speichern die Werte von AD-Pins (Adresse / Daten) oder Steuerpins. Andere speichern die aktuelle Adresse des Mikrocodes und des Mikrocodes sowie die Rücksprungadresse der Mikrocode-Routine. Der dritte speichert die Bits des Quell- und Ausgabebefehlsregisters und die ALU-Operation des Befehls. Viele speichern den Status des internen Zustands, den ich immer noch verstehe.





Kristall 86 zeigt das 8-Bit-Befehlsregister



Das Foto oben zeigt den 8086-Siliziumchip unter einem Mikroskop. Ich habe die Metall- und Polysiliciumschichten entfernt, damit Sie die Transistoren sehen können - insgesamt gibt es ungefähr 29.000. Der zugewiesene Bereich enthält einen 8-Bit-Befehlspuffer, der aus acht Latches besteht. Dieser 1978er Prozessor war immer noch einfach genug, damit ein einzelnes 8-Bit-Register eine relativ große Fläche einnimmt. Die Vergrößerung zeigt Silizium und Transistoren, die einen einzelnen Latch bilden.



So funktioniert ein dynamischer Latch



Der Latch ist eines der wichtigsten Elemente des 8086, da Latches verfolgen, was der Prozessor tut. Latches können auf verschiedene Arten durchgeführt werden. Der 8086 verwendet eine kompakte Schaltung, die als dynamischer Latch bekannt ist. Der dynamische Latch beruht auf dem Betrieb eines Zweiphasentaktgenerators, der häufig zur Steuerung von Mikroprozessoren dieser Zeit verwendet wurde. Der Zweiphasentakt erzeugt zwei Taktsignale, die wiederum aktiv sind. In der ersten Phase ist die Hauptuhr hoch und die zugehörige Uhr niedrig. Dann wechseln sie die Plätze. Der Zyklus wird mit einer Taktfrequenz von beispielsweise 5 MHz wiederholt.



Viele Mikroprozessoren verwenden NAND-Gatter, um RS-Flipflops zu bilden. Ein RS-Flip-Flop nimmt normalerweise mehr Platz ein als ein dynamischer Latch, insbesondere wenn zusätzliche Schaltungen hinzugefügt werden, um die Taktfrequenz aufrechtzuerhalten. D-Trigger (Delay-Trigger) sind ebenfalls beliebt, werden jedoch noch komplexer und verwenden sechs Gates. In vielen Fällen ist ein Durchgangstransistor ausreichend; Es kann einen Wert für einen Taktzyklus speichern, bietet jedoch keine Langzeitspeicherung.



Für Prozessoren wird immer die höchstmögliche Taktrate gewählt. Der erste 8086 arbeitete mit bis zu 5 MHz, und später unterstützte der 8086-1 bis zu 10 MHz. Aufgrund der Verwendung dynamischer Logik hat der 8086 jedoch auch eine minimale Taktfrequenz: 2 MHz. Wenn der Taktgenerator langsamer läuft, besteht die Gefahr eines Ladungsverlusts aus den Leitern, bevor die Schaltkreise darauf zugreifen, was zu Fehlern führt.





Der Latch im 8086-Prozessor besteht aus vier Durchgangstransistoren und zwei Invertern. Der Latch arbeitet mit intermittierenden Taktsignalen.



Das obige Diagramm zeigt einen typischen 8086-Latch. Er besteht aus zwei Wechselrichtern und mehreren Durchgangstransistoren. Für unsere Zwecke kann der Durchgangstransistor als Schalter betrachtet werden: Wenn 1 zum Gate kommt, überträgt der Transistor das Signal weiter. Wenn 0 kommt, blockiert der Transistor das Signal. Der Durchgangstransistor wird durch mehrere Signale gesteuert: Last, die ein wenig in den Latch lädt; halten (halten), den vorhandenen Bitwert halten; die Uhr der ersten Phase und die Uhr der zweiten Phase invertiert.



Das folgende Diagramm zeigt, wie ein Wert (in diesem Fall 1) in den Latch geladen wird. Das Lastsignal steigt an, so dass das Eingangssignal (1) den Transistor passieren kann. Da das Taktsignalhoch geht das Signal durch den zweiten Transistor zum Wechselrichter, der 0 ausgibt. In diesem Moment blockiert der dritte (Takt-) Transistor das Signal.





Das Eingangssignal wird in den Zwischenspeicher geladen, wenn das Lastsignal hoch ist.



In der nächsten Taktphase geht das Taktsignal hoch, wodurch das 0-Signal den zweiten Wechselrichter erreicht, der 1 ausgibt. Da das Haltesignal hoch ist, geht das Signal zurück, wird jedoch vom Takttransistor blockiert... Was diese Schaltung dynamisch macht, ist, dass derzeit keine Eingangssignale an den ersten Wechselrichter gesendet werden. Sein Eingang bleibt aufgrund der Kapazität der Schaltung 1 (grau dargestellt). Eines Tages wird diese Ladung auslaufen, der Wert wird verloren gehen, aber vor diesem Moment wird ein neues Schalten des Taktimpulsgenerators stattfinden.





Wenn das Taktsignal hoch geht, durchläuft der Wert den zweiten Wechselrichter. Der Eingang zum ersten Wechselrichter (grau) wird von der Kapazität der Schaltung unterstützt.



Nach dem Umschalten des Zustands des Taktgenerators liefert der Eingang des zweiten Wechselrichters die Schaltungskapazität (siehe unten). Das Signal kommt zurück und lädt den Eingang des ersten Wechselrichters auf und aktualisiert ihn. Bei nachfolgenden Taktschaltern wechselt der Latch zwischen diesem und dem vorherigen Muster, wobei der gespeicherte Wert beibehalten und der Ausgang stabil gehalten wird.



Der Schlüssel zum Betrieb des Latch ist das Vorhandensein von zwei Wechselrichtern, die das Ausgangssignal stabil halten. Eine ungerade Anzahl von Wechselrichtern würde Schwingungen verursachen - diese Funktion wird von der 8086-Ladungspumpe verwendet. Außerdem verwendet ein Wechselrichterpaar einen Satz von 8086-Registern zum Speichern von Bits. In einem Satz von Registern sind die beiden Wechselrichter jedoch ohne die taktgesteuerten Durchgangstransistoren direkt verbunden, was zu einem kompakteren, aber schwierig zu verwaltenden Speichersystem führt.





Wenn das Taktsignal hoch ist, durchläuft der Wert den ersten Wechselrichter.



Implementierung in Silizium



Der 8086 und andere Prozessoren dieser Zeit basierten auf N-MOS- Transistoren . Sie wurden aus einem Siliziumsubstrat hergestellt, dem während des Dotierungsprozesses , der die Transistoren bildete , Arsen- oder Borverunreinigungen zugesetzt wurden . Auf dem Silizium befand sich Polysilizium, das die Gates der Transistoren und die Leiter erzeugte, die alle Komponenten miteinander verbanden. Eine andere Schicht, Metall, lieferte zusätzliche leitende Verbindungen. Im Vergleich dazu verwenden moderne Prozessoren die CMOS- Technologie , eine Kombination aus N-MOS- und P-MOS-Technologien, und sie haben mehr als eine metallisch leitende Schicht.





Wie ein N-MOS-Transistor ( MOS-Struktur ) in einem IC implementiert wird



Das obige Diagramm zeigt den Aufbau des Transistors. Ein Transistor kann als Schalter betrachtet werden, der den Stromfluss von einem Abschnitt (Source) zu einem anderen (Drain) ermöglicht. Der Transistor wird von einem Gate angetrieben, das aus einer speziellen Art von Silizium - Polysilizium besteht. Durch Anlegen einer Spannung an das Gate kann Strom zwischen Source und Drain fließen, während das Ziehen des Gates auf 0 V den Strom blockiert. Das Gate ist durch eine isolierende Oxidschicht vom Silizium getrennt - daher arbeitet das Gate wie ein Kondensator, wie am Beispiel eines dynamischen Latch zu sehen ist.



Der Wechselrichter (unten) besteht aus einem N-MOS-Transistor und einem Widerstand. Wenn das Signal niedrig ist, ist der Transistor ausgeschaltet, sodass der Pull-up-Widerstand das Ausgangssignal nach oben zieht. Wenn das Signal hoch ist, schaltet sich der Transistor ein, verbindet den Ausgang mit Masse und zieht den Ausgang nach unten. Somit invertiert die Schaltung das Eingangssignal.



Der Pull-up-Widerstand im N-MOS-Gate wird unter Verwendung eines speziellen Transistortyps implementiert. Ein Verarmungstransistor arbeitet wie ein Widerstand, nimmt jedoch weniger Platz ein und ist effizienter.





Das Diagramm zeigt, wie ein Wechselrichter aus einem Transistor und einem Widerstand besteht. Das Foto zeigt, wie die Schaltung auf dem Chip implementiert ist. Die Metallschicht wurde entfernt, um Polysilicium und Silicium freizulegen.



Das Foto rechts zeigt, wie der 8086 einen Wechselrichter physisch implementiert. Die gelblichen Bereiche sind leitfähiges Silizium mit Verunreinigungen, und die fleckigen Bereiche sind oben aus Polysilizium. Der Transistor wird dort hergestellt, wo das Polysilicium das dotierte Silizium kreuzt. Polysilicium bildet das Gate des Transistors, und Siliziumabschnitte auf beiden Seiten bilden die Source und den Drain des Transistors. Ein großes Polysiliciumrechteck bildet einen Pull-up-Widerstand zwischen + 5V und dem Ausgang. Sie können die Struktur dieser physikalischen Strukturen mit einem Diagramm vergleichen.



Das folgende Diagramm zeigt die Implementierung des Latch auf dem Chip. Ein Durchgangstransistor und zwei Wechselrichter sind markiert; Der erste Wechselrichter ist oben beschrieben. Polysiliciumleiter verbinden Komponenten miteinander. Zusätzliche Verbindungen wurden durch eine Metallschicht bereitgestellt (für das Foto entfernt). Die komplexe Form der Transistoren ermöglicht die effizienteste Raumnutzung.





Mikroskopisches Foto des Latch im 8086-Prozessor. Die Metallschicht mit den Leitern wurde entfernt, ihre Spuren sind jedoch in Form rötlicher vertikaler Linien sichtbar. Foto um 180 ° gedreht, um dem Layout zu entsprechen.



Der Latch verwendet Ausgangspuffer, die nicht im Diagramm markiert sind, um Hochstromsignale für den Ausgang und den invertierten Ausgang bereitzustellen. Diese Puffer haben einen lustigen Namen, "Superbuffers" - weil sie einen viel höheren Strom liefern als ein typischer N-MOS-Wechselrichter. Das Problem mit einem N-MOS-Wechselrichter besteht darin, dass er beim Ansteuern einer Schaltung mit hoher Kapazität langsam läuft. Da der Superbuffer mehr Strom liefert, schaltet er das Signal viel schneller um. Dies wird erreicht, indem der Pull-up-Widerstand durch einen Transistor ersetzt wird, der mehr Strom liefert. Der Nachteil ist, dass der Pull-Up-Transistor zum Betrieb einen Wechselrichter benötigt, so dass die Superpuffer-Schaltung komplizierter ist. Daher wird der Superbuffer nur bei Bedarf verwendet - normalerweise beim Senden eines Signals an viele Gates oder beim Fahren eines langen Busses.





Die 8086-Latch-Implementierung des Superbuffers. Beachten Sie, dass die +5 V- und Erdungsverbindungen zu den Transistoren ganz rechts verschoben werden.



Das obige Diagramm zeigt eine schematische Darstellung des 8086-Latch-Superpuffers. Im Gegensatz zu einem herkömmlichen Superbuffer hat dieser sowohl einen invertierenden als auch einen nicht invertierenden Superpuffer. Beachten Sie zum Verständnis der Schaltung, dass der Mittenwiderstand und der Transistor einen Wechselrichter bilden. Der Wechselrichterausgang ist mit den oberen Transistoren verbunden, und der nicht invertierte Eingang ist mit den unteren Transistoren verbunden. Wenn der Eingang 1 ist, werden die unteren Transistoren eingeschaltet, und wenn der Eingang 0 ist, werden dank des Wechselrichters die oberen Transistoren eingeschaltet. Wenn der Eingang 1 ist, ziehen die unteren Transistoren den Ausgang nach oben und den entsprechenden Ausgang nach unten. Wenn der Eingang 0 ist, ziehen die oberen Transistoren den Ausgang und den entsprechenden Ausgang nach unten- auf.



Das Problem mit dem N-MOS-Wechselrichter besteht darin, dass der Pull-up-Widerstand einen begrenzten Strom hat. Wenn der Ausgang 0 ist, zieht der Transistor im Wechselrichter schnell und mit relativ hohem Strom den Ausgang nach unten. Wenn der Ausgang jedoch 1 ist, wird der Ausgang durch einen viel schwächeren Pull-up-Widerstand hochgezogen.



Ein Superbuffer ähnelt einem CMOS-Inverter dahingehend, dass er einen Pull-Up-Transistor und einen Pull-Down-Transistor aufweist. Der Unterschied besteht darin, dass CMOS P-MOS- und N-MOS-Transistoren verwendet, während P-MOS einen invertierten Gate-Eingang verwendet. Umgekehrt benötigt ein N-MOS-Superpuffer einen separaten Wechselrichter. Mit anderen Worten, ein CMOS-Inverter verwendet zwei Transistoren, und der Superbuffer ist viel weniger effizient, da er vier Transistoren benötigt.



Der Superbuffer verwendet einen Enhancement-Mode-Transistor zum Hochziehen und einen Enhancement-Mode-Transistor zum Herunterziehen. Die Schwellenspannung eines Transistors mit eigenem Kanal liegt unter Null, wodurch sein Ausgang auf 5 V gezogen und bei einer niedrigeren Spannung nicht ausgeschaltet werden kann. Wenn der Ausgang niedrig ist, ist der selbstkanalisierende Transistor immer noch eingeschaltet und verhält sich wie ein normaler Pull-up in einem herkömmlichen Wechselrichter, sodass eine bestimmte Strommenge durch ihn fließt. Hier können Sie mehr über den Superbuffer lesen .



Befehlsregister



Wie die meisten Prozessoren verfügt der 8086 über ein Befehlsregister, in dem der aktuell ausgeführte Befehl gespeichert ist. Im 8086 enthält das Befehlsregister das erste Byte des Befehls (das mehrere Bytes sein kann), sodass es aus acht Latches besteht. Man würde denken, dass sie identisch wären, jedoch hat jeder von ihnen seine eigene Form. Das Layout des 8086 ist stark optimiert, sodass die Form jedes Riegels so gestaltet ist, dass der verfügbare Platz aufgrund der Einschränkungen der umgebenden Leiter optimal genutzt wird. Beachten Sie insbesondere, dass einige Verriegelungen miteinander verbunden sind und Strom und Masse gemeinsam nutzen. Anscheinend gehen die Riegel aus dem gleichen Grund nicht hintereinander.





Alle 8 Riegel haben leicht unterschiedliche Formen, die für die umgebenden Leiter optimiert sind. Zu Beginn des Artikels wurde die Verriegelung Nr. 1 um 180 ° gedreht. Rote vertikale Linien sind Spuren der entfernten Metallschicht.



Das Team fährt den 8086 auf einem kurvenreichen Weg. Der Prozessor verwendet leistungssteigerndes Prefetching und lädt Anweisungen aus dem Speicher, bevor sie benötigt werden. Sie werden in der Befehlswarteschlange gespeichert, einer 6-Byte-Warteschlange, die sich in der Mitte eines Registersatzes befindet. Im Vergleich dazu verfügen moderne Prozessoren über einen Befehls-Cache, der mehrere Megabyte groß sein kann.



Wenn ein Befehl ausgeführt wird, wird er ungefähr in der Mitte des Chips im Befehlsregister gespeichert. Die relativ großen Entfernungen erklären die Notwendigkeit eines Superpuffers. Das Befehlsregister leitet den Befehl an das "Gruppenentschlüsselungs-ROM" weiter. Dieses ROM definiert die allgemeinen Merkmale des Befehls - ob es sich um ein Einzelbyte oder ein Multibyte handelt oder um das Befehlspräfix. Und dies ist nur ein kleiner Teil des komplexen 8086-Befehlsverarbeitungssystems. Andere Latches enthalten Teile der Befehle, markieren die Registernutzung und ALU-Operationen, und eine separate Schaltung steuert die Mikrocode-Engine - aber ich werde dies separat beschreiben.





Crystal 8086, Schlüsselkomponenten für die Befehlsverarbeitung, sind markiert. Entlang des Umfangs verbinden Lötdrähte den Kristall mit externen Kontakten.



Fazit



Der 8086 verwendet in großem Umfang dynamische Latches, um interne Zustände zu speichern. Sie sind unter einem Mikroskop sichtbar und ihre Schaltkreise können verfolgt und verstanden werden. Der 8086-Kristall ist interessant zu analysieren, da seine Transistoren im Gegensatz zu modernen Prozessoren groß genug sind, um unter einem Mikroskop gesehen zu werden. Es war ein hoch entwickelter Prozessor mit 29.000 Transistoren für seine Zeit, aber einfach genug, um seine Schaltungen zu verfolgen und zu verstehen.



All Articles