UNIVERSITÄT STUTTGART Institut für Technische Informatik Abteilung Rechnerarchitektur Prof. Dr. Hans-Joachim Wunderlich

Skript zur Vorlesung

Rechnerorganisation (Studiengang Informatik)

Technische Informatik II (Studiengang Softwaretechnik)

WS 2008/2009

2 Das Skript zur Vorlesung Rechnerorganisation (später auch Technische Informatik II für Softwaretechniker) wurde für das WS 1996/97 von Gundolf Kiefer, Arno Wacker und Armin Thumm ausgearbeitet. Gundolf Kiefer pflegte das Skript bis zum Wintersemester 1999/2000. Für das Wintersemester 2001/2002 erfolgte eine Überarbeitung des Inhaltes. Daran waren Prof. Dr. rer. nat. Wunderlich, Rainer Dorsch, Christian Schwenke, Sascha Opletal und Martin Schwienbacher beteiligt. Parallel zur Überarbeitung des Inhalts wurde das Skript nach LATEX portiert. Hierbei war der freie LATEX-Editor LYX (http://www.lyx.org) eine große Hilfe. Wir danken den LYX-Entwicklern sowie Donald Knuth und Leslie Lamport für die Entwicklung von TEX und LATEX . Ein besonderer Dank geht auch an all die zuverlässigen Postskript-Druckertreiber, die uns bei der Portierung des Skripts eine große Stütze waren und uns die Pluralität des Begriffs Standard wieder einmal auf’s Neue verdeutlicht haben. Bei der Überarbeitung wurden einige Fehler aus dem Skript entfernt und zahlreiche neue hinzugefügt. Falls Sie einen Fehler im Skript finden sollten oder hilfreiche Beispiele entwickelt haben, können Sie zur Verbesserung des Skripts beitragen, indem Sie eine Email mit der Beschreibung des Problems bzw. Beispiels an [email protected] senden.

Stuttgart, 15. Oktober 2001 Rainer Dorsch

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3 Für das Wintersemester 2003/04 wurde das Skript von Michael Imhof, Stefan Holst und Günter Bartsch erneut überarbeitet. Dabei wurden die Kapitel 3, 8 und 9 vom DLX- auf den MIPS-Prozessor umgestellt. Diese Änderung war notwendig, weil auch die Lehrbücher, auf denen die Vorlesung basiert, nun MIPS als Beispiel betrachten. In den überarbeiteten Kapiteln wurden auch viele Fehler behoben, die meist typographischer Natur waren und von der Konvertierung nach LYX herrührten. Es wurde dabei sehr deutlich, dass es noch ein weiter Weg bis zu einem wirklich guten, satztechnisch ansprechenden Skript ist. LATEX ist ein hervorragendes Satzsystem, allerdings enthalten die Quellen des Skripts noch viele Konvertierungsartefakte (insbesondere in Formeln und Grafiken), die von Hand korrigiert werden müssen. Wir sind auch weiterhin für Hinweise auf Fehler und Unstimmigkeiten, sowohl inhaltlicher als auch formaler Natur sehr dankbar. Schicken Sie eine Email mit der Beschreibung des Problems an [email protected]

Stuttgart, 24. September 2003 Günter Bartsch

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

Inhaltsverzeichnis 1 Einleitung 1.1 Informationsverarbeitende Systeme . . . . . . . . . . . . 1.1.1 Algorithmen und Programme . . . . . . . . . . . 1.1.2 Rechnerarchitektur und Rechnerorganisation . . 1.1.3 Rechnerorganisation durch Mensch und Maschine 1.1.4 Abstraktes Rechnermodell . . . . . . . . . . . . 1.1.5 Grenzen von Computern . . . . . . . . . . . . . 1.2 Aus der Geschichte . . . . . . . . . . . . . . . . . . . . 1.2.1 Mechanische Maschinen . . . . . . . . . . . . . 1.2.2 Elektrische Maschinen . . . . . . . . . . . . . . 1.2.3 Elektronische Rechner . . . . . . . . . . . . . . 1.2.4 Speicherprogrammierbare Rechner . . . . . . . . 1.2.5 Prozessor-Entwicklung . . . . . . . . . . . . . . 1.2.6 Rechnergenerationen . . . . . . . . . . . . . . . 1.3 Technologische Grundlagen . . . . . . . . . . . . . . . . 1.3.1 Leistungsentwicklung . . . . . . . . . . . . . . . 1.3.2 Technologietrends . . . . . . . . . . . . . . . . . 1.3.3 Kosten . . . . . . . . . . . . . . . . . . . . . . . 1.3.4 Realisierungsalternativen . . . . . . . . . . . . . 1.4 Grundstrukturen . . . . . . . . . . . . . . . . . . . . . . 1.4.1 Grundkonzepte . . . . . . . . . . . . . . . . . . 1.4.2 Befehlszyklus . . . . . . . . . . . . . . . . . . . 1.4.3 Stack-basierte Rechner . . . . . . . . . . . . . . 1.4.4 Akkumulator-basierte Rechner . . . . . . . . . . 1.4.5 Rechner mit allgemeinem Registersatz . . . . . . 1.5 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . 1.5.1 Lernziele . . . . . . . . . . . . . . . . . . . . . 1.5.2 Kontrollfragen . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . .

21 21 21 21 22 23 24 25 25 29 31 32 32 34 35 35 36 37 40 55 55 56 57 59 61 64 64 65

2 Informationsdarstellung 2.1 Datentypen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 Bits, Bytes & Codes . . . . . . . . . . . . . . . . . . . . . . 2.1.2 Fehlererkennung und -korrektur . . . . . . . . . . . . . . . .

67 68 68 72

4

. . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . .

INHALTSVERZEICHNIS

2.2

5

2.1.3 Zahldarstellung . . . . . . . . . . . . . . . . . 2.1.4 Zusammenfassung . . . . . . . . . . . . . . . Befehlssätze . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Allgemeine Registermaschinen . . . . . . . . . 2.2.2 Adressierung . . . . . . . . . . . . . . . . . . 2.2.3 Operationsarten . . . . . . . . . . . . . . . . . 2.2.4 Unterstützung von Hochsprachen . . . . . . . . 2.2.5 Befehlsformate . . . . . . . . . . . . . . . . . 2.2.6 Bewertung und Optimierung von Befehlssätzen

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

3 MIPS als RISC-Beispiel 3.1 Befehlssatz . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 MIPS Hardwarearchitektur vs. MIPS Virtual Machine . 3.1.2 Datentransfer-Befehle . . . . . . . . . . . . . . . . . . 3.1.3 Arithmetisch-logische Befehle . . . . . . . . . . . . . 3.1.4 Sprungbefehle . . . . . . . . . . . . . . . . . . . . . . 3.1.5 Gleitkomma-Befehle . . . . . . . . . . . . . . . . . . 3.1.6 Zusammenfassung des MIPS-Befehlssatzes . . . . . . 3.2 MIPS-Assembler und -Simulator . . . . . . . . . . . . . . . . 3.2.1 Assembler . . . . . . . . . . . . . . . . . . . . . . . . 3.2.2 Cross-Simulation . . . . . . . . . . . . . . . . . . . . 3.2.3 Praktische Hinweise . . . . . . . . . . . . . . . . . . 4 Arithmetisch-logische Grundelemente 4.1 Fläche und Geschwindigkeit . . . . . . . . . . 4.1.1 Gatterverzögerung . . . . . . . . . . . 4.1.2 Schaltungsmodellierung . . . . . . . . 4.1.3 Sensibilisierbare Pfade . . . . . . . . . 4.1.4 Bestimmung sensibilisierbarer Pfade . . 4.1.5 Methoden zur Zeitanalyse . . . . . . . 4.1.6 Verzögerungsmodelle . . . . . . . . . . 4.2 Addition und Subtraktion . . . . . . . . . . . . 4.2.1 Ripple-Carry-Addierer . . . . . . . . . 4.2.2 Carry-Lookahead-Addierer . . . . . . . 4.2.3 Subtraktion . . . . . . . . . . . . . . . 4.2.4 Addition mehrerer Summanden . . . . 4.3 Übersicht über Grundelemente . . . . . . . . . 4.3.1 Verbindungselemente . . . . . . . . . . 4.3.2 Kombinatorische Verknüpfungselemente 4.3.3 Sequentielle Elemente . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . .

76 88 89 90 91 103 109 114 119

. . . . . . . . . . .

121 121 122 122 124 126 131 133 137 137 141 144

. . . . . . . . . . . . . . . .

145 145 145 147 148 149 150 151 151 151 153 155 156 158 159 163 166

5 Hardware-Modellierung 169 5.1 Register-Transfer-Beschreibungen . . . . . . . . . . . . . . . . . . . 170

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

6

INHALTSVERZEICHNIS . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

170 170 177 179 184 191 197 202 207 213

6 Operationswerke 6.1 Ganzzahlige Multiplikation . . . . . . . . . . . . . . . . . . . 6.1.1 Multiplikationsschaltnetze . . . . . . . . . . . . . . . 6.1.2 Serielle Multiplikation . . . . . . . . . . . . . . . . . 6.2 Ganzzahlige Division . . . . . . . . . . . . . . . . . . . . . . 6.2.1 Division mit Rückspeichern . . . . . . . . . . . . . . 6.2.2 Division ohne Rückspeichern . . . . . . . . . . . . . . 6.3 Gleitkommaoperationen . . . . . . . . . . . . . . . . . . . . . 6.3.1 Implementierungsmöglichkeiten . . . . . . . . . . . . 6.3.2 Rundung . . . . . . . . . . . . . . . . . . . . . . . . 6.3.3 Beschreibung der Gleitkomma-Addition auf RT-Ebene

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

221 221 221 225 228 229 230 230 231 232 235

. . . . . . . . . . .

239 242 242 247 252 254 262 263 263 266 267 272

. . . . . .

275 275 280 281 282 284 288

5.2

5.1.1 5.1.2 VHDL 5.2.1 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7

Aufbau und Einsatz von RT-Beschreibungen Entwurfsschritte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Grundstrukturen . . . . . . . . . . . . . . . Arbeiten mit VHDL . . . . . . . . . . . . . Arbeiten mit VHDL - Simulator Scirocco . Datenobjekte und Datentypen . . . . . . . Parallele und sequentielle Sprachkonstrukte Testbenches . . . . . . . . . . . . . . . . . Synthese . . . . . . . . . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

7 Steuerwerke 7.1 Mikroprogrammierte Steuerung . . . . . . . . . . . . . . . 7.1.1 Prinzip . . . . . . . . . . . . . . . . . . . . . . . . 7.1.2 Optimierungsmöglichkeiten . . . . . . . . . . . . 7.1.3 Minimierung der Programmlänge H . . . . . . . . 7.1.4 Beispiel . . . . . . . . . . . . . . . . . . . . . . . 7.1.5 Vor- und Nachteile µ-programmierter Steuerwerke 7.2 Festverdrahtete Steuerwerke . . . . . . . . . . . . . . . . 7.2.1 1-aus-n-Steuerungen . . . . . . . . . . . . . . . . 7.2.2 Zählerbasierte Steuerwerke . . . . . . . . . . . . . 7.2.3 Beispiel . . . . . . . . . . . . . . . . . . . . . . . 7.2.4 Steuerwerkssynthese mit VHDL . . . . . . . . . . 8 Befehlszyklus und Unterbrechungen 8.1 Einfache CPU-Steuerung . . . . . . . . . . . . . . . . . 8.2 Steuerung eines RISC-Prozessors am Beispiel des MIPS 8.2.1 Befehlsformat . . . . . . . . . . . . . . . . . . . 8.2.2 Befehlszyklus . . . . . . . . . . . . . . . . . . . 8.2.3 Steuerung . . . . . . . . . . . . . . . . . . . . . 8.3 Unterbrechungen . . . . . . . . . . . . . . . . . . . . .

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

. . . . . .

. . . . . . . . . .

. . . . . . . . . . .

. . . . . .

. . . . . . . . . . .

. . . . . .

. . . . . . . . . . .

. . . . . .

. . . . . . . . . . .

. . . . . .

. . . . . . . . . . .

. . . . . .

Rev : 796

INHALTSVERZEICHNIS 8.3.1 8.3.2

7

Synchronisation mit Peripherie . . . . . . . . . . . . . . . . . 290 Einfluss auf Prozessorsteuerung . . . . . . . . . . . . . . . . 294

9 Pipelining 9.1 Prinzip . . . . . . . . . . . . . . . . . . . . . 9.2 Leistungsanalyse und Durchsatzmaximierung 9.3 Befehlspipelines . . . . . . . . . . . . . . . . 9.4 Pipeline-Simulatoren . . . . . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

297 297 299 302 314

10 Statisches Scheduling 10.1 Prinzip . . . . . . . . . . . . . . . . . . . . . . . . 10.2 Reduktion der Branch-Penalty . . . . . . . . . . . 10.3 Abhängigkeiten . . . . . . . . . . . . . . . . . . . 10.3.1 Datenabhängigkeit . . . . . . . . . . . . . 10.3.2 Steuerungsabhängigkeiten . . . . . . . . . 10.4 Scheduling von Schleifen . . . . . . . . . . . . . . 10.4.1 Abhängigkeiten in Schleifen . . . . . . . . 10.4.2 Entrollen von Schleifen . . . . . . . . . . . 10.4.3 Software-Pipelining . . . . . . . . . . . . . 10.4.4 Schleifen Entrollen vs. Software-Pipelining 10.5 Pipelining und Unterbrechungen . . . . . . . . . . 10.6 Befehle mit unterschiedlicher Zyklenzahl . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

315 315 316 317 317 319 319 319 321 323 325 326 327

. . . .

11 Speicherorganisation 11.1 Speicherhierarchie . . . . . . . . . . . . . . . . 11.2 Pufferspeicher (Cache) . . . . . . . . . . . . . 11.2.1 Lesen und Schreiben mit Cache . . . . 11.2.2 Cache-Strukturen . . . . . . . . . . . . 11.3 Hauptspeicher . . . . . . . . . . . . . . . . . . 11.3.1 Systemaufbau . . . . . . . . . . . . . . 11.3.2 Dynamische RAMs . . . . . . . . . . . 11.3.3 Methoden zur Durchsatzsteigerung . . . 11.4 Virtueller Speicher . . . . . . . . . . . . . . . 11.4.1 Segmentierung . . . . . . . . . . . . . 11.4.2 Seitenverwaltung . . . . . . . . . . . . 11.4.3 Segmentierung mit Seitenverwaltung . . 11.4.4 Virtueller Speicher und Cache . . . . . 11.5 Unterschiede zwischen den Hierarchien Cache Hauptspeicher - Sekundärspeicher . . . . . . . 11.6 Ersetzungsstrategien . . . . . . . . . . . . . . .

. . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hauptspeicher . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . und . . . . . .

331 331 332 334 335 338 340 342 343 344 346 348 350 351 353 354

12 Leistung und Geschwindigkeit 357 12.1 Rechnervergleich und Rechnertuning . . . . . . . . . . . . . . . . . . 357

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

8

INHALTSVERZEICHNIS 12.1.1 Amdahl’s Law . . . . . . . . . . . . . 12.2 Leistungsbewertung . . . . . . . . . . . . . . . 12.2.1 Auswertung von Hardware-Parametern 12.2.2 Maßzahlen zur Leistungsbewertung . . 12.2.3 Laufzeitmessungen . . . . . . . . . . . 12.2.4 Überwachung des Betriebes . . . . . . 12.2.5 Modelltheoretische Verfahren . . . . . 12.2.6 Zusammenfassung . . . . . . . . . . . 12.3 Warteschlangenmodelle . . . . . . . . . . . . . 12.3.1 M/M/1-Modelle . . . . . . . . . . . . . 12.3.2 Leistungsparameter eines WS-Systems . 12.3.3 Erweiterungen von M/M/1-Modellen . . 12.3.4 Beispiel . . . . . . . . . . . . . . . . .

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

358 358 359 359 360 363 363 364 364 365 367 370 371

Rev : 796

Abbildungsverzeichnis 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21 1.22 1.23 1.24 1.25 1.26 1.27 1.28 1.29 1.30 1.31 1.32 1.33

Rechnerarchitektur und Rechnerorganisation . . . . . . . . . . . . . Organisation einer Maschine . . . . . . . . . . . . . . . . . . . . . Rekonstruktion von Schickards Rechenmaschine . . . . . . . . . . Skizzen von Schickard . . . . . . . . . . . . . . . . . . . . . . . . Maschine zur Addition und Subtraktion von Blaise Pascal . . . . . . Maschine von Leibniz . . . . . . . . . . . . . . . . . . . . . . . . . Blockstruktur einer Differenzmaschine für Polynome 3. Grades . . . „Analytical Engine“ von C. Babbage . . . . . . . . . . . . . . . . . Aufbau der Z3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ENIAC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Intel 4004 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Typisches PC-System . . . . . . . . . . . . . . . . . . . . . . . . . Leistungsentwicklung . . . . . . . . . . . . . . . . . . . . . . . . . Waferherstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . Kostenentwicklung bei dynamischen Speichern . . . . . . . . . . . Strukturgröße bei verschiedenen Mikroprozessorgenerationen . . . Kostenentwicklung von Produktionsanlagen für die jeweils neueste Technologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Realisierungsalternativen . . . . . . . . . . . . . . . . . . . . . . . Gate-Array-Treiberzelle, vollkundenspezifisch entworfen . . . . . . Beispiel einer Standard-Zelle (GNAND2) . . . . . . . . . . . . . . Gate-Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sea-of-Gates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Programmierbares logisches Array . . . . . . . . . . . . . . . . . . Implementierung eines PLA . . . . . . . . . . . . . . . . . . . . . Struktur eines FPGAs . . . . . . . . . . . . . . . . . . . . . . . . . Verbindungsmatrix zwischen Verbindungsleitungen . . . . . . . . . XC3000 Configurable Logic Block (CLB) . . . . . . . . . . . . . . FPGAs der Actel-Familie . . . . . . . . . . . . . . . . . . . . . . . Kosten pro Chip für verschiedene Entwurfsstile . . . . . . . . . . . Motorola PowerPC 604e . . . . . . . . . . . . . . . . . . . . . . . Motorola 68HC912 . . . . . . . . . . . . . . . . . . . . . . . . . . Compiler und Assembler . . . . . . . . . . . . . . . . . . . . . . . Stack-basierter Rechner . . . . . . . . . . . . . . . . . . . . . . . . 9

22 23 25 25 26 26 28 29 30 32 33 34 36 37 38 39 40 41 43 44 45 46 47 47 48 49 50 50 51 53 54 56 59

10

ABBILDUNGSVERZEICHNIS 1.34 1.35

Akkumulator-basierter Rechner . . . . . . . . . . . . . . . . . . . . Maschine mit allgemeinem Registersatz . . . . . . . . . . . . . . .

2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 2.16 2.17 2.18 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.35 2.36 2.37 2.38 2.39 2.40

Informationsdarstellung im Rechner . . . . . . . . . . . . . Fehlererkennung mit Paritätsschaltung . . . . . . . . . . . . Fehlerkorrektur und -erkennung mittels der Hammingdistanz Hardware zur Fehlererkennung und -korrektur . . . . . . . . Addition von Einerkomplementzahlen . . . . . . . . . . . . 3-Bit-Zweierkomplementzahlen . . . . . . . . . . . . . . . BCD-Darstellung . . . . . . . . . . . . . . . . . . . . . . . Gleitkomma-Darstellung . . . . . . . . . . . . . . . . . . . Darstellbare Zahlen mit impliziter 1 . . . . . . . . . . . . . Maschinenformate des IEEE-Standards . . . . . . . . . . . Übersicht über Datentypen . . . . . . . . . . . . . . . . . . Klassen von GPR-Maschinen . . . . . . . . . . . . . . . . . Adressräume des MC 68020 . . . . . . . . . . . . . . . . . Bytenummerierung . . . . . . . . . . . . . . . . . . . . . . Schaltnetz zur Adressausrichtung (Barred Shifter ) . . . . . . Ausrichtung der Adressgrenzen . . . . . . . . . . . . . . . . Klassifikation von Adressierungsarten . . . . . . . . . . . . Direktoperand . . . . . . . . . . . . . . . . . . . . . . . . . Adressierungsart "Register-direkt" . . . . . . . . . . . . . . Adressierungsart "absolut" . . . . . . . . . . . . . . . . . . Adressierungsart "Register-indirekt" . . . . . . . . . . . . . Prädekrement-Adressierungsart "Prädekrement" . . . . . . . Adressierungsart "Postinkrement" . . . . . . . . . . . . . . Adressierungsart "Register-indirekt mit Displacement" . . . Adressierungsart "Indiziert" . . . . . . . . . . . . . . . . . Adressierungsart "Speicher-indirekt" . . . . . . . . . . . . . Adressierungsart "Nachindiziert" . . . . . . . . . . . . . . . Adressierungsart "Vorindiziert" . . . . . . . . . . . . . . . . Sprungbefehlstabelle . . . . . . . . . . . . . . . . . . . . . Zugriff auf die Zahl 12345 . . . . . . . . . . . . . . . . . . Beispiele für Datentransportbefehle . . . . . . . . . . . . . Wirkung von LEA . . . . . . . . . . . . . . . . . . . . . . . Integer-Arithmetik . . . . . . . . . . . . . . . . . . . . . . Bitverarbeitende logische Befehle . . . . . . . . . . . . . . Wortverarbeitende logische Befehle . . . . . . . . . . . . . Beispiele für Schiebebefehle . . . . . . . . . . . . . . . . . Umgebungsmodell und Funktionsaufruf . . . . . . . . . . . Programmbeispiel . . . . . . . . . . . . . . . . . . . . . . . Sichtbarkeit von Variablen beim Beispiel aus Abbildung 2.38 Struktur von Aktivierungsblöcken . . . . . . . . . . . . . .

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

60 62 67 73 75 76 80 81 84 85 86 87 89 91 92 93 93 94 94 95 95 95 96 96 97 97 99 100 101 102 103 103 105 105 106 107 107 108 109 110 110 112

Rev : 796

ABBILDUNGSVERZEICHNIS 2.41

11

2.42 2.43 2.44 2.45 2.46

Beispiel für das Stack-Layout bei der Ausführung des Programmes von Abbildung 2.38 . . . . . . . . . . . . . . . . . . . . . . . . . . Sprungbefehle JSR und RTS . . . . . . . . . . . . . . . . . . . . . Registerfenster . . . . . . . . . . . . . . . . . . . . . . . . . . . . Terminologie bei Befehlsformaten . . . . . . . . . . . . . . . . . . Möglichkeiten der Datentypspezifikation . . . . . . . . . . . . . . . Beispiel zur speichereffizienten Kodierung . . . . . . . . . . . . . .

112 113 114 115 116 118

3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11

Ausgerichtete Speicherzugriffe . . . . . . . . . . . . . Prinzip des Pipelining . . . . . . . . . . . . . . . . . . Programm-Beispiel und zugehöriger Aktivierungsblock Konvertierung von Integer nach Double . . . . . . . . Assemblerprogramm und zugehöriger Maschinencode Auflösung von Labels . . . . . . . . . . . . . . . . . . Beispiele zu arithmetischen Ausdrücken . . . . . . . . Beispiel für eine Assembler-Datei . . . . . . . . . . . Software-Entwicklung auf dem Zielsystem . . . . . . . Software-Entwicklung auf einem Fremdsystem . . . . Graphisches Frontend xspim . . . . . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

124 128 130 132 137 139 140 140 141 142 143

4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 4.14 4.15 4.16 4.17 4.18 4.19 4.20 4.21 4.22 4.23

Minimale Schaltzeit . . . . . . . . . . . . . . . . . . . . . . . . Beschreibung eines Bibliothekselementes: INV . . . . . . . . . Netz-Verzögerungen . . . . . . . . . . . . . . . . . . . . . . . Schaltwerk und Schaltungsgraph . . . . . . . . . . . . . . . . . Ereignisse an einem Gatter . . . . . . . . . . . . . . . . . . . . Logischer Pfad . . . . . . . . . . . . . . . . . . . . . . . . . . Verzögerungsmodelle . . . . . . . . . . . . . . . . . . . . . . . Halbaddierer . . . . . . . . . . . . . . . . . . . . . . . . . . . Volladdierer . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ripple-Carry-Addierer . . . . . . . . . . . . . . . . . . . . . . 3-Bit-Carry-Lookahead-Addierer . . . . . . . . . . . . . . . . . 7-fach UND, realisiert durch UND2 - Baum . . . . . . . . . . . Mischung von Ripple-Carry- und Carry-Lookahead-Addierern . Addierer/Subtrahierer . . . . . . . . . . . . . . . . . . . . . . . Carry-Save-Addierer . . . . . . . . . . . . . . . . . . . . . . . Addiererbaum für mehrere Summanden . . . . . . . . . . . . . Multiplexer und Demultiplexer . . . . . . . . . . . . . . . . . . Schaltbild und logisches Verhalten eines 1-aus-4-Multiplexers . Implementierung eines 1-aus-4-Multiplexers mit Enable-Eingang Schaltbild und logisches Verhalten eines 1-aus-4-Demultiplexers 3x8 Decoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . Verbindung über ein Bussystem mit Steuerung . . . . . . . . . . Logische Verknüpfungselemente . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

145 146 147 148 149 150 151 152 152 153 154 155 155 156 158 158 160 160 161 161 162 163 164

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

Rev : 796

12

ABBILDUNGSVERZEICHNIS 4.24 4.25 4.26 4.27 4.28 4.29

Schiebeschaltnetz (Barrel shifter) . . . . . . . . . Einfache ALU . . . . . . . . . . . . . . . . . . . ALU in Bitscheibenstruktur mit 4-Bit-Elementen Einfaches Register . . . . . . . . . . . . . . . . Modulo-16 - Zähler . . . . . . . . . . . . . . . . Zähler mit Inkrementier-Schaltnetz . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

165 165 166 167 168 168

5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 5.12 5.13 5.14 5.15 5.16 5.17 5.18 5.19 5.20 5.21 5.22 5.23 5.24 5.25 5.26 5.27 5.28 5.29 5.30 5.31 5.32 5.33 5.34 5.35 5.36

Beschreibungsebenen und Sichten digitaler Systeme . . . . . . . Formale Beschreibung eines 8-Bit-Multiplizierers . . . . . . . . Strukturdiagramm ohne Kontrollpunkte . . . . . . . . . . . . . Strukturdiagramm mit und ohne Kontrollpunkte . . . . . . . . . Implementierung einiger Kontrollpunkte . . . . . . . . . . . . . 8-Bit-Multiplizierer mit Kontrollpunkten . . . . . . . . . . . . . VHDL-Schnittstellenbeschreibung eines Halbaddierers . . . . . Verhaltensbeschreibung des Halbaddierers . . . . . . . . . . . . Datenflussbeschreibung eines Halbaddierers . . . . . . . . . . . Datenflussbeschreibung eines Halbaddierers mit Zeitinformation Strukturbeschreibung des Halbaddierers . . . . . . . . . . . . . Hierarchiebildung in VHDL . . . . . . . . . . . . . . . . . . . Konfiguration für den Halbaddierer . . . . . . . . . . . . . . . . Konfiguration für den Volladdierer . . . . . . . . . . . . . . . . Entwurfsablauf . . . . . . . . . . . . . . . . . . . . . . . . . . Datei "exor.vhd" . . . . . . . . . . . . . . . . . . . . . . . . . . Datei "ha.vhd" . . . . . . . . . . . . . . . . . . . . . . . . . . . Datei "fa.vhd" . . . . . . . . . . . . . . . . . . . . . . . . . . . Auswahlbox des VHDL-Debuggers . . . . . . . . . . . . . . . Hauptfenster des VHDL-Debuggers . . . . . . . . . . . . . . . Hierarchie-Browser . . . . . . . . . . . . . . . . . . . . . . . . Waveform Viewer . . . . . . . . . . . . . . . . . . . . . . . . . Hauptmenü-Fenster . . . . . . . . . . . . . . . . . . . . . . . . Simulator Invocation Dialog . . . . . . . . . . . . . . . . . . . Simulationskontoll-Fenster . . . . . . . . . . . . . . . . . . . . Waveform-Fenster . . . . . . . . . . . . . . . . . . . . . . . . . Hierarchy-Browser . . . . . . . . . . . . . . . . . . . . . . . . Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Verhalten von Variablen und Signalen . . . . . . . . . . . . . . Zeitdiagramm für Signal- und Variablenwechsel . . . . . . . . . Testbench, die die Simulationsantworten selber auswertet . . . . Testbench zum Vergleich von Spezifikation und Implementierung Waveform-Ausgabe der Testbench . . . . . . . . . . . . . . . . Simulation mit zufälligen Stimuli . . . . . . . . . . . . . . . . . ALU für Zweierkomplementzahlen . . . . . . . . . . . . . . . . Befehlskodierung und Ansteuerung für die ALU . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

169 172 173 174 175 176 179 180 180 181 181 182 183 183 185 186 186 187 188 189 190 190 192 193 194 195 196 200 207 207 208 208 212 213 214 215

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . .

Rev : 796

ABBILDUNGSVERZEICHNIS

13

5.37 5.38 5.39 5.40 5.41

Festlegen der Don’t-Care-Stellen auf einen Default-Wert Ausnutzen von Don’t-Care-Stellen zur Logikoptimierung Automatisch synthetisierte ALU-Ansteuerung . . . . . . Steuerwerk gegeben durch Zustandsübergangstabelle . . Zielstruktur . . . . . . . . . . . . . . . . . . . . . . . .

. . . . .

. . . . .

6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 6.10 6.11 6.12 6.13

UND-Feld für 3-Bit-Multiplizierer . . . . . . . . . . . . . Addition von 1-Bit-Produkten . . . . . . . . . . . . . . . . Array-Multiplizierer . . . . . . . . . . . . . . . . . . . . Multiplikation, 2-schrittig als Schaltwerk . . . . . . . . . . Even-Odd-Feld . . . . . . . . . . . . . . . . . . . . . . . Operationswerk zur Multiplikation . . . . . . . . . . . . . Carry-Save-Multiplizierer . . . . . . . . . . . . . . . . . . Beispiel für Carry-Save-Multiplikation . . . . . . . . . . . Schriftliche Division im Dualsystem . . . . . . . . . . . . Operationswerk für die serielle Division . . . . . . . . . . Beispiele für Rundung bei drei signifikanten Dezimalstellen Algorithmus zur Gleitkomma-Addition auf RT-Ebene . . . Datenpfad zur Gleitkomma-Addition . . . . . . . . . . . .

. . . . . . . . . .

7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 7.10 7.11 7.12 7.13 7.14 7.15 7.16 7.17 7.18 7.19 7.20 7.21

. . . . .

. . . . .

. . . . .

. . . . .

215 216 217 218 219

. . . . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

222 222 223 224 225 226 227 228 228 229 232 237 238

Zusammenspiel von Steuer- und Operationswerk . . . . . . . . . . Moore-Schaltwerk . . . . . . . . . . . . . . . . . . . . . . . . . . Mealy-Schaltwerk . . . . . . . . . . . . . . . . . . . . . . . . . . . Zustandsübergangstabelle . . . . . . . . . . . . . . . . . . . . . . . Einfaches mikroprogrammiertes Steuerwerk (nach Wilkes, 1951) . . Beispiele für Befehlsformate . . . . . . . . . . . . . . . . . . . . . Horizontale und vertikale Mikroprogrammierung . . . . . . . . . . Unterschiedlich starke Kodierung von Steuerinformationen . . . . . Mikroprogrammierte Steuerung mit µ-Programmzähler und explizitem µ-Befehlsregister . . . . . . . . . . . . . . . . . . . . . . . . . Mehrphasentakt . . . . . . . . . . . . . . . . . . . . . . . . . . . . Optimierungsmöglichkeiten bei der Adressierung . . . . . . . . . . Mikrobefehle und aktivierte Steuersignale . . . . . . . . . . . . . . Überdeckungstabelle . . . . . . . . . . . . . . . . . . . . . . . . . Minimale Überdeckung . . . . . . . . . . . . . . . . . . . . . . . . Optimale Kodierung . . . . . . . . . . . . . . . . . . . . . . . . . Beispiel eines µ-Programms . . . . . . . . . . . . . . . . . . . . . Struktur mit Kontrollpunkten für die Zweierkomplement- Multiplikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Algorithmische Beschreibung . . . . . . . . . . . . . . . . . . . . µ-Befehlsformat . . . . . . . . . . . . . . . . . . . . . . . . . . . . µ-Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . µ-programmierte Steuereinheit . . . . . . . . . . . . . . . . . . . .

240 240 240 241 242 244 244 245

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

246 247 247 249 250 251 252 253 255 256 257 258 259

Rev : 796

14

ABBILDUNGSVERZEICHNIS 7.22 7.23 7.24 7.25 7.26 7.27 7.28 7.29 7.30 7.31 7.32 7.33 7.34 7.35 7.36 7.37 7.38

Decodierlogik . . . . . . . . . . . . . . . . . . . . . Kodierung gemäß Funktion . . . . . . . . . . . . . . Mehrere Befehlsformate . . . . . . . . . . . . . . . Mikroprogramm mit mehreren Befehlsformaten . . . Flussdiagramm und 1-aus-n-Steuerung . . . . . . . . Erzeugung der Steuersignale . . . . . . . . . . . . . Einfügen eines D-Flipflops . . . . . . . . . . . . . . Verzweigung des Eingangs eines D-Flipflops . . . . Zusammenfassung von Linien in einem ODER-Gatter Umwandlung von Verzweigungen . . . . . . . . . . Wiederholter Schleifendurchlauf . . . . . . . . . . . Steuerung mit Modulo-k-Zähler . . . . . . . . . . . Zustandsübergangstabelle . . . . . . . . . . . . . . . Steuerwerksstruktur . . . . . . . . . . . . . . . . . . Zustandskodierung . . . . . . . . . . . . . . . . . . 1-aus-n Steuerung . . . . . . . . . . . . . . . . . . . Zählerbasierte Steuerung . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

260 261 262 262 264 264 265 265 265 266 266 267 268 269 269 270 271

8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 8.10 8.11 8.12 8.13 8.14 8.15 8.16 8.17 8.18 8.19 8.20 8.21

Befehlssatz der Einfachst-CPU . . . . . . . . . . . . . . . . . . . . Struktur der Einfachst-CPU . . . . . . . . . . . . . . . . . . . . . . CPU-Verhalten als geschlossene Schleife . . . . . . . . . . . . . . Flussdiagramm der Befehlsabarbeitung . . . . . . . . . . . . . . . Steuerung der Einfachst-CPU . . . . . . . . . . . . . . . . . . . . . Steuersignale in der Einfachst-CPU . . . . . . . . . . . . . . . . . MIPS-Struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . MIPS-Befehlsformat . . . . . . . . . . . . . . . . . . . . . . . . . MIPS-Befehlszyklus . . . . . . . . . . . . . . . . . . . . . . . . . Zustandsübergangsdiagramm für MIPS . . . . . . . . . . . . . . . Datentransfer: Adressrechnung und Speicherzugriff . . . . . . . . . ALU-Operationen . . . . . . . . . . . . . . . . . . . . . . . . . . . Bedingtes Setzen . . . . . . . . . . . . . . . . . . . . . . . . . . . Sprünge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Verzweigungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mikroprogrammierte Steuerung für den MIPS . . . . . . . . . . . . Mögliches Mikrobefehlsformat beim MIPS . . . . . . . . . . . . . Kodierung von Steuerleitungen nach Funktion . . . . . . . . . . . . Mehrere Befehlsformate . . . . . . . . . . . . . . . . . . . . . . . Zentraleinheit und Peripherie . . . . . . . . . . . . . . . . . . . . . Systemstruktur mit Interface-Bausteinen für Kommunikation mit Peripherie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synchronisation durch Polling oder "Busy-Waiting" . . . . . . . . . Synchronisation durch Unterbrechung . . . . . . . . . . . . . . . . Daisy-Chain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

275 276 277 278 279 279 281 281 283 284 285 285 286 286 286 287 287 288 288 290

8.22 8.23 8.24

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

291 291 292 293

Rev : 796

ABBILDUNGSVERZEICHNIS

15

8.25 8.26 8.27

Kodierte Anforderung . . . . . . . . . . . . . . . . . . . . . . . . . 293 Systemstruktur für kodierte Interruptanforderungen . . . . . . . . . 294 Berücksichtigung von Unterbrechungen im Zustandsübergangsdiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 9.10 9.11 9.12 9.13 9.14

Prinzip des Pipelining . . . . . . . . . . . . . . . . . . . . . . . . . Pipeline-Implementierung eines Gleitkomma-Addierers . . . . . . . Pipeline-Belegung beim Gleitkomma-Addierer . . . . . . . . . . . Belegung der MIPS-Pipeline . . . . . . . . . . . . . . . . . . . . . Zeiten beim MIPS ohne Pipeline . . . . . . . . . . . . . . . . . . . Zeiten beim MIPS mit Pipeline . . . . . . . . . . . . . . . . . . . . Zuordnung von Operationen zu Pipeline-Stufen . . . . . . . . . . . Aufteilung auf Pipeline-Stufen . . . . . . . . . . . . . . . . . . . . Datenpfad mit Pipeline . . . . . . . . . . . . . . . . . . . . . . . . Leerlauf in der Pipeline . . . . . . . . . . . . . . . . . . . . . . . . Wartezyklen bei nur einem Speicherport . . . . . . . . . . . . . . . RAW-Datenkonflikt . . . . . . . . . . . . . . . . . . . . . . . . . . Konfliktauflösung durch "Forwarding" . . . . . . . . . . . . . . . . Forwarding, falls Schreiben zu Beginn und Lesen am Ende eines Taktzyklus erfolgt . . . . . . . . . . . . . . . . . . . . . . . . . . . Bypass-Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . Nutzen der Systemlatches für „Forwarding“ . . . . . . . . . . . . . Forwarding zur ALU und zum MDR . . . . . . . . . . . . . . . . . Bei Speicherzugriffen kann trotz Forwarding ein Wartezyklus nötig sein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Wartezyklus bei Speicherzugriff . . . . . . . . . . . . . . . . . . . Wartezyklen bei Sprungbefehlen . . . . . . . . . . . . . . . . . . . Einfluss der Vorhersage „Verzweigung nicht genommen“ . . . . . . Verzweigungszielspeicher . . . . . . . . . . . . . . . . . . . . . . . 2-Bit-Sprungvorhersage . . . . . . . . . . . . . . . . . . . . . . . .

297 298 299 299 301 301 303 304 305 306 307 308 309

Beispiel-Code vor und nach statischem Scheduling . . . . . . . . . Delayed Branching . . . . . . . . . . . . . . . . . . . . . . . . . . Scheduling für verzögerte Sprünge . . . . . . . . . . . . . . . . . . Beispiele für Steuerungsabhängigkeiten . . . . . . . . . . . . . . . Beispiel für schleifeninterne und schleifenübergreifende Abhängigkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.6 Programm mit schleifenübergreifender Abhängigkeit . . . . . . . . 10.7 Äquivalentes Programm ohne schleifenübergreifende Abhängigkeit 10.8 Assembler-Code für eine einfache Schleife . . . . . . . . . . . . . . 10.9 Entrollte Schleife . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.10 Prinzip des Software-Pipelining . . . . . . . . . . . . . . . . . . . 10.11 Beispielprogramm . . . . . . . . . . . . . . . . . . . . . . . . . .

316 316 317 319

9.15 9.16 9.17 9.18 9.19 9.20 9.21 9.22 9.23 10.1 10.2 10.3 10.4 10.5

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

309 309 310 310 311 311 312 312 313 314

320 320 320 322 323 324 324

Rev : 796

16

ABBILDUNGSVERZEICHNIS 10.12 10.13 10.14 10.15 10.16 10.17 10.18 10.19 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.10 11.11 11.12 11.13 11.14 11.15 11.16 11.17 11.18 11.19 11.20 11.21 11.22 11.23 11.24 11.25 11.26 11.27 11.28 11.29 12.1

Zusammenfassen eines neuen Schleifenrumpfes . . . . . . . . . . . Resultierender Schleifenrumpf . . . . . . . . . . . . . . . . . . . . Beispiel zu Software-Pipelining . . . . . . . . . . . . . . . . . . . Vergleich der Hardware-Nutzung beim Schleifen Entrollen und Software-Pipelining . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unterbrechungsmöglichkeiten bei Befehlsbearbeitung des MIPS . . Beispiel für Unterbrechungen in verschiedenen Phasen . . . . . . . Befehlspipeline mit funktionalen Einheiten, die nicht als Pipeline organisiert sind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Pipeline mit unterschiedlicher Zyklenzahl . . . . . . . . . . . . . . Leistungsentwicklung von DRAMs . . . . . . . . . . . . . . . . . Leistungsvergleich CPU - Speicher . . . . . . . . . . . . . . . . . . Systemstruktur mit CPU, Hauptspeicher und Cache . . . . . . . . . Cache-Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . Vollassoziativer Cache . . . . . . . . . . . . . . . . . . . . . . . . Direkt abgebildeter Cache . . . . . . . . . . . . . . . . . . . . . . Teilassoziativer Cache . . . . . . . . . . . . . . . . . . . . . . . . Aufbau von RAMs . . . . . . . . . . . . . . . . . . . . . . . . . . Lesezyklus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Schreibzyklus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16K × 32 RAM aus 16K × 8 Bausteinen . . . . . . . . . . . . . . 64K × 8 RAM aus 16K × 8 Bausteinen . . . . . . . . . . . . . . . 1 MB SIMM aus 1Mbit-Chips . . . . . . . . . . . . . . . . . . . . 1 Mbit-DRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . Breitere Speicherorganisation . . . . . . . . . . . . . . . . . . . . . Interleaving . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Prinzip eines virtuellen Speichers . . . . . . . . . . . . . . . . . . . Typische Parameter eines virtuellen Speichersystems . . . . . . . . Arbeitsweise der MMU bei Segmentierung mit Blockunterteilung . Abbildung vom virtuellen in den realen Adressraum . . . . . . . . . Fragmentierung und Kompaktierung . . . . . . . . . . . . . . . . . Seitenverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . Einfacher Speicherschutz mit Hilfe der Statussignale des Prozessors Segmentierung mit Speicherverwaltung . . . . . . . . . . . . . . . Implementierung von Daten-Sharing . . . . . . . . . . . . . . . . . Virtuelle Cache-Adressierung . . . . . . . . . . . . . . . . . . . . . Reale Cache-Adressierung . . . . . . . . . . . . . . . . . . . . . . Direktspeicherzugriff . . . . . . . . . . . . . . . . . . . . . . . . . Unterschiede zwischen den Hierarchien Cache - Hauptspeicher und Hauptspeicher - Sekundärspeicher . . . . . . . . . . . . . . . . . .

324 325 325 326 327 327 328 328 333 333 334 335 336 337 338 339 339 340 341 341 342 342 344 344 345 346 347 347 348 349 349 350 351 352 352 353 354

SPEC92 Benchmark-Programme . . . . . . . . . . . . . . . . . . . 361

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

ABBILDUNGSVERZEICHNIS 12.2 12.3 12.4 12.5 12.6 12.7

17

Normalisierung verfälscht Durchschnittsbildung . . . . . . . . . . . Übersicht über Rechnerbewertung und ihre Anwendungsmöglichkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Warteschlangen-System . . . . . . . . . . . . . . . . . . . . . . . . Verteilung für festes n und λ . . . . . . . . . . . . . . . . . . . . . Exponentialverteilung . . . . . . . . . . . . . . . . . . . . . . . . . Warteschlangennetzwerk . . . . . . . . . . . . . . . . . . . . . . .

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

363 364 365 366 367 370

Rev : 796

Tabellenverzeichnis 1.1 1.2 1.3 1.4 1.5 1.6

Entwicklung mechanischer Rechenautomaten . . . . . Rechnergenerationen . . . . . . . . . . . . . . . . . . Systemkosten . . . . . . . . . . . . . . . . . . . . . . Elemente einer Bibliothek . . . . . . . . . . . . . . . Anwendungsbereiche der verschiedenen Entwurfsstile . Ausführung eines Befehls . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

31 35 39 44 52 64

2.1 2.2 2.3 2.4 2.5 2.6

ASCII-Code . . . . . . . . . . . . . . . . . . . . . . . . . . . Bedeutung der Sonderzeichen im ASCII-Code nach DIN 66003 Zahlsysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . Möglichkeiten zur Darstellung negativer Zahlen . . . . . . . . . Zusammenfassung des 32-Bit-IEEE-Formats . . . . . . . . . . Adressauflösung für einige Rechner . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

70 71 77 83 87 92

3.1 3.2 3.3 3.4 3.5 3.6 3.7

Beispiele für Load- und Store-Befehle des MIPS Beispiele für arithmetisch-logische Befehle . . . Beispiele für Sprungbefehle . . . . . . . . . . . Datentransfer-Befehle . . . . . . . . . . . . . . Arithmetisch-logische Befehle . . . . . . . . . . Sprungbefehle . . . . . . . . . . . . . . . . . . Gleitkomma-Befehle . . . . . . . . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

123 126 127 133 134 135 136

4.1 4.2

Klassifizierung der Grundelemente . . . . . . . . . . . . . . . . . . . 159 Funktionen der ALU . . . . . . . . . . . . . . . . . . . . . . . . . . 163

5.1

Zustandsübergangstabelle für das Steuerwerk des Multiplizierers . . . 177

6.1 6.2

Beispiele für Guard-, Round- und Sticky-Bits . . . . . . . . . . . . . 233 Implementierung der Rundungsmodi . . . . . . . . . . . . . . . . . . 234

7.1

Vereinfachte Überdeckungstabelle . . . . . . . . . . . . . . . . . . . 251

8.1 8.2

Bearbeitung des Befehls add $1, $2, $3 . . . . . . . . . . . . . 283 Bearbeitung des Befehls beqz $1, . . . . . . . . . . . 284

10.1 Beispiel für die Latenz bei abhängigen Befehlen

18

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . .

. . . . . . .

. . . . . .

. . . . . . .

. . . . . .

. . . . . . .

. . . . . .

. . . . . . .

. . . . . . .

. . . . . . . . . . . 318

TABELLENVERZEICHNIS

19

11.1 Speicherhierarchie . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 11.2 Beispiele für teilassoziative Caches . . . . . . . . . . . . . . . . . . 338 12.1 Auswirkung von Verbesserungsmaßnahmen . . . . . . . . . . . . . . 357 12.2 Normalisierung von Gleitkommaoperationen . . . . . . . . . . . . . 360

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

20

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

TABELLENVERZEICHNIS

Rev : 796

Kapitel 1 Einleitung 1.1 Informationsverarbeitende Systeme Die Veranstaltung Rechnerorganisation bzw. Technische Informatik II befasst sich mit dem Aufbau von Rechnersystemen (Hardware) und weniger mit deren Programmierung (Software). Da jedoch Hardware häufig gebaut wird, um Software ablaufen zu lassen, und die Grenzen bzw. Schnittstellen zwischen Hard und Software nicht immer ganz klar sind, sollen zunächst einige grundlegende Begriffe definiert werden.

1.1.1 Algorithmen und Programme Ein Algorithmus ist eine durch endlich viele Zeichen eindeutig bestimmte Vorschrift zum Umformen zeichenweise dargestellter Informationen bzw. Daten. Ein Programm ist die Darstellung eines Algorithmus unter Einhaltung gewisser syntaktischer Regeln. Gesucht ist ein System zur Ausführung unterschiedlicher Programme mit unterschiedlichen Daten.

1.1.2 Rechnerarchitektur und Rechnerorganisation Unter Rechnerarchitektur versteht man die funktionale Erscheinungsform eines Rechnersystems gegenüber einem unmittelbaren Anwender (Amdahl, 1964). Dies kann z.B. der Befehlssatz eines Prozessors sein. Unter Rechnerorganisation versteht man die Strukturen eines Rechnersystems (Komponenten und Verbindungen). Dazu gehört die Implementierung (Beschreibung der Systemstruktur) und die Realisierung (tatsächlicher technischer Aufbau). 21

22

KAPITEL 1. EINLEITUNG

Der Zusammenhang zwischen Rechnerarchitektur und Rechnerorganisation ist in Abbildung 1.1 dargestellt. Der Benutzer sieht in dem Computer eine Maschine, die einen in einer Programmiersprache wie C oder Pascal dargestellten Algorithmus ausführen kann. Die Implementierung und Realisierung der Maschine kann wiederum auf verschiedenen Hierarchieebenen (z.B. Gatterebene, Schaltungsebene, Layout) betrachtet werden. Algorithmus: Programm:

formale Spezifikation PASCAL, C, C++, FORTRAN, Assembler, Maschinensprache

Computer

Rechnerarchitektur Rechnerorganisation

Digitale Schaltelemente Elektronische Bauteile

(NAND, Flipflop,...) (Transistoren,...)

Abbildung 1.1: Rechnerarchitektur und Rechnerorganisation

1.1.3 Rechnerorganisation durch Mensch und Maschine Um die grundlegende Organisation einer Rechenmaschine einzuführen, soll zunächst analysiert werden, wie ein Mensch eine Aufgabe (z.B. eine Übungsaufgabe zu dieser Veranstaltung) bearbeitet. Zunächst wird die Aufgabenstellung aufgenommen (Eingabe) und auf Papier notiert. Die Eingabe wird dann nach bestimmten Regeln, die ebenfalls auf dem Papier stehen können (z.B. Aufgabentext, Vorlesungsmitschrift, Bücher), verarbeitet. Die Ergebnisse werden danach wieder ausgegeben (Vortrag während des Übungstermins). Die Steuerung des Ablaufs erfolgt zentral durch das Gehirn. Eine speicherprogrammierbare Maschine (Abbildung 1.2) ist sehr ähnlich organisiert. Der Speicher entspricht dem Papier, auf dem ein Mensch Zwischenrechnungen durchführt. Die Zentraleinheit entspricht dem menschlichen Gehirn und besteht aus zwei Komponenten. Das Operationswerk führt einzelne Rechenschritte durch (z.B. Addition, Subtraktion, Multiplikation etc. bei einer Rechenaufgabe), die Steuereinheit ist für die Steuerung des Gesamtablaufes zuständig.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.1. INFORMATIONSVERARBEITENDE SYSTEME

23

Z en trale in h eit

S teu er e in h eit

B efeh l e S p eich er

O p er at io n s w e rk

E in - / A u s g ab e

D at en

Abbildung 1.2: Organisation einer Maschine

1.1.4 Abstraktes Rechnermodell Eine Berechnung ist die Auswertung einer Funktion Z = f (X). Z und X können Zahlen, Worte, Beweise, Dateien und anderes sein. Um f (X) auf einem Rechner auszuwerten, muss f in eine Folge von Teilfunktionen f1 , f2 , f3 ,..., fn aus dem Befehlssatz zerlegt werden: Y1 = f1 (X) Y2 = f2 (Y1 ) ... Z = fn (Yn−1 ) An ein Rechnermodell werden allgemein die folgenden Anforderungen gestellt: • Die Maschine hat nicht alle Antworten auf alle Befehle gespeichert. • Die Informationsverarbeitung geschieht in endlicher Zeit. Ein Beispiel für ein abstraktes Rechnermodell ist die in der Vorlesung Theoretische Informatik vorgestellte Turingmaschine.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

24

KAPITEL 1. EINLEITUNG

1.1.5 Grenzen von Computern Nach der Church’schen These ist alles, was der mächtigste Computer berechnen kann, auch mit einer Turingmaschine berechenbar. Es gibt jedoch Funktionen, die von einer Turingmaschine (und damit auch von einem beliebigen realen Computer) nicht berechnet werden können. Eine Funktion f heißt effektiv berechenbar, wenn f (X) für jedes X in einer endlichen Anzahl von Schritten durch eine Turingmaschine berechnet werden kann. Kurt Gödel (1906-1978) war der erste, der zeigte, dass es sinnvolle Funktionen gibt, die nicht effektiv berechenbar sind. Ein Beispiel hierfür ist das Halteproblem der Turingmaschine: Es sei (M, X) eine Turingmaschine M mit Eingabeband X. (M, X) hält, wenn M bei der Eingabe X nach endlichen Schritten hält. Eine Funktion f h (M, X) sei definiert durch: • fh (M, X) = 1 : (M, X) hält • fh (M, X) = 0 : sonst M. Minsky zeigte 1967, dass fh (M, X) nicht berechenbar ist. Wenn eine Funktion nach obiger Definition effektiv berechenbar ist, so heißt das nicht, dass sie auf jedem realen Rechner tatsächlich berechnet werden kann. Je nach Problemgröße kann die Zeitkomplexität oder der Speicherbedarf so groß sein, dass die Funktion zwar theoretisch, jedoch nicht praktisch berechnet werden kann. Man spricht dann von einem unbehandelbaren Problem. Üblicherweise gilt die folgende Definition: Ein Problem ist behandelbar, wenn die Zeitkomplexität durch ein Polynom p(n) in der Problemgröße n beschränkt ist: O(p(n)). Hierzu kann als Vergleich die Problemklasse P der Komplexitätstheorie herangezogen werden, da ein solches Problem nach den obigen Anmerkungen durch eine deterministische Turingmaschine in polynomial beschränkter Zeit gelöst werden kann. Zahlreiche Probleme sind nach dieser Definition nicht behandelbar und können daher nur approximiert werden. Nicht behandelbare Probleme liegen in der Terminologie der Komplexitätstheorie nicht in der Klasse P. Nach den obigen Definitionen sind dieses Probleme aus der Klasse N P, da sie zwar durch eine Turingmaschine berechenbar sind, aber nicht durch eine deterministische in polynomial beschränkter Zeit.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.2. AUS DER GESCHICHTE

25

1.2 Aus der Geschichte 1.2.1 Mechanische Maschinen Der erste mechanische Rechner wurde vermutlich 1623 von Wilhelm Schickard entworfen (Abbildungen 1.3, 1.4). Schickard (1592-1635) war in Tübingen Professor für biblische Sprachen, später Mathematik und Astronomie. Es ist bis heute nicht bekannt, ob seine Maschine damals tatsächlich gebaut wurde.

Abbildung 1.3: Rekonstruktion von Schickards Rechenmaschine

Abbildung 1.4: Skizzen von Schickard 1642 baute der Franzose Blaise Pascal (1623-1662) eine Maschine zur Addition und Subtraktion (s. Abbildung 1.5). Sie enthielt 2 Sätze von je 6 Zählscheiben, in die jeweils 10 Ziffern eingraviert waren. Ein Satz W diente als Akkumulator, der andere Satz Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

26

KAPITEL 1. EINLEITUNG

W’ wurde verwendet, um eine Zahl, die zum Akkumulator addiert (oder subtrahiert) werden sollte, einzugeben. W und W’ waren mechanisch gekoppelt, d. h. wenn eine Zählscheibe von W’ gedreht wurde, drehte sich eine Scheibe von W entsprechend mit. Als besondere Leistung galt, dass der Übertrag von einer Stelle zur nächsten korrekt behandelt wurde, d. h. immer, wenn eine Stelle von 9 auf 0 übergeht, wird das nächste Rad um eine Einheit weitergedreht.

Abbildung 1.5: Maschine zur Addition und Subtraktion von Blaise Pascal Um 1671 konstruierte Gottfried Wilhelm Leibniz (1646-1716) eine Maschine, die auf der von Pascal basierte und zusätzlich multiplizieren und dividieren können sollte (s. Abbildung 1.6). Weil zur Zahlendarstellung das Dezimalsystem verwendet wurde, traf er dabei auf mechanische Probleme, die später von dem Pfarrer und Uhrmacher Philip Hahn (1739-1790) gelöst wurden.

Abbildung 1.6: Maschine von Leibniz Eine sehr bedeutende Rolle in der Geschichte der Rechenmaschinen spielte der Engländer Charles Babbage (1792-1871). Er entwarf zwei „Computer“: die Differenzmaschine (1823) und die „Analytical Engine“ (1834). Die Differenzmaschine wurde in erster Linie für die Erstellung von Navigationstafeln entworfen. Tatsächlich können mit ihr Polynome der Form f (X) = an xn + an−1 xn−1 + ... + a0 x0 Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.2. AUS DER GESCHICHTE

27

berechnet werden. Würde die Polynomberechnung direkt implementiert, so wären als Hardwareoperationen die Addition, Multiplikation und evtl. Potenzierung notwendig. Die Differenzmaschine benötigt dagegen nur einen Addierer. Angenommen, f (X) soll für eine Folge von Eingaben x0 , x1 , x2 , ..., wobei xj −xj−1 =: ∆x konstant ist, berechnet werden. Die i-te Differenz von f (xj ), ∆i f (xj ) ist rekursiv wie folgt definiert:

∆0 f (xj ) = f (xj ) ∆i f (xj ) = ∆i−1 f (xj+1 ) − ∆i−1 f (xj ) für} i ≥ 1

