PowerPC MPC750


Einleitung
Architektur
Instruction Unit
Branch-Processing-Unit (BPU)
Completion-Unit
Execution-Unit
Memory-Management-Unit (MMU)
Cache
Bus-Interface-Unit
Pipeline
Power-Saving-Modi, Temperaturmanagement

Einleitung

Die Architektur des PowerPC soll anhand des MPC750 erläutert werden. Der MPC750 ist ein RISC-Computer (Reduced Instruction Set Computer), verwendet also einen kleinen Befehlssatz einfacher Befehle mit kurzer Ausführungszeit. Er ist in 32-Bit-Architektur ausgelegt, mit 32-Bit effektiven Adressen und 32 bzw. 64-Bit Datenbus.
Der MPC750 kann als superskalarer Prozessor bezeichnet werden, da abgesehen von der gleichzeitigen Bearbeitung der Befehle in der Pipeline wirklich zwei Befehle gleichzeitig an die Execution-Units weitergegeben werden können.
Der MPC750 ist schnell. So verwendet er z.B. eine in 3 Stufen gepipelinete Floatingpoint-Unit und die meisten Integer-Befehle brauchen nur einen Takt.
Es gibt neben den getrennten L1-Caches für Befehle und Daten eine L2-Cache-Verwaltung (incl. Tag-Memory) auf dem Chip.
Der MPC750 ist in CMOS-Technologie gefertigt.

Architektur

Der Prozessor besteht aus:


Instruction Unit

Die Instruction-Unit steuert zentral die Abfolge der abzuarbeitenden Befehle und den Befehlsfluß zu den Execution-Units.
Der sequentielle Fetcher holt sequentiell Befehle aus dem Instruction-Cache. Dazu gibt er die in der Instruction-Unit berechnete Adresse des zu holenden Befehls an die Instruction-Management-Unit (Instruction MMU), welche ihrerseits den Instruction-Cache veranlaßt, bis zu 4 Befehle, genauer soviel, wie freie Pläzte in der Queue sind, gleichzeitig ('gleichzeitig' heißt in diesem Zusammmenhang 'innerhalb eines Takts') in die Instruction-Queue in der Instruction-Unit zu leiten.
Außerdem meldet der Fetcher den Befehl an die Completion-Unit, da eine vorhergesagte und daher in Ausführung gegebene sequentielle Befehlsfolge falsch sein kann. Die aus dem Instruction-Cache gefetchten Befehle werden in der als Zwischenspeicher dienenden Instruction-Queue abgelegt, welche Platz für 6 Befehle hat.
Um Sprünge ausrechnen und die benötigten Befehle fetchen zu können, ist in der Instruction-Unit die Branch-Processing-Unit (BPU) eingebaut. Wenn ein Sprung vorhergesagt ist, meldet die BPU die Befehlsadresse an den Fetcher, der an dieser neuen Stelle sequentiell fortfährt.
Von den unteren Plätzen der Instruction-Queue gelangen die Befehle in die Dispatch-Unit, welche jeweils 2 Befehle gleichzeitig (->superskalarer Prozessor) an die Execution-Units leiten kann. Gleichzeitig werden diese Befehle auch an die Completion-Unit weitergegeben. Die Dispatch-Unit prüft auf Datenabhängigkeiten in Quell- und Zielregister.


Branch-Processing-Unit (BPU)

