9.0 Komplexe Schaltwerke Die Ziele dieses Kapitels sind: Lernen komplexe Schaltwerke mittels kleinerer, kooperierender Schaltwerke zu realisieren Verstehen wie aufgabenspezifische Mikroprozessoren funktionieren Die Funktionsweise universeller Mikroprozessoren kennen zu lernen, die mittels Software zum Lösen vielfältiger Aufgabenstellungen eingesetzt werden können Seite 9-0
Besitzt ein Schaltwerk eine große Anzahl von Zuständen so spricht man von einem komplexen Schaltwerk. Beim Entwurf solcher Schaltwerke ist zu empfehlen diese Schaltwerke in kleinere miteinander kooperierende Schaltwerke zu zerlegen, die einfacher zu realisieren sind. Bei Schaltwerken für komplizierte Aufgabenstellungen, in denen Daten verarbeitet werden, ist eine Aufteilung in ein Operationswerk, in dem die Daten verarbeitet werden, und ein Steuerwerk, das den Ablauf der Datenverarbeitung steuert, vorzunehmen. Diese funktionale Aufteilung in ein verarbeitendes und ein steuerndes Schaltwerk vereinfacht erheblich den Entwurf, da beide Komponenten getrennt voneinander entwickelt und optimiert werden können. In der nachfolgenden Abbildung ist das Blockschaltbild eines komplexen Schaltwerkes zum Verarbeiten von Daten, das aus zwei kooperierenden Schaltwerken, dem Operationswerk und dem Steuerwerk aufgebaut ist, dargestellt. Sowohl aufgabenspezifische als auch universelle Mikroprozessoren sind aus kooperierenden Schaltwerken aufgebaut. Nachfolgende Abbildung zeigt nochmals, etwas mehr im Detail, einen solchen Aufbau, bestehend aus Steuerwerk und Operationswerk. Seite 9-1
Im Blockschaltbild des Steuerwerkes sind die drei Funktionseinheiten, Zustandsregister, Übergangsschaltnetz und Ausgangsschaltnetz dargestellt. Das Ausgangschaltnetz generiert die Steuersignale zum Steuern des Operationswerkes. Abhängig von berechneten Ergebnissen, erzeugt das Operationswerk Statussignale, die dem Übergangsschaltnetz und gegebenenfalls dem Ausgangsschaltnetz, als Eingangssignale zugeleitet werden, damit dieses passende Steuersignale zum Abarbeiten eines Algorithmuses generieren kann. 9.1 Aufgabenspezifische Mikroprozessoren Aufgabenspezifische Mikroprozessoren haben die Aufgabe Daten nach einem festgelegten Algorithmus zu verarbeiten. Zur Ausführung des Algorithmuses wird ein entsprechendes Operationswerk entworfen. Zudem muss ein passendes Steuerwerk entworfen werden, das die Steuerung bei der Abarbeitung des Algorithmuses übernimmt. Ein solcher Prozessor kann dann nur diese eine, durch den Algorithmus beschriebene Seite 9-2
Aufgabe lösen. Das Lösen dieser Aufgabe wird dabei sehr schnell und effizient vollzogen, da die Hardware genau auf diese Aufgabenstellung zugeschnitten ist. Aufgabenspezifische Prozessoren können als Komponenten z. B. als arithmetische Coprozessoren oder Graphikprozessoren, in universellen Mikroprozessoren eingesetzt werden. Universelle Prozessoren können eine Vielzahl von Aufgaben, softwaregesteuert lösen. Sie sind damit sehr vielseitig. Die Lösung einer bestimmten Aufgabe erfolgt jedoch in der Regel nicht so schnell und effizient wie bei einem speziell ausgelegten aufgabenspezifischen Mikroprozessor. Die Gründe dafür ergeben sich wenn man den genauen Ablauf der Abarbeitung eines Algorithmuses in einem universellen Prozessor anschaut. 9.2 Universelle Mikroprozessoren Aufbau und Funktionsweise der Von-Neumann-Rechner Obwohl die Von- Neumann-Architektur eines Rechners bis in die Anfänge der Computertechnik zurückreicht, prägt sie bis heute, in abgewandelter Form, den Aufbau moderner Computer. Nachfolgende Abbildung zeigt das Blockschaltbild eines typischen Von-Neumann-Rechners. Seite 9-3
Alle Von-Neumann-Rechner sind, unabhängig von ihrer speziellen Ausprägung, durch folgende Merkmale gekennzeichnet: Das Herzstück eines Rechners ist ein Mikroprozessor als zentrale Steuerkomponente, die neben der Befehlsausführung, auch die Koordination des Restsystems übernimmt. Gemäß dieser zentralen Bedeutung wird der Mikroprozessor, der aus Steuerwerk ( CU ), auch Leitwerk genannt, und Rechenwerk ( ALU ) besteht, als Zentraleinheit oder CPU ( Central Processing Unit ) bezeichnet. In modernen Rechnern können auch mehrere Mikroprozessoren auf einem Chip integriert sein. Man spricht dann von Mehrkernprozessorsystemen. Der Rechner ist programmgesteuert. Hierzu werden im Speicher ( RAM ) abgelegte Programmbefehle von der CPU entsprechend einem definierten Befehlssatz interpretiert und ausgeführt. Ein Von- Neumann-Rechner ist durch die freie Programmierbarkeit universell einsetzbar, und nicht für eine spezielle Aufgabe konzipiert. Der Befehlssatz des Prozessors muss demzufolge mächtig genug sein, um jeden nur denkbaren Algorithmus ausführen zu können. Neben dem Datenaustausch mit dem Speicher, muss dazu insbesondere auch die Fähigkeit vorhanden sein, im Programmablauf bedingte Sprünge ausführen zu können. In einem Von-Neumann-Rechner werden Programmcode und Daten in einem gemeinsamen Hauptspeicher abgelegt und verwaltet. Die CPU entscheidet anhand des aktuell eingelesenen Befehls, ob der Inhalt der nächsten Speicherzelle als Befehls- oder Datenwort zu interpretieren ist. Nachfolgende Abbildung zeigt, etwas mehr im Detail, den prinzipiellen Aufbau eines Von-Neumann-Rechners. Seite 9-4
A = Adressen B = Befehle D = Daten S = Steuersignale Seite 9-5
In der Grundstruktur besteht ein von NEUMANN-Rechner aus vier Funktionseinheiten: Rechenwerk, Leitwerk, Speicher und Ein/Ausgabeeinheit. Rechenwerk und das durch Maschinenbefehle (Instructions) steuerbare Leitwerk bilden den eigentlichen Prozessor auch CPU (Central Processing Unit) genannt, was einem verallgemeinerten komplexen Schaltwerk entspricht. Die einzelnen Funktionseinheiten kommunizieren über Steuer- Adress- und Datenbus miteinander. Dabei besteht ein Bus aus einem Bündel von Leitungen, die alle dem gleichen Zweck dienen. Als zweckmäßig erwiesen hat sich eine Aufteilung in interne und externe Busse. Dabei werden die beiden Bussysteme über ein- bzw. bidirektionale Bustreiber ( TriState-Buffer ) miteinander verbunden. Durch diese Trennung kann man z. B. mit unterschiedlichen internen und externen Busbreiten arbeiten, was den Leitungs- und Kontaktstellen-aufwand reduziert. Seite 9-6
Funktionsweise einer CPU In der nachfolgenden Abbildung ist das Blockschaltbild des inneren Aufbaus eines typischen Mikroprozessors, einer CPU, gezeigt. Eine typische CPU lässt sich in Registersatz, Steuerwerk und Rechenwerk unterteilen. Das Steuerwerk der CPU übernimmt die Aufgabe, den Kontroll- und Datenfluss zu überwachen und den korrekten Datentransport zwischen den Registern, dem Rechenwerk und der Außenwelt sicher zu stellen. Wird ein Maschinenwort ( Programmbefehl ) in die CPU geladen, so wird es zunächst vom Steuerwerk, mit Hilfe des Instruktionsdekoders, analysiert und anschließend in eine Reihe von Steuersignalen umgesetzt, um den weiteren Ablauf der Befehlsbearbeitung zu beeinflussen. Abhängig von der Komplexität des Befehlssatzes werden Steuerwerke als mikroprogrammierte Steuerwerke oder als fest verdrahtete Steuerwerke ausgelegt. Bei CPUs mit komplexen Befehlssätzen kommen mikroprogrammierte Steuerwerke zum Einsatz. Die eigentliche Verarbeitung der Daten erfolgt im Rechenwerk. Rechenwerke können von ihrer Komplexität sehr unterschiedlich ausgelegt sein. Die Spannweite reicht von einfachen Addiereinheiten bis zu komplexen Signalprozessoren, die über umfangreiche arithmetisch- logische Einheiten mit mehreren parallel ausgelegten Operationseinheiten verfügen. Seite 9-7
Die Register einer CPU lassen sich in Universal- und Hilfsregister unterteilen. Universalregister dienen zum Zwischenspeichern von Datenworten und können mit beliebigen Werten beschrieben werden. Diese Register sind so ausgelegt, dass sie sehr schnell beschrieben und gelesen werden können. Aus theoretischer Sicht würde ein Universalregister ausreichen. Jedoch würde dies, beim Abarbeiten bestimmter Algorithmen, zu großen Verzögerungen führen, da Zwischenergebnisse in den relativ langsamen Hauptspeicher geschrieben, und später wieder gelesen werden müssten. Die Anzahl der Universalregister schwankt je nach Prozessortyp sehr stark. Mikroprozessoren mit komplexen Befehlssätzen haben in der Regel weniger Register als solche mit einfachen Befehlssätzen. Hilfsregister sind im Gegensatz zu den Universalregistern für eine bestimmte Aufgabe reserviert. Der Instruktionszähler ( PC-Register ) enthält die Speicheradresse des nächsten auszuführenden Befehls. Bei einem konsekutiven Ablauf eines Programms wird die Speicheradresse jeweils um eins erhöht. Ein Sprung im Programmablauf kann dadurch realisiert werden, dass die Zieladresse in das PC-Register geschrieben wird. Das Statusregister ( SR ) wird vom Rechenwerk beschrieben und enthält zahlreiche Statusbits, die Aufschluss über das Ergebnis der zuletzt durchgeführten arithmetischen Operation geben. Das Carry-Bit C signalisiert so z. B. ob im Rechenwerk bei der zuvor durchgeführten Operation ein Überlauf vorlag. Das Zero-Bit ist genau dann 1, wenn das berechnete Ergebnis gleich 0 ist. Das Negativ-Bit ist genau dann eins, wenn eine negative Zahl berechnet wurde. In den meisten Mikroprozessortypen werden Statusbits zur Realisierung von bedingten Sprüngen eingesetzt. Das Stapelregister ( stack pointer ) speichert die Adressen eines speziellen Speicherbereichs, des sogenannten Stapels ( Stacks ), im Hauptspeicher, wo die Rücksprungadressen beim Aufruf von Unterprogrammen abgelegt werden. Damit auch verschachtelte Unterprogrammaufrufe möglich sind, ist dieses Register als LiFo ( Last in First out ) Register ausgelegt, wie in nachfolgender Graphik dargestellt: Seite 9-8
Befehlsablauf im Mikroprozessor Da die meisten Befehle eine komplexe Interaktion zwischen Steuerwerk, Rechenwerk und Registern bedingen, muss er in Einzelschritten durchgeführt werden. Im Allgemeinen durchläuft ein typischer Mikroprozessor zur vollständigen Ausführung eines Befehls, nacheinander die Phasen, die in der nachfolgenden Abbildung dargestellt sind. 1.) Befehlholphase ( Fetch ) Der Hauptspeicher wird mit dem aktuellen Inhalt des Adressregisters des Instruktionszählers adressiert und der auszuführende Befehl über den Datenbus in die CPU eingelesen. Anschließend wird der Instruktionszähler um eins erhöht. 2.) Dekodierphase ( Decode ) Das Steuerwerk dekodiert den eingelesenen Befehl und lädt, abhängig von diesem Befehl, die Operanden nach. 3.) Ausführungsphase ( Execute) Nach Abschluss der Dekodierphase wird das Rechenwerk über Steuersignale aktiviert und die Operanden werden miteinander verknüpft. 4.) Speicherphase ( Write back ) Das berechnete Ergebnis wird zurückgeschrieben. In Abhängigkeit vom auszuführenden Befehl wird das Ergebnis in den Speicher zurückgeschrieben, in einem internen Register abgelegt, oder, im Falle eines Sprungbefehls, als Adresse in den Instruktionszähler geladen. Seite 9-9
Aufbau und Funktionsweise eines einfachen Modellprozessors ( M. D. Hoffmann, Hanser Verlag ) Nachdem im vorigen Abschnitt der prinzipielle Aufbau und die Funktionsweise von Mikroprozessoren erläutert wurde, sollen diese Kenntnisse anhand eines einfachen konkreten Mikroprozessors vertieft werden. Nachfolgende Abbildung zeigt das Blockschaltbild des einfachen Modellprozessors. Der Modellprozessor ist durch folgende Eigenschaften gekennzeichnet: Die Registerbreite beträgt, der vereinfachten Betrachtung wegen, nur 4 Bit. Sie lässt sich jedoch ohne weiteres auf die Bitbreite moderner Rechner, z. B. 64 Bit, erweitern. Die Breite des Adressbusses soll ebenfalls nur 4 Bit betragen. Damit können nur 16 Befehls- bzw. Datenworte adressiert werden. Ansonsten ist eine komplexere Adressierungslogik notwendig. Auch hier kann die Bitbreite einfach erweitert werden. Jeder Befehl wird zusammen mit seinem Operanden in einem einzigen Datenwort von 8 Bit, wie dies in nachfolgender Abbildung dargestellt ist, codiert. Seite 9-10
Dieses Befehlsformat führt dazu, dass der mögliche Befehlssatz des Prozessors sehr eingeschränkt wird. Für Befehle und Daten soll je ein Hauptspeicher mit separatem Buszugriff vorhanden sein. Der Modellprozessor besitzt demnach keine Von-Neumann-Architektur, sondern eine Harvard-Architektur. Der Modellrechner führt jeden Befehl in einem einzigen Taktzyklus durch. Die Holphase wird dabei im ersten Teil der Taktphase durchgeführt. Im zweiten Teil der Taktphase erfolgt dann die Abarbeitung der Befehlsphasen Decode, Execute und Write, wie in nachfolgender Abbildung dargestellt ist. Als Arithmetisch-Logische Einheit besitzt der Modellprozessor lediglich einen Akkumulator. Ohne die grundlegende Struktur des Prozessors zu verändern, ist auch eine leistungsfähigere ALU implementierbar. Neben je einem RAM für Befehle und Daten, sind keine weiteren Komponenten angeschlossen. Seite 9-11
Der mögliche Befehlssatz eines Mikroprozessors wird durch die Hardware bestimmt. Soll umgekehrt ein bestimmter Befehlssatz realisiert werden, so muss die Hardware entsprechend ausgelegt werden. Auf dem Modellrechner ist der in folgender Abbildung dargestellt Befehlssatz lauffähig. Abgesehen vom NOP-Befehl lassen sich die Befehle in drei Gruppen einteilen: 1.) Lade- und Speicherbefehle Im Befehlssatz liegen Befehle mit unmittelbarer und direkter Adressierung vor. Enthält das Befehlswort direkt den Operanden ( # Operand ), so spricht man von unmittelbarer Adressierung. Enthält das Befehlswort die Adresse, wo der Operand steht ( (n) = Adresse wo Operand steht ), so spricht man von direkter Adressierung. 2.) Arithmetik-Befehle Den Addier- und Subtrahierbefehl gibt es jeweils mit unmittelbarer und direkter Adressierung. 3.) Sprungbefehle Mittels dieser Befehle wird die Zieladresse beim Springen ermittelt. Die Sprungbefehle können in unbedingte, JMP n, und bedingte Sprünge, BRZ#n, BRC#n und BRN#n unterteilt werden. Seite 9-12
Der Datenfluss und die dazu notwendigen Steuersignale m 1, m 2, für die verschiedenen Lade- Speicher- und Sprungbefehle, sind in nachfolgender Abbildung dargestellt. Um den Ablauf beim Abarbeiten eines Programms des Modellprozessors besser zu verstehen, soll ein einfaches Beispielprogramm betrachtet werden. In nachfolgender Abbildung ist ein einfaches Assemblerprogramm für den Modellprozessor dargestellt, mit dem das Produkt zweier Zahlen berechnet werden kann. Seite 9-13
Bei diesem Programm wird angenommen, dass der Multiplikator bereits in der Speicherzelle 13, und der Multiplikand bereits in der Speicherzelle 14 abgelegt ist. Das Ergebnis der Berechnung wird in die Speicherzelle 15 geschrieben. Bei den verschiedenen Programmzeilen werden folgende Aktionen durchgeführt: 0: Es wird eine 0 ins Akkumulatorregister geladen. 1: Beginn einer Schleife. Es wird zunächst, beim ersten Durchlauf, der Ergebnisspeicherplatz 15 mit einer 0 initialisiert. 2: Es wird der Multiplikator in das Akkumulatorregister geladen. 3: Es wird geprüft ob das Zero-Bit 0 ist. Wenn es null ist, wird das Programm durch einen Sprung ans Ende des Programms beendet. 4: Vom Multiplikator wird im Akkumulator 1 abgezogen. 5: Das Ergebnis wird in der Speicherzelle des Multiplikators (13) abgelegt. 6: Es wird der Speicherinhalt der Ergebnisspeicherzelle (15) ins Akkumulatorregister geladen. 7: Es wird der Multiplikand dazu addiert. 8: Es wird an den Anfang der Schleife gesprungen und das Ergebnis in die Ergebnisspeicherzelle geschrieben. Seite 9-14
Die Schleife wird so häufig durchlaufen, wie es der Multiplikator angibt. Genauso viele Male wird der Multiplikand aufaddiert, um das Endergebnis zu erhalten, das dann in der Speicherzelle 15 steht. Der detailierte Ablauf innerhalb des Modellrechners für die Ausführung des Multiplikationsprogramms für die Berechnung von 2 3, ist in nachfolgender Abbildung dargestellt. Seite 9-15
Als Assemblerprogrammierer ist es notwendig den Befehlssatz des Prozessors zu kennen, und seine Funktionsweise auf der Register-Transfer- Ebene zu verstehen. Detailkenntnisse auf der Gatterebene sind nicht unbedingt notwendig. Im nachfolgenden sollen die Komponenten Instruktionsdekoder, Statusregister, Akkumulator und Steuereinheit noch etwas näher bezüglich ihres Aufbaus, und ihrer Funktionalität untersucht werden. Instruktionsdekoder In nachfolgender Abbildung ist der im Modellprozessor verwendete Instruktionsdekoder dargestellt. Dieser Instruktiondekoder wandelt die 4-Bit Befehlscodierung in 1-Bit Befehlssignale für jeden Befehl um. Die Befehle mit unmittelbarer und direkter Adressierung werden dabei zusammengefasst, und der Unterschied mit einem zusätzlichen 1-Bitsignal ind angezeigt. Seite 9-16
Statusregister Nachfolgende Abbildung zeigt das im Modellrechner eingesetzte Statusregister. Das Carry-Bit kann direkt im Akkumulatorregister abgegriffen werden. Das Negativ-Bit ergibt sich bei Zweierkomplementdarstellung sofort aus dem Wert der höchstwertigsten Bitposition, hier q 3. Das Zero-Bit wird aus dem Inhalt des Akkumulatorregisters über ein negiertes ODER-Gatter generiert. Sind alle Bitstellen q 3 q 2 q 1 q 0 = 0 so ergibt sich am Ausgang des NOR-Gatters eine 1. Seite 9-17
Akkumulator In nachfolgender Abbildung ist der Schaltplan des im Modellprozessor eingesetzten Akkumulators gezeigt. Das Signal ld dient zum Durchschalten eines externen Datenwortes um das Akkumulatorregister damit zu laden. Das Signal sub dient zum Umschalten des Addierers zwischen Addition und Subtraktion. Steuereinheit In nachfolgender Tabelle sind, für die verschiedenen Befehle und die verschiedenen Werte der Statusvariablen, die notwendigen Steuersignale für die Holphase und die Ausführungsphase dargestellt. Seite 9-18
Daraus lassen sich direkt die Schaltfunktionen des Steuerwerks ableiten. Damit ergibt sich der Schaltplan des Steuerwerks, der in folgender Abbildung dargestellt ist. Seite 9-19