(1.1)

Es kann leicht gezeigt werden, dass ∆n f (xj ) konstant ist und ∆i f (xj ) = 0 für alle i > n gilt. Gleichung (1.1) kann umgeformt werden zu:

∆i f (xj+1 ) = ∆i f (xj ) + ∆i+1 f (xj ) für i ≥ 0

(1.2)

Sind nun die ersten n+1 Differenzen ∆0 f (x0 ), ..., ∆n f (x0 ) bekannt, so kann sukzessive anhand von (1.2) alleine durch Addition eine Wertetabelle der Funktion erstellt werden. Beispiel: Berechnung der Funktion x2 − x + 41 für alle x0 = 0, x1 = 1, ... Zunächst werden die Differenzfunktionen formal bestimmt: ∆0 f (x) = f (x) = x2 − x + 41 ∆1 f (x) = ∆0 f (x + 1) − ∆0 f (x) = (x + 1)2 − (x + 1) + 41 − (x2 − x + 41) = 2x ∆2 f (x) = ∆1 f (x + 1) − ∆1 f (x) = 2(x + 1) − 2x = 2 Anschließend werden die ersten Differenzen ∆0 f (x0 ), ..., ∆2 f (x0 ) von Hand berechnet: ∆0 f (x0 ) = ∆0 f (0) = 41 ∆1 f (x0 ) = ∆1 f (0) = 0 ∆2 f (x0 ) = ∆2 f (0) = 2 Diese Werte dienen als Eingabe für die Differenzmaschine, deren Blockstruktur in Abbildung 1.7 dargestellt ist.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

28

KAPITEL 1. EINLEITUNG yj = f(xj)

∆3 y0 ∆ 3 Register Addierer

∆2 y0

∆ 2 Register Anfangswerte Addierer ∆ 1y0 ∆ 1 Register Addierer

∆0y 0

y ∆ 0 Register

j

Abbildung 1.7: Blockstruktur einer Differenzmaschine für Polynome 3. Grades Alle weiteren Funktionswerte können nun mechanisch durch Anwendung von (1.2) bestimmt werden: ∆2 f (x1 ) = ∆2 f (x0 ) + ∆3 f (x0 ) = ∆2 f (0) = 2 , da ∆i f (xj ) = 0 für alle i > n (hier: n = 2) ∆1 f (x1 ) = ∆1 f (x0 ) + ∆2 f (x0 ) = 0 + 2 = 2 ∆0 f (x1 ) = ∆0 f (x0 ) + ∆1 f (x0 ) = 41 + 0 = 41 Die folgende Tabelle verdeutlicht den Ablauf: xj 0 1 2 3 4 ...

∆0 f (xj ) = f (xj ) 41 41 43 47 53 ...

∆1 f (xj ) 0 2 4 6 8 ...

∆2 f (xj ) 2 2 2 2 2 ...

Dieses Verfahren kann man zur Berechnung beliebiger Funktionen verwenden, die sich als Polynom approximieren lassen. Es gilt z.B.: ex =

∞ P

ˆi=0

xi i! 3

5

sin x = x − x3! + x5! − ... 2 4 cos x = 1 − x2! + x4! − ... Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.2. AUS DER GESCHICHTE

29

Babbage begann mit dem Bau einer Maschine für Polynome 6-ten Grades und 20stellige Zahlen, die jedoch nie fertiggestellt wurde. In einem Brockhaus-Conversations-Lexikon, 1882 findet man dazu: „Seine Rechenmaschine sollte zufolge ihres Zwecks, mathematische und seemännische Tafeln zu berechnen und zu drucken, aus zwei wesentlich verschiedenen Teilen, einem rechnendem und einem druckenden, bestehen. Der erste wurde 1828 zu bauen angefangen und war 1833 zum größten Teil in bewunderungswürdiger Schönheit und Vollkommenheit vollendet, als eine Unterbrechung am Bau der Maschine eintrat. Der druckende Teil war damals noch nicht halb fertig, und dennoch war der Gesamtaufwand beim Bau bis auf 17.000 Pfund Sterling gestiegen. Da die vollständige Ausführung noch auf doppelt so viel veranschlagt wurde, so ließ man die Sache liegen.“ Einige kleiner dimensionierte Differenzmaschinen wurden von anderen Erbauern erfolgreich vollendet. Dazu gehört eine 15-stellige Maschine für Polynome dritten Grades von dem Schweden Georg Scheutz (1785-1873). Charles Babbage entwarf unterdessen seine „Analytical Engine“, die in der Lage sein sollte, beliebige mathematische Operationen automatisch auszuführen. Die Struktur ist in Abbildung 1.8 dargestellt. Die Maschine besteht aus einem Rechenwerk, einem Steuerwerk, einem Speicher und einer Ausgabeeinheit. Die Programmsteuerung erfolgte über Lochkarten. Als besondere Neuerung galt ein Mechanismus zur Unterstützung von bedingten Sprüngen, die durch Vor- und Rücklaufen der als Band angeordneten Lochkarten realisiert wurden. Die Ausgabe sollte direkt über Stahlstempel erfolgen. Auch die „Analytical Engine“ wurde nie vollständig aufgebaut. R e ch en w e rk (“th e m ill” ) (+ ,−, · ,÷)

S peich e r (“th e sto re” )

D ru ck w e rk o de r K artenlo c he r

S teu erun g

“O p eratio n ska rte n” “ V a riab len karte n” (zu r A u sw a h l vo n Sp eic he rp lätz en )

Abbildung 1.8: „Analytical Engine“ von C. Babbage

1.2.2 Elektrische Maschinen Nach Babbages Tod wurden für lange Zeit keine bemerkenswerten Versuche unternommen, digitale Universalrechner zu bauen. In den dreißiger Jahren des 20. JahrDate : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

30

KAPITEL 1. EINLEITUNG

hunderts wurden dann solche Rechner in mehreren Ländern unabhängig voneinander entwickelt. In Deutschland baute Konrad Zuse einen mechanischen Computer, die Z1, der, im Gegensatz zu den Babbage-Maschinen, eine binäre anstatt einer dezimalen Zahlendarstellung verwendete. Von dem Nachfolger, der Z3 (1941), nimmt man an, dass es sich um den ersten programmgesteuerten Universalrechner handelt. Die Struktur der Z3 ist in Abbildung 1.9 dargestellt. Die wesentlichen Merkmale sind: • Binärdarstellung von Befehlen und Zahlen • Binäre Schaltelemente für Speicherung und Verarbeitung • Verwendung des Aussagenkalküls (UND, ODER, NICHT) zur Realisierung der Rechenoperationen • Gleitkomma-Darstellung von Zahlen (Vorzeichen, Exponent, Mantisse) • Darstellung des Ablaufs als Folge von Rechenschritten (noch keine bedingten Befehle) • Aufbau mit elektromagnetischen Relais (600 für Rechenwerk, 1400 für Speicherwerk, 64 für 22-Bit Wörter) • Steuerung über 8-Kanal-Lochstreifen • Geschwindigkeit: 3 Sekunden für Multiplikation, Division, Wurzelziehen

Programmspeicher (“Plan-Speicherwerk”) Steuerwerk (“Planwerk”, “Pro grammwerk”) Eingabewerk: Tastenfel d und Lochs treifen

Wähl werk Rechenwerk (“Arbeitswerk”)

Speicher (“Speicherwerk”)

Ausgabe: Anzeigenfel d (Lamp en)

Abbildung 1.9: Aufbau der Z3 Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.2. AUS DER GESCHICHTE

31

1944 wurde die etwa zur gleichen Zeit von Howard Aiken (1900-1973) entworfene Havard Mark I gebaut. In Tabelle 1.1 ist die Entwicklungsgeschichte mechanischer Rechenautomaten zusammengefasst. Zeit

Erfinder, Maschine

Fähigkeiten

Innovation

1623

Schickard

Grundrechenarten

erster Vorschlag

1642

Pascal

Addition, Subtraktion

Übertrag, Komplementdarstellun

1671

Leibniz

Grundrechenarten

Multiplikation und Division durch Schieben

1827

Babbage: Differenzmaschine

Polynomauswertung

automatische Mehrschrittoperation

1834

Babbage: Analytical Engine

Universalrechner

programmierbarer Befehlsablauf

1941 1944

Zuse: Z3 Aiken: Mark I

Universalrechner

erste funktionierende Rechner

Tabelle 1.1: Entwicklung mechanischer Rechenautomaten

1.2.3 Elektronische Rechner Die Leistungsfähigkeit mechanischer Rechner ist durch die Trägheit bewegter Teile stark eingeschränkt. Der erste bekannte elektronische Universalrechner war der ENIAC („Electronical Numerical Integrator and Calculator“), gebaut 1943-1946 von John W. Mauchly und J. Presper Eckert. Hier einige Kennwerte: • 17468 Röhren • 1500 Relais • 174 kW Leistung • 30 t Gewicht Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

32

KAPITEL 1. EINLEITUNG • 0,2 ms Additionszeit • 2,8 ms Multiplikationszeit

Die Programmierung des ENIAC erfolgte festverdrahtet über Schalttafeln (s. Abbildung 1.10). Ein Zitat von J. P. Eckert: „Das Konzept des elektronisch gespeicherten Programms ist aus Verzweiflung über das Einstellen der Schalter und das Stecken der Schaltleitungen bei der Umprogrammierung des ENIAC entstanden.“

Abbildung 1.10: ENIAC

1.2.4 Speicherprogrammierbare Rechner Die beiden ersten Rechner, bei denen das Programm und die Daten in einem gemeinsamen Speicher abgelegt werden, waren der EDVAC („Electronic Discrete Variable Computer“, 1945-1951) und der IAS-Rechner. Letzterer wurde 1946-1948 von A. W. Burks und H. H. Goldstine entwickelt und kann von seiner Struktur her als Prototyp für alle später entwickelten Universalrechner angesehen werden. In der Literatur wird dieses Konzept häufig als „Von-Neumann-Konzept“ bezeichnet. Der IAS-Rechner ist als 1-Adressmaschine konzipiert, arbeitet mit einer Wortlänge von 40 Bit und besitzt eine ALU, einen Befehlszähler, ein Befehlsregister und einen Speicher für ca. 4000 Wörter.

1.2.5 Prozessor-Entwicklung Im Jahr 1969 gab die Firma Datapoint bei Intel eine Bildschirmsteuerung in Auftrag. Entstanden ist dabei 1971 der Mikroprozessor Intel 4004 (s. Abbildung 1.11), der Vorgänger der heutigen Pentium-Prozessoren. Kurioserweise wurde der Chip von Datapoint für ungeeignet gehalten und nicht übernommen. Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.2. AUS DER GESCHICHTE

33

Abbildung 1.11: Intel 4004 Der 1972 entwickelte Nachfolger, der Intel 8008, besaß einen 8-Bit-Daten- und einen 14-Bit-Adressbus. Er beherrschte Befehle zur Addition und Subtraktion sowie Logikbefehle. Zu der Zeit verfolgte man allgemein das Ziel, universelle Prozessoren zu bauen, die für alle Arten von Steuerungsaufgaben eingesetzt werden konnten. Die eigentliche Funktionsbeschreibung sollte nicht durch den Entwurf von Hard- sondern von Software geschehen („Opcodes statt Gatter“). Davon versprach man sich (wegen hoher Stückzahlen) geringere Hardware-Entwicklungskosten und eine vereinfachte Lagerung und Wartung. Dabei unterschätzte man jedoch das Problem der Software-Entwicklung. Als Faustregel gilt, dass ein 1-kByte-Programm etwa 500-1000 Gatter ersetzt (8-16 Bit pro Gatter). Ab 1974 wurden von verschiedenen Herstellern 8-Bit-Prozessoren mit 64 kByte Adressraum entwickelt: Intel 8080, Motorola 6800, Intel 8085, Zilog Z80. Um 1980 folgten 16-Bit-Prozessoren wie der Intel 8086 oder MC 68000. Abb. 1.12 zeigt den schematischen Aufbau eines heute typischen PC-Systems.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

34

KAPITEL 1. EINLEITUNG

Typisches PC−System Microprocessor

Hard disk

Video monitor

Keyboard

Video control

Keyboard control

Communica− tion network

CPU Main Memory M

Cache

Hard disk control

Network control

I/O expansion slots

Bus interface unit

I/O local bus

Peripheral (I/O) interface control unit

System bus

Abbildung 1.12: Typisches PC-System Heutige Prozessoren arbeiten mit einer Daten- und Adressbreite von 32 oder 64 Bit. Die Forschungs- und Entwicklungsschwerpunkte liegen bei innovativen Strukturen (z.B.: Superskalar-Rechner, Multiprozessoren, schnelle Computerarithmetik).

1.2.6 Rechnergenerationen Tabelle 1.2 zeigt eine Einteilung der elektronischen Rechner in Rechnergenerationen.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

Generation

Technologien

Hardwaremerkmale

35 Softwaremerkmale

Produkt

Maschinensprache kommerzielle elektronische Rechner

1) 1946 - 1959 Vakuumröhren

Festkommaarithmetik

2) 1960 - 1968 Diskrete Transistoren Ferritkerne Magnetplatten

Fließkommaarithmetik Hochsprachen ProgrammbiblioIndexregister theken E / A - Prozessoren Stapelmonitore

billigere Computer

3) 1969 - 1977 Integrierte Schaltungen Mikroprogrammierung Multiprograming, Minicomputer (SSI und MSI) -processing, Pipelining Betriebssysteme Cache -Speicher virtueller Speicher 4) 1978 - 199? LSI, VLSI Halbleiterspeicher

5) 199?

Parallelrechner

Mikroprozessor Mikrocomputer

Problemorientierte PCs Workstations Sprachen

massive Parallelität

Parallele Sprachen Multiprozessoren

Beispiel

IAS, UNIVAC I IBM 701

Burroughs 6500 CDCI 604, 6600 IBM 7094

IBM / 360 DEC PDP -8, 11

Sun, PCs

Tabelle 1.2: Rechnergenerationen

1.3 Technologische Grundlagen 1.3.1 Leistungsentwicklung Wie in Abbildung 1.13 zu sehen ist, wuchs die Leistung moderner Rechner mit der Zeit exponentiell, und dieser Trend wird sich voraussichtlich weiter fortsetzen. Die Triebkräfte für diese Leistungssteigerung sind: • Technologieentwicklung. Die immer höher werdende Integrationsdichte und die Entwicklung neuer Technologien (aktuell: High-Performance CMOS) ermöglichen die Implementierung neuer Architekturkonzepte. • Innovative Architekturkonzepte. Einen noch größeren Einfluss auf die Leistungsentwicklung hat die Umsetzung neuer Architekturkonzepte (z. B.: RISC, Parallelismus). • Standardisierte Softwareschnittstelle. Es ist wichtig, dass die Architekturentwicklung nicht durch die Existenz von Software gebremst wird, die nur auf veralteten Prozessoren lauffähig ist. Standardisierte Betriebssysteme und Programmiersprachen (z. B.: Unix, C) schaffen einen größeren Freiraum. • Aus der Geschichte: Während der 70-er Jahre dominierten Mainframes und Minicomputer die Industrie. Ihre Rechenleistung nahm jährlich um ca. 25 % bis 30 Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