Die Branch-Processing-Unit (BPU) erhält alle Sprungbefehle aus dem Fetcher, wertet diese aus, errechnet Sprungziele und updatet den Programmcounter (Countregister-CTR). Die Berechnung, ob ein Bedingter-Sprung genommen werden muß oder nicht, dauert einen Takt, was zu einem Loch in der zeitlichen Befehlsabfolge führen müßte, weil der auf den Sprung folgende Befehl noch nicht bekannt ist. Daher ist es sinnvoll, in geeigneter Weise den Sprung vorherzusagen, um ohne Verzögerungen von einem Takt im Programm fortfahren zu können. Im Falle einer falschen Vorhersage müssen allerdings die Wirkungen aller auf den Sprung folgenden Befehle rückgängig gemacht werden und im korrekten Befehlspfad weitergearbeitet werden.
Es gibt zwei Arten von Sprungvorhersagen (branch prediction), statische und dynamische. Für die statische Sprungvorhersage wird ein (64-entry, 16-set, 4-way-set-associativ ) Branch-Target-Instruction-Cache (BTIC) mit den Sprungzielen der letzten Befehle im Programmablauf verwendet. Für die dynamische Sprungvorhersage wird ein (512-entry) Branch-History-Table (BHT) verwendet, welcher in 2 Bits die Wahrscheinlichkeit eines Sprungs für die letzten Befehle speichert. Diese Wahrscheinlichkeiten werden je nach Ergebnis des tatsächlichen Sprungverhaltens geupdatet und sagen aus, ob ein Sprung 'unwahrscheinlich', 'höchst unwahrscheinlich', 'wahrscheinlich' oder 'höchst wahrscheinlich' ist. So wird in den meisten Fällen nur ein Takt pro Sprungbefehl benötigt.


Completion-Unit

Die Completion-Unit arbeitet eng mit der Instruction-Unit zusammen. Befehle werden in der Instruction-Unit in sequentieller Folge gefetcht und dispatched, und zwar in der Reihenfolge, wie sie durch den Programmlauf vorgegeben ist. Nach Aufteilung der Befehle an die Execution-Units muß diese Reihenfolge irgendwo gespeichert werden. Denn, falls bei einem falsch vorhergesagtem Sprung oder bei einer Exception einige Befehle, die sich bereits in den Execution-Units befinden, nicht ausgeführt werden dürfen, so darf ihr Resultat nicht endgültig in die Register geschrieben werden. Daher wird jeder dispatchte Befehl in Reihenfolge in den (6-entry) Reorder-Buffer, einer Queue in der Completion-Unit, geschrieben. Dort ist Platz für 6 Befehle, denn es können maximal 6 Befehle gleichzeitig in den 6 Execution-Units behandelt werden. Entsprechend kann ein Befehl erst dispatched werden, wenn wieder Platz in der Queue ist. Wenn ein Befehl in einer Execution-Unit fertig ausgeführt ist, wird das Resultat der Berechnung in ein Register (GPR, FPR, CTR) geschrieben, und zwar in der Reihenfolge, wie sie in der Reorder-Buffer-Queue steht. Wird ein Befehl wegen falscher Sprungvorhersage oder einer Exception zurückgezogen, so wird er aus der Queue gestrichen. Dies kann passieren, solange er noch in der Queue steht. Entsprechend muß auch das Resultat der Execution-Unit ggfs. wieder gestrichen werden. Daher werden diese Resultate in den Registern zunächst in entsprechende Rename-Buffer mit 6 Einträgen geschrieben, entsprechend dem Reorder-Buffer der Completion-Unit. Erst wenn keine Gefahr für einen Befehl mehr besteht, annuliert zu werden, er fertig ausgeführt ist und keine Exceptions stattfanden, wird er von den unteren Plätzen der Queue in der Completion-Unit gestrichen und das entsprechende Resultat aus dem Rename-Buffer in das Register übernommen (und zwar maximal 2 Befehle entsprechend den 2 dispatchten Befehlen pro Takt).


Execution-Unit

Neben der Branch-Processing-Unit gibt es 5 unabhägige Execution-Units.


Memory-Management-Unit (MMU)

Es gibt jeweils eine MMU für Daten und eine für Befehle entsprechend den getrennten L1-Caches. Die MMU unterstützt 252 virtuelle und 232 physikalische Adressen für Daten und Befehle und kontrolliert den Daten- bzw. Befehlsfluß zwischen Load-/Store-Unit bzw. Instruction-Unit und den L1-Caches. Dazu übersetzt die MMU die in der Instruction- bzw. Load-/Store-Unit berechneten effektive Adressen in die physikalischen für den Speicherzugriff. Dabei können Seiten von 4-Kbyte oder Blöcke von 128-Kbyte bis 256-Mbyte verwendet werden. Im optionalen Real-addressing-mode ist die Übersetzung abgeschaltet, effektive sind dann gleich physikalischen Adressen.
Die Interaktion zwischen Cache und Hauptspeicher kann nach dem Write-Back oder der Write-Through Prinzip gewählt werden. Der Cache kann auch abgeschaltet werden, und der Speicherzugriff kann auf einzelnen Befehlen, block- oder seitenweise geschehen.
Die übersetzten physikalischen Adressen werden zusammen mit ihren effektiven im Pagetable (block-address-translation-buffer, DBAT bzw. IBAT) gespeichert. Für einen schnellen Zugriff gibt es für beide Pagetable eine Art Cache (128-entry, 2-way-set-associativ, LRU-replacement-algorithmus), den Translation-Lookaside-Buffer (TLB) zu dieser Tabelle (DTLB bzw ITLB) für die zuletzt gebrauchten Adressen. Die Suche im Pagetable ist in Hardware implementiert.


Cache

Zugriffe auf den Hauptspeicher dauern einige Zeit. Daher ist es sinnvoll, einen schnellen Zwischenspeicher (Cache) für die am häufigsten benötigten Daten/Befehle zwischen Prozessor und Hauptspeicher auf den Chip zu setzen.
Auf dem MPC750 befinden sich für Daten und Befehle getrennte L1-Caches, sowie ein L2-Cache-Interface.

L1-Caches

Der Befehls- und der Datencache sind jeweils 32 kByte groß und mengenassoziativ mit 8 Einträgen/Blöcken pro Index (d.h. pro Menge) (8-way-set-associative). Die Indices und Tags beziehen sich auf die physikalischen Adressen der Einträge.
Jeder Eintrag besteht aus dem Adressen-Tag (das sind die Adressenbits ohne dem Index), einem Zustandsbit und 8 aufeinander folgenden Worten (also einem 32 Byte, 8-Wort Block). Als erstes Wort ist jeweils nur jedes achte zugelassen, so daß die 8-Wort-Blöcke sich nie überschneiden. Die Bits 27-31 sind somit für die Adressierung dieser 8 Worte und ihrer 4 Bytes vorgesehen. Es ergeben sich demnach (wegen der 32 kByte) 128 Mengen (128Mengen*8Blöcke*8Wörter*4Byte<Wortlänge> = 32 kByte).

Um ein Wort/Befehl im Cache zu finden, stellt man mit den ersten 7 Bits der physikalischen Adresse die Menge fest, in der sich das Wort befinden muß (die Menge ist direkt adressiert). Dann überprüft man für jeden der 8 Blöcke, ob Bit 7-26 dem eingetragenen Tag entspricht. Falls nein, so ist das Wort nicht enthalten, falls ja, so kann man mit den Bits 27-29 das Wort unter den 8 eingetragenen identifizieren.
Um ein Wort im Cache einzutragen, ermittelt man wie oben die Zielmenge und trägt den dieses Wort umfassenden 8er-Block in einen noch freien Block ein oder überschreibt einen nach einem Least-Recently-Used-Replacement-Algorithmus zu ermittelnden Block. Dabei geht man davon aus, daß die am längsten nicht benötigten Daten/Befehle im Cache am unwahrscheinlichsten benötigt werden und sie daher überschrieben werden können. Der L1-Cache arbeitet wahlweise mit dem Write-Back- oder Write-Through-Verfahren. Es können 2 Worte bzw. 4 Befehle pro Takt aus dem Cache gelesen werden. Der Cache kann softwareseitig abgeschaltet oder gesperrt werden.
Desweiteren seien der Branch-Target-Instruction-Cache in der Branch-Unit und die TLBs als weitere Caches erwähnt (s.o.).

L2-Cache-Interface