36

KAPITEL 1. EINLEITUNG % zu. Ende der 70-er stieg diese Steigerungsrate auf ca. 35 % jährlich; was insbesondere auf das Aufkommen des Mikroprozessors zurück zu führen ist. Mit diesem konnte man technologische Verbesserungen bei den integrierten Halbleiterschaltungen schneller umsetzen als mit Mainframes oder Mikrocomputern (diese Verbesserungen führten insbesondere zu einer Steigerung der Taktfrequenz). Die Abkehr von der Assemblerprogrammierung (im hohen Maße architekturabhängig) und die Schaffung von standardisierten Betriebssystemen (wie UNIX) führten zu dann auch zu einer Senkung von Kosten und Risiken bei der Einführung neuer Architekturen. Die in den frühen 80-iger Jahren aufkommenden RISC basierten Architekturen erhöhten die Steigerungsrate auf über 50 % jährlich. Gründe hierfür sind die weitere Steigerung der Takfrequenz (weiterhin ca. 35%) und Verbesserungen in der Prozessorarchitektur, wie das Pipelining. • Abbildung 1.13 zeigt die Auswirkungen dieser unterschiedlichen Steigerungsraten. Der untere Graf zeigt die mögliche Leistungssteigerung, wenn es bei 35 % geblieben wäre, was der technologiebedingten Steigerung entspricht. Der obere Graf verdeutlicht die tatsächliche Entwicklung, die neben der technologiebedingten Steigerung auch die Steigerung durch Verbesserungen der Architektur enthält. 350

DEC Alpha

300

1,58x pro Jahr 250

SPECint 200 Bewertung

DEC Alpha

150 100 50

IBM Power2 DEC Alpha 1,35x HP IBM 9000 MIPS Power1 MIPS R3000 SUN4 R2000

pro Jahr

0 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995

Jahr

Abbildung 1.13: Leistungsentwicklung

1.3.2 Technologietrends Bei hochintegrierten Schaltungen können die folgenden Trends beobachtet werden: Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

37

• Die Transistordichte vervierfacht sich alle drei Jahre. • Die Chipfläche wächst um 10% -25% jedes Jahr. • Die Transistorzahl pro Chip wächst damit um 60% - 80% jedes Jahr. • Durch die Verkleinerung der einzelnen Transistoren wächst deren Schaltgeschwindigkeit. Die Vergrößerung der Chipfläche zieht längere Leitungen nach sich. So kommt es, dass die Betriebsfrequenz zunehmend von den Leitungslaufzeiten und weniger von den Transistorschaltzeiten bestimmt wird. Abbildung 1.14 zeigt Wafer mit modernen Prozessoren. Wafer mit Pentium-Prozessoren

480.7 mm2 pro Chip 63 Chips

Wafer mit PowerPC 601 Prozessoren

122.7 mm2 pro Chip 200 Chips

Abbildung 1.14: Waferherstellung Bei Halbleiterspeichern vervierfacht sich die Dichte etwa alle drei Jahre, die Zykluszeit konnte in den letzten 10 Jahren jedoch nur um etwa 30% verringert werden. Die Tatsache, dass die Geschwindigkeit von Prozessoren deutlich schneller wächst, führt zu der Entwicklung von immer aufwendigeren und leistungsfähigeren Caches. Bei Magnetspeichern beobachtet man seit 1990 etwa eine Vervierfachung der Speicherdichte alle drei Jahre (zuvor: Verdopplung alle drei Jahre). Die Zugriffszeit wurde innerhalb von 10 Jahren um 30% reduziert.

1.3.3 Kosten Abbildung 1.15 zeigt die Kostenentwicklung dynamischer Speicher. Die Preise werden anfangs durch die Entwicklungskosten bestimmt, später konvergieren sie gegen die reinen Materialkosten. Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

38

KAPITEL 1. EINLEITUNG 80 16 Mb 70 60

Dollar pro 50 DRAMChip 40

256 Kb

4 Mb

1 Mb

endgültige Chipkosten

30 64 Kb 20 10 16 Kb

Jahr

 











 



 

 



 



 

 



  

 

 







  



 







 













 



Abbildung 1.15: Kostenentwicklung bei dynamischen Speichern In Tabelle 1.3 ist dargestellt, wie sich die Kosten eines Computers auf die Systemkomponenten verteilen. Den größten Bestandteil bilden dabei die verwendeten hochintegrierten Schaltungen. Die Kosten eines ICs ergeben sich wie folgt: IC-Kosten =

Kosten des Chipplatzes + Kosten des Chiptests + Kosten des Gehäuses Ausbeute

Daraus folgt u. a., dass die Chipkosten nicht linear mit der Chipfläche, sondern viel stärker steigen. Je größer ein Chip ist, umso aufwendiger wird nämlich der Test, und umso geringer wird die Ausbeute.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

Teilsystem Gehäuse

39

Komponenten Metall, Plastik Netzteil, Lüfter Kabel, Schrauben, ...

Hauptplatine

I/O

Kostenbestandteil 1% 2% 1% 4% Prozessor 6% DRAM 36 % Video-System, Graphik 14 % I/O-System 3% Platine 1% 60 % Tastatur und Maus 1% Bildschirm 22 % Platte 7% Laufwerk 6% 36 %

Tabelle 1.3: Systemkosten Die ständig sinkenden Strukturgrößen (s. Abbildung1.16) führen dazu, dass die Produktionsanlagen für die jeweils neueste Technologie immer aufwendiger und teurer werden (s. Abbildung1.17). 10 

8086 8080



 

4004

i386 80286

1

Pentiums i486



 

Pentium Pro





0,1





1 0,01 1971

1976

1981

1986 Jahr

1991

1996

2001

2006

Abbildung 1.16: Strukturgröße bei verschiedenen Mikroprozessorgenerationen

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

40



#

 $ 

  " !         

+ + * ) ) ( %   # # '

KAPITEL 1. EINLEITUNG 10.000 1.000 100

    ! ## !&  %!

10 1 1 1966

1974

1982

Jahr

1990

1998

2006

Abbildung 1.17: Kostenentwicklung von Produktionsanlagen für die jeweils neueste Technologie

1.3.4 Realisierungsalternativen Für integrierte Schaltungen gibt es unterschiedliche Herstellungsvarianten sowie Anwendungsgebiete: 1. Standardschaltungen 2. Beispiele: Speicher, logische Grundschaltungen Merkmale: • große Stückzahlen • große Einsatzbreite 3. Anwenderprogrammierbare Schaltungen Beispiele: Prozessoren, Microcontroller, FPGA Merkmale: • große Stückzahlen • große Einsatzbreite 4. Anwendungsspezifische Schaltungen Merkmale: • kleine bis mittlere Stückzahlen • geringe Einsatzbreite • spezielle Leistungsanforderungen realisierbar

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

41

In den Fällen 1) und 2) ist wegen der großen Stückzahlen ein großer Entwurfsaufwand wirtschaftlich vertretbar, bei 3) würde er zu sehr hohen Kosten pro Chip führen. Entsprechend gibt es verschiedene Entwurfsstile, die durch mehr oder weniger hohen Entwicklungsaufwand charakterisiert sind und zu mehr oder weniger leistungsfähigen Chips führen (s. auch Abbildung1.18): 1. vollkundenspezifischer Entwurf (FCD - Full Custom Design) 2. Zellentwürfe: Makrozellen, Standardzellen (SZ) 3. Entwurf mit Feldern: Gate Array (GA), Sea Of Gates, Programmierbare Felder (PLA - Programmable Logic Array) 4. Programmierbare Entwürfe (Programmable Logic Devices): • PROM (Programmable Read Only Memory) • EPROM (Erasable Programmable ROM) • EEPROM (Electronically Erasable PROM) • FPGA (Field Programmable Gate Array) • FPLA (Field Programmable Logic Array) • LCA (Logic Cell Array) Von 1) nach 4) sinkt dabei sowohl der Entwurfsaufwand als auch die Leistungsfähigkeit der Schaltungen.

Realisierungsalternativen

ASIC-Implementierung

programmierbare Bausteine

zweistufige Logik

mehrstufige Logik

...

...

PLA ROM

Gate Matrix

Zellenlogik

zweistufige Logik (PLD)

mehrstufige Logik (PGA)

... ROM PAL FPLA Altera

... Xilinx Actel LCA

Abbildung 1.18: Realisierungsalternativen Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

42

KAPITEL 1. EINLEITUNG

Vollkundenspezifischer Entwurf Beim vollkundenspezifischen Entwurf wird das Layout der Prozessmasken manuell erstellt. Das hat die folgenden Konsequenzen: • Keine Beschränkung der Entwurfsfreiheit • Variable Dimensionierung der Schaltelemente • Große Freiheitsgrade zur Optimierung der Fläche, der Laufzeit oder der Verlustleistung • Komplexe Entwurfsregeln • Großes Expertenwissen nötig Die verwendeten Entwurfswerkzeuge sollten die folgenden Anforderungen erfüllen: • Automatische Partitionierung des Entwurfs auf höherer Ebene (Handentwurf ist nur für kleinere Einheiten möglich). • Ausnutzen von Regularität • Automatische Zellgenerierung • Layoutoptimierung Die erforderlichen langen Entwurfszeiten führen zu hohen Entwicklungskosten. Typische Anwendungen für den vollkundenspezifischen Entwurf sind daher: • Chips mit sehr hohen Stückzahlen • Chips mit besonderen Leistungsanforderungen • Speicherchips • Zellbibliotheken Abbildung1.19 zeigt ein Beispiel für einen solchen Entwurf.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

43

Abbildung 1.19: Gate-Array-Treiberzelle, vollkundenspezifisch entworfen Entwurf mit Zellen Der Zellentwurf basiert auf einer vordefinierten Bibliothek mit Standardzellen. Die Geometrie dieser Zellen ist standardisiert, so dass sie in Zeilen angeordnet werden können (gleiche Höhe, ähnliche Größe, Versorgungsleitungen längs der Zeilen, Ein/Ausgänge an Ober-/Unterkante, Verdrahtung zwischen den Zeilen). Da eine Zellbibliothek für viele Entwürfe verwendet werden kann, lohnt es sich, größeren Aufwand beim (vollkundenspezifischen) Entwurf der einzelnen Zellen zu treiben und sie sehr gut zu optimieren. Tabelle 1.4 zeigt eine Liste typischer Bibliothekselemente. Die Schaltung und das Layout einer Zelle sind in Abbildung1.20 dargestellt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

44

KAPITEL 1. EINLEITUNG

Name

Funktion

GIN1 GIN8 GB12 GNAND2 GNAND4 GNOR4 GOR3 GF06 GF52 GXOR1 GTLRP GT00 GTRRP

Inverter Array-Treiber Buffer NAND mit 2 Eingängen NAND mit 4 Eingängen NOR mit 4 Eingängen OR mit 3 Eingängen F = A1 + A2 + B1 * B2 F = A1 * (B1 + B2 + B3) Exklusiv/Oder D-Latch Master-Slave-Flipflop Master-Slave-Flipflop

Äquivalente Gatterzahl 1/2 4 2 1 2 2 2 2 2 2 3 4 6

Tabelle 1.4: Elemente einer Bibliothek A1 A2

F F = A1 · A2

UDD

°

P

°

A1 A2

P

F N N

USS Abbildung 1.20: Beispiel einer Standard-Zelle (GNAND2) Entwurfswerkzeuge gibt es für die folgenden Aufgaben: • Schaltungssynthese – Logiksynthese Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

45

– Platzierung – Verdrahtung • Bibliothekspflege – automatische Technologieanpassung – automatische Zellgenerierung Der Zellentwurf bietet einen Kompromiss zwischen Entwurfsaufwand und effizientem Layout. Oft enthalten Zellentwürfe neben Standardzellen auch Makrozellen, die z.B. ein PLA, ein RAM oder ein ROM realisieren. Entwurf mit Gate-Arrays Beim Gate-Array-Entwurf wird eine Matrix von Transistoren auf dem Chip vorgefertigt (s. Abbildung1.21), entwurfsspezifisch ist lediglich die Verdrahtung. Solche Master können in großen Stückzahlen sehr kostengünstig gefertigt werden. Die Schaltung besteht aus einem Kernbereich und einem Peripheriebereich. Die Verdrahtung von Transistoren zu Zellen erfolgt mittels Bibliotheken.

Abbildung 1.21: Gate-Array Die Entwurfswerkzeuge unterstützen: • Logiksynthese, Technology-Mapping • Platzierung, Verdrahtung

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

46

KAPITEL 1. EINLEITUNG

Durch die starke Entwurfsvereinfachung eignen sich Gate-Arrays für ASICs (Application Specific Integrated Circuits) kleinen und mittleren Stückzahlen. Der Hauptnachteil sind die geringen Freiheitsgrade zur Layout- und Leistungsoptimierung. Eine Variante des Gate-Array-Entwurfs ist der „Sea-of-Gates“ (SoG)- Entwurf (s. Abbildung1.22). Es gibt keine speziellen Verdrahtungskanäle, stattdessen wird der Platz über nichtbenutzten Transistoren als Verdrahtungsraum genutzt. Aus Platzgründen wird in mehreren Metallebenen verdrahtet (-> erfordert mehr Prozessschritte als Gate-Array-Design). Da es mehr Freiheitsgrade bei der Platzierung und Verdrahtung gibt, ist eine bessere Flächenausnutzung möglich. Allerdings sind für die flexiblere Struktur auch aufwendigere Entwurfswerkzeuge nötig.

Abbildung 1.22: Sea-of-Gates Programmierbares logisches Array (PLA) Mit PLAs können Schaltnetze, die als eine boolesche Funktion durch eine Summe von Produkttermen dargestellt sind, durch eine reguläre Struktur realisiert werden. Abbildung1.23 zeigt die Struktur eines PLA. In dem Dekodierfeld werden zu jeder Eingangsvariablen ein negiertes und ein nicht-negiertes Signal erzeugt. Bei dem UNDund dem ODER-Feld handelt es sich in Wirklichkeit um eine NOR-NOR-Struktur (siehe Abbildung1.24).

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

e1

l1

0 4

. . .

3 1 0

2 -

./ -

en

47

l1 .. . ln

UND-Feld

,

ln

. . . .. .

ODER-Feld

F1 Fm

Abbildung 1.23: Programmierbares logisches Array

Standardform eines PLA F1 = p1_∨ p2, F2 = p2 ∨ p3_, p1 = e1e2, p2 = e1e3, p3 = e3e4

NOR-NOR-Form 1

p1 p2 p3 e1 e2 e3 e4

e1

11

e2

11

e3

11

e4

11

1 1 1 1 1

F1 F2

1 1

F1 F2

Abbildung 1.24: Implementierung eines PLA Entwurfswerkzeuge für PLAs müssen eine gegebene Funktion in eine disjunktive Form bringen und evtl. minimieren und anschließend eine 0-1-Matrix für die UNDund ODER-Felder erstellen. PLAs ermöglichen einen einfachen, schnellen und billigen (günstige Vorfertigung) Entwurf, große Schaltungen werden dabei aber nicht flächen- und zeitoptimal. Reine PLA-Entwürfe findet man selten, häufiger werden PLA-Generatoren verwendet, um Makrozellen für einen Zellentwurf zu erzeugen.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

48

KAPITEL 1. EINLEITUNG

Anwenderprogrammierbare Schaltungen -FPGAs Eine komplexere Struktur als PLAs besitzen FPGAs („Field Programable Gate Arrays“). Damit können auch sequentielle Schaltungen sowie Funktionen, die sich nur schlecht zweistufig als Summe von Produkttermen darstellen lassen, realisiert werden. FPGAs besitzen einen Kernbereich und einen Peripheriebereich. Im Kernbereich sind logische Zellen und Verdrahtungskanäle angeordnet, die Peripherie beherbergt Ein/Ausgabeelemente (s. Abbildung1.25).

Logik-Block L

C

L

C

S

C

L

C

L

. . .

I/O-Zelle

. . .

...

... .

.

.

L

C

L

C

S

C

L

C

L

. . .

. . .

... L

C

L

L

C

L

C

S

C

C

S

C

L

C

L

L

C

L

Leitungssegmente ...

Abbildung 1.25: Struktur eines FPGAs Sowohl die Funktion der logischen Zellen (CLB, „configurable logic block“), als auch die Verbindungen in den Verdrahtungskanälen können vom Anwender programmiert werden. Die Programmierung geschieht entweder über SRAM-Elemente (s. Abbildung1.26) oder Antifuse-Elemente. Im ersten Fall muss der FPGA-Chip zusammen mit einem Speicher (z.B. ROM oder EPROM) betrieben werden. Eine Zusatzlogik auf dem FPGA sorgt dafür, dass beim „Power-Up“ zunächst die Programmierung aus dem Speicher gelesen wird. Der Vorteil dabei ist, dass das FPGA für andere Anwendungen wiederverwendet werden kann. Die Programmierung mit Antifuse-Elementen kann man mit der Programmierung eines PROMs vergleichen. Durch eine stark erhöhte Spannung werden gezielt einzelne Verbindungen „gebrannt“. Dieser Vorgang kann nur einmal durchgeführt werden, dafür entfällt der Ladevorgang beim Einschalten, und es ist kein externer Speicher notwendig. Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

SRAM

SRAM

49

SRAM

SRAM

SRAM

SRAM

SRAM

SRAM

SRAM

Abbildung 1.26: Verbindungsmatrix zwischen Verbindungsleitungen Der Aufbau der Logikblöcke und die Anordnung der CLBs und der Verdrahtungskanäle hängt stark von dem FPGA-Typ und -Hersteller ab. Abbildung 1.26 und Abbildung 1.27 beziehen sich auf den Baustein XC3000 der Firma Xilinx, Abbildung1.28 zeigt den Aufbau von FPGAs der Firma Actel. Wie in Abbildung1.27 zu sehen ist, enthält ein CLB des Xilinx-XC3000 einen kombinatorischen Block mit 5 Eingängen A, ..., E und zwei Ausgängen F und G. Die Funktion des Blockes wird durch ein 32-Bit-SRAM ausgewählt. Die Programmierung ermöglicht entweder die Realisierung einer 5-stelligen Funktion H = h(A, B, C, D, E) oder zweier 4-stelligen Funktionen F = f (A, B, C, D) und G = g(B, C, D, E). Die beiden Flipflops erlauben die Programmierung von sequentiellen Funktionen. Die Select-Leitungen der Multiplexer in Abbildung1.27 werden ebenfalls von SRAM-Zellen angesteuert.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

50

KAPITEL 1. EINLEITUNG ENABLE RESET CLOCK

DATA IN

A B C D E

R QX M1 C2/1 1,2 D

MUX kombina- F torischer G Block MUX

MUX

X

MUX

Y

1,2 D C2/1 QY M1 R

Abbildung 1.27: XC3000 Configurable Logic Block (CLB)

I/O and Peripheral Circuits

7

Logic Modules

A0

Routing Control

A1

Logic Modules

SA

Routing Control

6 5

OUT

7 6 5

Routing Control

B0 B1

Logic Modules

SB Routing Control Logic Modules I/O and Peripheral Circuits

Actel ACT FPGA

S0 S1

Das Actel-Logik-Modul

Abbildung 1.28: FPGAs der Actel-Familie Die Abbildung einer entworfenen Schaltung auf Logikmodulen geschieht in der Regel automatisch durch Entwurfswerkzeuge, die von den FPGA-Herstellern zur Verfügung gestelltwerden. Mit FPGAs sind (im Gegensatz zu PLAs) relativ komplexe Funktionen realisierbar. Dadurch, dass die Abbildung der entworfenen Schaltung auf die FPGA-Struktur automatisch und für den Entwerfer weitgehend transparent geschieht, sind die Entwurfsfreiheiten stärker begrenzt als z.B. beim Standardzell- oder Vollkundenentwurf. FPGAs eignen sich besonders für das Prototyping und für die Fertigung in kleinen Stückzahlen.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

51

Kriterien zur Auswahl der Entwurfsstile Bei der Auswahl eines passenden Entwurfsstiles spielen die folgenden Aspekte eine Rolle: • Die Kosten pro Chip. Die Entwurfsstile unterscheiden sich in den Kosten pro Chip, die sich aus den Entwurfskosten und den Herstellungskosten (Maskenherstellung, Prozesskosten, Testkosten) zusammensetzen. • Die Komplexität der zu entwerfenden Schaltung. • Die Entwicklungszeit. In der heutigen Zeit ist es wichtig, dass neue Produkte so schnell wie möglich zur Marktreife gebracht werden. • (Spezifizierte) Anforderungen hinsichtlich Geschwindigkeit oder Energieverbrauch an die zu entwerfende Schaltung (z.B. bei mobilen Geräten). Abbildung1.29 zeigt für verschiedene Entwurfsstile, wie die Kosten pro Chip von der produzierten Stückzahl abhängen. K o s te n /C h ip

G a te -A rra y s S tan d a rd z ellen V o llk u n d en G a teA rra y s

S ta n d ard z ellen

V o llK u n d en

S tü ck z a h l

Abbildung 1.29: Kosten pro Chip für verschiedene Entwurfsstile Man sieht, dass beim Vollkundenentwurf die Chipkosten bei kleinen Stückzahlen wegen des hohen Entwicklungsaufwands größer als beim Standardzell- oder Gate-ArrayEntwurf sind. Bei sehr großen Stückzahlen wirkt sich die Tatsache aus, dass Vollkundenentwürfe am besten optimiert werden können, so dass dann die Chipkosten minimal sind. Tabelle 1.5 zeigt typische Anwendungsbereiche für die einzelnen Entwurfsstile.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

52

KAPITEL 1. EINLEITUNG Entwurfsstil Vollkundenspezifisch Makrozellen Standardzellen Sea-of-Gates Gate-Arrays PLAs Programmierbar

genuetzte Layoutdichte hoch

Entwurfsaufwand hoch

gering

gering

Prozessschritte Voll Voll Voll 4-5 2-4 0-Voll 0

Stueckzahlen 103 104 104 103 103 103

Typische Anwendungen Speicher Mikroprozessor ASIC ASIC ASIC Steuerung ASIC

Tabelle 1.5: Anwendungsbereiche der verschiedenen Entwurfsstile Bei sehr komplexen ICs wie z.B. Mikroprozessoren kommen verschiedene Entwurfsstile gemischt zur Anwendung. Abbildung1.30 und Abbildung1.31 zeigen das Layout der Motorola-Prozessoren 604e und 68HC912.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.3. TECHNOLOGISCHE GRUNDLAGEN

53

Abbildung 1.30: Motorola PowerPC 604e

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

54

KAPITEL 1. EINLEITUNG

Abbildung 1.31: Motorola 68HC912

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.4. GRUNDSTRUKTUREN

55

1.4 Grundstrukturen 1.4.1 Grundkonzepte Moderne Rechner sind durch die folgenden Eigenschaften gekennzeichnet: • Der Rechner ist zentral gesteuert und besteht aus den folgenden Komponenten: – Zentraleinheit, bestehend aus Steuerwerk und Operationswerk – Eingabe-/Ausgabesystem als Schnittstelle nach außen – Speicher zur Ablage von Daten und Programmen • Der Speicher besteht aus Plätzen fester Wortlänge, die über Adressen jeweils einzeln angesprochen werden können. • Befehle und Daten werden gleichermaßen als Binärzahlen dargestellt. • Programme und Daten können an derselben Stelle gespeichert werden. • Programme können verarbeitet werden und sich selbst modifizieren. Das Eingeben von Befehlen als Binärzahlen ist sehr mühsam und stattdessen verwendet man Assembler, die Befehle in einer für den Menschen lesbaren Form in die entsprechenden Maschinenbefehle übersetzen. Eine noch komfortablere Programmierung erlauben Compiler, die Programme in einer Hochsprache wie C oder Pascal in ein äquivalentes Assembler-Programm übersetzen. Der Ablauf ist in Abbildung 1.32 dargestellt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

56

KAPITEL 1. EINLEITUNG

Hochsprache C

swap(int v[ ], int k); {int temp; temp = v[k]; v[k] = v[k+1]; v[k+1] = temp; }

C Compiler

Assembler für MIPS

swap: multi $5,4 add lw lw sw 0($2) sw 4($2) jr

$2, $2, $4,$2 $15, 0($2) $16, 4($2) $16, $15, $31

Assembler

Maschinensprache für MIPS

000000001010000100000000000110 00 000000001000111000011000001000 01 100011000110001000000000000000 00 100011001111001000000000000001 00 101011001111001000000000000000 00 101011000110001000000000000001 00 000000111110000000000000000010 00

Abbildung 1.32: Compiler und Assembler Der Befehlssatz und somit die Assemblersprache sind stark maschinenabhängig. Hochsprachen versucht man dagegen so zu entwerfen, dass sie maschinenunabhängig sind (was in der Praxis nie vollständig gelingt). So kann man erreichen, dass bei der Einführung eines neuen, besseren Prozessors mit einem neuen Befehlssatz nur ein Compiler geschrieben werden muss. Bestehende Anwendungssoftware kann weiterverwendet werden, nachdem sie mit dem neuen Compiler übersetzt wurde.

1.4.2 Befehlszyklus Um ein Programm abzuarbeiten, muss ein Prozessor viele verschiedene Aufgaben erledigen. Die Befehle müssen in der richtigen Reihenfolge aus dem Speicher eingelesen und interpretiert werden. Je nach Befehlstyp (Sprungbefehl, arithmetisch-logischer Befehl, Speicherzugriff) können sehr verschiedene Aktionen zur Ausführung notwendig sein. Der immer wiederkehrende Vorgang, bei dem ein Prozessor einen Befehl einliest und ausführt, wird Befehlszyklus genannt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.4. GRUNDSTRUKTUREN

57

Der Befehlszyklus moderner Prozessoren lässt sich in eine Interpretationsphase und eine Ausführungsphase unterteilen (-> 2-Phasen-Konzept). Diese Phasen zerfallen dann weiter in einzelne Schritte. 1. Interpretationsphase: Befehlszähler zeigt die Adresse einer Speicherzelle an, deren Inhalt geholt und als Befehl interpretiert wird. (a) Transport des Befehls vom Hauptspeicher in das Befehlsregister. Erhöhen des Befehlszählers 2. Ausführungsphase: Der Inhalt weiterer Speicherzellen, deren Adressen im Befehl spezifiziert sind, wird geholt und verarbeitet. (a) Transport der Operanden vom Hauptspeicher oder dem Register in das Operationswerk (b) Ausführen der Operation (c) Transport des Resultats vom Operationswerk in den Hauptspeicher oder den Registerspeicher. Weiter bei Schritt 1. In den folgenden Abschnitten sollen grundlegende Rechnerkonzepte vorgestellt werden.

1.4.3 Stack-basierte Rechner Die Struktur eines Stack-Rechners ist in Abbildung1.33 dargestellt. Er unterstützt im wesentlichen die folgenden Befehle: PUSH Speicher POP OP

Speicher

Der Inhalt der Adresse Speicher wird auf den Stack gelegt. Das oberste Wort wird vom Stack entfernt und an die Adresse Speicher geschrieben. n Operanden werden vom Stack entfernt, entsprechend der Operation Op verknüpft, und das Ergebnis wird auf den Stack zurückgelegt.

Die arithmetisch-logischen Befehle („Op“) besitzen keine expliziten Operanden (0AddressBefehle), denn die Operanden werden stets aus dem Stack gelesen bzw. auf den Stack zurückgeschrieben. Das folgenden Beispielprogramm liest die Speicherstellen A und B, bildet die Summe und speichert das Ergebnis an der Speicherstelle C ab:

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

58

KAPITEL 1. EINLEITUNG PUSH PUSH ADD POP

A B C

Den Pascal-Code for i := 1 to 10 do a[i] := b[i] + c[i]; könnte man wie folgt übersetzen: PUSH loop: POP PUSH

#1 X X

; X: Indexregister

; a[i] := b[i] + c[i] ...

PUSH PUSH ADD POP

b (X) c (X)

PUSH ADD

#1

; i := i + 1

POP PUSH PUSH

X X X

; oberstes Element verdoppeln ...

PUSH

#11

; Vergleich, ob i = 11

SUB JNEZ

loop

; oberstes Element (= Ergebnis vom Vergleich) entfernen und ggfs. springen

a (X)

Der Hauptvorteil der Stackmaschine ist, dass das Konzept einen einfachen Befehlssatz und eine einfache Hardware erlaubt. Der Nachteil ist, dass der Code für viele typische Aufgaben kompliziert und lang werden kann. Das macht die Maschine zum einen langsam und zum anderen ist es aufwendig, passende Compiler zu bauen. Früher wurden stack-basierte Universalrechner von der Firma Borroughs (B 5500) und HP (HP 3000/7) entwickelt, heute werden sie in Spezialanwendungen eingesetzt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.4. GRUNDSTRUKTUREN

59

Hauptspeicher

ALU

Stack Abbildung 1.33: Stack-basierter Rechner

1.4.4 Akkumulator-basierte Rechner Akkumulator-Rechner besitzen ein Universalregister, den Akkumulator, mit dem alle Rechenoperationen ausgeführt werden. Die Struktur ist in Abbildung 1.34 dargestellt, die typischen Befehle sind: LOAD

Speicher

STORE Speicher OP

Speicher

Der Inhalt der Adresse Speicher wird in den Akku geladen. Der Inhalt des Akku wird an die Adresse Speicher geschrieben. Inhalt der Adresse Speicher wird mit Akkumulator verknüpft und in Akku gespeichert.

Ein Programm zur Berechnung von C:= A + B, wobei A, B und C Speicherplätze sind, würde wie folgt aussehen: LOAD ADD STORE

A B C

Die arithmetisch-logischen Befehle besitzen exakt einen Operanden (1-Adress-Konzept). Um Zugriffe auf variable Speicheradressen zu ermöglichen (z.B. Array-Zugriffe), besitzen Akkumulator-Maschinen oft spezielle Index-Register. Diese können in der Regel nur geladen und gespeichert werden, es sind jedoch keine allgemeinen ALUOperationen möglich. Der Pascal-Code for i := 1 to 10 do a[i] := b[i] + c[i]; lässt sich wie folgt übersetzen: Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

60

KAPITEL 1. EINLEITUNG LDA STA loop: LDX LDA ADD STA LDA ADD STA

#1 i i b (X) c (X) a (X)

; X: Indexregister ; a[i] := b[i] + c[i] ...

i #1 i

; i := i + 1 ...

SUB #11 JNEZ loop

; Vergleich, ob i = 11 ; Sprung, falls nein

Die Befehle LDA und STA laden bzw. speichern hierbei den Akkumulator-Inhalt, der Befehl LDX lädt das Index-Register X. Die Symbole a, b, c und i stehen für Speicheradressen. Das 1-Adress-Konzept von Akkumulator-basierten Rechnern erlaubt im Vergleich zur Registermaschine (s.u.) eine kompakte Kodierung der Befehle und auch eine relativ einfache Hardware. Der Hauptnachteil sind die sehr häufigen Speicherzugriffe, was die Maschine langsam macht. d

ALU

Hauptspeicher Akkumulator Abbildung 1.34: Akkumulator-basierter Rechner

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.4. GRUNDSTRUKTUREN

61

1.4.5 Rechner mit allgemeinem Registersatz Register-Maschinen besitzen einen Satz mit mehreren (z.B. 8, 32, manchmal auch über 100) gleichberechtigten Registern. Mit jedem arithmetisch-logischen Befehl müssen zwei Quell- und ein Zielregister (oder -speicherstelle) spezifiziert werden. Man unterscheidet 2-Adress-Befehle, bei denen das Zielregister mit einem Quellregister identisch ist, und 3-Adress-Befehle, die flexibler sind, aber ein längeres Befehlswort zur Kodierung benötigen. Typische 2-Adress-Befehle sind: LOAD STORE ADD

R1, Spadr Spadr, R1 R1, Konst

: Inhalt der Adresse Spadr wird in das Register geladen. : Spadr ← R1 : R1 ← R1 + Konst

Ein Programm zur Berechnung von C:= A + B würde wie folgt aussehen: LOAD ADD STORE

R1,A R1,B C,R1

Ein typischer 3-Adress-Befehl ist: ADD R1, R3, Konst

:

R1 ← R3 + Konst

Den Pascal-Code for i := 1 to 10 do a[i] := b[i] + c[i]; könnte man wie folgt übersetzen: LOAD loop: LOAD LOAD ADD STORE ADD SUB JNEZ

R1, # 1

; R1 enthält i

R2, b (R1) R3, c (R1) R4, R2, R3 a(R1), R4

; a[i] := b[i] + c[i] ...

R1, R1, # 1 R2, R1, # 11 ; Vergleich,ob R1 = 11 R2, loop ; Sprung, falls nein

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

62

KAPITEL 1. EINLEITUNG

Die Struktur einer Maschine mit allgemeinem Registersatz ist in Abbildung 1.35 dargestellt. Diese Skizze ist detaillierter als Abbildung 1.33 und Abbildung 1.34, und an ihr soll der Befehlszyklus beispielhaft erläutert werden.

Zentraleinheit Steuerwerk µ PC

Adressenspeicher

+1

Mikroprogrammspeicher C

µ IR

Operationswerk

SR

cc

S

IR IR

A

DB1

DR1

AR

ALU PC

Registerspeicher

+1

DR2

DR

Hauptspeicher

DB2 D

Abbildung 1.35: Maschine mit allgemeinem Registersatz Die Zentraleinheit setzt sich aus einem Operationswerk, das alle Operationen ausführt, und einem Steuerwerk, das das Operationswerk steuert, zusammen. Die Komponenten des Operationswerks haben die folgenden Aufgaben: • Der Registerspeicher enthält die Register, auf die mit Maschinenbefehlen zugegriffen werden kann (R1, R2, ..., Rn). • Die ALU (= arithmetisch-logische Einheit) enthält Schaltnetze, um Additionen, Subtraktionen, Schiebeoperationen, logische Verknüpfungen etc. durchzuführen. • Die ALU erwartet ihre Operanden grundsätzlich in zwei internen Datenregistern DR1 und DR2.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.4. GRUNDSTRUKTUREN

63

• Der Befehlszähler PC enthält die Adresse des aktuellen bzw. nächsten auszuführenden Maschinenbefehls. • Das Adressregister AR speichert die Adresse für alle Arten von Speicherzugriffen. • Das Datenregister DR puffert bei allen Speicherzugriffen (egal ob Schreiben oder Lesen, ob Daten- oder Programmzugriff) das zu schreibenden oder das gelesene Datenwort. Das Operationswerk kommuniziert mit dem Hauptspeicher und mit Ein-/Ausgabegeräten (nicht in Abbildung 1.35 dargestellt) über den Adressbus A und den Datenbus D. Das Beispiel enthält ein mikroprogrammiertes Steuerwerk, das in dem Kapitel über Steuerwerke genauer beschrieben wird. Hier genügt es, zu wissen, dass für jeden Maschinenbefehl eine kurze Sequenz von Mikrobefehlen ausgeführt wird, wobei ein Mikrobefehl konkrete Steuerinformationen für alle Komponenten des Operationswerkes enthält. Die Komponenten des Steuerwerkes haben die folgenden Aufgaben: • Das Befehlsregister IR speichert den aktuell bearbeiteten Maschinenbefehl. • Das Statusregister SR speichert diverse "Flags", z.B. ob bei der letzten Addition ein Übertrag aufgetreten ist. Es wird z.B. bei bedingten Sprungbefehlen abgefragt. • Der Mikroprogrammspeicher enthält das Mikroprogramm. • Der Adressenspeicher enthält für jeden Maschinenbefehl die Einsprungadresse im Mikroprogrammspeicher. • Der Mikrobefehlszähler µPC und das Mikrobefehlsregister µIR enthalten analog zu PC und IR die Adresse des nächsten auszuführenden Mikrobefehls sowie den aktuellen Mikrobefehl. Zur Ausführung eines Befehls der Form „SUB R1, , R2“ laufen die folgenden Schritte ab:

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