Neben den L1-Caches ist ein weiterer L2-Cache zwischen L1-Cache und Hauptspeicher vorgesehen. Dieser umfaßt Daten wie Befehle gleichermaßen und empfängt Anforderungen von den L1-Caches. Auf dem Chip ist allerdings nur eine Kontrolleinheit und ein mengenassoziativer Speicher (mit 2 Einträgen pro Index) für 2*4k  Tags vorhanden. Die Daten werden in externen SRAMs variabler Größe (256 kByte bis 1MByte) gespeichert. Anfragen vom L1-Cache resultieren, wenn Daten/Befehle dort nicht vorhanden sind oder bei Write-Through-Operationen, d.h. dem Updaten des übergeordneten Speichers mit den Daten des L1-Caches. Die Anfragen werden mit den Tags des L2-Caches verglichen. Falls kein Treffer vorliegt, wird die Anfrage an die Bus-Interface-Unit weitergeleitet.  Der L2-Cache arbeitet mit dem Write-Back-Verfahren.


Bus-Interface-Unit

Es gibt jeweils eine Bus-Interface-Unit als Schnittstelle zum Speicher des L2-Caches und zum Hauptspeicher mit einem 32 Bit Adressbus und 64 Bit Datenbus zum Hauptspeicher und einem 17 Bit Adressbus und 64 Bit Datenbus zum L2-Cache-Datenspeicher.


Pipeline

Der MPC750 ist ein gepipelineter superskalarer Prozessor. Eine Pipeline teilt die Ausführung der Befehle in mehrere Stufen auf, so daß innerhalb eines Taktes an mehreren Befehlen gleichzeitig gearbeitet werden kann, die ungenutzten Abarbeitungsstufen eines Befehls in einem Takt also für andere Befehle genutzt werden können. Z.B. kann Befehl Y schon gefetcht werden, während Befehl X in einer Execution-Unit bearbeitet wird.
Bei einem superskalaren Prozessor werden mehrere Befehle gleichzeitig in verschiedenen Execution-Units bearbeitet. Die Pipeline alleine würde nur eine Execution-Unit innerhalb eines Taktes versorgen, die anderen lägen brach. Superskalarität nutzt mehrere Execution-Units gleichzeitig. Um den Zeitgewinn auch wirklich nutzen zu können, können 4 Befehle innerhalb eines Taktes aus dem Instruction-Cache gefetcht werden und 2 dispatchet werden. (Ein Teil der Befehle wird in der BPU dazwischen verarbeitet.) Das ganze wird mit erhöhtem Verwaltungsaufwand erkauft (getrennte Register für Integer- und FP-Daten).
Die Pipeline des MPC750 hat 4 Stufen, durch die alle Befehle gehen müssen: Die FP-Unit hat wiederum 3 Pipelinestufen: Multiplizieren, Addieren, Runden. Die Load/Store-Unit hat 2 Stufen: Berechnung der effektiven Adresse incl. Übersetzung in Physikalische Adresse, Zugriff der Daten im Cache.

Zwischen den Pipelinestufen muß es Register zum Zwischenspeichern der Resultate einer Stufe geben. Es sind dies

Diese Register reduzieren Stalls und sind desweiteren in Zusammenhang mit der Sprungvorhersage wichtig.


Power-Saving-Modi, Temperaturmanagement

Der MPC750 kennt vier verschiedene Power-Saving-Modi. Damit können vorübergehend nicht benötigte Einheiten in einen geeigneten Energiesparmodus gesetzt werden ohne die Performance negativ zu beeinflussen (Dynamic-Power-Management) oder Einheiten teilweise abgeschaltet werden (Doze, Nap, Sleep), wobei je nach Deaktivierungsgrad nur wenige Takte benötigt werden, um den Prozessor in den Full-Power-Modus zu überführen.
Es gibt eine Temperaturüberwachung und Temperaturmanagement, nützlich für portable Computer mit kleinen Abmessungen. Die Temperatur wird geregelt, indem die Systemgeschwindigkeit verändert oder Operationen vorübergehend gestoppt werden.
Die Instruction-Fetch-Rate kann geregelt werden, um die Energieaufnahme zu begrenzen (z.B. bei Embedded-Systems).

(The images are taken from the Motorola Website. If anyone there should be bothered about finding them here, please mail.)
zum Inhalt