64

KAPITEL 1. EINLEITUNG

1. 2. 3.

PC → DB1 → AR, PC+1 → PC

Das erste Befehlswort wird gelesen und in das Be-

AR → A → Speicher → 1.Befehlswort

fehlsregister übertragen.

→ D→ DR

schieht mit Hilfe der Register AR und DR.

Der Speicherzugriff ge-

DR → DB1 → IR 4.

Auswerten des Operationscodes und der Adressie-

Befehlsinterpretation

rungsarten

5.

PC → DB1 → AR, PC+1 → PC

6.

AR → A → Speicher → 2.Befehlswort

Lesen der Adressse des ersten Operanden aus dem Hauptspeicher

→ D → DR

7. 8.

DR→DB1→AR AR → A → Speicher→ Operand → D → DR

Lesen des ersten Operanden aus dem Hauptspeicher

9.

DR → DB1 → DR1,

isterspeicher nach DR2

nach DR1 und des zweiten Operanden aus dem Reg-

Registeroperand → DB2 → DR2

10.

DR2→DR1→ALU-Ausgang→DB1 → Registerspeicher,Statusinformation→SR, weiter

Ausführen der Subtraktion, Schreiben des Resultats

bei Schritt 1

in den Registerspeicher und Speichern der Statusinformation in SR (CC-Bits)

Tabelle 1.6: Ausführung eines Befehls

1.5 Zusammenfassung 1.5.1 Lernziele 1. Grundzüge der historischen Entwicklung 2. Grundlegende technologische Neuerungen und ihr Einfluss auf Rechnerarchitektur 3. Ebenen der Rechnerdarstellung 4. Äquivalenz und Unterschiede bei Implementierungen in Hard- und Software 5. Befehlszyklus und sog. „Von-Neumann“-Maschine 6. Grundstrukturen

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

1.5. ZUSAMMENFASSUNG

65

1.5.2 Kontrollfragen 1. Führen Sie eine geschichtliche Einteilung in Rechnergenerationen durch, grenzen Sie die einzelnen Generationen voneinander ab. 2. Was ist bestimmend in der historischen Abfolge - Technologie oder Rechnerkonzepte? Geben Sie Beispiele. 3. Nennen Sie am Beispiel eines Macintosh jeweils fünf Begriffe aus dem Bereich der Architektur, Struktur und Realisierung. 4. Wie würden Sie bei der Aufteilung eines Systems in Hardware und Software vorgehen? Gibt es algorithmische Konstrukte, die für eine HardwareImplementierung weniger geeignet sind? 5. Zeichnen Sie die Grundstruktur einer „Von-Neumann“-Maschine, und erläutern Sie daran den Befehlszyklus. 6. Übersetzen Sie untenstehendes Programmstück in den kürzestmöglichen Code für eine Stack-, Akkumulator- und Registermaschine: • A := B + C • A := E - B • F := A + C

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

66

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

KAPITEL 1. EINLEITUNG

Rev : 796

Kapitel 2 Informationsdarstellung Die Informationen, die von einem Rechner verarbeitet werden, lassen sich im wesentlichen in Daten und Befehle einteilen (Abb. 2.1)

Information

Daten

Nicht− numerische Daten

Befehle

Zahlen

Gleitkomma

Binär

Festkomma

Dezimal

Binär

Abbildung 2.1: Informationsdarstellung im Rechner 67

Dezimal

68

KAPITEL 2. INFORMATIONSDARSTELLUNG

2.1 Datentypen Ein Datentyp ist definiert durch einen Wertebereich und eine Menge von Operationen. Bei Zahlen ist der Wertebereich z.B. durch den Umfang (kleinste & größte darstellbare Zahl) und die Genauigkeit bestimmt. Die Operationen wären „Addition“, „Subtraktion“ etc.

2.1.1 Bits, Bytes & Codes Bei heutigen Rechnern werden alle Daten als Folge von Bits dargestellt. Mit einem einzelnen Bit lassen sich alle Datentypen darstellen, deren Wertebereiche zwei Elemente (z.B.: 0/1, wahr/falsch) enthalten. Für Datentypen mit größeren Wertebereichen werden mehrere Bits zu einem Wort zusammengefasst. Es gibt grundsätzlich Darstellungsformen mit einer festen und mit einer variablen Wortlänge. Für feste Formate haben sich die folgenden Bezeichnungen eingebürgert: Byte Halbwort Wort Doppelwort

8 Bit 16 Bit 32 Bit 64 Bit

In diesem Skript wird der Begriff „Wort“ nicht nur für 32-Bit Daten, sondern auch als Oberbegriff für ein Datum mit beliebiger Bitzahl verwendet. Was jeweils gemeint ist, geht aus dem Zusammenhang hervor. Bei Formaten mit variablen Wortlängen müssen bei einem Zugriff sowohl der Ort als auch die Länge des Datums spezifiziert werden. Sie sind deshalb aufwendiger zu handhaben. Boolesche Variablen Boolesche Variablen benötigen zur Speicherung ein Bit, somit können mehrere Variablen in einem Speicherwort untergebracht werden (z.B.: ein Byte → 8 boolesche Variablen). In der Praxis wird jedoch von dieser Möglichkeit oft kein Gebrauch gemacht und in einem Byte (oder Halbwort oder Wort, je nach Wortbreite des Rechners) nur eine boolesche Variable gespeichert. Das erhöht zwar den Speicherbedarf, jedoch sind Variablen dann einfacher adressierbar, so dass Programme schneller laufen. Als Operationen sind aussagenlogische Verknüpfungen B n → B (UND, ODER etc.) definiert.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.1. DATENTYPEN

69

Character, Zeichen Für die Darstellungen von Zeichen wurden die folgenden Standards eingeführt: • 7 Bit: ASCII (American Standard Code for Information Interchange), ISO, DIN 66003 • 8 Bit: EBCDIC Als Operation auf einzelnen Zeichen ist der Vergleich definiert. So ist z.B. ein alphabetisches Sortieren möglich. Tabelle 2.1 stellt den vollständigen ASCII-Code dar. Die Spaltenbeschriftung enthält die führenden 3 Bits, die folgenden 4 Bits sind der Zeilenbeschriftung zu entnehmen. Der ASCII-Code für das Zeichen „>“ ist z.B. 0111110. Nicht alle ASCII-Codes entsprechen realen Zeichen. Einige Codes dienen z.B. bei Druckern zur Steuerung des Druckkopfes. Diese Sonderzeichen sind in Tabelle 2.2 dargestellt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

70

KAPITEL 2. INFORMATIONSDARSTELLUNG

000

001

010

011

100

101

110

111

0000

NUL

DLE

SP

0

@

P



p

0001

SOH

DC1

!

1

A

Q

a

q

0010

STX

DC2

"

2

B

R

b

r

0011

ETX

DC3

#

3

C

S

c

s

0100

EOT

DC4

$

4

D

T

d

t

0101

ENQ

NAK

%

5

E

U

e

u

0110

ACK

SYN

&

6

F

V

f

v

0111

BEL

ETB



7

G

W

g

w

1000

BS

CAN

(

8

H

X

h

x

1001

HAT

EM

)

9

I

Y

i

y

1010

LD

SUB

*

:

J

Z

j

z

1011

VT

ESC

+

;

K

[

k

{

1100

FF

FS

,




N

ˆ

n

} ∼

1111

SI

US

/

?

O

_

o

DEL

Tabelle 2.1: ASCII-Code

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.1. DATENTYPEN

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 7F

NUL SUH STX ETX EOT ENQ ACK BEL BS HAT LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US SP DEL

Null Start of Heading Start of Text End of Text End of Transmission Enquiry Acknowledge Bell Backspace Horizontal Tabulation Line Feed Vertical Tabulation Form Feed Carriage Return Shift Out Shift In Data Link Escape Device Control 1 Device Control 2 Device Control 3 Device Control 4 Negative Acknowledge Synchronous Idle End of Transmission Block Cancel End of Medium Substitute Escape File Separator Group Separator Record Separator Unit Separator Space Delete

71

Füllzeichen Anfang des Kopfes Anfang des Textes Ende des Textes Ende der Übertragung Stationsaufforderung Positive Rückmeldung Klingel Rückwärtsschritt Horizontal-Tabulator Zeilenvorschub Vertikal-Tabulator Formalvorschub Wagenrücklauf Dauerumschaltung Rückschaltung Datenübertr. Umschaltung Gerätesteuerung 1 Gerätesteuerung 2 Gerätesteuerung 3 Gerätesteuerung 4 Negative Rückmeldung Synchronisierung Ende des Übertragungsblockes Ungültig Ende der Aufzeichnung Substitution Umschaltung Hauptgruppen-Trennung Gruppen-Trennung Untergruppen-Trennung Teilgruppen-Trennung Zwischenraum Löschen

Tabelle 2.2: Bedeutung der Sonderzeichen im ASCII-Code nach DIN 66003

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

72

KAPITEL 2. INFORMATIONSDARSTELLUNG

2.1.2 Fehlererkennung und -korrektur Fehlererkennende und -korrigierende Codes werden u.a. bei der Datenübertragung und bei Speichern verwendet und dienen dazu, Fehler, die bei der Übertragung (oder Speicherung) aufgetreten sind, zu erkennen bzw. zu korrigieren. Dazu erweitert der Sender die Datenwörter um zusätzliche, redundante Prüfbits. Als Fehler bezeichnet man in diesem Zusammenhang das „unerwünschte” Flippen (z.B. durch Signalstörungen etc. bedingt) eines oder mehrerer Bits (1 -> 0 oder 0 -> 1) im zu übertragenden Codewort, was zu einem neuen nicht mehr korrekten Codewort führt. Paritätsbit Ein n-Bit-Wort X = (x0 , x1 , ..., xn−1 ) wird ergänzt zu einem (n+1)-Bit-Wort X ∗ = (x0 , x1 , ..., xn−1 , c0 ). c0 ist das Paritätsbit und wird wie folgt gebildet: Gerade Parität: c0 := x0 ⊕ x1 ⊕ ... ⊕ xn−1 Ungerade Parität: ¬c0 := x0 ⊕ x1 ⊕ ... ⊕ xn−1 Das n-Bit-Wort X wird also jeweils so ergänzt, dass die Anzahl der ’1’-en im (n+1)Bit-Wort X ∗ gerade bzw. ungerade ist. Sämtliche korrekten Worte X ∗ des ergänzten Codes haben nun eine Hammingdistanz (Erklärung siehe unten) von mindestens zwei, wohingegen sie bei den verschiedenen Worten X des Ausgangscodes nur mindestens eins beträgt. Der Sender verschickt X ∗ . Beim Empfänger kommt die Information X ′ an. Aus der empfangenen Information berechnet der Empfänger seinerseits die Parität: c∗0 := x′0 ⊕ x′1 ⊕ ... ⊕ x′n−1 (gerade Parität). Wenn der berechnete Wert (c∗0 ) sich vom mitgesendeten (c′0 ) unterscheidet, so ist die Information fehlerhaft: c∗0 6= c′0 ⇒ Information fehlerhaft Es ist leicht zu beweisen, dass durch ein Paritätsbit jeder Einzelfehler erkannt wird. Abbildung 2.2 skizziert die Schaltungen, die zur Erzeugung und Überprüfung eines 8-Bit-Codes mit gerader Parität nötig sind.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.1. DATENTYPEN

73

redundante Codierung: 7-Bit-Code

Fehlererkennung:

8-Bit-Code mit gerader Parität

8-fach XOR 7-fach XOR

0: kein Bitfehler 1: Bitfehler

8-Bit-Code mit gerader Parität

Abbildung 2.2: Fehlererkennung mit Paritätsschaltung Zum Erkennen von Mehrfachfehlern sind mehrere Prüfbits erforderlich. Die Hamming-Distanz d(X, Y ) zweier Codewörter X und Y ist definiert als die Anzahl der Bits, in denen sich X und Y unterscheiden. Um n-fach-Fehler erkennen zu können, müssen die Prüfbits so berechnet werden, dass zwei korrekte Codewörter (inkl. Prüfbits) stets eine Hamming-Distanz von mindestens n + 1 besitzen (gilt nur im Falle einer reinen Fehlererkennung - keine Korrektur). Werden dann in einem korrekten Codewort bis zu n einzelne Bits verändert (von 0 nach 1 oder von 1 nach 0 geflippt - z.B. aufgrund von Störungen bei der Signalübertragung), entsteht garantiert kein anderes korrektes Codewort, und der Empfänger weiß, dass die Übertragung des Codeworts fehlerhaft war. Fehlerkorrektur Generell muss zur Korrektur von Fehlern (m-fach Fehler) jedes Datenwort X des Codes derart zu einem neuen Datenwort X ∗ erweitert werden, dass selbst nach dem Flippen von m ver. Bits im Datenwort X ∗ immer noch eine eindeutige Zuordnung zum korrekten Datenwort X ∗ möglich ist. Daraus folgt, dass die Hammingdistanz zwischen allen Datenwörten X ∗ mindestens 2*m + 1 betragen muss. Generell muss auch vorher entschieden werden, ob eine Fehlerkorrektur oder erkennung (siehe oben) realisiert werden soll. In diesem Fall werden z.B. (m+1)-fach oder (m+m)-fach Fehler nicht erkannt, sondern unter Umständen als m-fach oder 1-fach Fehler interpretiert und falsch korrigiert. Vergrößert man allerdings die Hammingdistanz auf 2*m + 2, so können neben der KorrekDate : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

74

KAPITEL 2. INFORMATIONSDARSTELLUNG

tur von m-fach Fehlern auch (m+1)-fach Fehler erkannt werden. Eine Hammingdistanz von (2*m + 3) ist allerdings bereits zur Korrektur von (m+1)-fach Fehlern geeignet. Unter sinnvoller Ausnutzung einer minimalen Hammingdistanz zur Korrektur von mfach Fehlern kann also maximal eine sinnvolle (die Codewörter nicht unnötig verlängernde) Erweiterung zur Erkennung von (m+1)-fach Fehlern realisiert werden. Beispiel für m = 1 siehe Abbildung 2.3. Möchte man Übertragungsfehler korrigieren können, so ist eine Fehlerlokalisierung notwendig. Ist bekannt, dass genau das Bit xi fehlerhaft ist, so kann dieses durch Invertieren korrigiert werden. Sei n die Zahl der Datenbits und c die Zahl der Prüfbits. Es stellt sich die Frage, wie groß c sein muss, damit eine Lokalisierung von Einzelfehlern möglich ist. Es gibt n+c mögliche Fehlerstellen (auch die Prüfbits können falsch übertragen werden) und den Fall, dass kein Fehler auftritt. Insgesamt müssen also anhand der Prüfbits n + c + 1 verschiedene Fälle unterscheidbar sein, was erfüllt ist, wenn 2c ≥ n + c + 1

(2.1)

gilt. Für n = 16 wären z.B. c ≥ 5 oder für n = 32 wären c ≥ 6 Prüfbits nötig. Man kann zeigen, dass es stets Codes mit einer minimalen Anzahl von Prüfbits gibt, die eine Einzelfehlerkorrektur ermöglichen. Das soll hier nicht bewiesen, aber anhand eines Beispieles veranschaulicht werden. Beispiel Bei n = 8 Datenbits sind nach (2.1) c ≥ 4 Korrekturbits nötig, d.h. übertragen wird ein Wort der Form X = (d0 , ..., d7 , c0 , ..., c3 ). Die Rechenvorschriften zur Bestimmung der c0 , ..., c3 müssen die folgenden Eigenschaften erfüllen: • Die Mengen von Prüfbits, die von einem bestimmten Datenbit abhängen, sind für alle Datenbits verschieden. Das ist notwendig, damit ein fehlerhaftes Datenbit eindeutig identifiziert werden kann. • Jedes Datenbit wird von mindestens zwei Prüfbits überwacht. Das ist notwendig, damit ein fehlerhaftes Prüfbit von einem fehlerhaften Datenbit unterschieden werden kann. Ein möglicher Code, der diese Eigenschaften erfüllt, ist der folgende: c0 = d 0 ⊕ d 1 ⊕ d 2 ⊕ d 3 ⊕ d 4 ⊕ d 5 ⊕ d 6 c1 = d 0 ⊕

d2 ⊕

d4 ⊕

d6 ⊕ d7

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.1. DATENTYPEN c2 =

d1 ⊕ d2

75 ⊕ d5 ⊕ d6 ⊕ d7

d3 ⊕ d4 ⊕ d5 ⊕ d6

c3 =

Das empfangene bzw. gelesene Wort sei X ′ = (d′0 , ..., d′7 , c′0 , ..., c′3 ). Aus den Datenbits errechnet der Empfänger einen neuen Satz von Prüfbits (c∗0 , ..., c∗3 ). Aus diesem und den empfangenen Prüfbits wird der sog. Fehlervektor E := (c′0 ⊕ c∗0 , ..., c′3 ⊕ c∗3 ) bestimmt. Es ist leicht zu sehen, dass im Falle E = (0, ..., 0) kein Fehler aufgetreten ist. Ist in E genau ein Bit gesetzt, so ist ein Korrekturbit fehlerhaft, bei zwei oder mehr gesetzten Bits wurde ein Datenbit falsch übertragen. Es gilt zum Beispiel: E = (0, 1, 0, 0) ⇔ c1 ’ fehlerhaft E = (1, 1, 0, 0) ⇔ d0 ’ fehlerhaft E = (1, 0, 1, 0) ⇔ d1 ’ fehlerhaft E = (1, 1, 1, 0) ⇔ d2 ’ fehlerhaft 4−fach Fehler bleiben u.U. unerkannt

Erkennen von 2−fach Fehlern

1

1

1

1 F

Korrektes Codewort

Korrektur von 1−fach Fehlern

F

F

Hammingdistanz 4

3−fach Fehler u.U. als 1−fach Fehler interpretiert u. falsch korrigiert

Korrektes Codewort

Korrektur von 1−fach Fehlern

Abbildung 2.3: Fehlerkorrektur und -erkennung mittels der Hammingdistanz Häufig werden sog. SEC/DED-Codes ("single error correcting - double error detecting") verwendet. Sie weisen die folgenden Eigenschaften auf: Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

76

KAPITEL 2. INFORMATIONSDARSTELLUNG • Einzelfehler können korrigiert werden. • Doppelfehler können erkannt werden. • Doppelfehler können von Einfachfehlern unterschieden werden, so dass in diesem Fall nicht fälschlicherweise eine Korrektur eingeleitet wird. • Die Hammingdistanz zwischen allen korrekten Wörtern des Codes beträgt mindestens 4 (vgl. Abbildung 2.3).

Eine Schaltung zur Erzeugung von SECDED-Codes und zur Fehlerkorrektur/-erkennung ist in Abbildung 2.4 skizziert. Übertragungsstrecke Daten

Fehler-

.. .

.. Korrektur .. . . ... ...

PrüfbitGenerator

PrüfbitGenerator

FehlerErkennung

Abbildung 2.4: Hardware zur Fehlererkennung und -korrektur

2.1.3 Zahldarstellung Zahlsysteme Zahlen werden allgemein in einem Stellenwertsystem als Ziffernfolge der Form zn zn−1 ...z1 z0 dargestellt. Der Stellenwert der Position i, 0 ≤ i ≤ n, ist die Potenz bi einer Basis b. Tabelle 2.3 zeigt einige häufig verwendete Zahlsysteme. Der Wert Xb einer Zahl zn zn−1 ...z1 z0 zur Basis b errechnet sich wie folgt: Xb = zn zn−1 ...z1 z0 =

n X

zi bi

i=0

Zur Umwandlung von Zahlsystemen gibt es verschiedene Verfahren.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.1. DATENTYPEN

77

Basis

Bezeichnung

Ziffern

2

Dualzahl

{0,1}

8

Oktalzahl

{0, ... ,7}

10

Dezimalzahl

{0, ... ,9}

16

Hexadezimalzahl

{0, ... ,9, A, ... ,F}

Tabelle 2.3: Zahlsysteme Euklidischer Algorithmus Gegeben sei eine Zahl im Dezimalsystem: z = zn 10n + ... + z−m 10−m . Die Darstellung mit der Basis b ist gesucht: z = yp bp + ... + y−q b−q Die Umrechnung erfolgt in zwei Schritten. Zuerst bestimmt man p so, dass bp ≤ z ≤ bp+1 gilt. Durch wiederholtes Dividieren und Restbilden erhält man im zweiten Schritt die gewünschte Darstellung: yi := z div bi z := z mod bi Die Dezimalzahl 12310 wird z.B. wie folgt ins Dualsystem (b = 2) konvertiert: 2p y6 y5 y4 y3 y2 y1 y0

≤ 12310 < 2p+1 ⇒ = = = = = = =

123 59 27 11 3 3 1

div 64 = div 32 = div 16 = div 8 = div 4 = div 2 = div 1 =

p=6 1 1 1 1 0 1 1

z z z z z z z

:= 123 mod 64 = := 59 mod 32 = := 27 mod 16 = := 11 mod 8 = := 3 mod 4 = := 3 mod 2 = := 1 mod 1 =

59 27 11 3 3 1 0 → Ende

Die gesuchte Darstellung ist: 12310 = 11110112 Umwandlung ganzer Zahlen durch fortgesetzte Division Gegeben sei eine Zahl za im Zahlensystem a, gesucht ist ihre Darstellung xb im Zahlensystem b. za wird so oft durch b, also durch die Basis des „Zielsystems“, ganzzahlig dividiert bis das Ergebnis Null ist, also der Divisor größer als der Divident wird. Die Reste, die bei dieser Division entstehen, ergeben die gewünschte Darstellung. Als Beispiel soll die Zahl 1574110ins Hexadezimalsystem (x16 ) gewandelt werden:

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

78

KAPITEL 2. INFORMATIONSDARSTELLUNG 15741 983 61 3

: : : :

16 16 16 16

= = = =

983 61 3 0

Rest 13 (Ziffer „D“) Rest 7 Rest 13 (Ziffer „D“) Rest 3

Die Reste ergeben von unten nach oben gelesen die gewünschte Zahl. Es ist also 1574110 = 3D7D16 Gruppenweise Konvertierung Falls eine Basis Potenz einer anderen ist, können mehrere Stellen zusammengefasst werden. Dies wird deutlich bei der Konvertierung von Dualzahlen in Hexadezimalzahlen. Wenn man z.B. die Dualzahl 1101001101012ins Hexadezimalsystem konvertieren will, so kann man die Ziffern der Dualzahl in 4er Gruppen teilen und jede Gruppe für sich wandeln: 1101001101012 = 1101 0011 01012 = D3516 Umwandlung von Dezimalbrüchen Gegeben sei eine Zahl Y mit 0 < Y < 1, die in eine Darstellung zur Basis b der Form 0,y−1y−2 ...y−m+1 y−m gebracht werden soll. Der Wert dieser Zahl berechnet sich mit folgender Formel: Y = y−1 b−1 + y−2 b−2 + ... + y−m+1 b−m+1 + y−m b−m Mit der Horner-Umformung ergibt sich: Y = ( ... (y−m b−1 + y−m+1 )b−1 + ... + y−1 )b−1 Für die Darstellung zur Basis b bedeutet die Multiplikation mit b die Verschiebung des Kommas um eine Stelle nach rechts, d.h. es ist: Y ∗ b = (y−1 , y−2...y−m )b . Somit lässt sich eine Konvertierung folgendermaßen durchführen: Y ∗ b = ( .. (y−m b−m + y−m+1 )b−1 + ...y−2 )b−1 +y−1 → y−1 = ⌊Y ∗ b⌋ {z } | 9 ⇒Korrektur: +6 0110 0101 0010

Festkommazahlen Festkommazahlen werden wie ganze Zahlen dargestellt, wobei eine feste Anzahl k an Stellen als Nachkommastellen interpretiert werden. Für den Wert Xb einer Zahl zn zn−1 ...z1 z0 zur Basis b gilt dann: Xb = zn bn−k + ... + z0 b−k Für die Codierung der Ziffern (BCD/dual), die Darstellung des Vorzeichens und die Anzahl der Ziffern (variabel/fest) gelten die gleichen Kriterien wie bei ganzen Zahlen. Die Addition und Subtraktion werden unabhängig von k genauso realisiert wie bei ganzen Zahlen. Bei der Multiplikation muss das Ergebnis zur Korrektur um k Stellen nach rechts, nach einer Division um k Stellen nach links geschoben werden. Festkommazahlen eigenen sich gut für kaufmännische Anwendungen, so lassen sich z.B. Geldbeträge in e gut mit zwei Dezimalstellen hinter dem Komma darstellen.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.1. DATENTYPEN

85

Gleitkommazahlen Einführung Bei Gleitkommazahlen wird eine Information über die Anzahl der Nachkommastellen in das Datenwort aufgenommen. Die Darstellung von negativen Zahlen durch ein Zweierkomplement ist bei Gleitkommazahlen unzweckmäßig, man verwendet eher eine Darstellung mit Betrag und Vorzeichen. Das Datenwort enthält damit 3 Komponenten: s: Vorzeichen F : Mantisse E: Exponent Der Wert V einer Gleitkommazahl beträgt V = (−1)s · F · RE

(2.2)

wobei R die Basis (R = 2 bei Dualzahlen) ist. Für ein und dieselbe Zahl gibt es verschiedene Darstellungen. So könnte die Zahl 12,5 durch F =125 und E = −1, oder aber durch F = 1, 25 und E = 1 dargestellt werden (R = 10). Werden Gleitkommazahlen normalisiert dargestellt, so dass 1≤F 0 + leichter Datenzugriff + hohe Befehlsdichte − Operanden nicht äquivalent − variierende Taktzahl • Speicher-Speicher-Maschine: (m, m) + kompakt − viele Speicherzugriffe − variierende Taktzahl Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE Zahl der Speicheradressen pro ALUBefehl (m) 0 1 2 3

91

Maximale Zahl der Operanden (n) 2 3 2 3 2 3 3

Beispiel DEC α Station SPARC, MIPS, HP Precision Architecture PDP-10, Motorola 68000, z.T. IBM 360 PDP-11, National 32x32, z.T. IBM 360 VAX (besitzt auch 2-Operanden-Format)

Abbildung 2.12: Klassen von GPR-Maschinen

2.2.2 Adressierung Adressräume Eine Maschine besitzt verschiedene Funktionseinheiten, auf die anhand von Adressen zugegriffen wird: • Hauptspeicher • Registerspeicher • Kontrollspeicher • Kellerspeicher (Stack) • Ein-/Ausgabe Diese Adressräume müssen nicht unbedingt physikalisch oder logisch getrennt sein. So kann z.B. der Stack physikalisch im Hauptspeicher abgelegt sein, oder der Ein/Ausgabe-Bereich kann logisch über Hauptspeicher- Adressen ansprechbar sein. Abbildung 2.13 zeigt die Adressräume des MC 68020 als Beispiel.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

92

KAPITEL 2. INFORMATIONSDARSTELLUNG 000000 000040 000060 000080 0000C0 000400

0

Vordefinierte Vektoren Reserviert Interrupt-Vektoren Trap-Vektoren Anwender Hauptspeicher

.. .

Daten-Register 7 0

Adreß-Register 7

.. . I/O-Raum

Hauptspeicher-Raum

Status-Register Programmzähler Basisregister Kellerzeiger Cache-Steuerregister Funktionscode-Register

Control-Raum Abbildung 2.13: Adressräume des MC 68020 Auflösung und Ausrichtung Unter Adressauflösung versteht man die kleinste Anzahl von Bits, die über die gleiche Adresse angesprochen werden. Bei den meisten Rechnern beträgt sie 8 bit (Speicher ist byte-adressierbar). Es wäre auch denkbar, jedes einzelne Bit adressierbar zu machen, was dann jedoch ein längeres Adresswort erfordern würde. Die Adressauflösung kann auch für Befehle und Daten unterschiedlich sein. Tabelle 2.6 zeigt einige Beispiele.

Befehl: Datum:

MC68020 16 8

VAX-11 8 8

IBM/370 16 8

B1700 1 1

Tabelle 2.6: Adressauflösung für einige Rechner Ist die Wortbreite eines Datums größer als die Adressauflösung, werden also z.B. 32Bit-Worte in einem byteadressierbaren Speicher abgelegt, so muss vereinbart werden, in welcher Reihenfolge die Bytes, aus denen sich ein Wort zusammensetzt, abgelegt werden. Eine einheitliche Bit-, Byte- oder Wortnummerierung wäre wichtig für die Portabilität von Software. Leider hat sich (noch) kein einheitliches Format durchgesetzt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

93

Bei einigen Prozessoren wird das niederstwertige Byte eines Wortes zuerst abgelegt ("Little Endian"), bei anderen steht das höchstwertige Byte an der ersten Adresse ("Big Endian"). Abbildung 2.14 veranschaulicht das.

Wortadresse 0 4

Bytenummer: 3 2 1 7 6 5

(x86, VAX)

Wortadresse

0 4

Byte 3 Byte 2 Byte 1 Byte 0

“Little Endian”

Bit 31

Bit 0

Bytenummer:

0 4

0 4

(680x0, IBM)

1 5

2 6

3 7

Byte 0 Byte 1 Byte 2 Byte 3

“Big Endian”

Bit 31

Bit 0

Abbildung 2.14: Bytenummerierung Viele Rechnersysteme besitzen z.B. einen Datenbus mit der Breite von 32 Bit, erlauben aber eine byteweise Adressierung. Bei einem Zugriff auf ein einzelnes Byte wird dann das gesamte Wort, das dieses Byte enthält, gelesen und anhand der niederwertigen Adressbits das Byte extrahiert. Das kann einerseits durch ein spezielles Schaltnetz (Barred Shifter: s. Abbildung 2.15, schnell aber groß) oder ein Schieberegister (kleiner als ein Schaltnetz, dafür langsam) geschehen. Byte im Register 0

1

2

3

1

2

3

Schaltnetz 0

Wort im Speicher

Abbildung 2.15: Schaltnetz zur Adressausrichtung (Barred Shifter ) Soll auf ein Halbwort oder Wort zugegriffen werden, dessen Adresse nicht durch 2 bzw. 4 teilbar ist, so sind u.U. zwei Speicherzugriffe notwendig. In Abbildung 2.16 ist das bei dem Halbwort C und dem Wort D der Fall. Das Halbwort B kann dagegen mit einem Zugriff gelesen werden. Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

94

KAPITEL 2. INFORMATIONSDARSTELLUNG

Adreßzählung 31 ~

N N+4 N+8

23

Byte(A) -wort (C)

15

7

Halbwort (B)

0

~

Halb-

Wort (D)

~

~

Abbildung 2.16: Ausrichtung der Adressgrenzen Adressierungsarten Adressierungsarten lassen sich nach der Anzahl der Komponenten, d.h. der Anzahl der Register- und Speicherinhalte, die zur Bestimmung der eigentlichen Datums notwendig sind, klassifizieren (s. Abbildung 2.17). Konstanten und Direktwerte werden dabei nicht mitgezählt. 0 Komponenten

Direktoperand (immediate, unmittelbar)

1 Komponente

Register direkt Speicher Register indirekt Speicher indirekt

2 Komponenten

indiziert basiert basiert indiziert

Datenadresse

speicherindirekt nachindiziert Mehrere Komponenten

. . .

Abbildung 2.17: Klassifikation von Adressierungsarten Im folgenden sollen die gebräuchlichsten Adressierungsarten vorgestellt werden. Direktoperand Ein Direktoperand ist eine Konstante, die als Befehlsbestandteil im Programm enthalten ist. Ein Beispiel für einen Befehl mit Direktoperand ist: ADD R4, # 3 ; R4 ← R4 + 3 Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

95

Abbildung 2.18 zeigt eine grafische Darstellung dieser Adressierungsart. Befehlsbestandteil

Operand (#3) Abbildung 2.18: Direktoperand Register-direkt

Hier steht der Operand in einem Register (s Abbildung 2.19), z.B.:

ADD R4, R3 ; R4 ← R4 + R3 Befehlsbestandteil

.

Register (R3)

Operand

Abbildung 2.19: Adressierungsart "Register-direkt" Speicher-direkt (absolut) Der Operand wird aus dem Speicher gelesen, wobei die Adresse als Direktwert im Befehl enthalten ist (s. Abbildung 2.20), z.B.: ADD R1, (1001) ; R1 ← R1 + Mem[1001] Die absolute Adressierung eignet sich z.B. zum Zugriff auf I/O-Adressen oder auf globale Variablen, deren Speicheradressen während der Compilation bestimmt werden können. Befehlsbestandteil

effektive Adresse

.

Speicher (Adr. 1001)

Operand

Abbildung 2.20: Adressierungsart "absolut" Register-indirekt Ein Register zeigt auf die Speicherstelle, die den Operanden enthält (s.Abbildung 2.21), z.B.: ADD R4, (R1) ; R4 ← R4 + Mem[R1]

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

96

KAPITEL 2. INFORMATIONSDARSTELLUNG Befehlsbestandteil

.

Register (R1)

effektive Adresse

.

Speicher

Operand

Abbildung 2.21: Adressierungsart "Register-indirekt" Diese Adressierungsart eignet sich z.B. für die Dereferenzierung von Zeigern, wenn die Zeigervariable in einem Register gespeichert ist, z.B.: var a: integer; b: ˆinteger; ... a := bˆ; Der Variablen a wird der Wert, auf welchen der Zeiger b zeigt, zugewiesen. Diese Adresse wird in dem Register abgelegt, worüber dann auf den Speicher zugegriffen wird. Prädekrement und Postinkrement Diese Adressierungsarten ähneln "Registerindirekt". Zusätzlich wird der Wert des Registers, das auf die Adresse des Operanden zeigt, vor dem Zugriff erniedrigt (Prädekrement, s.Abbildung 2.22) oder nach dem Zugriff erhöht (Postinkrement, s. Abbildung 2.23), z.B.: ADD R1, -(R2) ; R2 ← R2 - 1, R1 ← R1 + Mem[R2] oder ADD R1, (R2)+ ; R1 ← R1 + Mem[R2], R2 ← R2 + 1 Die Prädekrement- und Postinkrement- Adressierungen eignen sich für das effiziente Durchlaufen eines Arrays oder für die Implementierung eines Stacks.

Befehlsbestandteil

.

Register (R2)

Speicheradresse Speicher

decr= 1,2 oder 4



effektive Adresse

Operand

Abbildung 2.22: Prädekrement-Adressierungsart "Prädekrement" Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE Befehlsbestandteil

.

97 Register (R2)

effektive Adresse

incr= 1,2 oder 4

.

Speicher

Operand

+

Abbildung 2.23: Adressierungsart "Postinkrement" Gegeben sei zum Beispiel das folgende Programm, geschrieben in einer stackorientierten Hochsprache, das die Berechnung von z:=x + y durchführt: PUSH PUSH ADD POP

X Y Z

Bei Verwendung der Prädekrement- und Postinkrement- Adressierung lässt sich jede Zeile unmittelbar in eine einzelne Assembler-Anweisung umsetzen (das rechte Argument wird zuerst ausgewertet): MOVE MOVE ADD MOVE

-(R1) , X -(R1) , Y (R1) , (R1)+ Z , (R1)+

Das Register R1 dient dabei als Stapelzeiger. Der ADD-Befehl liest dabei die Speicherstelle, auf die R1 zeigt, inkrementiert R1 dann und schreibt die Summe zum Schluss an die Adresse, auf die R1 jetzt zeigt. Register-indirekt mit Displacement Hier wird wieder indirekt auf den Speicher zugegriffen, wobei sich die effektive Adresse aus der Summe eines Registerinhaltes und eines konstanten Displacements ergibt (s. Abbildung 2.24), z.B.: ADD R4, 100(R1) ; R4 ← R4 + Mem[100+R1] Diese Adressierungsart wird in der Regel von Compilern für Zugriffe auf lokale Variablen, die in einem Aktivierungsblock (s. Abschnitt 2.2.4) gespeichert sind, verwendet. Befehlsbestandteile

Register (R1) Speicheradresse Speicheradresse

effektive Adresse Speicher

Displacement (100)

+

Operand

Abbildung 2.24: Adressierungsart "Register-indirekt mit Displacement" Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

98

KAPITEL 2. INFORMATIONSDARSTELLUNG

Sei folgendes Programmfragment gegeben: var a,b: integer; a := b; Die Adresse des Aktivierungsblockes wird in einem Register abgelegt, während das Displacement angibt, an welcher Stelle innerhalb des Stackframes die jeweilige Variable (a oder b) steht. Ein weiteres Beispiel zu dieser Adressierungsart ist ein Feldzugriff über einen Zeiger. Sei z.B. folgendes Programmfragment gegeben: var a: integer; b: ˆrecord c, d, e: integer; end; ... a := bˆ.d; Die Variable b ist ein Zeiger auf einen Record mit dem Inhalt c, d und e. Der gesamte Record ist im Speicher abgelegt. Um auf d zugreifen zu können, müssen wir sowohl die Stelle des gesamten Records im Speicher als auch die relative Adresse von d in Bezug auf den Record kennen. Die Variable b wird somit in einem Register abgelegt und die relative Adresse von d im Displacement (vgl. Abbildung 2.24). Indiziert Die effektive Adresse ergibt sich ähnlich wie bei der Adressierungsart "Register-indirekt mit Displacement", wobei zu der effektiven Adresse zusätzlich der Inhalt eines weiteren Registers (Index), multipliziert mit einem Skalierungsfaktor, addiert wird (s. Abbildung 2.25), z.B.:

ADD R1, 100(R2) [R3]; R1 ← R1 + Mem[R2 + 100 + R3*scale] Diese Adressierungsart ist in erster Linie für den Zugriff auf Arrays konzipiert. Diese können sich auch innerhalb eines Stackframes befinden.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE Befehlsbestandteile

99 Register (R2)

Speicheradresse Speicheradresse

effektive Adresse Speicher

Displacement (100)

+

+

Operand

Register (R3)

Index scale = 1, 2 oder 4

Abbildung 2.25: Adressierungsart "Indiziert" Folgendes Programmfragment ist ein Beispiel für diese Adressierungsart. var a, i: integer; b: array [0 to 99] of integer; ... a := b [i]; Das Array b befindet sich in einem Stackframe (s. Abschnitt 2.2.4), d.h. um auf die Elemente des Arrays zugreifen zu können, braucht man die Startadresse des Stackframes (im Register abgelegt) und die relative Adresse des Arrays zu dem Stackframe (im Displacement abgelegt). Weiterhin braucht man einen Index, um auf ein bestimmtes Element des Arrays zugreifen zu können (im Index-Register abgelegt). In Abbildung 2.25 gibt es zusätzlich noch den Faktor „scale“. Dieser wird, abhängig von dem Datentyp, welcher in dem Array gespeichert ist, gesetzt. Speicher-indirekt Bei der Adressierungsart "Speicher-indirekt" wird zunächst durch einen Zugriff vom Typ "Register-indirekt" eine indirekte Adresse aus dem Speicher gelesen. Zu dieser Adresse wird eine Konstante (Displacement 2) addiert, und durch einen erneuten Speicherzugriff wird der Operand gelesen (s. Abbildung 2.26). Ein Beispiel ist:

ADD R1, [25 (R3)] 35 ; R1 ← R1 + Mem[35 + Mem [R3 + 25]] Diese Adressierungsart eignet sich für die Dereferenzierung von Zeigern, wenn die Zeigervariable in einem Stackframe abgelegt ist.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

100

KAPITEL 2. INFORMATIONSDARSTELLUNG Befehlsbestandteile

Register (R3) Speicheradresse Speicheradresse Speicher

Displacement 1 (25) Displacement 2 (35)

+

indirekte Adresse + eff. Adresse

Operand

Abbildung 2.26: Adressierungsart "Speicher-indirekt" Das Programmfragment var a: integer; b: ˆrecord c, d, e: integer; end; ... a := bˆd; ist ein typisches Beispiel für die Adressierungsart „Speicher-indirekt“. Wenn die Zeigervariable in einem Stackframe abgelegt ist, so brauchen wir, genauso wie im Beispiel zu „Indiziert“, erst die Startadresse des Stackframes, welche in einem Register abgelegt ist, und die relative Adresse der Variablen in Bezug auf den Stackframe, welche hier im Displacement 1 abgelegt ist. In Displacement 2 wird die relative Adresse von d in Bezug auf den Record abgelegt. Nachindiziert Hier handelt es sich um eine Erweiterung der Adressierungsart "Speicher-indirekt". Zusätzlich zu dem Displacement 2 wird zur indirekten Adresse noch ein variabler Index (ähnlich wie bei "indiziert") addiert (s. Abbildung 2.27).

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE Befehlsbestandteile

101 Register effektive Adresse

Speicheradresse Speicheradresse

Speicher

Displacement 1

+

Displacement 2

+

indirekte Adresse +

Register

Index scale = 1, 2 oder 4

+ eff. Adresse

Operand

Abbildung 2.27: Adressierungsart "Nachindiziert" Ein Beispiel für diese Adressierungsart stellt folgendes Programmfragment dar: var i: integer; a: char b: ˆrecord alter : integer; name : string[20]; vorname : string[20]; end; ... a := bˆ.name [i]; Wenn man davon ausgeht, dass die Variablen in einem Stackframe abgelegt sind, so braucht man zunächst die Adresse des Stackframes (in einem Register abgelegt), und die relative Adresse des Records in Bezug auf den Stackframe (im Displacement 1 abgelegt). Damit ist die indirekte Adresse des Records bekannt. Um auf die einzelnen Komponenten diese Records zugreifen zu können, braucht man noch die relativen Adresse der einzelnen Komponenten innerhalb des Records, die im Displacement 2 abgelegt ist. Im obigen Beispiel wird auf eine Komponente zugegriffen, welche ein Array darstellt - dafür braucht man noch einen Index (im IndexRegister abgespeichert), um auf die einzelnen Felder zugreifen zu können (vgl. Abbildung 2.27). Vorindiziert Hier handelt es sich ebenfalls um eine Erweiterung der Adressierungsart "Speicher-indirekt". Der variable Index wird zu dem Displacement 1 addiert, so dass ein Array von indirekten Adressen angesprochen werden kann (s. Abbildung 2.28). Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

102

KAPITEL 2. INFORMATIONSDARSTELLUNG Befehlsbestandteile

Register effektive Adresse

Speicheradresse Speicheradresse

Speicher

Displacement 1

+

+

indirekte Adresse

Register

Index scale = 1, 2 oder 4

Displacement 2

+ eff. Adresse

Operand

Abbildung 2.28: Adressierungsart "Vorindiziert" Diese Adressierungsart eignet sich für den Zugriff auf Arrays von Datensätzen, z.B. bei dem folgenden Programmfragment: var a, i: integer; b: array [0 to 99] of ˆrecord d, e: integer; end; ... a := b [i]ˆ.e; Wenn man davon ausgeht, dass das Array, also die Zeiger auf die Records, in einem Stackframe abgelegt sind, so braucht man wieder, wie in den Beispielen zu „indiziert“ und „Speicher-indirekt“, die Startadresse des Stackframes. Diese wird in einem Register abgelegt. Innerhalb des Stackframes braucht man noch die relative Startadresse des Arrays, welche im Displacement 1 abgelegt wird. Genauso wie bei der Adressierungsart „Indiziert“ braucht man noch die Information darüber, auf welches Element man zugreifen will, also den Index. Damit ist die Adresse des Records (welches im Speicher liegt) vollständig bestimmt, allerdings braucht man noch die Information, auf welchen Teil des Records man zugreifen will. Dies wird in Displacement 2 abgespeichert. Befehlszählerrelativ Bei den meisten Sprungbefehlen ist das Sprungziel nicht weit von dem Sprungbefehl entfernt. Deshalb wird bei vielen Prozessoren in dem Sprungbefehl nicht die absolute Zieladresse, sondern die Differenz zwischen Zieladresse und dem aktuellen PC-Inhalt gespeichert, die sich mit weniger Bits kodieren lässt. Bei der PC-relativen Adressierung mit Indizierung wird zu der Zieladresse zusätzlich der Inhalt eines Indexregisters Xn addiert. So kann man mit Hilfe einer Sprungbefehlstabelle eine größere "CASE"-Anweisung effizient realisieren (s. Abbildung 2.29). Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

103 Programmspeicher

(PC)

~

.

~ JMP

disp (PC) (Xn)

-

+ disp

JMP

ZIEL 0

JMP

ZIEL 1

JMP

ZIEL 2

JMP

ZIEL 3

+ (XN)

~

~ Abbildung 2.29: Sprungbefehlstabelle

Zusammenfassung Abbildung 2.30 zeigt, wie mit den in diesem Abschnitt vorgestellten Adressierungsarten auf die Zahl 12345 zugegriffen werden kann. Speicher

Register R0 R1 R2

R6

12345 130 1132 2 -6 3 1100

R7

32

R3 R4 R5

1130 1132

6000

6003 PC

12345

1130

Unmittelbar Register-direkt Speicherdirekt Register-indirekt Speicherindirekt Register-indirekt mit Displacement Vorindiziert Nachindiziert Indiziert PC-relativ PC-relativ mit Indizierung

#12345 R0 1132 (R2) [6000(R5)]0 1138(R4) [6000(R4)(R5*2)]2 [6000(R5)](R4*2)12 0(R6) (R7) 130 (PC) 0(PC) (R1)

1132

1002

Abbildung 2.30: Zugriff auf die Zahl 12345

2.2.3 Operationsarten Die von einem Prozessor unterstützten Befehle lassen sich nach ihrer Funktion in die folgenden Gruppen aufteilen: Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

104

KAPITEL 2. INFORMATIONSDARSTELLUNG

• Arithmetische und logische Befehle • Datentransferbefehle • Steuerungsbefehle • Systembefehle • Gleitkommabefehle • Stringbefehle Das Ergebnis jeder Operation besteht aus dem eigentlichen Resultat, das in ein Register oder in den Speicher geschrieben wird und häufig einer Veränderung von Bedingungsbits im Statusregister. Einige dieser Bedingungsbits sind: C

Übertrag

V

Überlauf

N

negatives Resultat

Z

Resultat = 0

In den folgenden Teilabschnitten werden die einzelnen Operationsarten diskutiert. Transportbefehle Transportbefehle übertragen Daten zwischen Registern und / oder Speicherstellen. Abbildung 2.31 zeigt einige Beispiele. Dabei stehen "s" und "d" wahlweise für Operanden, wobei verschiedene der in Abschnitt 2.2.2 vorgestellten Adressierungsarten verwendet werden können.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

105

Z . B. L O A D , S T O R E , M O V E , C LR B efe h l

F u nk tio n

K o m m en tar

N ZV C

→d

M OVE

d ,s

m o ve s

M O V SX

d ,s

m o ve w ith si gn ex tension →d s(s ig n exten d ed)

MO V ZX

d ,s

m ov e w i th z ero ex tens io n →d s (zero exten d ed)

LE A

d ,s

P U SH P OP

vv00 Q u ell-/Z ielfo rm ate : .B /.W .B /.L .W / .L

vv00

loa d effe ctiv e add re ss →d eff. A d res se v o n s

D i rektop e ran d- u n d R egi st er-A d res si erun g , eff. A d res se h at 3 2 B its

----

s

p ush o n th e stac k S P -n → SP , s → (SP )

S P = U S P /S SP

----

d

po p fro m th e stac k (SP ) → d , SP + n →(SP )

.W : n = 2 .L : n = 4

vv00

vv00

( v b e ein flu ß t, - u nb e ein flu ß t)

Abbildung 2.31: Beispiele für Datentransportbefehle Der Befehl LEA ("load effective address") spielt eine Sonderrolle. Bei der Spezifikation des Quelloperanden kann eine beliebige Adressierungsart außer "unmittelbar" und "Register-direkt" verwendet werden. An das Ziel wird jedoch nicht der Operand, sondern dessen effektive Adresse geschrieben. Abbildung 2.32 zeigt ein Beispiel dazu.

LEA R3, 4(R0) (R1)

Registerspeicher 31 $0000 A000 R0 $0000 0006 R1 R2 R3 ~

0

$0000 A00A ~

Abbildung 2.32: Wirkung von LEA Arithmetisch-logische Befehle Die arithmetisch-logischen Befehle lassen sich in die folgenden Untergruppen gliedern:

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

106

KAPITEL 2. INFORMATIONSDARSTELLUNG

1. Arithmetische Befehle • Integer-Arithmetik • Gleitkomma-Arithmetik 2. Logische Befehle • Bitverarbeitend • Wortverarbeitend 3. Schiebebefehle 4. Befehle für Codeumwandlungen, z.B.: • Integer ↔ Gleitkomma • ASCII ↔ EBCDIC • Integer ↔ BCD (evtl. als Anpassungsfunktionen in Verbindungen mit arithmetischen Operationen realisiert) • packed BCD ↔ unpacked BCD Abbildung 2.33 zeigt Beispiele für arithmetische Befehle für Integer-Zahlen. In der Regel besitzen Prozessoren Befehle zur Addition und Subtraktion, oft sind auch Multiplikations- und Divisionsbefehle vorhanden. Gleitkomma-Befehle werden in dem Kapitel über den MIPS-Prozessor vorgestellt. Befehl

Funktion

Kommentar

NZ VC

ADD(C) d,s

add (with carry) d + s (+ C) →d

C: Carrybit

vv vv

SUB(C) d,s

subtract (with carry) →d d - s (- C)

vv vv

MULU MULS

d,s d,s

multiply unsigned multiply signed .W:d w .sw →dL .L:d L .sL →dLL

vv v0

DIVU DIVS

d,s

divide unsigned divide signed .W:d L /s w →dL r: Rest .L:d LL /s L→dLL q: Quotient

vv v0

Abbildung 2.33: Integer-Arithmetik Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

107

Bei den logischen Befehlen unterscheidet man zwischen den bitverarbeitenden Befehlen, mit denen einzelne Bits (zurück-)gesetzt, negiert oder abgefragt werden können (s. Abbildung 2.34) und wortverarbeitenden Befehlen, bei denen ganze Register bitweise verknüpft werden (s. Abbildung 2.35). Befehl

Funktion

Kommentar

N Z V C

BTST

s,d

test bit NOT d ⇒ Z

s gibt Bitposition als Offset an

- v - -

BSET

s,d

test and set bit NOT d ⇒ Z 1 →d

.B: Offset = 0 bis 7 .W: Offset = 0 bis 15 .L: Offset = 0 bis 31

- v - -

BCLR

s,d

test and clear bit NOT d ⇒ Z 0 →d

- v - -

BINV

s,d

test and invert bit NOT d ⇒ Z NOT d → d

- v - -

31

B C L R .B #5 ,R 0

9 9

9 9

7 5 10100110

0 R0 Z=0

te st

9 9

cle ar

9 9

10000110

R0

Abbildung 2.34: Bitverarbeitende logische Befehle Befehl

Funktion

Kommentar

NZV C

AND

d,s

and s AND d → d

OR

d,s

or

XOR

d,s

exclusive or s XOR d → d

vv00

NOT

d

not NOT d → d

vv00

s OR d → d

vv00 vv00

Abbildung 2.35: Wortverarbeitende logische Befehle Bei Schiebeoperationen ist die Richtung (links/rechts), die Anzahl der Verschiebungen, sowie die Art des Schieben (arithmetisch/logisch) festzulegen. Die Schiebearten Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

108

KAPITEL 2. INFORMATIONSDARSTELLUNG

"arithmetisch" und "logisch" unterscheiden sich in der Behandlung des Vorzeichenbits beim Rechtsschieben. Beim logischen Schieben werden die hereingeschobenen Stellen stets mit 0 aufgefüllt, beim arithmetischen Schieben nach rechts werden sie mit dem Vorzeichenbit aufgefüllt. Arithmetisch betrachtet bedeutet das Schieben um eine Stelle nach rechts die „Halbierung” der Wertes (genauer: X div 2). Beim SRA-Befehl („shift right arithmetically“) bleibt diese Eigenschaft auch für Zweierkomplementzahlen bestehen. Die Zahl 111101102 hat z.B. den Wert -10. Arithmetisch nach rechts geschoben ergibt sich 111110112 = -5, schiebt man logisch, so erhält man 011110112 = 123. Abbildung 2.36 zeigt Beispiele für Schiebebefehle.

a) Formatumwandlungen. Bei Schiebebefehlen sind festzulegen: Art, Zahl, Richtung Befehl ASR

Funktion

Kommentar

N Z V C

arithmetic shift right

.B: n = 1 ... 7 .W: n = 1 ... 15 .L: n = 1 ... 35

v v v v

s,d

d

C

LSL

s,d

logical shift left

v v 0 v

LSR

s,d

C d 0 logical shift right

v v 0 v v v 0 v

0 ROL

s,d

d rotate leftC

ROR

s,d

rotate right

C

d d

v v 0 v

C

b) Codeumwandlungen Extern - intern (z.B. ASCII - EBCDIC) Intern - intern (Integer - Gleitkomma, packed BCD unpacked BCD) Abbildung 2.36: Beispiele für Schiebebefehle Steuerbefehle In der Gruppe der Steuerbefehle werden alle Befehle zusammengefasst, die eine nichtlineare Abarbeitungsfolge ermöglichen: Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

109

• Sprünge (unbedingt, bedingt) • Aufrufe von / Rücksprünge aus Unterprogrammen • TRAP-Befehle zum Aufruf von Unterbrechungsroutinen

2.2.4 Unterstützung von Hochsprachen Der größte Anteil an Maschinencode wird heutzutage nicht von Assembler- Programmierern, sondern automatisch von Compilern erzeugt. Entsprechend ist es wichtig, dass der Befehlssatz einer Maschine an die Struktur von Hochsprachen angepasst ist. Das betrifft zum einen die Auswahl von implementierten Adressierungsarten. In Abschnitt 2.2.2 wurde bereits an einigen Beispielen verdeutlicht, wie sich typische Konstrukte in Hochsprachen auf spezielle Adressierungsarten abbilden lassen. Zum anderen erlauben die meisten Hochsprachen, Funktionen oder Prozeduren mit lokalen Variablen zu definieren, um Modularität und Abstraktion zu ermöglichen und um die Codelänge zu reduzieren. Die Sichtbarkeit von lokalen und globalen Variablen wird durch ein Umgebungsmodell festgelegt. Abbildung 2.37 zeigt ein Beispiel mit einer aufrufenden ("Caller") und einer aufgerufenen Funktion ("Callee"). Beide Funktionen besitzen jeweils eine Menge von lokalen Variablen, auf die die jeweils andere Funktion keinen Zugriff hat. Zusätzlich gibt es eine gemeinsame Umgebung, die Variablen enthält, auf die beide zugreifen können.

Hauptprogramm Call (Aktivierung) (Parameter)

Prozedur A aufrufende Funktion

aufgerufene Funktion

Prozedur B Funktion C

lokale Variable

(zurückgegebener Wert)

lokale Variable

Gemeinsame Umgebung

Abbildung 2.37: Umgebungsmodell und Funktionsaufruf

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

110

KAPITEL 2. INFORMATIONSDARSTELLUNG

Die lokalen Variablen einer aufgerufenen Funktion müssen in der Regel nicht permanent gespeichert werden und brauchen deshalb nur Platz im Hauptspeicher zu belegen, solange die Funktion aktiv ist. Bei Funktionen, die sich rekursiv selbst aufrufen, können mehrere Instanzen gleichzeitig aktiv sein. Deshalb können die lokalen Variablen nicht an festen, zur Compile-Zeit festgelegten Speicherstellen stehen, sondern es ist eine dynamische Speicherbelegung erforderlich. Abbildung 2.38 zeigt ein etwas komplexeres Beispiel mit mehreren, teilweise verschachtelt deklarierten, Pascal-Prozeduren. In Abbildung 2.39 ist für verschiedene Programmzeilen dargestellt, welche Variablen jeweils sichtbar sind. program Main (input, output) var I, J, K: integer ; R: real;

1

2

(* Main program, outermost block (* Global variable declaration

*) *)

procedure A (var X: integer ); ... var J, L, M: integer ; begin ... end;

(* Function declaration, X is a (* formal parameter, by reference (* Local variable declaration

*) *) *)

procedure B (Y: integer ); ... var K, L, P: integer ; ... function C (Z: real): integer ; var J, L, M: integer ; begin C := ... end;

(* Function declaration, Y is a (* formal parameter, by value (* Local variable declaration

*) *) *)

(* Nested function declaration (* Local variable declaration

*) *)

(* Return value assigned to (* function C

*) *)

(* Function call (* R is an actual parameter (* the return value is passed to J

*) *) *)

(* Start of main program (* Initialize I and K

*) *)

A(K);

(* Function call

*)

B(I);

(* Function call

*)

begin ... J := C(R); ... end;

3

4

begin I := 1; K := 2;

end.

Abbildung 2.38: Programmbeispiel program Main I J K R A B

procedure A procedure B J L M X K L P C Y

function C J L M Z

Zeile 1

v - v v v v

v v v v

- - - - -

- - - -

Zeile 2

v - - v v v

- - - -

v - v v v

v v v v

Zeile 3

v v - v v v

- - - -

v v v v v

- - - -

Zeile 4

v v v v v v

- - - -

- - - - -

- - - -

v = sichtbar - = unsichtbar

Abbildung 2.39: Sichtbarkeit von Variablen beim Beispiel aus Abbildung 2.38 Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

111

In dem nächsten Abschnitt wird die Verwaltung von lokalen Daten und Parametern mit Hilfe von Aktivierungsblöcken beschrieben. Alternativen dazu werden in Abschnitt 2.2.4 angesprochen. Struktur und Aufbau von Aktivierungsblöcken Ein Aktivierungsblock repräsentiert die lokale Umgebung einer Funktion und enthält die folgenden Informationen: • Explizite Parameter • Implizite Parameter: – statischer Zeiger (auf umgebende Funktion) – dynamischer Zeiger (auf aufrufende Funktion) – Rücksprungadresse – sonstige • lokale Daten Den Unterschied zwischen dem dynamischen und dem statischen Zeiger kann man an dem Beispiel aus Abbildung 2.38 verdeutlichen, wenn man annimmt, dass die Funktion C sich rekursiv aufruft. Der dynamische Zeiger würde dann jeweils auf den Aktivierungsblock der aufrufenden Funktion (C oder B) zeigen. Der statische Zeiger zeigt stets auf den Aktivierungsblock von B. Aktivierungsblöcke werden in einem Stack verwaltet und jeweils beim Prozeduraufruf angelegt und beim Rücksprung entfernt. Abbildung 2.40 zeigt die Struktur eines Aktivierungsblockes. Eine Momentaufnahme des kompletten Stacks, wenn in dem Beispiel von Abbildung 2.38 gerade Zeile 2 ausgeführt wird, ist in Abbildung 2.41 dargestellt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

112

KAPITEL 2. INFORMATIONSDARSTELLUNG Richtung des Stack

Lokale Datenstrukturen Lokale Skalare Dynamischer Zeiger Statischer Zeiger Rücksprungsadresse

SP Lokale Daten DL SL PC

Implizite Parameter

Andere implizite Parameter Aktueller Parameter N Explizite Parameter Aktueller Parameter 1 Vorhergehender Aktivierungsblock

Abbildung 2.40: Struktur von Aktivierungsblöcken

R i c h t u n g d e s S t a c k

M L J DL = saved FP SL Rücksprungadresse (PC) Andere implizite Parameter Z P L K DL SL PC Andere implizite Parameter Y R K J I DL = NIL SL = NIL PC = NIL Andere implizite Parameter

SP Lokale Daten FP Implizite Parameter

Aktivierungsblock von C

Explizite Parameter Lokale Daten Implizite Parameter

Aktivierungsblock von B

Explizite Parameter Lokale Daten

Implizite Parameter

Aktivierungsblock von Main

Abbildung 2.41: Beispiel für das Stack-Layout bei der Ausführung des Programmes von Abbildung 2.38 Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

113

Zum Aufruf von Funktionen besitzen viele Prozessoren zwei Sprungbefehle JSR ("jump to subroutine") und RTS ("return from subroutine"). JSR legt den Inhalt des Programmzählers auf den Stack und springt zu einer angegebenen Adresse, RTS holt eine Rücksprungadresse von Stack und springt dorthin (s. Abbildung 2.42).

Befehl JSR d

Funktion jump to subroutine SP − 4 → SP, PC→ (SP) eff. Adresse von d→ PC

RTS

return from subroutine (SP) → PC, SP + 4 → SP

JSR SUBR Befehl

.. . SUBR Befehl .. . RTS

User-/Supervisor-Stack vor JSR ~15 0~

0~

~15

N-2 N

JSR mit 32-BitDisplacement

M M+2 M+4 M+6

~

~ ~ Befehl

~ ~

~ ~ RTS

~

nach JSR

~ ~

~

(SP)

letzter Eintrag

~

Befehl

SUBR

N ZVC - - - -

- - - -

Programmspeicher

Programm

.. .

Kommentar d ≠ RegisterAdressierung

~

Rücksprungsadresse M + 6

N-4 N-2 N

~ nach RTS ~ N-2 N

~ ~ (SP)

letzter Eintrag

~

(SP)

~

Abbildung 2.42: Sprungbefehle JSR und RTS Alternativen zur Datenhaltung auf dem Stack Die oben dargestellte Verwaltung von Aktivierungsblöcken bietet ein hohes Maß an Flexibilität, allerdings erfordern die Zugriffe auf Variablen aufwendige Speicherzugriffe. Intelligente Compiler versuchen daher, lokale Variablen und Übergabeparameter möglichst in Registern zu halten. So kann die Geschwindigkeit beträchtlich erhöht werden, allerdings ist die Anzahl der Register beschränkt und Arrays können so z.B. nicht gespeichert werden; in nahezu allen Programmiersprachen werden daher Arrays (und meist auch alle anderen nicht primitiven Datentypen) beim Methoden- / Prozeduraufruf als „call by reference” übergegeben (Parameter im Methoden- / Prozedurkopf). Außerdem müssen bei rekursiven Aufrufen die verwendeten Register auf dem Stack gesichert werden, so dass wiederum Speicherzugriffe nötig werden. Eine spezielle Hardware zur Unterstützung von Parametern und lokalen Variablen in Registern bietet das Konzept der Registerfenster. Dies ist in dem RISC II-Prozessor

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

114

KAPITEL 2. INFORMATIONSDARSTELLUNG

realisiert, der an der Universität von Berkeley entwickelt wurde und die Grundlage für die SPARC-Architektur darstellt. Der RISC II besitzt insgesamt 138 Register, von denen jedoch immer nur 32 zugänglich sind. Die ersten 10 von den 138 Registern sind permanent unter den Namen R0 bis R9 ansprechbar. Unter den anderen Namen R10 bis R31 sind jeweils 22 Registern ab der Nummer 16n + 10, 0 ≤ n ≤ 7, eingeblendet (s. Abbildung 2.43). Mit einem speziellen CPU-Befehl wird bei einem Prozeduraufruf auf das nächsthöhere Fenster und bei einem Rücksprung auf das vorhergehende Fenster umgeschaltet. Die Fenster überlappen sich in 6 Registern, d.h. die Register, die für die aufrufende Prozedur als R26 bis R31 eingeblendet waren, sind für die aufgerufene Prozedur unter R10 bis R15 zugänglich. Sie können damit für die Übergabe von Parametern und die Ergebnisrückgabe verwendet werden. Fenster

(a) R0

R9

R10 R15 R16 Register für Eingabevariablen

Globale Register

R25 R26 Lokale Register

R31

Ausgegebene Variablen

(b) 0

9 10

31

Globale Register 10 15 16

47

137

25 26 31

Fenster 1 10 15 16

25 26 31

Fenster 2

26 31

Wrap around

10 15 16

25

Fenster 7

Abbildung 2.43: Registerfenster

2.2.5 Befehlsformate In diesem Abschnitt soll die Kodierung von Befehlen diskutiert werden. Zu einem gegebenen Befehlssatz muss ein Befehlsformat gefunden werden, mit dem die folgenden Informationen kodiert werden können: • Spezifikation der Operation

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

115

• Zahl der Operanden (entfällt, wenn die Zahl der Operanden konstant ist) • Lokalisierung der Daten (Adressierungsart) • Spezifikation des Datentyps (Integer mit/ohne Vorzeichen, Gleitkomma einfacher/doppelter Genauigkeit etc.) • Wertspezifikation (z.B. Direktwerte, Adressen, Displacements) Ein Befehl besteht aus einem Basisteil und einer Operandenerweiterung. Der Basisteil enthält die Spezifikation der Operation (Opcode), und der Operanden. Konstanten (Direktwerte, Adressangaben etc.) werden meist außerhalb des Basisteils in der Befehlserweiterung abgelegt. Abbildung 2.44 zeigt den allgemeinen Aufbau eines Befehls am Beispiel „ADD.W A(PC),D1“. B eispiel: A D D . W A (PC ), D 1 Befeh l

Op cod e 4 ADD

Op erand S pecifier

Op erand S pecifier O pm od e 3 D1

1

2

' 0 ' .W

3

3

16

M od us Regis ter =7 =2

O peran d

Dis placem en t A

O peran d

B asiste il O pm ode: Rich tun g (Sp eicher

Ope ran den erw eiterun g

→ R egister: 0 ), D atenty p

Abbildung 2.44: Terminologie bei Befehlsformaten Datentypspezifikation Zur Spezifikation des Datentyps gibt es grundsätzlich drei Möglichkeiten (s. auch Abbildung 2.45): 1. Im Opcode. Je nach Operation wird der Typ aller oder einzelner Operanden zusammen mit der Operation kodiert. Der Datentyp muss während der Compilation bekannt Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

116

KAPITEL 2. INFORMATIONSDARSTELLUNG sein. Ist eine Konvertierung erforderlich, so ist ebenfalls der Compiler dafür verantwortlich, entsprechenden Code zu erzeugen. Da die Typspezifikation im Opcode in Bezug auf den Speicherbedarf und die Befehlsdekodierung effizienter ist als b) oder c), wird sie in der Praxis am häufigsten verwendet.

2. Im Operand. Diese Variante bietet keine Vorteile gegenüber a) und wird deswegen in kommerziellen Systemen nicht eingesetzt. 3. Im Datum. Diese Variante hat den Vorteil, dass die Operationen generisch spezifiziert werden können. Der Datentyp steht erst zur Laufzeit fest, und ein und dasselbe Programm kann z.B. sowohl für Integer-Werte und Gleitkomma-Zahlen verwendet werden. Der Nachteil liegt in dem erhöhten Speicherbedarf und in dem erhöhten Zeitbedarf, der zur Befehlsdekodierung und Typüberprüfung nötig ist. Verwendet wurde dieser Ansatz bei Maschinen der Firma Bourroughs ("Tagged Architecture"). 1. Im Opcode: ... Opcode DT

Operand 1

Operand N

2. Im Operand: ... Opcode

DT 1 Operand 1

DT N Operand N

3. Im Datum: ... Opcode

Operand 1

Operand N

DT N

Data N .. .

DT 1

Data 1

Abbildung 2.45: Möglichkeiten der Datentypspezifikation

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

117

Wertspezifikation Konstante Werte (z.B. Direktwerte, Adressen, Displacements) können entweder als Operandenerweiterung oder im Befehlsbasisteil gespeichert werden. Im letzteren Fall ist eine schnellere Befehlsdekodierung möglich, so werden bei RISC-Prozessoren in der Regel alle Befehle komplett in einem Datenwort konstanter Länge kodiert. Dafür ist der Wertbereich und die Anzahl der Operanden dann eingeschränkt. Befehlskodierung Für die Befehlskodierung gibt es prinzipiell zwei Optimierungskriterien: • Speichereffiziente Kodierung: – Unterschiedliche Befehl kommen unterschiedlich häufig vor: ∗ Kodiere die häufigsten Befehle am kürzesten (wie Morsealphabet) ∗ Huffman-Kodierung • Geschwindigkeitseffiziente Kodierung – Unterstützt Befehlsdekodierung In den nächsten Teilabschnitten werden Ansätze für die Optimierung beider Kriterien vorgestellt. Speichereffiziente Befehlskodierung Gegeben sei ein Befehlssatz mit n Befehlen, die mit einer Häufigkeit von p1,1 , ..., p1,n auftreten. Eine kompakte Befehlskodierung kann dann mit dem folgenden Algorithmus erzeugt werden: 1. Bilde geordnete Liste L1 = mit p1,j ≥ p1,j+1 . 2. Ersetze p1,n und p1,n−1 durch p1,n + p1,n−1 und sortiere L1 neu. Dies ergibt L2 = . 3. Wiederhole Schritt (2) bis Ln−1 = . 4. Die Codes 0 und 1 werden pn−1,1 und pn−1,2 aus Ln−1 zugeordnet. 5. Wenn pn−1,k mit Code ci aus der Addition von pn−2,2 und pn−2,3 entstanden ist, weise diesen Werten in Ln−2 die Codes ci .0 und ci .1 zu. 6. Die restlichen Elemente aus Ln−2 übernehmen die Codes aus Ln−1 . Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

118

KAPITEL 2. INFORMATIONSDARSTELLUNG

7. Wiederhole (5) und (6) für n-2, ... , 1. Danach ist jedem Element pk aus L1 ein Wort zugeordnet. Dies ist die gesuchte Befehlskodierung. Beispiel Sei n= 4, p1,1 = 0,49, p1,2 = 0,26, p1,3 = 0,13 und p1,4 = 0,12. Zuerst werden p1,3 und p1,4 zu p2,3 = p1,3 + p1,4 =0,25 zusammengefasst. Mit p2,1 = p1,1 und p2,2 = p1,2 erhält man L2 . Analog wird L3 anhand von L2 gebildet. Abbildung 2.46 zeigt, wie die pi,j baumartig von links nach rechts zusammengefasst werden (Schritte (1) bis (3) im Algorithmus). Die Codes für die einzelnen Befehle erhält man nun, indem man den Graphen von rechts nach links durchläuft (Schritte (4) bis (7) im Algorithmus). Den Knoten auf oberster Ebene werden die Codes 0 und 1 zugewiesen, und an jeder Verzweigung wird jeweils 0 und 1 an den aktuellen Code angehängt. Die Codierung der Befehle 1 bis 4 kann schließlich der Ebene L1 entnommen werden.

L2

L1

L3

pi,1

0,49 1

0,49 1

0,51 0

pi,2

0,26 00

0,26 00

0,49 1

pi,3

0,13 010

0,25 01

p

0,12 011

i,4

Abbildung 2.46: Beispiel zur speichereffizienten Kodierung Geschwindigkeitseffiziente Befehlskodierung ten Kodierung haben alle Befehle möglichst

Bei einer geschwindigkeitseffizien-

• die gleiche Länge, • das gleiche Format und • in jedem Feld die gleiche Bedeutung. In diesem Fall ist eine einheitliche Dekodierung ("Fixed Field Decodierung") möglich. Bereits nach dem Lesen des Befehls sind die Operandenadressen bekannt, und die Dekodierung der Operation kann parallel zum Operandenzugriff erfolgen.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

2.2. BEFEHLSSÄTZE

119

2.2.6 Bewertung und Optimierung von Befehlssätzen Bei der Optimierung von Befehlssätzen gilt das Prinzip, dass die häufigsten Befehle am effizientesten zu implementieren sind. Der Begriff "Häufigkeit" kann dabei unterschiedlich definiert werden. Die statische Häufigkeit eines Befehls ist die Häufigkeit, mit der dieser Befehl im Programmcode vorkommt. Sie ist relevant für den Speicherbedarf eines Programmes. Die dynamische Häufigkeit ist die Häufigkeit, mit der dieser Befehl ausgeführt wird. Sie ist relevant für die Ausführungsgeschwindigkeit eines Programmes. Um die statischen und dynamischen Häufigkeiten zu ermitteln, ist es sinnvoll, die Compilerausgabe von "typischen" Programmen auszuwerten und zu simulieren. Weiterhin erhält man so einen Hinweis, welche Programmkonstrukte (Prozeduraufrufe, Variablenzugriffe) durch Hardware unterstützt werden sollten. Man wird feststellen, dass die Befehls-Häufigkeiten in der Regel exponentialverteilt sind: sehr wenige Befehle belegen den größten Teil des Speichers / der Zeit. Ein großer Befehlssatz erfordert zum einen eine große Chipfläche und reduziert zum anderen die Geschwindigkeit (Decodierung, Pipelining aufwendiger). Es kann deshalb sinnvoll sein, nur die wichtigsten und häufigsten Befehle zu implementieren. RISC und CISC Die technologischen Fortschritte bei der IC-Herstellung führten in den 70er Jahren in erster Linie dazu, dass man versuchte, immer komplexer werdende Befehlssätze zu unterstützen. Ziel war es, eine Maschine zu bauen, die direkt in einer Hochsprache programmiert werden kann („high-level-language computer architecture“, HLLCA) und so einen Compiler überflüssig macht (→ „Semantic Gap“, Schlagwort Ende der 70er Jahre). Das Problem bei solchen Prozessoren ist, dass sie auf bestimmte Programmiersprachen festgelegt sind und nicht flexibel auf Neuentwicklungen bei den Hochsprachen reagiert werden kann. Weiterhin erfordert ein aufwendiger Befehlssatz auch eine aufwendige (und damit langsame) Prozessorsteuerung. Analysiert man den Code, den ein typischer Compiler für einen CISC-Prozessor (CISC = „complex instruction set computer“) erzeugt, gelangt man i. A. zu den folgenden Ergebnissen: • Einfache Operationen und Adressierungsarten sind ausreichend. Komplexe Befehle werden von Compilern schlecht genutzt. • Kleine Werte für Konstanten und Displacement sind ausreichend. • Einen großen Teil der Zeit verbringt der Prozessor mit Prozeduraufrufen. Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

120

KAPITEL 2. INFORMATIONSDARSTELLUNG

• Die am häufigsten aufgerufenen Prozeduren besitzen nur wenige Parameter und lokale Daten. Aus diesen Analyseergebnissen resultiert das RISC-Konzept (RISC = „reduced instruction set computer“). RISC-Prozessoren sind durch die folgenden Merkmale charakterisiert: • LOAD/STORE-Architektur. Von der Ablaufsteuerung her sind Speicherzugriffe problematisch, da ihr Zeitbedarf nicht konstant ist (z.B. bei Verwendung von Caches). Dadurch, dass nur bei wenigen Befehlen (nämlich LOAD und STORE, nicht bei arithmetischen Befehlen) ein Speicherzugriff möglich ist, wird die Prozessorsteuerung vereinfacht. • Großer Registersatz, um die Anzahl an (langsamen) Speicherzugriffen zu minimieren. • Einfache Befehle, die dafür sehr schnell (möglichst in einem Takt) ausgeführt werden können. Konkret bedeutet das u.a.: – Feste Befehlslänge (z.B. 32 Bit) – Wenige Befehlsformate – Wenige, einfache Adressierungsarten Durch die Einfachheit des Befehlssatzes ist es möglich, eine kurze Zykluszeit (bzw. hohe Takfrequenz) zu erreichen und den Prozessor durch ausgeprägtes Pipelining zusätzlich zu beschleunigen.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

Kapitel 3 MIPS als RISC-Beispiel Die Befehlssätze moderner RISC-Prozessoren (z.B. PowerPC, Sparc V9, HP PARISC, ...) unterscheiden sich nicht wesentlich untereinander. In diesem Kapitel soll als repräsentatives Beispiel der MIPS R2000 vorgestellt werden (im Folgenden als MIPS bezeichnet). Der MIPS wird kommerziell gefertigt und verkauft und eignet sich sehr gut für Studienzwecke, da eine Vielzahl an Materialien wie z.B. Simulatoren für verschiedene Varianten des Prozessors (z.B. mit/ohne Pipelining, mit verschiedenen Gleitkomma-Einheiten) und auch Maschinen mit MIPS-basierten Prozessoren verfügbar sind. Die Struktur, der Befehlssatz und der Befehlszyklus des MIPS werden auch in dem Kapitel über Befehlszyklen und Unterbrechungen behandelt (siehe Kapitel 8.2).

3.1 Befehlssatz Der MIPS besitzt 30 allgemein verwendbare Integer-Register ($2 bis $31), mit deren Hilfe Ganzzahlen verschiedener Wortbreite (8, 16 oder 32 Bit) mit und ohne Vorzeichen bearbeitet werden können. Das Pseudo-Register $0 repräsentiert die Konstante 0. Es kann überall verwendet werden, wo ein Integerregister als Quelloperand erwartet wird. Das Pseudo-Register $1 ist für den Assembler reserviert und sollte nicht verwendet werden (siehe unten). Für die Behandlung von Gleitkommazahlen mit einfacher (32-Bit) oder doppelter (64 Bit) Genauigkeit besitzt der MIPS eine Gleitkommaeinheit mit einem eigenen Registersatz. Dieser besteht aus 32 Registern ($f0, ..., $f31), die entweder für Zahlen mit einfacher oder doppelter Genauigkeit genutzt werden können. Register können auch zwei Zahlen mit einfacher Genauigkeit enthalten. Hierfür bietet der MIPS eigene Befehle. Alle Befehle des MIPS lassen sich thematisch in die folgenden Befehlsgruppen unterteilen: 121

122

KAPITEL 3. MIPS ALS RISC-BEISPIEL

• Datentransfer-Befehle • Arithmetisch-logische Befehle • Sprungbefehle • Gleitkommabefehle Die einzelnen Befehlsgruppen werden in den folgenden Abschnitten genauer beschrieben. Ein vollständige Liste aller Befehle ist in Abschnitt 3.1.6 angegeben.

3.1.1 MIPS Hardwarearchitektur vs. MIPS Virtual Machine Für die Programmierung der MIPS-Architektur ist eine Virtuelle Maschine definiert. Damit ist gemeint, dass MIPS-Assembler neben den echten, in Hardware implementierten MIPS-Befehlen zusätzliche, sog. Pseudoinstruktionen verstehen. Diese werden vom Assembler automatisch durch kleine Sequenzen aus echten MIPS-Instruktionen ersetzt (als Nebeneffekt ist deshalb per Konvention das Register $1 für den Assembler reserviert). Daneben besitzen MIPS-Assembler weitere Fähigkeiten, die Instruktionen umsortieren und andere Hilfestellungen zur Assemblerprogrammierung. Wenn nichts Anderes gesagt wird, ist im Folgenden immer von den echten MIPSBefehlen die Rede und nicht von den zusätzlichen virtuellen.

3.1.2 Datentransfer-Befehle Speicherzugriffe Die Load- und Store-Befehle des MIPS unterstützen genau eine Adressierungsart, nämlich „Register-indirekt mit Displacement“. Die effektive Adresse ergibt sich aus der Summe eines Registerinhaltes mit einem konstanten Displacement. Implizit sind damit die Adressierungsarten „absolut“ und „Register-indirekt“ eingeschlossen: für die absolute Adressierung wird als Register $0 gewählt, für die Register-indirekte Adressierung wird ein Displacement von 0 eingesetzt. Oben wurde gesagt, dass der MIPS Integerzahlen mit unterschiedlicher Wortbreite (8, 16, 32 Bit) bearbeiten kann. Tatsächlich wird intern stets mit 32 Bit gerechnet, und Zahlen geringerer Wortbreite werden beim Laden vorzeichenrichtig erweitert und konvertiert. Dementsprechend gibt es die folgenden Varianten des Load-Befehls: • lbu („load byte unsigned“): ein Byte (8 Bit) wird gelesen und die oberen 24 Bit des Zielregisters werden auf 0 gesetzt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3.1. BEFEHLSSATZ

123

• lb („load byte“): ein Byte (8 Bit) wird gelesen und das Vorzeichenbit (Bit 7) wird in die oberen 24 Bit des Zielregisters kopiert. • lhu („load halfword unsigned“): wie lbu, allerdings wird ein 16-Bit-(Halb-) Wort gelesen. • lh („load halfword“): wie lb, allerdings wird ein 16-Bit-(Halb-)Wort gelesen. • lw („load word“): liest ein 32-Bit Wort. • l.s („load fp single“): liest einen Gleitkommawert mit einfacher Genauigkeit. • l.d („load fp double“) : liest einen Gleitkommawert mit doppelter Genauigkeit. Analog gibt es die Store-Befehle sb, sh, sw, s.s und s.d. Tabelle 3.1 zeigt einige Beispiele für Load- und Store-Befehle. Zur Schreibweise: Ein Ausdruck der Form xn bezeichnet das Bit n in dem Wort x. Dabei ist x0 das niederwertigste Bit. Eine Ausdruck der Form xn steht für eine n-fache Kopie des Wortes x. Das Zeichen „## “ kennzeichnet die Verkettung zweier Bitwörter. Befehl

Name

Bedeutung

lw $1, 30($2)

Load word

Regs[$1]←32 Mem[30+Regs[$2]]

lw $1,1000($0)

Load word

Regs[$1]←32 Mem[1000+0]

lh $1,40($3)

Load half word

Regs[$1]←32 (Mem[40+Regs[$3]]15 )16 # # Mem[40+$egs[$3]]

lb $1,40($3)

Load byte

Regs[$1]←32 (Mem[40+Regs[$3]]7 )24 # # Mem[40+Regs[$3]]

lbu $1,40($3)

Load byte unsigned

Regs[$1]←32 024 # # Mem[40+Regs[$3]]

l.s $f0,50($3)

Load float

Regs[$f0]←32 Mem[50+Regs[$3]]

l.d $f0,50($2)

Load double

Regs[$f0]# # Regs[$f1]←64 Mem[50+Regs[$2]]

sw $3, 500($4)

Store word

Mem[500+Regs[$4]]←32 Regs[$3]

Tabelle 3.1: Beispiele für Load- und Store-Befehle des MIPS Bei den Load und Store-Befehlen muss die effektive Adresse ausgerichtet sein, d.h. sie muss z.B. bei lh.../sh... durch 2 und bei lw/sw durch 4 teilbar sein. Abbildung 3.1 zeigt, welche Adressen je nach Wortbreite erlaubt sind. Bei einem Datenbus von 32 Bit können nicht ausgerichtete Adressen zwei Speicherzugriffe nötig machen. Anders als manche anderen Prozessoren (z.B. der Intel Pentium) besitzt der MIPS keine spezielle Logik, um diesen Fall aufzulösen.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

124

KAPITEL 3. MIPS ALS RISC-BEISPIEL

0 1 2 3 4 5 6 7 Byte Halbwort

Wort

Abbildung 3.1: Ausgerichtete Speicherzugriffe Datentransfer zwischen Registern Es gibt eine Reihe von Befehlen für den Datentransfer: • Datenaustausch mit den Coprozessoren (z. B. mit der Floating Point Unit): mfc1.d, mtc1.d (move from coprocessor, move to coprocessor) • Datenaustausch mit den Spezialregistern lo und hi(die Befehle mul und div legen Ergebnisse in diesen Registern ab, s.u.): mfhi, mflo, mthi, mtlo Es gibt jedoch keine Befehle • zum Transfer zwischen zwei Integer-Registern. In der virtuellen Maschine ist dazu die Pseudo-Instruktion move definiert, die vom Assembler in addu von Quellregister und $0 ins Zielregister umgesetzt wird. • Konstanten in Register laden. Einige Alu-Operationen wie ori und addi haben 16-Bit immediate Operanden, durch ori $x, $0, const kann also beispielsweise eine 16-Bit-Konstante in ein beliebiges Register x geladen werden. Die oberen 16 Bit können vorher, falls nötig (in der Praxis kommen häufig kleine Konstanten vor) mit Hilfe des Befehls lui geladen werden. Die in der virtuellen Maschine definierte Pseudo-Instruktion li wird vom Assembler nach diesem Schema umgesetzt.

3.1.3 Arithmetisch-logische Befehle Beim MIPS wird ein 3-Adress-Konzept verfolgt, d.h. jeder ALU-Befehl besitzt einen Ziel- und zwei Quelloperanden. Der Ziel- und der erste Quelloperand sind dabei stets Register, der zweite Quelloperand kann ein Register oder ein 16-Bit Direktwert sein. Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3.1. BEFEHLSSATZ

125

Die unterstützten Operationen lassen sich wie folgt gruppieren: • arithmetische Operationen: add, sub, mult, div • logische Verknüpfungen: and, or, ... • Schiebeoperationen (rechts/links, arithmetisch/logisch): srl, sra, sll, ... • Vergleichsoperationen: slt („set on less than“) Bei den Befehlen mult und div gibt es eine Besonderheit: Die Befehle haben nur zwei Register als Operanden und legen das Ergebnis in den Spezialregistern lo und hi ab. Im Falle von mult liegen im lo-Register die unteren und im hi-Register die oberen 32 Bit des Ergebnisses. Im Fall von div enthält lo den Quotient und hi den Rest. Mit Schiebebefehlen ist es möglich, Registerinhalte um eine beliebige Anzahl von Bitstellen nach links bzw. rechts zu verschieben. Man unterscheidet zwischen arithmetischem und logischem Schieben. Beim logischen Schieben werden die hereingeschobenen Stellen stets mit 0 aufgefüllt, beim arithmetischen Schieben nach rechts werden sie mit dem Vorzeichenbit aufgefüllt. Arithmetisch betrachtet bedeutet das Schieben um eine Stelle nach rechts die „Halbierung” des Wertes (genauer: sra x = x div 2). Beim sra-Befehl („shift right arithmetically“) bleibt diese Eigenschaft auch für Zweierkomplementzahlen bestehen. Die Zahl 111101102 hat z.B. den Wert -10. Arithmetisch nach rechts geschoben ergibt sich 111110112 = -5, schiebt man logisch, so erhält man 011110112 = 123. Zur Unterstützung von bedingten Sprüngen kennt MIPS lediglich eine Operation slt. Diese vergleicht die beiden Quelloperanden und schreibt in das Zielregister eine 1, falls die Bedingung wahr ist, d. h. der erste Quelloperand kleiner als der zweite ist. Andernfalls wird in das Zielregister der Wert 0 geschrieben. ALU-Befehle können dazu genutzt werden, Daten zwischen Integerregistern zu verschieben bzw. Integerregister mit einem Direktwert zu laden. Der Befehl add $2, $0, $3 kopiert z.B. den Inhalt von $3 nach $2 und der Befehl ori $2, $0, 5 lädt $2 mit der Konstanten 5. Das Laden von 32-Bit-Konstanten ist mit dem Befehl lui („load upper immediate“) möglich. Er lädt eine 16-Bit-Konstante in die oberen 16 Bit des Zielregisters und löscht die unteren 16 Bit. So ist es möglich, mit zwei aufeinanderfolgenden Befehlen der Form lui $2, Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

126

KAPITEL 3. MIPS ALS RISC-BEISPIEL

add $2, $2, eine beliebige 32-Bit-Konstante in ein Register zu laden. Tabelle 3.2 zeigt einige Beispiele für arithmetische und logische Befehle. Befehl

Name

Bedeutung

add $1,$2,$3 addi $1,$2,3 or $1,$2,$3 sll $1,$2, 5 slt $1,$2,$3

Add Add immediate Or Shift left logical Set less than

Regs[$1]←Regs[$2]+Regs[$3] Regs[$1]←Regs[$2]+3 Regs[$1]←Regs[$2] ∨ Regs[$3] Regs[$1]←Regs[$2]< $3 ? # $2 < $4 ? # logisches UND # Sprung, falls NEIN

$5, $0, 5

A LTERNATIVE B: slt beq nop slt beq nop then: addi cont: ....

$10, $2, $3 $10,$0, cont

# $2>$3 ? # Sprung, falls NEIN

$10, $2, $4 # $2 < $34? $10, $0, cont # Sprung, falls NEIN $5, $0, 5

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

130

KAPITEL 3. MIPS ALS RISC-BEISPIEL

3. Dieses Beispiel, welches die Speicherzellen 100-199 mit ‘0’ füllt, soll die Benutzung einer Schleife deutlich machen: add loop: addi sw bnez nop

$2, $2, $0, $2,

$0, 100 # $2:= 100 $2, -4 # $2 erniedrigen 100 ($2) loop # Sprung solange $26=0

4. Mit diesem Beispiel wird die Verwendung von Unterprogrammen verdeutlicht: trans: add sub jr nop main:

$2, $2, $4 $3, $3, $4 $31

addi $2, $0, 5 addi $3, $0, 7

# Unterprogramm # $4 zu $2 addieren # $4 von $3 abziehen # Rücksprung # Hauptprogramm # $2=5 # $3=7

... addi $4, $0, 3 jal trans nop

# $4 mit 3 laden # -> $2 = 8, $3 = 4

... 5. Für die Verwaltung von lokalen Variablen und Parametern in Aktivierungsblöcken (s. Kapitel 2.2 über Befehlssätze) erzeugt ein Compiler sogenannten Prozedur-Eintritts- und Austrittscode. Abbildung 3.3 zeigt ein PascalProgrammfragment und den konkreten Aufbau des Aktivierungsblocks der Prozedur A. procedure Main; var i,j,k: integer; r: real; procedure A (x: integer); var j,l,m: integer; begin ... end;

SP´-28

SP´-16 SP´-12 SP´-8 SP´-4

begin ... end;

← SP

j l m ← PP Dynamischer Zeiger Statischer Zeiger Rücksprungadresse x ← SP´ Vorhergehender Aktivierungsblock

Abbildung 3.3: Programm-Beispiel und zugehöriger Aktivierungsblock Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3.1. BEFEHLSSATZ

131

Für die Verwaltung des Aktivierungsblocks reserviert der Compiler einige ProzessorRegister, z.B.: $29

- Stackpointer (sp)

$20

- aktueller dynamischer Zeiger (fp), Zugriff auf x, j, l, m

$28

- aktueller statischer Zeiger (gp), Zugriff auf i, j, k, r

Der Eintritts- und Austrittscode für die lauten: procA: sw $31, -8($20) sw $22, -12($20) sw $21, -16($20) addi $21, $20, -16 addi $20, $20, -28 .... addi lw lw lw jr nop

$20, $21, $22, $31, $31

$20, 28 -16($20) -12($20) -8($20)

Prozedur A in Abbildung 3.3 könnte dann # Rücksprungadresse speichern # statischen Zeiger speichern # dynamischen Zeiger (alten FP) # speichern # FP setzen - in Abbildung 3.3 mit PP # gekennzeichnet # SP setzen, Platz für lokale Variablen # schaffen # Rumpf der Prozedur # SP restaurieren # dynamischen Zeiger restaurieren # statischen Zeiger restaurieren # Rücksprungadresse lesen # Rücksprung

3.1.5 Gleitkomma-Befehle Die Gleitkomma-Einheit des MIPS beherrscht die vier Grundrechenarten und bearbeitet wahlweise Daten einfacher (32-Bit) oder doppelter (64-Bit) Genauigkeit. Der Befehl mul.x $f0, $f1, $f2 multipliziert z.B. die Inhalte der Register $f1 und $f2 mit einfacher/doppelter Genauigkeit und schreibt das Ergebnis in das Register $f0. In Abschnitt 3.1.2 wurden bereits Befehle zum Transfer zwischen Gleitkomma- und Integer-Registern angesprochen. Diese Befehle kopieren ein Datenwort bitweise und es wird keinerlei Konvertierung vorgenommen. Um zwischen verschiedenen Zahlendarstellungen zu konvertieren gibt es Befehle der Form cvt.x.y, wobei x und y stehen können für:

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

132

KAPITEL 3. MIPS ALS RISC-BEISPIEL

• w - Integerzahl • f - Gleitkommazahl mit einfacher Genauigkeit • d - Gleitkommazahl mit doppelter Genauigkeit Analog zum slt-Befehl gibt es Vergleichsbefehle für Gleitkommazahlen (z.B. c.lt.x, c.le.x, c.eq.x mit x∈{ s, d }). Der Befehl c.lt.s $f0, $f1 prüft z.B., ob $f0 < $f1 ist und speichert das Ergebnis in einem Flag, das von den bedingten Sprungbefehlen bc1t („branch on floating point true“) oder bc1f („... false“) abgefragt werden kann. Konvertierung zwischen Floatingpoint- und Integerdaten Die oben erwähnten Befehle zur Konvertierung zwischen Floatingpoint- und Integerdaten werden auf Floatingpointregister angewandt, die Integerdaten müssen also zunächst in das Floatingpointregister kopiert und dort dann konvertiert werden, wie beispielsweise in Abbildung 3.4 zu sehen ist. l.s $f0, 36($fp) cvt.d.w $f0, $f0 Abbildung 3.4: Konvertierung von Integer nach Double Beispiel Das folgende Programmfragment berechnet den Wert des Bruchs 13/7: addi mtc1.s cvt.s.w addi mtc1.s cvt.s.w div.s

$2, $0, 13 $f1, $1 $f2, $f1 $2, $0, 7 $f1, $2 $f3, $f1 $f1, $f2, $f3

# $2 mit 13 laden # $2 nach $f1 kopieren # $f1 in float wandeln => $f2 # $2 mit 7 laden # $2 nach $f1 kopieren # $f1 in float wandeln => $f3 # Division durchführen # Ergebnis steht in $f1

Um die Division durchführen zu können, müssen die Operanden in FP-Registern stehen. Der Befehl cvt.s.w (Convert Integer to Single) erwartet allerdings zwei FP-Register, also müssen die Integer-Zahlen erst in die FP-Register kopiert (mittels mtc1.s) und danach konvertiert werden. Erst jetzt ist die Division korrekt durchführbar. Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3.1. BEFEHLSSATZ

133

3.1.6 Zusammenfassung des MIPS-Befehlssatzes In Tabelle 3.4 - Tabelle 3.7 ist eine vollständige Übersicht aller MIPS-Befehle dargestellt. Dabei steht $x/$y/$z für Integer-Register, $fx/$fy/$fz für FließkommaRegister, n für eine natürliche Zahl und # n für eine Konstante. Befehl lb sb lw sw lui mfhi mflo

$x, $x, $x, $x, $x, $x $x

$y(n) $y(n) $y(n) $y(n) n

Bedeutung

Bemerkung

Load byte Store byte Load word Store word Load upper immediate Move hi Move lo

$x=hi $x=lo

Tabelle 3.4: Datentransfer-Befehle

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

134

KAPITEL 3. MIPS ALS RISC-BEISPIEL

Befehl add addu addi sub subu mult

$z, $z, $z, $z, $z, $x,

multu

$x, $y

Multiply (unsigned)

div

$x, $y

Divide (signed)

divu

$x, $y

Divide (unsigned)

and andi ori ori xor xori lui

$z, $z, $z, $z, $z, $z, $y,

sll

$z, $x, Sa

Shift left logical

sllv

$z, $x, $y

Shift left logical

srl, sra srlv

$z, $x, Sa $z, $x, $y

Shift right logical, Shift right arithmetic Shift right logical

slt

$z, $x, $y

Set less than (signed)

slti

$z, $x, Imm

sltu

$z, $x, $y

Set less than (signed, immediate) Set less than (unsigned)

$x, $x, $x, $x, $x, $y

$x, $x, $x, $x, $x, $x, Imm

$y $y Imm $y $y

$y Imm $y Imm $y Imm

Bedeutung

Bemerkung

Add Add (unsigned) Add immediate (signed) Subtract (signed) Subtract (unsigned) Multiply (signed)

$z=$x+$y $z=$x+$y $z=$x+Imm $z=$x-$y $z=$x-$y hi, lo = $x*$y (hi = high 32 bits, lo = low 32 bits) hi, lo = $x*$y (hi = high 32 bits, lo = low 32 bits) lo = $x/$y, hi = $x mod $y (integer division) lo = $x/$y, hi = $x mod $y (integer division) $z = $x • $y $z = $x \bullet Imm $z = $x + $y $z = $x + Imm $z = $x ⊕$y $z = $x \oplus Imm $y[31:16]=Imm, $y[15:0]=0 $z = $x left shifted by Sa bits $z = $y left shifted by $x bits $z = $x right shifted by Sa bits $z = $y right shifted by $x bits $z = 1 if $x < $y, $z = 0 if $x >= $z $z = 1 if $x < Imm, $z = 0 if $x >= Imm $z = 1 if $x < $y, $z = 0 if $x >= $z

And And (immediate) Or Or (immediate) exclusive or exclusive or Load immediate (unsigned)

Tabelle 3.5: Arithmetisch-logische Befehle Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3.1. BEFEHLSSATZ Befehl beq

135 Bedeutung

bgez bgezal bgtz blez blezal

$x, $y, label $x, label $x, label $x, label $x, label $x, label

bltzal

$x, label

bltz bne j jal

$x, label $x, $y, label label label

jr

$x

jalr

label

Bemerkung

Branch to label if $x == $y Branch to label if $x >= 0 (signed) Branch to label and link if $x>=0 Branch to label if $x > 0 (signed) Branch to label if $x = 0 (signed) Branch to label and link if $x < 0 (signed) Branch to label if $x < 0 (signed) Branch to label if $x \neq $y Jump to label unconditionally Jump to label and link unconditionally Jump to location in $x unconditionally Jump to location in $x and link unconditionally

Tabelle 3.6: Sprungbefehle

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

136

KAPITEL 3. MIPS ALS RISC-BEISPIEL

Befehl abs.d

$fz, $fx

abs.s

$fz, $fx

add.d

$fz, $fy $fz, $fy $fz, $fz, $fz, $fz, $fz, $fz, $fz, $fz, $fz, $fz, $fz, $fz, $fz, $fy $fz, $fy $fz, $fz, $fz, $fz, $fz, $fy $fz, $fy $fz, $fz, $fz, $fz, $fz, $fy $fz, $fy

add.s c.eq.d c.eq.s c.le.d d.cle.s c.lt.d c.lt.s cvt.d.s cvt.d.w cvt.s.d cvt.s.w cvt.w.d cvt.w.s div.d div.s l.d l.s mov.d mov.s mul.d mul.s neg.d neg.s s.d s.s sub.d sub.s

Name

$fx,

Floating Point Absolute Value (Double) Floating Point Absolute Value (Single) Floating Point Addition (Double)

$fx,

Floating Point Addition (Single)

$fx $fx $fx $fx $fx $fx $fx $fx $fx $fx $fx $fx $fx,

Compare Equal (Double) Compare Equal (Single) Compare Less Than Equal (Double) Compare Less Than Equal (Single) Compare less than (Double) Compare less than (Single) Convert Single to Double Convert Integer to Double Convert Double To Single Convert Integer to Single Convert Double to Integer Convert Single to Integer Floating Point Divide (Double)

$fx,

Floating Point Divide (Single)

$fx $fx $fx $fx $fx,

Load Floating Point (Double) Load Floating Point (Single) Move Floating Point (Double) Move Floating Point (Single) Floating Point Multiply (Double)

$fx,

Floating Point Multiply (Single)

$fx $fx $fx $fx $fx,

Negate (Double) Negate (Single) Store Floating Point (Double) Store Floating Point (Single) Floating Point Substract (Double)

$fx,

Floating Point Substract (Single)

Bedeutung

Tabelle 3.7: Gleitkomma-Befehle Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3.2. MIPS-ASSEMBLER UND -SIMULATOR

137

3.2 MIPS-Assembler und -Simulator Für die praktischen Übungsaufgaben über den MIPS ist auf den Rechnern des Instituts für Technische Informatik ein MIPS-Simulator mit integriertem Assembler „SPIM“ installiert. Eine vollständige Anleitung zu SPIM („SPIM S20: A MIPS R2000 Simulator“) ist über die Webseiten des Instituts verfügbar. Eine Einführung in die Bedienung mit erläuternden Beispielen wird in den folgenden beiden Abschnitten gegeben.

3.2.1 Assembler Ein Assembler übersetzt ein Maschinenprogramm in textueller Darstellung in eine binäre Form, die vom Prozessor gelesen und ausgeführt werden kann (s. Abbildung 3.5). Eine Assembler-Datei kann mit einem beliebigen Texteditor (z.B. ‘emacs’, ‘vi’ oder die mitgelieferten Editoren der Desktopumgebungen KDE und GNOME) erstellt werden. Label

Befehl/Direktive

main:

li $5, 4

Assembler-Umsetzung

Maschinencode

ori $5, $0, 4

0x34050004

.text

li $2, size

sll $2, $2, 2

loop:

lui $1, 4097 [size]

0x3c011001

lw $2, 0($1) [size]

0x8c220000

sll $2, $2, 2

0x00021080

move $4, $0

addu $4, $0, $0

0x00002021

addi $2, $2, -4

addi $2, $2, -4

0x2042fffc

lw $3, array ($2)

lui $1, 4097 [array]

0x3c011001

addu $1, $1, $2

0x00220821

lw $3, 4($1) [array]

0x8c230004

add $4, $4, $3

add $4, $4, $3

0x00832020

bne $2, $0, loop

bne $2, $0, -20 [loop-0x0040004c]

0x1440fffb

nop

nop

0x00000000

.align 4 .data size:

.word 4

0x00000004

array:

.word 42, 23, 26,4711

0x00000042 0x00000023 0x00000026 0x00004711

Abbildung 3.5: Assemblerprogramm und zugehöriger Maschinencode

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

138

KAPITEL 3. MIPS ALS RISC-BEISPIEL

Befehle und Operanden werden genauso geschrieben, wie sie in Kapitel 2.2 eingeführt wurden. Konstanten werden per Default zur Basis 10 angegeben, für Hexadezimalzahlen muss „0x” vorangestellt werden (beispielsweise bezeichnen 256 und 0x100 den gleichen Wert). Zur Eingabe von Daten und um anzugeben, wie das Programm und die Daten in dem SPIM-Speicher abgelegt werden sollen, gibt es eine Reihe von Assembler-Direktiven, die anstelle von MIPS-Befehlen in der Assembler-Datei auftreten können. Die wichtigsten Direktiven sind: Gibt die Anfangsadresse des Programmes

.text :

an. .data :

Gibt die Anfangsadresse für Daten an.

.byte / .word / .ascii / .float/ .double

Fügt Daten in verschiedenen Formaten in den Datenbereich ein reserviert Bytes im Datenbereich.

.space :

Einige Beispiele für Assembler-Direktiven sind: .text

0x100

# alle Befehle werden ab 10016 abgelegt # alle Daten werden ab 20016 abgelegt

.data

0x200

.byte

15, 63, 255

.double

1.2, 3.1415926535

.space

1024 1024

# Bytes freihalten

Moderne Assembler kennen auch Macros, beispielsweise durch Direktiven wie .macro und .endmacro. Da diese Direktiven von spim nicht unterstützt werden, haben sie für die Rechnerübungen keine praktische Bedeutung. Die Funktionsweise ist im folgenden Programmausschnitt dargestellt: .macro

djnz (reg,label) sub

reg, reg, 1

bnez reg, label

reg, label

nop .endmacro ... djnz

$4, loop



addi

$4, $4, -1

bnez

$4, loop

nop

Um dem Programmierer die Eingabe von absoluten oder relativen Adressen bei Datenzugriffen und Sprüngen zu erleichtern, können Labels verwendet werden. Ein Label ist eine Folge von Buchstaben, Ziffern und den Zeichen ‘_’ und ‘$ ’, wobei das erste Zeichen keine Ziffer sein darf. Ein Ausdruck der Form :

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3.2. MIPS-ASSEMBLER UND -SIMULATOR

139

ordnet dem Label die Adresse des/der hinter dem Doppelpunkt stehenden Befehls/Direktive zu. Auf diese Adresse kann später unter Verwendung des Labelnamens zugegriffen werden. Abbildung 3.6 zeigt, wie der Assembler Labels in absolute oder relative Adressen umsetzt. a) absolute Adressierung .data 0x100 size: .word 4 array:.word 3, 17, 19, 2

⇒ size = 0x0100 ⇒ array = 0x0104

... r2, array (r1) → lw r2, 0x0104(r1) → 0x8x220104

lw

b) relative Adressierung (0x0210) loop: sub

r1, r1, #4

... (0x0228) (0x022c)

bnez

r1, loop

0x1420ffe4

loop = 0x0210 0x0210 - 0x022c = -0x1c im 2er-Komplement (16 Bit): 0xffe4

Abbildung 3.6: Auflösung von Labels Kommentare in Assemblerdateien beginnen mit einem ‘#’ und enden mit dem Zeilenende. Arithmetische Ausdrücke, welche vom MIPS-Assembler unterstützt werden, sind Konstanten, die mit Operatoren verknüpft werden können. Konstanten können sein: • Dezimalzahlen, z.B. 3, -7, 0, ... • Hexadezimalzahlen, z.B. 0x3e, 0xffff, ... • Labels Negative Zahlen werden automatisch ins 2er-Komplement gewandelt, und Gleitkommazahlen werden nach dem IEEE-Standard kodiert. Operatoren können sein: Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

140

KAPITEL 3. MIPS ALS RISC-BEISPIEL

• Grundrechenarten: +, -, *, /, % (modulo) • logische Op.: & (und), | (oder), ˆ (xor) • Schieben: < > • Klammerung: (, ) Einige Beispiele zu arithmetischen Ausdrücken sind in Abbildung 3.7 dargestellt.

.data first: .word last: .word ... add lhi add

0x100 1,2,3,4,5,6 7 $2, $0, (last-first)/4+1 # =7 $4, 1000000 > > 16 # = 0xf $4, $4, 1000000 % 65536 # = 0x4240

Achtung: Alle Ausdrücke werden beim Assemblieren aufgelöst und dürfen nur Konstanten bzw. Labels enthalten! Falsch Richtig add $4, $2, $3 + 7 add $3, $3, 7 add $4, $2, $3 Abbildung 3.7: Beispiele zu arithmetischen Ausdrücken Abbildung 3.8 zeigt eine vollständige Assemblerdatei. Als Übung sollte der Leser versuchen, zu beschreiben, was das dargestellte Programm tut. Die Auflösung wird in Abschnitt 3.2.2 gegeben.

Label .data .double a: x: .double xtop:.double .text l.d add loop: l.d

Start des Datenbereichs 0x0000 3.14159 1,2,3,4,5 42 Start des Programmbereichs Kommentarzeichen $f2, a $2,$0,xtop # $2 mit d Adresse von "xtop" laden $f0,0($2)

Abbildung 3.8: Beispiel für eine Assembler-Datei

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3.2. MIPS-ASSEMBLER UND -SIMULATOR

141

3.2.2 Cross-Simulation Die meisten Leser werden sicherlich schon das eine oder andere Computerprogramm selbst geschrieben haben. Vermutlich sind diese Programme auf dem gleichen Computer entwickelt worden, auf dem sie laufen sollten. Der Entwicklungsfluss ist in Abbildung 3.9 dargestellt. Das geschriebene Programm wird mit einem Assembler oder Compiler (bei Hochsprachen) übersetzt. Es entsteht ausführbarer Code, den man einfach laufen lässt, um die Korrektheit und die Leistungsfähigkeit zu überprüfen. Assembler−Programm/ Programm in Hochsprache

Assembler/ Compiler

Maschinencode

Abbildung 3.9: Software-Entwicklung auf dem Zielsystem Es kann aber auch vorkommen, dass bei der Software-Entwicklung das Zielsystem überhaupt nicht zur Verfügung steht. Ein Software-Hersteller, der seine Programme für ein neues Rechnersystem oder eine neue Prozessorvariante auf den Markt bringen will, muss mit der Software-Entwicklung so früh wie möglich beginnen, andernfalls würde er wertvolle Marktanteile an die Konkurrenz verlieren. Auf die Produktionsreife der Hardware kann er meist nicht warten. Um Software für einen noch nicht verfügbaren Prozessortyp zu schreiben, wird ein Simulator verwendet, der zum einen den Befehlssatz und das Verhalten des Zielsystems simuliert und zum anderen statistische Daten sammelt, mit denen man z.B. bestimmen kann, wie lange die Ausführung eines Programmes auf einem realen Zielsystem dauern würde. Dieser Entwicklungsfluss ist in Abbildung 3.10 dargestellt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

142

KAPITEL 3. MIPS ALS RISC-BEISPIEL Assembler−Programm/ Programm in Hochsprache

Cross−Assembler/ Cross−Compiler

MIPS−Maschinencode

Simulator

Ausgabedaten Statistiken

Abbildung 3.10: Software-Entwicklung auf einem Fremdsystem Für die Übungsaufgaben ist sowohl eine echte MIPS-Maschine als auch der Simulator SPIM verfügbar. SPIM ist kommandozeilenorientiert. Zusätzlich ist auf den Rechnern des Instituts ein graphisches Front-End "xspim" installiert, dessen Benutzung dringend zu empfehlen ist. Ein Screenshot ist in Abbildung 3.11 zu sehen. Das Frontend wird von der Kommandozeile mit einem Aufruf wie xspim -nopseudo -delayed_branches -delayed_loads -file foo.s gestartet.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

3.2. MIPS-ASSEMBLER UND -SIMULATOR

143

Abbildung 3.11: Graphisches Frontend xspim Einige Hinweise zu SPIM: • das step-Kommando / -Button (xspim) ist zum Debuggen von Programmen sehr nützlich • SPIM stellt eine Art einfachst-Betriebssystem zur Verfügung, das über die Pseudo-Instruktion syscall Funktionen zur Verfügung stellt. Im Register $2 wird dabei die Nummer des gewünschten Systemrufs übergeben, beispielsweise entspricht Systemruf 4 der Funktion print_string, Systemruf 1 der Funktion print_int. In Register $4 wird der Operand (Adresse des Strings im Speicher bzw. der Auszugebende Zahlenwert in diesem Fall) übergeben. Beispiel für print_int: li $2, 1 # print_int auswählen li $4, 42 # auszugebender Zahlenwert syscall # Systemruf

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

144

KAPITEL 3. MIPS ALS RISC-BEISPIEL

Eine vollständige Beschreibung aller Simulatorbefehle findet man in der Anleitung „SPIM S20: A MIPS R2000 Simulator“, die über die Webseite des Instituts verfügbar ist.

3.2.3 Praktische Hinweise Zum Abschluss sei der Leser an die folgenden Fallstricke erinnert: 1. $0 ist kein Register, sondern repräsentiert die Konstante 0 (vgl. Kapitel 3.1). 2. Es gibt keine Befehle, um Konstanten in Integer-Register zu laden, bzw. um Daten zwischen Integer-Registern zu verschieben. Stattdessen müssen arithmetische Befehle verwendet werden (vgl. Kapitel 3.1.5). 3. Bei der Multiplikation und Division von Integer-Zahlen werden die Ergebnisse in den Spezialregistern hi und lo abgelegt (vgl. Kapitel 3.1.3). 4. Adressen und Konstanten können nur mit einer geringeren Wortbreite als 32 Bit direkt geladen werden (vgl. Kapitel 3.1.3). 5. Es sind nur ausgerichtete Speicherzugriffe erlaubt (vgl. Kapitel 3.1.2). Andernfalls tritt zur Laufzeit eine Unterbrechung auf und das Programm kann nicht weiter ausgeführt werden. Man beachte, dass dabei die effektive Adresse ausschlaggebend ist. Um den Befehl lw $2, 17 ($3) ausführen zu können, muss $3 also 3, 7, 11, . . . enthalten, was bedeutet, dass die effektive Adresse wegen des Befehls lw durch 4 teilbar sein muß. 6. Bedingt durch Pipelining wird jeder auf einen Sprungbefehl folgende Befehl ausgeführt („delayed branching“). Um nächtelange Fehlersuchen zu vermeiden, sollte man sich anfangs angewöhnen, hinter jedem Sprungbefehl ein nop einzufügen (vgl. Kapitel 3.1.4).

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

Kapitel 4 Arithmetisch-logische Grundelemente 4.1 Fläche und Geschwindigkeit Die beiden wichtigsten Kriterien, nach denen eine Schaltung (z.B. eine spezielle Implementierung eines Addierers) beurteilt wird, sind die Größe (Bedarf an Chipfläche) und die Geschwindigkeit. Allgemein besteht jede Schaltung aus getakteten Speicherelementen (Flipflops) und Schaltnetzen. Die maximale Betriebsfrequenz (bzw. die minimale Schaltzeit TC ) hängt im wesentlichen von der Verzögerung des Schaltnetzes ab (s. Abbildung 4.1). Eingangsregister

Ausgangsregister

Schaltnetz

C1

C2

C1 C2 T0

TC

T1

Abbildung 4.1: Minimale Schaltzeit

4.1.1 Gatterverzögerung Die Verzögerung eines einzelnen Gatters setzt sich zusammen aus einer internen Schaltzeit und einer relativen Verzögerung. Beide Größen hängen von den elektrischen 145

146

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

Eigenschaften des Gatters ab, die relative Verzögerung zusätzlich von der zu treibenden Last und der Leitungskapazität. Die Schaltzeiten lassen sich näherungsweise durch vier Kenngrößen beschreiben. Die Parameter tplh und tphl beschreiben die interne Verzögerung, wenn der Ausgang von 0 nach 1 (low→high) bzw. von 1 nach 0 (high→low) übergeht. Analog beschreiben ∆tplh und ∆tphl die externe Verzögerung relativ zu der zu treibenden Last (einschließlich Leitungskapazitäten). Abbildung 4.2 zeigt die Beschreibung eines Bibliothekselementes. Für alle Größen ist der minimale („min“), der maximale („max“) und der typische zu erwartende Wert („typ“) angegeben. Die Spalte „mil“ enthält Abschätzungen, die noch pessimistischer als die „max“-Werte sind. Mit diesen Werten wird im militärischen Bereich gearbeitet, wo ein besonderes Maß an Robustheit und Zuverlässigkeit erwartet wird.

INVERTER

A

Y INV

Y=A Parameter

Value

Unit

Size Cin_A Fanout_Y total cap transistors

14.4 - 76.0 0.14 1.43 0.17 4

µm2 pF pF pF

Parameter tplh tphl ∆tplh ∆tphl

from

to

min

typ

max

mil

Unit

any any any any

Y Y Y Y

0.23 0.16 0.41 0.35

0.55 0.39 0.97 0.85

1.09 0.79 1.91 1.66

1.32 0.92 2.31 2.0

ns ns ns/pF ns/pF

Abbildung 4.2: Beschreibung eines Bibliothekselementes: INV Aus den Verzögerungen einzelner Gatter kann die Verzögerung eines ganzen Netzes bestimmt werden. Dies soll an einem Beispiel erläutert werden. Angenommen, in der Schaltung von Abbildung 4.3 ändert sich der Pegel eines Einganges des XOR-Gatters von 0 nach 1. Die Leitungskapazitäten seien vernachlässigbar klein. Die Zeit, die vergeht, bis das Flipflop seinen Zustand wechseln kann, errechnet sich wie folgt: tlh

= = = =

tXOR + tAN 2 + SF Fsetup tplhXOR + ∆tplhXOR · CinAN 2 + tplhAN 2 + ∆tplhAN 2 · CinSF F + SF Fsetup 2, 95ns + 1, 88 · 0, 08ns + 1, 92ns + 1, 64 · 0, 1ns + 5, 1ns 10, 28ns

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.1. FLÄCHE UND GESCHWINDIGKEIT

147

Dabei ist SF Fsetup die Zeit, für die das Signal an dem Flipflop-Eingang stabil anliegen muss, bis es durch einen Taktwechsel übernommen werden kann. 0 0 1

S

=1

&

SFF1 Q1 S=0 S=1 CK

QZ

Abbildung 4.3: Netz-Verzögerungen Man beachte, dass in diesem Beispiel nur ein möglicher Signalwechsel für einen einzelnen Pfad analysiert wurde. Um die maximal mögliche Taktfrequenz einer Schaltung zu ermitteln, müssen jedoch sämtliche möglichen Signalwechsel und alle Pfade betrachtet werden. Das ist in der Praxis nicht ohne weiteres möglich, denn die Zahl der Signalwechsel steigt exponentiell mit der Zahl der Eingänge und die Anzahl der Pfade evtl. exponentiell mit der Anzahl der Gatter. Mit dem Problem, trotzdem eine realistische Abschätzung für maximale mögliche Verzögerung zu erhalten, beschäftigen sich die nächsten Abschnitte.

4.1.2 Schaltungsmodellierung Signale werden von den Schaltnetzeingängen zu den Ausgängen über Pfade weitergeleitet. Die Gesamtverzögerung wird bestimmt durch die Zahl der Bauelemente und die zu treibenden Lasten auf dem Pfad. Eine Schaltung lässt sich durch einen Graph modellieren. Definition 3.1: Ein Schaltungsgraph G := (V, E) ist ein gerichteter Graph mit den Knoten V und den Kanten E ⊂ V × V . V := VC ∪ VS ∪ I ist eine disjunkte Vereinigung kombinatorischer Knoten VC , sequentieller Knoten VS und Eingänge I. Abbildung 4.4 zeigt ein Schaltwerk und den zugehörigen Schaltungsgraph. Dabei ist: I VC VS

= = =

{PI1, PI2, PI3, PI4, PI5} {K1, K3, K4, K7, K8, K11, PO2, PO3} {K2, K5, K6, PO1, K12}

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

148

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

Schaltwerk:

PI1

&

PI2 PI3 PI4

& K1 D

≥1 K3 K2

>C

=1

PI5

K4

PO1

K7

1

D >C

D K5 >C D K6 >C

PO2

& K11 D >C

K8

1

1

PO3

K12

C LOCK

Schaltungsgraph:

K7

PI1

PI2

PI3

K3

K1

PI4

PO2

PO1

K5

K2

K11

K4

K6

K12

PO3

K8

PI5

Abbildung 4.4: Schaltwerk und Schaltungsgraph Neben dem Schaltungsgraph gibt es zu jeder Schaltung auch einen Schaltnetzgraph, der keine sequentiellen Knoten enthält. Er entsteht aus dem Schaltungsgraph, indem jeder sequentielle Knoten aus VS durch jeweils einen neuen Ein- und Ausgangsknoten ersetzt wird.

4.1.3 Sensibilisierbare Pfade Sei G = (V, E) ein Schaltungsgraph und Π :=< k0 , k1, ..., ki >mit < kj−1 , kj >∈ E ein Pfad. Ein Ereignis ej ist ein Signalwechsel (1 → 0 oder 0 → 1) am Knoten kj . Man sagt, das Ereignis ej pflanzt sich fort, wenn es ein Ereignis ej+1 an kj+1 verursacht. Ob sich ein Ereignis durch ein Gatter fortpflanzt, hängt von der Belegung der übrigen Gattereingänge ab. Abbildung 4.5 zeigt zwei Situationen, in denen ein Pfad durch ein Gatter blockiert oder sensibilisiert wird.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.1. FLÄCHE UND GESCHWINDIGKEIT

ej-1 sensibilisiert:

ej-1 blockiert: 0 & kj-1 0→1: ej-1

149

1

1 & kj-1 0→1: ej-1

1→0: ej

Abbildung 4.5: Ereignisse an einem Gatter Ein Pfad von einem Primäreingang zu einem Primärausgang heißt sensibilisiert, wenn sich ein Ereignis über den kompletten Pfad fortpflanzen kann. Ob ein Pfad sensibilisiert ist, hängt von den Eingangsbelegungen des Schaltnetzes ab. Ein Pfad heißt sensibilisierbar, wenn es eine Eingabe gibt, so dass er sensibilisiert wird. Im allgemeinen ist nicht jeder Pfad einer Schaltung sensibilisierbar. Der längste sensibilisierbare Pfad wird kritischer Pfad genannt. Er ist verantwortlich für die maximal mögliche Verzögerung bzw. für die maximale erlaubte Taktfrequenz.

4.1.4 Bestimmung sensibilisierbarer Pfade Um den längsten sensibilisierbaren Pfad zu finden, braucht man eine Methode, um für einen gegebenen Pfad herauszufinden, ob er sensibilisierbar ist. Ein logischer Pfad (e; < k1 , ..., kn >) ist definiert als ein Signalwechsel e (0→1 oder 1→0) zusammen mit einem Pfad < k1 , ..., kn >im Schaltungsgraph. Alle Signale einer Schaltung, die sich auf einem gegebenen Pfad befinden, bezeichnet man als On-Path-Signale. Diejenigen direkten Vorgänger von On-Path-Signalen, die nicht auf dem Pfad liegen, nennt man Off-Path-Signale. Die On- und Off-Path-Signale für den markierten Pfad in Abbildung 4.6 sind: On-Path-Signale Off-Path-Signale

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

: {k1 , k3 , k6 , k8 } : {k2 , k4 , k5 , k7 }

Rev : 796

150

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE k1 k2

k4 k5

k9

& 0

k3

1

&

MUX

k6

≥1

k7

k10

k8

Abbildung 4.6: Logischer Pfad Die Sensibilisierung eines Pfades hängt von der Belegung der Off-Path-Signale ab. Der logische Pfad ( 0 → 1; < k1 , k3 , k6 , k8 >) kann z.B. mit k2 = k5 = 1 und k4 = k7 = 0 sensiblisiert werden. Die Zuweisung solcher fester Werte an die Off-Path-Signale wird statische Sensibilisierung genannt und ist lediglich eine hinreichende Bedingung, dass sich ein Ereignis fortpflanzen kann. Die Off-Path-Signale können evtl. auch nur kurzzeitig sensibilisierende Werte annehmen; auch eine derartige dynamische Sensibilisierung hat Einfluss auf die Schaltngsgeschwindigkeit.

4.1.5 Methoden zur Zeitanalyse Zur Analyse der maximalen Verzögerung einer Schaltung gibt es die folgenden Ansätze: 1. Verifikation. Der längste sensibilisierbare Pfad wird analytisch z.B. mit den folgenden Schritten bestimmt: • Ordne jedem Knoten k Verzögerungszeiten zu: thl (k), tlh (k). • Zähle logische Pfade (e; < k1 , ...ki , ..., kn >) mit absteigender Gesamtzeit Σ txx (ki ) auf. • Stelle fest, ob (e; < k1 , ..., kn >) sensibilisierbar ist, falls ja: Σ txx (ki ) ist die Maximalverzögerung des Schaltnetzes und bestimmt die Betriebsfrequenz. Im ungünstigsten Fall wächst die Anzahl der logischen Pfade exponentiell mit der Schaltungsgröße. Der Ansatz liefert zwar immer die korrekte Lösung, ist aber unter Umständen zu rechenaufwendig. Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.2. ADDITION UND SUBTRAKTION

151

2. Simulation. Diese Methode wird in der Praxis häufig angewendet. Das Problem ist, passende Eingangsstimuli festzulegen. Eine vollständige Simulation mit allen möglichen Eingaben ist zu rechenaufwendig, daher gibt normalerweise der Entwerfer eine Menge von „sinnvollen“ Eingabemustern vor. Dass dabei tatsächlich der kritische Pfad sensibilisiert wird, ist nicht unbedingt garantiert. 3. Worst-Case-Abschätzung. Es wird der längste Pfad im Schaltnetzgraphen gesucht, ungeachtet davon, ob er auch sensibilisierbar ist.

4.1.6 Verzögerungsmodelle Für die Simulation auf Gatterebene gibt es verschiedene Verzögerungsmodelle; einige davon sind in Abbildung 4.7 dargestellt. a

1

y

a y y y y y

Eingangssignal Einheitsverzögerung Anstiegzeit t r=1, Abfallzeit t f=2 Intervalle: ∆min=2, ∆max=3 Träge Totzeit < 1 mit Einheitsverzögerung Träge Totzeit > 3

2

4

6

8

Zeitschritt

Simulation mit (y) und ohne (y’) Berücksichtigung der trägen Totzeit:

a b c

≥1

y

a b c y y’

Abbildung 4.7: Verzögerungsmodelle

4.2 Addition und Subtraktion 4.2.1 Ripple-Carry-Addierer Ein Halbaddierer (s. Abbildung 4.8) addiert zwei Bitwerte a und b und berechnet ein Summen- und ein Übertragsbit. Aus zwei Halbaddierern kann man einen Volladdierer (s. Abbildung 4.9) zusammensetzen, der drei Eingabebits addiert und die Summe und den Übertrag bestimmt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

152

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

Schaltbild und Schaltsymbol:

Funktionstabelle: a 0 0 1 1

b 0 1 0 1

s 0 1 1 0

a

c 0 0 0 1

b

_ _ s=ab∨ab=a⊕b c=ab

a

=1

s

&

c

Σ

s co

b

c

Abbildung 4.8: Halbaddierer

Schaltnetz und Schaltsymbol:

Funktionstabelle: ai 0 0 0 0 1 1 1 1

bi 0 0 1 1 0 0 1 1

ci 0 1 0 1 0 1 0 1

si 0 1 1 0 1 0 0 1

ci+1 0 0 0 1 0 1 1 1

si = ai ⊕ bi ⊕ c i ci+1 = aici ∨ bici ∨ aibi = (ai ⊕ bi) ci ∨ aibi

ai bi

=1 & Halbaddierer 1

si

=1

ci

≥1

&

ci+1

Halbaddierer 2

ai bi ci

Σ ci

si co

ci

Abbildung 4.9: Volladdierer Durch Verkettung von n Volladdierern kann ein Ripple-Carry-Addierer (s. Abbildung 4.10) aufgebaut werden, der n-bit breite Zahlen addiert.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.2. ADDITION UND SUBTRAKTION

a0 b 0

a1 b 1

153

a2 b2

Σ

an b n

Σ

Σ

Σ ...

c0=0

ci

co

c1

ci

s0

co

c2

ci

s1

co

c3

cn

s2

ci

co

cn+1 sn

Abbildung 4.10: Ripple-Carry-Addierer Der kritische Pfad eines Ripple-Carry-Addierers durchläuft alle Übertragungssignale c1 , ..., cn , und dessen Länge ist damit linear von der Datenbreite abhängig. Der Leser mag sich als Übungsaufgabe ein Paar von Eingaben überlegen, die den längsten Pfad sensibilisieren.

4.2.2 Carry-Lookahead-Addierer Die Pfadverzögerungen eines Ripple-Carry-Addierers sind bei heute üblichen Datenbreiten (32 oder 64 Bit) unakzeptabel lang. Ein Carry-Lookahead-Addierer (CLA) besitzt eine separate Übertragslogik, die eine Verzögerung in O(log n) ermöglicht. Zu jeder Bitposition werden zwei Signale gi („generate“) und pi („propagate“) berechnet. Das Signal gi zeigt an, ob an der entsprechenden Position ein Übertrag erzeugt wird. Die „propagate“-Leitung zeigt an, ob ein Übertrag an der vorherigen Bitposition an die nächste Bitposition weitergereicht wird. Die beiden Signale errechnen sich wie folgt: Carry-generate Carry-propagate

: gi := ai ∧ bi : pi := ai ⊕ bi

Das Übertragssignal ci+1 einer Bitstelle i ist gesetzt, wenn an der Stelle ein Übertrag erzeugt wird oder das vorherige Übertragssignal ci gesetzt ist und über die i. Stelle propagiert wird. Es gilt also: Carry

: ci+1 := gi ∨ pi ci

Durch wiederholtes Einsetzen kann man nun für alle ci eine Formel finden, die nur von den „generate“- und „propagate“-Leitungen und dem globalen Carry-Eingang c0 abhängen: c1 = g 0 ∨ p 0 c0 c2 = g 1 ∨ p 1 g 0 ∨ p 1 p 0 c0 c3 = g 2 ∨ p 2 g 1 ∨ p 2 p 1 g 0 ∨ p 2 p 1 p 0 c0 Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

154

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

... Abbildung 4.11 zeigt die komplette Implementierung eines 3-Bit-CLA. b 0 a0

& g0

b1 a1

=1

&

p0

g1

=1

s0

b 2 a2

=1

&

p1

g2

=1

c0

s1

=1 p2

parallele Übertragslogik

=1

c1

s2

≥1

c2

c3

≥1 &

&

≥1 &

&

&

&

c0

Abbildung 4.11: 3-Bit-Carry-Lookahead-Addierer Jedes ci wird bestimmt mit einer disjunktiven Form aus i ODER-Gliedern mit Produkttermen aus maximal i UND-Gliedern. Möchte man die Übertragslogik mit diskreten Gattern implementieren, so benötigt man für das Signal ci ein ODER-Gatter mit i + 1 Eingänge und i UND-Gatter mit 2, 3, ..., i + 1 Eingängen. In der Praxis lassen sich jedoch keine UND- und ODER-Gatter mit einer beliebig großen Anzahl von Eingängen bauen. Man ersetzt daher ein n-fach UND (ODER) durch eine baumformige Anordnung von k-fach-UND (ODER) Gattern (k ≪ n). Das ist so möglich, dass die maximale Signallaufzeit O(log n) beträgt. Abbildung 4.12 zeigt dazu ein Beispiel mit k = 2 und n = 7.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.2. ADDITION UND SUBTRAKTION

I1 I2

155

& &

I3 I4 I5 I6 I7

&

O

& & &

Abbildung 4.12: 7-fach UND, realisiert durch UND2 - Baum In der Praxis findet man oft Mischformen verschiedener Addiererbauformen. Abbildung 4.13 zeigt eine Kaskadierung von zwei Carry-Lookahead-Addierern. b0 b7 a0 a7

...

b8 b15 a8 a15

...

...

. 7. . . . .

Σ

. 7. . . . .

. 7. . . . .

P

0

7.

0

0

. 7. . . . .

. ..

Σ .. Q

0

0

CI

...

Σ P 7.

. ..

Σ .. Q

0

0

CO

CI

...

s 0 s7

CO

c

...

s8 s15

Abbildung 4.13: Mischung von Ripple-Carry- und Carry-Lookahead-Addierern

4.2.3 Subtraktion Eine Zahl Y wird von einer Zahl X subtrahiert, indem das Zweierkomplement addiert wird. Es sei Y¯ das Einerkomplement von Y . Dann gilt: X − Y = X + (Y¯ + 1) = (X + Y¯ ) + 1 Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

156

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

Abbildung 4.14 zeigt einen Addierer/Subtrahierer. Über die Leitung „select“ wird die Funktion ausgewählt (0 = Addieren, 1 = Subtrahieren). Bei der Subtraktion wird Y¯ mit Hilfe der XOR-Gatter erzeugt, die Addition von 1 wird durch eine entsprechende Belegung des Carry-In-Einganges des n-Bit-Addierers erreicht.

X

Y select

n n

=1 n

Carry-out

n-Bit-Addierer

Carry-in

n

Z=X±Y Abbildung 4.14: Addierer/Subtrahierer

4.2.4 Addition mehrerer Summanden Manchmal müssen mehr als zwei Summanden addiert werden, z.B. bei der Multiplikation. Die Laufzeit eines m-bit breiten CLAs liegt in O(log m), die Addition von N Zahlen läge dann in O((N − 1) log m). Da jedoch nicht jede partielle Summe vollständig bekannt sein muss, kann die Laufzeit wie folgt reduziert werden. Ein Volladdierer erzeugt aus drei Eingabebits ein Summen- und ein Übertragsbit. Die lose Aneinanderreihung von Volladdierern, die untereinander nicht verbunden sind, wird Carry-Save-Addierer (CSA) genannt. Ein CSA erzeugt aus drei Eingabeworten ein Summenwort S und ein Übertragswort C, d. h. zwei Wörter, deren Summe die gleiche ist wie die der drei Eingaben. Abbildung 4.15 zeigt die Kaskadierung zweier CSAs. Die dargestellte Schaltung bildet zu 4 Eingabewörtern ein Summen- und ein Übertragswort. Auf diese Weise können beliebig viele Summanden in der Zeit O(N − 2) verarbeitet werden, und nur in der letzten Stufe ist ein herkömmlicher Addierer (z.B. CLA) notwendig (s. Abbildung 4.16). Als Beispiel werden nun die Zahlen a = ’1111’ = 15; b = ’1111’ = 15; c = ’1101’ = 13 und d = ’1000’ = 8 mittles zweier CSA und eines herkömmlichen Addierers in drei Stufen addiert: In der esten Stufe bildet ein CSA aus a, b und c: Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.2. ADDITION UND SUBTRAKTION a b c s1 c1

157

1111 1111 1101 1101 1111

Also das Summenwort s1 = ’01101’ und das Übertragswort c1 = ’11110’. Das Übertragswort muss hier als um eine Stelle nach links verschoben (rechts ’0’ eingefügt) betrachtet werden, da es für die bei der Bildung des Summenwortes durch den CSA nicht berücksichtigten Carry-Bits steht. In der zweiten Stufe bildet ein CSA nun aus d, s1 und c1: d s1 c1 s2 c2

01000 01101 11110 11011 01100

Also das Summenwort s2 = ’011011’ und das Übertragswort c2 =’011000’. In der letzten Stufe addiert ein herkömmlicher Addierer nun s2 und c2 zum Ergebnis: s2 c2 e

011011 011000 110011

Das Ergebis e = ’110011’ = 51 = 15 + 15 + 13 + 8 konnte also in den ersten beiden Stufen mit konstanter Zeitkomplexität (unabhängig von der Länge der Summanden) errechnet werden, erst in der letzten Stufe mussten die Carrybits (vorher repräsentiert durch das Übertragswort) auch tatsächlich Schritt für Schritt übertragen werden, also z.B. beim CLA mit logarithmischer Zeitkomplexität in Abhägigkeit von der Länge der Summanden.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

158

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE x3

y3

x2 z3

+

y2

x1 z2

+

w3

y1

x0 z1

+

w2

y0

CSA1 z0

+

w1

w0

CSA2 + s3

+ c2

s2

+ s1

c1

+ c0

s0

Abbildung 4.15: Carry-Save-Addierer X

Y

Z

CS-Addierer

W

CS-Addierer C

S

CLA

Abbildung 4.16: Addiererbaum für mehrere Summanden

4.3 Übersicht über Grundelemente In diesem Abschnitt sollen Schaltungselemente vorgestellt werden, die benötigt werden, um den Datenpfad einer Schaltung (z.B. Operationswerk eines Mikroprozessors) zu implementieren. Die Grundelemente lassen sich wie in Tabelle 4.1 dargestellt klassifizieren.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.3. ÜBERSICHT ÜBER GRUNDELEMENTE Typ Verbindungselemente

Kombinatorische Verknüpfungselemente

Sequentielle Elemente

159

Komponenten Multiplexer

Funktion Datenleitung und Funktionserzeugung

Kodierer, Dekondierer

Kodeprüfung, Datenkonversion, Adressierung Boolsche Operationen

Gatter in Wortbreite Programmierbare Felder

Funktionserzeugung

Arithmetische Elemente (Addierer, ALUs) (Parallele) Register

Numerische Operationen

Schieberegister

Informationsspeicherung und Konvertierung

Zähler

Erzeugung von Steuer- und Zeitsignalen

Informationsspeicherung

Tabelle 4.1: Klassifizierung der Grundelemente

4.3.1 Verbindungselemente Verbindungen können mit Hilfe von Multiplexern und Demultiplexern geschaltet werden. Multiplexer besitzen n Daten-Eingänge und genau einen Ausgang. Mit Hilfe von ⌈log2 n⌉Auswahl-Leitungen („select“) wird einer der Dateneingänge auf den Ausgang durchgeschaltet. Demultiplexer besitzen einen Dateneingang und n Ausgänge, wobei der Eingang je nach Belegung der Select-Signale auf einen der Ausgänge durchgeschaltet wird (s. Abbildung 4.17).

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

160

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

S

S

1 2 . . Ausgänge . . m

1 2 . Eingänge . . . n Multiplexer

Demultiplexer

Abbildung 4.17: Multiplexer und Demultiplexer Abbildung 4.18 zeigt das Schaltbild und das logische Verhalten eines 1-aus-4Multiplexers. Manchmal ist eine zusätzliche Enable-Leitung vorhanden, die entweder gesetzt oder nicht gesetzt sein muss (je nach Implementierung), damit überhaupt ein Eingang durchgeschaltet wird. Die Implementierung eines solchen Multiplexers ist in Abbildung 4.19 dargestellt (schaltet nur durch falls E = ’0’).

s0 s1

MUX 0}G0 1 3

e0 e1 e2 e3

0 1 2 3

a

s0 0 0 1 1

s1 0 1 0 1

a e0 e1 e2 e3

s0 s1 e0 e1 e2 e3

a

Abbildung 4.18: Schaltbild und logisches Verhalten eines 1-aus-4-Multiplexers

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.3. ÜBERSICHT ÜBER GRUNDELEMENTE E

161

1

(enable)

e0

&

e1

&

E S1 0 0 0 0 0 1 0 1 1 x

>1 e2

&

e3

& 1

E

1

1

S1

a e0 e1 e2 e3 0

a

Eingänge S0

S0 0 1 0 1 x

e0 e1 e2 e3 S 0

a Ausgang S1

1

Abbildung 4.19: Implementierung eines 1-aus-4-Multiplexers mit Enable-Eingang Abbildung 4.20 zeigt das Schaltbild und das logische Verhalten eines 1-aus-4 Demultiplexers.

DX s0 s1

0 0 G3 1 :

0 1

a0

2

a2

3

a3

a1

s1

s0

a0

a1

a2

a3

0 0 1 1

0 1 0 1

e 0 0 0

0 e 0 0

0 0 e 0

0 0 0 e

e

Abbildung 4.20: Schaltbild und logisches Verhalten eines 1-aus-4-Demultiplexers Für einige Anwendungen (z.B. Auswahl eines Registers oder einer ALU-Funktion) werden Decoder benötigt, die eine Dualzahl in einen 1-aus-n-Code umsetzen. Die Wertetabelle und die Implementierung eines 3x8-Decoders sind in Abbildung 4.21 dargestellt. Ein Decoder lässt sich auch mit Hilfe eines Demultiplexers implementieren, bei dem der Dateneingang e mit 1 belegt wird.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

162

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

Index 0 1 2 3 4 5 6 7

a b c M 7 M 6 M 5 M 4 M3 M 2 M 1 M 0 0 0 0 0 1 1 1 1

0 0 1 1 0 0 1 1

0 1 0 1 0 1 0 1

0 0 0 0 0 0 0 1

1 a 1 b 1 c

0 0 0 0 0 0 1 0

0 0 0 0 0 1 0 0

0 0 0 0 1 0 0 0

0 0 0 1 0 0 0 0

0 0 1 0 0 0 0 0

&

M0

&

M1

&

M2

&

M3

&

M4

&

M5

&

M6

&

M7

0 1 0 0 0 0 0 0

1 0 0 0 0 0 0 0

Abbildung 4.21: 3x8 Decoder Das Zusammenspiel der vorgestellten Verbindungselemente soll an einem Beispiel verdeutlicht werden. Abbildung 4.22 zeigt die Ansteuerung eines Registersatzes, dessen Register über ein Bussystem verbunden sind. Mit den eingezeichneten Komponenten kann der Inhalt jedes Registers in ein beliebiges anderes Register übertragen werden. Das Quellregister wird über die Signale Q1 und Q0 ausgewählt und liegt stets an dem Ausgang des Multiplexers an. Über Z1 und Z0 wird das Zielregister ausgewählt. Der Decoder aktiviert jeweils die Schreibleitung von genau einem Register.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.3. ÜBERSICHT ÜBER GRUNDELEMENTE

163

Register A

Register B

0 4x1

1

MUX 2

Register C 3

Register D

Q

1

Q

0

0 1 2 3

DEC Zielregisterauswahl

Z

1

Z

0

Abbildung 4.22: Verbindung über ein Bussystem mit Steuerung

4.3.2 Kombinatorische Verknüpfungselemente Alle Prozessoren besitzen eine arithmetisch-logische Einheit (ALU). Eine ALU besitzt typischerweise zwei Eingabebusse X, Y und einen Ausgabebus Z der Wortbreite m. Über Steuerleitungen kann eine Verknüpfung (z.B. AND, OR, ADD oder SUB) ausgewählt werden. Diese Auswahl kann entweder durch einen Multiplexer implementiert oder zusammen mit der Verknüpfung minimiert werden. Angenommen, es soll eine ALU mit den in Tabelle 4.2 dargestellten Funktionen gebaut werden. c1 0 0 1 1

c2 0 1 0 1

Funktion NOT XOR OR AND

Tabelle 4.2: Funktionen der ALU Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

164

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

Für die Ausgänge Z gilt dann:

¯ ∨ c¯1 c2 (X ⊕ Y ) ∨ c1 c¯2 (X ∨ Y ) ∨ c1 c2 XY Z := c¯1 c¯2 X ¯ ∨ c¯1 c2 XY ¯ ∨ c¯1 c2 X Y¯ ∨ c1 c¯2 X ∨ c1 c¯2 Y ∨ c1 c2 XY := c¯1 c¯2 X Die Implementierung zeigt Abbildung 4.23. X

Y m

m

NOT EXCLUSIVE-OR

1:4 Dekodierer

OR AND

&

&

&

&

&

c1 c2

&

& m Z

Abbildung 4.23: Logische Verknüpfungselemente Die Implementierung logischer Funktionen (AND, OR, XOR etc.) ist trivial, Schaltnetze zur Addition und Subtraktion wurden in Abschnitt 4.2 diskutiert. Weiterhin unterstützen ALUs in der Regel Schiebeoperationen. Abbildung 4.24 zeigt einen BarrelShifter. Die Ausgabe ist gegenüber der Eingabe um eine Stelle nach links (bei C = 0) oder nach rechts (bei C = 1) verschoben. Den typischen Aufbau einer kompletten ALU zeigt Abbildung 4.25.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.3. ÜBERSICHT ÜBER GRUNDELEMENTE D1

D0

C

D2

D3

165 D5

D4

D6

D7

1

&

S0

&

&

&

&

&

&

&

&

&

&

&

&

≥1

≥1

≥1

≥1

≥1

≥1

S1

S2

S3

S4

S5

S6

&

S7

Abbildung 4.24: Schiebeschaltnetz (Barrel shifter)

Register X

Register Y

Multiplexerschaltnetz

s1 s2 cin

ALU1

zero sign

ALU2

arithmetisch-logisches Schaltnetz

verflow

ALU3

s3 s4 s5

cout Schiebeschaltnetz

s6 s7

Register Z

Abbildung 4.25: Einfache ALU Wie bereits in Abbildung 4.23 angedeutet wird, lassen sich ALUs durch das m-fache Aneinanderreihen gleichartiger Elemente, die jeweils ein Bit verarbeiten, aufbauen (sog. „Bitscheiben-Struktur“). Dies erlaubt ein reguläres und gut kompaktierbares Chiplayout. Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

166

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

Soll für die Addition aber z.B. ein schneller CLA (s. Abschnitt 4.2) verwendet werden, so ist dies nicht möglich, da ein CLA nicht regulär aus 1-Bit-Bausteinen aufgebaut wird. Ein Kompromiss ist möglich, wenn der Addierer durch eine Kaskadierung von kleineren CLAs aufgebaut wird (vgl. Abbildung 4.15). Abbildung 4.26 zeigt eine ALU mit Scheiben der Breite 4, bei der in jeder 4-Bitscheibe ein 4-Bit-CLA implementiert sein könnte. Eingänge

4-Bit-Register

cout

4-Bit-Register

4-Bit-Register

4-Bit-Register

ALU

ALU

ALU

ALU

Steuerung

Steuerung

Steuerung

Steuerung

c in

Ausgang

Abbildung 4.26: ALU in Bitscheibenstruktur mit 4-Bit-Elementen

4.3.3 Sequentielle Elemente Die wichtigsten sequentiellen Elemente in einem Operationswerk sind Register, Schieberegister und Zähler. Abbildung 4.27 zeigt ein Register, bestehend aus DelayFlipflops.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

4.3. ÜBERSICHT ÜBER GRUNDELEMENTE

Takt

Yn

167

Yn-1 1C

Y0 1C

D1

1C

D1 Yn

D1 Yn-1

Y0

Abbildung 4.27: Einfaches Register Ein Schieberegister besitzt einen zusätzlichen Dateneingang SDI („shift data in“), einen Datenausgang SDO („shift data out“) sowie eine Steuerleitung, um zu bestimmen, ob und in welcher Richtung geschoben wird. Zähler besitzen typischerweise die Steuereingänge COUNT (zählen/Wert beibehalten) und CLEAR (zurücksetzen). Abbildung 4.28 zeigt das Symbol eines Modulo-16Zählers und die Implementierung mit getakteten JK-Flipflops. Ist COUNT_ENABLE gesetzt, so sind Eingänge J und K jedes Flipflops sind so beschaltet (J = K = 1), dass das Flipflop mit jedem Takt seinen Zustand wechselt. Der Datenausgang ist mit dem Takteingang des nächsten Flipflops verbunden. Damit arbeitet das erste (in Abbildung 4.28 das linke) Flipflop als Frequenzhalbierer für das zweite usw. Beispiel für die Zählweise des aus JK-Flipflops (gesteuert durch Taktaufwärtsflanken) aufgebauten Zählers aus Abbildung 4.28: Start / Ausgangsbelegung z.B.: 1. Aufsteigende Taktflanke 2. Aufsteigende Taktflanke 3. Aufsteigende Taktflanke 4. Aufsteigende Taktflanke 5. Aufsteigende Taktflanke ...

z3 0 1 1 1 1 1 ...

z2 0 1 1 1 1 0 ...

z1 0 1 1 0 0 1 ...

z0 0 1 0 1 0 1 ...

Dezimalzahl 0 15 14 13 12 11 ...

Das Umschalten des ersten (ganz linken) JK-Flipflops von ’0’ auf ’1’ stellt am Takteingang des zweiten JK-Flipflops eine aufsteigende Taktflanke dar - dieses triggerd nun ebenfalls, triggerd das erste JK-Flipflop aber von ’1’ auf ’0’ so stellt dies am Eingang des zweiten eine absteigende Taktflanke dar und somit triggerd dieses nicht (gleiches gilt für die Flipflops weiter rechts). Der hier vorgestellte Zähler zählt also gerade von 15 - 0 abwärts, falls man die Aussgänge in der Reihenfolge z3 z2 z1 z0 als Binärzahl interprätiert. Soll der Zähler nun

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

168

KAPITEL 4. ARITHMETISCH-LOGISCHE GRUNDELEMENTE

aufwärts zählen, reicht es die vier Ausgänge jeweils zu invertieren oder anstatt Q den negierten Ausgang QN der JK-Flipflops auszuwerten.. COUNT ENABLE

J CLOCK

J

Q

CLOCK

K

C

Q

J

CLOCK

QN

K

CLOCK

QN C

K

Q

JJ

Q

CLOCK

CLOC K KQN C

QN C

CLEAR z1

z0

COUNT ENABLE CLEAR

z2

z3

Modulo 16 Zähler z0 z1 z2 z3 COUNT

Abbildung 4.28: Modulo-16 - Zähler Möchte man einen Zähler als synchrones Schaltwerk bauen, bei dem alle Flipflops gleich getaktet werden, so kann man ein gewöhnliches Register (bestehend aus DFlipflops) mit einem Inkrementier-Schaltnetz verwenden, das die Funktion y := x + 1 ausführt (s. Abbildung 4.29). Der Inkrementierer kann durch eine Kette von Halbaddieren implementiert werden, wobei ein Eingang des ersten Halbaddierers als EnableLeitung genutzt werden kann. Inkrementierer Enable

Inkrementierer

x0

Enable a

b

x1 a

HA Register

s

y0

b

xn-1 a

HA c

s

b

HA c

y1

s

c

yn-1

Abbildung 4.29: Zähler mit Inkrementier-Schaltnetz

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

Kapitel 5 Hardware-Modellierung Digitale Systeme lassen sich auf unterschiedlichen Abstraktionsebenen beschreiben. Zu jeder Ebene gibt es verschiedene Sichten auf die modellierten Objekte. In Abbildung 5.1 sind die einzelnen Beschreibungsebenen und die Modellierung verschiedener Sichten dargestellt.

Sicht

Funktion / Verhalten

Struktur

Geometrie

System

Leistungsanforderungen

Netzwerk

Systempartitionierung

Architektur

Algorithmen

Blockschaltbild

Floorplan

RegisterTransfer

Datenfluß, Steuerfluß

RTDiagramm

Logik

boolesche Gleichungen

Logiknetzliste

elektrisch

Differentialgleichungen

elektrisches Schaltbild

symbolisches Layout

physikalisch

Differentialgleichungen

Dotierungsprofile

Layout

Ebene

plazierte Standard- / Makrozellen

Abbildung 5.1: Beschreibungsebenen und Sichten digitaler Systeme

169

170

KAPITEL 5. HARDWARE-MODELLIERUNG

5.1 Register-Transfer-Beschreibungen 5.1.1 Aufbau und Einsatz von RT-Beschreibungen RT-Beschreibungen bilden die Schnittstelle zwischen der Verhaltens- und Strukturbeschreibung einer Schaltung. Werkzeuge zur High-Level-Synthese geben in der Regel Register-Transfer-Beschreibungen aus, die dann von Logiksynthese-Werkzeugen in Gatternetzlisten umgesetzt werden. Die verwendeten Sprachen sind mächtiger als etwa Gatternetzlisten. So muss z.B. nicht jede einzelne Leitung beschrieben werden, sondern es können Leitungen zu Bussen oder Flipflops zu Registern zusammengefasst werden. Damit ist eine übersichtlichere und kürzere Beschreibung möglich, die auch effizienter simuliert und validiert werden kann.

5.1.2 Entwurfsschritte Ein typischer Register-Transfer-Entwurf läuft in den folgenden Arbeitsschritten ab: 1. Beschreibe das gewünschte Verhalten (Algorithmus) durch eine Menge S von Register-Transfer-Operationen, so dass jede Operation mit den vorhandenen Komponenten realisiert werden kann. 2. Bestimme Typen und Zahl der benötigten Komponenten. 3. Erzeuge ein Strukturdiagramm D mit diesen Komponenten. Wähle die Verbindungen so, dass alle von S benötigten Datenpfade vorhanden sind. 4. Bestimme aus S und D die notwendigen Kontrollpunkte und Steuersignale. Führe die zur Realisierung benötigte Logik in die Schaltung ein. 5. Spezifiziere einen endlichen Automaten, der das Steuersignal geeignet erzeugt. 6. Entwerfe ein Schaltwerk für diesen Steuerautomaten. 7. Vereinfache die Schaltung wo möglich. Im folgenden werden diese Schritte anhand eines Beispiels genauer erläutert. Schritt 1: Algorithmus Für die Beispiel-Algorithmen in diesem Skript definieren wir eine Sprache mit den folgenden Bestandteilen: Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.1. REGISTER-TRANSFER-BESCHREIBUNGEN

171

1. Deklarationen von Registern und Bussen declare register A (0:7), ... declare bus BUS (0:7), ... 2. Marken BEGIN: 3. Zuweisungen und Operationen A(0:7) ← A(0:7) + M(1:7).Q(7) Dabei steht z.B.: • M(1:7) für die Bits 1 bis 7 des Registers M, • Q(7) für Bit 7 des Registers (oder Busses) Q, • M(1:7).Q(7) für die Verkettung der Bits 1 bis 7 von M und Bit 7 von Q. 4. Steueranweisung if then go to 5. Parallele und sequentielle Ausführung Operationen, die gleichzeitig ausgeführt werden, werden durch ein Komma getrennt. Ein Semikolon trennt Anweisungen, die nacheinander ausgeführt werden. Als Beispiel zeigt Abbildung 5.2 den Algorithmus zur Multiplikation zweier vorzeichenbehafteter 8-Bit-Zahlen (Darstellung: Betrag und Vorzeichen). Über den Eingabebus “INBUS“ werden zunächst die Faktoren in die Register M und Q eingelesen. M(0) und Q(0) sind jeweils die Vorzeichenbits. Dann werden seriell in 7 Iterationen die Beträge multipliziert. Schließlich wird das Vorzeichen berechnet (Zeile: FINISH) und das 16 Bit breite Ergebnis über den Ausgabebus „OUTBUS“ ausgegeben.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

172

KAPITEL 5. HARDWARE-MODELLIERUNG

declare register A(0:7), M(0:7), Q(0:7), COUNT(0:2) declare bus INBUS(0:7), OUTBUS(0:7) BEGIN: INPUT:

A ← 0,COUNT ← 0, M ← INBUS; Q ← INBUS;

ADD: RIGHTSHIFT:

A(0:7) ← A(1:7) + M(1:7) * Q(7); A(0) ← 0, A(1:7).Q ← A.Q(0:6), COUNT ← COUNT + 1; if COUNT ≠ 7 then go to ADD;

TEST: FINISH: OUTPUT:

A(0) ← M(0) ⊕ Q(7), Q(7)← 0; OUTBUS ← Q; OUTBUS ← A;

END: Abbildung 5.2: Formale Beschreibung eines 8-Bit-Multiplizierers Schritt 2: Bestimmung der Komponenten Aus dem in Schritt 1 erstellten Algorithmus werden die Typen und die Anzahl der benötigten Komponenten ermittelt. Busse und Register ergeben sich unmittelbar aus den "declare"-Zeilen. Aus den vorkommenden Anweisungen ist erkennbar, welche Register als Schieberegister oder Zähler ausgeführt werden müssen, und welche funktionalen Einheiten (Addierer, einfache Gatter etc.) zusätzlich benötigt werden. Für den Multiplizierer aus Abbildung 5.2 werden die folgenden Komponenten benötigt: • 4 Register (3 x 8 Bit, 1 x 3 Bit), wobei die Register A und Q ein 16-BitSchieberegister bilden und das 3-Bit-Register als Zähler ausgebaut sein muss. • 1 Addierer (7 Bit) • 1 XOR-Gatter • 1 UND-Gatter zur Abfrage des Zählerstandes Schritt 3: Strukturdiagramm

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.1. REGISTER-TRANSFER-BESCHREIBUNGEN

173

Aus den in Schritt 2 bestimmten Komponenten wird ein Strukturdiagramm des Operationswerkes erzeugt, so dass alle für die Ausführung des Algorithmus notwendigen Verbindungen vorhanden sind. Abbildung 5.3 zeigt die Struktur des 8-BitMultiplizierers (einschließlich Steuereinheit). Hierbei kennzeichnen die dünnen Linien 1-Bit-Leitungen, während die dicken Linien Busse mit mehreren Bits darstellen.

=1

M(0)

Q(7)

A

Q

M 7

M(1:7)

7

A(0:7)

8

A(1:7) Addierer

8

8

8

Q(7) Q(0:7)

8

8-BitDatenbusse

OUTBUS INBUS COUNT 3 =7

externe Steuersignale

BEGIN END

Steuereinheit

CLOCK

c0 c1

.. .

Interne Status- und Steuersignale

ck

Abbildung 5.3: Strukturdiagramm ohne Kontrollpunkte Schritt 4: Kontrollpunkte Um mit dem in Schritt 3 erzeugten Operationswerk einen Algorithmus ausführen zu können, muss es eine Schnittstelle besitzen, über die ihm mitgeteilt wird, • wie die Daten über die Verbindungselemente geleitet werden, • wann welche Funktionseinheiten aktiv sind, Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

174

KAPITEL 5. HARDWARE-MODELLIERUNG

• welche Funktionen von diesen ausgeführt werden. Abbildung 5.4 zeigt ein Strukturdiagramm einmal mit und einmal ohne Kontrollpunkte. Es gibt unterschiedliche Typen von Kontrollpunkten: • c1 und c2 entscheiden, ob die Register R1 bzw. R2 über den Bus neu geladen werden oder ihren Wert beibehalten. Auf Gatterebene entsprechen solche Kontrollpunkte dem Load-Eingang eines Registers. • c3 , c4 und c5 wählen aus, welches Signal auf den linken Eingang der Funktionseinheit geschaltet wird. Solche Kontrollpunkte könnten auf Gatterebene durch Multiplexer realisiert werden. • c8 ist, je nachdem, um was für eine Funktionseinheit es sich handelt, überflüssig, weil es für die Belegung des rechten Eingangs der Funktionseinheit keine Alternative gibt. • c10 und c11 wählen die Operation aus, die von der Funktionseinheit ausgeführt wird. Abbildung 5.5 zeigt die Implementierung von einigen in Abbildung 5.4 eingezeichneten Kontrollpunkten auf Gatterebene. BUS

BUS

c1 c3 R1

R1

R2

c4

Funktionseinheit

R3

c7

c2

R2

c6

c5

c10 c11

Funktions- c 8 einheit

R3

c9

Abbildung 5.4: Strukturdiagramm mit und ohne Kontrollpunkte

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.1. REGISTER-TRANSFER-BESCHREIBUNGEN

175

C3 C4 C5

4- bit encoder

R3

Bus R1 R2

4-input multiplexer

c10 c11

c8

&

Funktionseinheit

Abbildung 5.5: Implementierung einiger Kontrollpunkte Das Strukturdiagramm des 8-Bit-Multiplizierers mit Kontrollpunkten ist in Abbildung 5.6 dargestellt. Die einzelnen Operationen des Algorithmus kann man durch das Setzen von Steuersignalen ausführen, z.B.: A ← 0, Q ← 0 A(0) ← 0, A(1:7).Q ← A.Q(0:6) A(0:7) ← A(1:7) + M(1:7) OUTBUS ← Q

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

- Setzen von c3 und c6 - Setzen von c2 und c4 - Setzen von c7 - Setzen von c9

Rev : 796

176

KAPITEL 5. HARDWARE-MODELLIERUNG

"0“

=1 c2

c4

"0“

c1

"0“

c3 A

0

M(0)

Q(7)

c6 Shift

Shift 7

Q

0

M

0

7

7

M(1:7)

7

A(0:7)

c7

8

A(1:7)

c10 c8

Addierer 8

Q(0:7)

c9

c11

8

8

Q(7)

8

8-BitDatenbusse

OUTBUS INBUS COUNT

Reset inc

c0 c5

3 =7

externe Steuersignale

BEGIN END

Steuereinheit

CLOCK

c0 c1

.. .

Interne Status- und Steuersgnale

c11

Abbildung 5.6: 8-Bit-Multiplizierer mit Kontrollpunkten Schritt 5: Zustandsübergangstabelle Nach dem Einfügen der Kontrollpunkte stehen die Ein- und Ausgabeleitungen des Steuerwerkes fest. Für den Multiplizierer sind dies: • Eingabe: BEGIN, Q(7), COUNT = 7 • Ausgabe: c0 ,...,c11 , END Der Algorithmus wird in eine Zustandsübergangstabelle umgesetzt. Jeder Zustand entspricht einem Befehl bzw. einer Folge von Befehlen, die durch Komma getrennt sind. Die Zustandsübergangstabelle 5.1 enthält zu jedem Zustand eine Liste der Kontrollpunkte, die für das Ausführen des entsprechenden Befehls gesetzt werden müssen.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL Marke BEGIN: ADD: RIGHTSHIFT: TEST: FINISH: OUTPUT: END:

177 Zustand S0 S1 S2 S2 S3 S4 S4 S5 S6 S7 S8

Bedingung Q(7) = 1 Q(7) = 0 COUNT 6= 7 COUNT = 7 -

Folgezustand S1 S2 S3 S3 S4 S2 S5 S6 S7 S8 S8

Steuersignal auf 1 c3 , c0 , c11 c10 c7 c2 , c4 , c5 c1 , c6 c9 c8 -

Tabelle 5.1: Zustandsübergangstabelle für das Steuerwerk des Multiplizierers

Schritt 6: Entwurf eines Schaltwerkes für den Steuerautomaten Der Entwurf von Steuerwerken aus einer Zustandsübergangstabelle ist bereits aus der Vorlesung „Kombinatorische und Sequentielle Netzwerke“ bekannt. Schritt 7: Schaltung vereinfachen Methoden zur Logikminimierung werden z.B. in der Vorlesung „Kombinatorische und Sequentielle Netzwerke“ vorgestellt.

5.2 VHDL Für den rechnergestützten Schaltungsentwurf wird eine einheitliche Beschreibungssprache für Hardware benötigt, die es ermöglicht, unterschiedliche Sichten (z.B. Verhalten, Struktur) auf verschiedenen Abstraktionsebenen (z.B. System-, RT- oder Gatterebene) darzustellen. Die wichtigsten konkreten Anwendungen sind: • Spezifikation (z. B. Funktionsbeschreibung auf algorithmischer Ebene) • Simulation (um z. B. einen Entwurf auf RT- oder Gatterebene zu validieren) • Verifikation, d. h. automatisches Beweisen, dass ein Entwurf eine Spezifikation erfüllt oder daß zwei Darstellungen äquivalent sind Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

178

KAPITEL 5. HARDWARE-MODELLIERUNG

• Synthese, d.h. die automatische Umsetzung einer Spezifikation in einen Entwurf (z.B. RT-Beschreibung → Gatternetzliste) Einige Anforderungen an Hardwarebeschreibungssprachen werden bereits von üblichen Programmiersprachen (C, Pascal, ...) erfüllt. Was zusätzlich benötigt wird, sind Sprachkonstrukte • zur Beschreibung von Parallelität (Hardware arbeitet von Natur aus parallel, während Software hauptsächlich sequentiell ausgeführt wird) • zur Modellierung von Verzögerungszeiten • zur Beschreibung von Strukturen, Netzlisten • zur Verwaltung mehrerer Darstellungen eines Objektes: In C oder Pascal ist es selbstverständlich, dass zu einer Funktion genau eine Implementierung existiert. Eine Hardwarebeschreibungssprache muss dagegen mehrere alternative Repräsentationen (z.B. auf Verhaltens- und auf Strukturebene) zulassen. In den folgenden Abschnitten werden die Grundkonzepte der Hardwarebeschreibungssprache VHDL (VHDL = VHSIC Hardware Description Language, VHSIC = Very High Speed Integrated Circuits) vorgestellt. Anhand von Beispielen soll die Entwurfsmethodik und der praktische Umgang mit einem VHDL-Simulator gezeigt werden. Für eine vollständige Sprachbeschreibung sei auf weiterführende Literatur verwiesen, z. B.: • Kurup, Abbasi: „Logic Synthesis Using Synopsis - 2. edition“ Kluwer Academic Publishers 1997, ISBN 0-7923-9786-X • Ashenden, Peter: „The designers guide to VHDL“ Morgan Kaufmann Publishers 1994, ISBN 1-55860-270-4 • Hsu Tsai, Liu Lin: „VHDL Modeling for Digital Design Synthesis“ Kluwer Acad. Publishers 1995, ISBN 0-7923-9597-2 • Hunter, Johnson: „Introduction to VHDL“ Chapman & Hall 1995, ISBN 0-412-73130-4 • Mazor, Langstraat: „A Guide to VHDL - 2. edition“ Kluwer Academic Publishers 1993, ISBN 0-7923-9387-2

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL

179

5.2.1 Grundstrukturen Jede Schaltungskomponente, ob es sich um ein UND-Gatter, einen Addierer oder eine komplette ALU handelt, wird charakterisiert durch eine Schnittstellenbeschreibung und eine oder mehrere Architekturbeschreibungen. Die Schnittstellenbeschreibung beginnt mit dem Schlüsselwort entity und beschreibt die Richtung und den Datentyp der Ein- und Ausgänge. Abbildung 5.7 zeigt das Symbol und die Schnittstellenbeschreibung eines Halbaddierers. a b

Σ co

sum carry

entity HALF_ADDER is port (a,b: in STD_LOGIC; sum, carry : out STD_LOGIC); end HALF_ADDER;

Abbildung 5.7: VHDL-Schnittstellenbeschreibung eines Halbaddierers Beschreibungsstile Zu jeder Entity gehören eine oder mehrere Architekturbeschreibungen. Je nachdem, welche VHDL-Konstrukte dazu verwendet werden, gibt es unterschiedliche Beschreibungsformen. Die gebräuchlichsten sind: • Verhalten • Datenfluss • Struktur Die verschiedenen Beschreibungsstile werden durch beliebige Namen gekennzeichnet. Die Worte "structure", "behavior" und "dataflow", die im folgenden verwendet werden, sind also keine Schlüsselworte. Abbildung 5.8 zeigt die Beschreibung des Halbaddierers im Verhaltensstil. Das wesentliche Merkmal einer Verhaltensbeschreibung ist die Prozess-Umgebung ("process (a, b) ... end process;"), die eine Folge von Anweisungen enthält, die immer wiederkehrend nacheinander ausgeführt werden.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

180

KAPITEL 5. HARDWARE-MODELLIERUNG

architecture BEHAVIOR of HALF_ADDER is begin process (a, b) begin a b sum carry if (a = b) then sum connect0, carry => connect1); U1: HALF_ADDER port map(a => connect0, b => c_in, sum => sum, carry => connect2); U2: ORGATE port map(x => connect1, y => connect2, z =>c_out); end;

Abbildung 5.12: Hierarchiebildung in VHDL Konfigurationen Oft möchte man nicht innerhalb einer Strukturbeschreibung festlegen, welche Architektur für die untergeordneten Komponenten verwendet wird. Man kann in den obigen Beispielen deshalb die "for..."-Zeilen weglassen und stattdessen, z.B. in einer separaten Datei, eine Konfiguration definieren. So lassen sich leicht Entwurfsvarianten bilden

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL

183

(z.B. Bauelemente aus verschiedenen Bibliotheken wählen oder zwischen verschiedenen Architekturen einer Entity umschalten), ohne dass der Quelltext für die Strukturbeschreibung geändert werden muss. Abbildung 5.13 zeigt eine Konfigurationsdatei für den Halbaddierer, die äquivalent zu den beiden "for..."-Zeilen in Abbildung 5.11 ist.

configuration CFG_HA_STRUCTURE of HALF_ADDER is for STRUCTURE for U0: EXORGATE use entity WORK.EXORGATE(BEHAVIOR); end for; for U1: ANDGATE use entity WORK.ANDGATE(BEHAVIOR); end for; end for; end CFG_HA_STRUCTURE; Abbildung 5.13: Konfiguration für den Halbaddierer Die "for...use"-Anweisungen einer Konfiguration können wiederum auf andere Konfigurationen verweisen. Abbildung 5.14 zeigt eine Konfiguration für den Volladdierer, bei der für die Komponenten der Halbaddierer stets diejenige Architektur verwendet wird, die in "CFG_HA_STRUCTURE" eingestellt ist.

configuration CFG_FA_STRUCTURE of FULL_ADDER is for structure for U0, U1: HALF_ADDER use configuration WORK.CFG_HA_STRUCTURE; end for; for U2: ORGATE use entity WORK.ORGATE(BEHAVIOR); end for; end for; end CFG_FA_STRUCTURE; Abbildung 5.14: Konfiguration für den Volladdierer Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

184

KAPITEL 5. HARDWARE-MODELLIERUNG

Bibliotheken und Packages VHDL erlaubt das Arbeiten mit Bibliotheken. Eine Bibliothek ("library") ist eine Sammlung von Paketen ("package"). Ein Package kann mit den Kommandos library ; use ..all; eingebunden werden, z.B.: library IEEE; use IEEE.std_logic_1164.all; Bibliotheken können einerseits selbst angelegt werden (z.B. bei großen Projekten), andererseits gibt es einige sehr nützliche Standard-Bibliotheken. Die wichtigsten sind: • STD, IEEE: häufig benötigte Typen, Funktionen und Komponenten, von IEEE standardisiert • WORK: Pseudonym für den aktuellen Entwurf (vgl. auch obige Konfigurationsbeispiele) Die wichtigsten Packages sind: • IEEE.std_logic_1164.all: nützliche Datentypen (z.B. "STD_LOGIC") • IEEE.std_logic_arith.all: Datentypen und Funktionen zum Rechnen mit BitVektoren • STD.textio.all: enthält Funktionen zur Textein-/-ausgabe (nützlich beim Debuggen)

5.2.2 Arbeiten mit VHDL In diesem Abschnitt soll der Umgang mit dem VHDL-Analyser und dem VHDLDebugger der Firma Synopsys anhand des Volladdierer-Entwurfes aus dem vorherigen Abschnitt beispielhaft erläutert werden. Der Ablauf ist in Abbildung 5.15 dargestellt.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL

185 VHDL-Quellcode

Analysieren (Compilieren) : vhdlan .vhd

Design in Bibliothek WORK (default)

Simulieren: vhdldbx

Abbildung 5.15: Entwurfsablauf Zunächst muss der VHDL-Code mit einem Editor eingegeben und in entsprechenden Dateien abgespeichert werden. Es ist zu empfehlen, für jede Entity eine eigene (manchmal auch mehrere) Dateien anzulegen. In diesem Beispiel sind das die Dateien: • exor.vhd • and.vhd • or.vhd • ha.vhd • fa.vhd In Abbildung 5.16 bis Abbildung 5.18 sind diese Dateien (ausgenommen and.vhd und or.vhd, die genauso aufgebaut sind wie exor.vhd) vollständig aufgelistet.

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

186

KAPITEL 5. HARDWARE-MODELLIERUNG

Abbildung 5.16: Datei "exor.vhd"

Abbildung 5.17: Datei "ha.vhd"

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL

187

Abbildung 5.18: Datei "fa.vhd" Beim Analysieren der VHDL-Dateien sind bestimmte Regeln zu beachten: • Die "entity" muss vor der/den zugehörigen "architecture(s)" übersetzt werden. • Bei mehreren Dateien mit verschiedenen Architekturen ist darauf zu achten, dass die „entity”-Deklaration nur einmal vorhanden ist. • Elemente auf tieferen Hierarchiestufen müssen zuerst übersetzt werden („bottom-up“). Dementsprechend werden unsere Dateien wie folgt analysiert: vhdlan exor.vhd vhdlan and.vhd vhdlan or.vhd vhdlan ha.vhd vhdlan fa.vhd Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

188

KAPITEL 5. HARDWARE-MODELLIERUNG

Der Analyser überprüft den VHDL-Code auf Fehler und erzeugt einige Dateien mit den Endungen .sim und .mra, die wichtige Informationen für den Debugger/Simulator enthalten. Startet man den VHDL-Debugger mit vhdldbx & so erscheint zunächst die in Abbildung 5.19 gezeigte Dialogbox, in der das zu simulierende Design und die gewünschte Zeitauflösung eingestellt werden. Wir wählen als Zeitauflösung "ns" und als "Entwurf" die Konfiguration des Volladdierers "CFG_FA_STRUCTURE". Klickt man auf "ok", so öffnet sich das Hauptfenster (s. Abbildung 5.20).

NS einstellen

abschicken Abbildung 5.19: Auswahlbox des VHDL-Debuggers

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL

189

beobachte Signal weise Wert zu starte Simulation

Kommandozeile

Abbildung 5.20: Hauptfenster des VHDL-Debuggers Sämtliche Kommandos des VHDL-Debuggers können alternativ per Menü oder über die Kommandozeile aktiviert werden. Zuerst muss festgelegt werden, welche Signale während der Simulation im WaveformFenster angezeigt werden sollen. Das geschieht mit dem Befehl "trace ". Er kann in der Kommandozeile eingetippt werden. Bequemer ist es jedoch, die Signale im Hierarchie-Browser auszuwählen, der über das Menü "Misc" im Hauptfenster gestartet werden kann (s. Abbildung 5.21). Anschließend wird der Volladdierer simuliert, indem abwechselnd mit dem Kommando "assign" verschiedene Eingabewerte gesetzt werden und die Simulation mit dem Kommando "run" für eine gewisse Zeit gestartet wird. Das Ergebnis, dass in Abbildung 5.22 dargestellt ist, erhält man mit der folgenden Befehlsfolge: assign ’1’ /full_adder/a assign ’0’ /full_adder/b assign ’1’ /full_adder/c_in run 100 assign ’1’ /full_adder/b run 100 assign ’0’ /full_adder/a assign ’0’ /full_adder/c_in run 100 Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

190

KAPITEL 5. HARDWARE-MODELLIERUNG

Abbildung 5.21: Hierarchie-Browser

Abbildung 5.22: Waveform Viewer Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL

191

5.2.3 Arbeiten mit VHDL - Simulator Scirocco In diesem Abschnitt soll der Umgang mit dem VHDL-Analyser und dem VHDLDebugger der Firma Synopsys anhand des Volladdierer-Entwurfes aus dem vorherigen Abschnitt beispielhaft erläutert werden. Der Ablauf gliedert sich in die folgenden Schritte: 1. VHDL-Quellcodedateien werden erstellt 2. Designanalyse. Diese Dateien werden anaysiert (compiliert) : vhdlan .vhd 3. Die Ergebnisse der Designanalyse landen in der Bibliothek WORK (default) 4. Start der Simulation : scirocco Im Folgenden werden die nötigen Schritte zur Dürchführung einer Simulation des Entwurfes mittels des Simulators Scirocco erläutert. Zunächst muss der VHDL-Code mit einem Editor eingegeben und in entsprechenden Dateien abgespeichert werden. Es ist zu empfehlen, für jede Entity eine eigene (manchmal auch mehrere) Dateien anzulegen. In diesem Beispiel sind das die Dateien: • exor.vhd • and.vhd • or.vhd • ha.vhd • fa.vhd In Abbildung 5.16 bis Abbildung 5.18 sind diese Dateien (ausgenommen and.vhd und or.vhd, die genauso aufgebaut sind wie exor.vhd) vollständig aufgelistet. Beim Analysieren der VHDL-Dateien sind bestimmte Regeln zu beachten: • Die "entity" muss vor der/den zugehörigen "architecture(s)" übersetzt werden. • Bei mehreren Dateien mit verschiedenen Architekturen ist darauf zu achten, dass die „entity”-Deklaration nur einmal vorhanden ist. • Elemente auf tieferen Hierarchiestufen müssen zuerst übersetzt werden („bottom-up“). Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

192

KAPITEL 5. HARDWARE-MODELLIERUNG

Dementsprechend werden unsere Dateien wie folgt analysiert (Designanalyse): vhdlan and.vhd vhdlan or.vhd vhdlan exor.vhd vhdlan ha.vhd vhdlan fa.vhd Der Analyser überprüft den VHDL-Code auf Fehler und erzeugt einige Dateien mit den Endungen .sim und .mra, die wichtige Informationen für den Debugger/Simulator enthalten. Sollten dabei Fehler auftreten, so müssen sie den Entwurf korrigieren (die *.vhd) Dateien und dann erneut analysieren. Im Verzeichnis WORK sollten jetzt u.a. folgende Dateien stehen: CFG_VA_NETLIST.sim VA.mra VA__NETLIST.sim VA.sim Nach erfolgreicher Designanalyse folgt die Schaltungssimulation. Dazu muss zunächst die bei der Designanalyse erzeugte Datei CFG_VA_NETLIST.sim kompiliert werden. Geben sie dazu folgendes Kommando ein: scs CFG_FA_STRUCTURE Nach der erfolgreichen Kompilation rufen sie den Simulator über folgenden Befehl auf: scirocco & Wählen sie in dem Hauptmenü-Fenster (vgl. Abbildung 5.23) den Menüpunkt Interactive. Es öffnet sich ein neues Fenster („Simulator Invocation Dialog” vgl. Abbildung 5.24 ) in dem der verwendete Simulator (Scirocco) aufgerufen werden kann. Geben sie dazu in der Kommandozeile dieses Fensters folgendes ein: ./scsim

Abbildung 5.23: Hauptmenü-Fenster

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL

193

Abbildung 5.24: Simulator Invocation Dialog Nach der Bestätigung (z.B. auf den OK Button des Simulator Invocation Dialog klicken) erscheint ein Simulationskontroll-Fenster (vgl. Abbildung 5.25).

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

194

KAPITEL 5. HARDWARE-MODELLIERUNG

Abbildung 5.25: Simulationskontoll-Fenster Damit Signale in einem Timingdiagramm angezeigt werden, öffnen sie im Simulationskontrollfenster über den Menüpunkt |Window->Waveform| das Waveform-Fenster (vgl. Abbildung 5.26) und über den Menüpunkt |Window->Hierarchy| den HierarchyBrowser (vgl. Abbildung 5.27). Mit dem Hierachy-Browser können Signale und Komponenten durch Drag & Drop in andere Fenstern übertragen werden. Selektieren sie im Hierarchy-Brwoser die Komponente FULL_ADDER (mittlere Maustaste - gedrückt Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL

195

lassen) und ziehen sie sie in das Wavefom-Fenster (genauso wie beim Microsoft Windows Drag&Drop - nur halt mit der mittleren Maustaste). Die entsprechenden Signale werden dann in das Waveform-Fenster eingetragen.

Abbildung 5.26: Waveform-Fenster

Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

196

KAPITEL 5. HARDWARE-MODELLIERUNG

Abbildung 5.27: Hierarchy-Browser Um den Signalverlauf während der Simulation in dem Waveform-Fenster verfolgen zu können, muss das Waveform-Fenster mit dem Simulationskontroll-Fenster gelinkt sein. Dies geschieht z.B. über ein entsprechendes Icon im Waveform-Fenster (rechts außen in der Iconleiste des Fensters) . Per Default sollte dies aber bereits autmatisch beim Öffnen des Waveform-Fensters geschehen sein. Die Simulation wird über das Simulationskontroll-Fenster (vgl. Abbildung 5.25) gesteuert. Die Befehlseingabe erfolgt über das Textfeld „Command” in diesem Fenster. Die verschiedenenen Befehle für den Simulator können mit help angzeigt werden. Mit dem Kommando assign können Signalleitungen logische Werte zugewiesen werden, z.B. setzt folgendes Kommando alle Eingänge auf 0 : assign ’0’ /FULL_ADDER/a /FULL_ADDER /b /FULL_ADDER /c_in oder: assign ’0’ a b c_in Date : 2008 − 10 − 1015 : 39 : 06 + 0200(F ri, 10Oct2008)

Rev : 796

5.2. VHDL

197

falls der Scope im entsprechenden Textfeld „Scope” (unten im SimulationskontollFenster) auf „/FULL_ADDER” gesetzt wird. Um den Simulationsprozess zu starten, geben sie das Kommando run 10 ein. Damit wird Ihre Schaltung für 10 Zeiteinheiten simuliert. Das Ergebnis kann im WaveformFenster (vgl. Abbildung 5.26) abgelesen werden. Legen sie z.B. alle möglichen Eingabestimuli (000 ... 111) an die primären Eingänge des Volladdierers, und simulieren sie jeweils für 10 Zeiteinheiten. Anhand des Timingdiagramms (im Waveform-Fenster) kann dann geprüft werden, ob die Funktion der Schaltung mit der Spezifikation übereinstimmt. Beendet werden kann die Simulatiosumgebung über die Schaltfäche Exit im Hauptmenü- Fenster (vgl. Abbildung 5.23).

5.2.4 Datenobjekte und Datentypen Datenobjekte In VHDL gibt es die folgenden Datenobjekte: • Variablen zum Speichern temporärer Daten. Die Wertzuweisung erfolgt mit dem Zuweisungsoperator ":=". Beispiel: variable counter: integer; ... counter := 1; • Konstanten Beispiel: constant zero: bit_vector (3 downto 0) := "0000"; • Signale, mit denen Verbindungen zwischen Komponenten oder auch Zustände von Registern dargestellt werden. Im Gegensatz zu Variablen erlauben Signale die Modellierung von Zeitverhalten. Die Signalzuweisung erfolgt mit dem Operator "