Rechnerstrukturen Michael Engel und Peter Marwedel TU Dortmund, Fakultät für Informatik Sommer 2014 Folien a. d. Basis von Materialien von Gernot Fink und Thomas Jansen 24. April 2014 1/45 1 Boolesche Funktionen und Schaltnetze Schaltnetze Rechner-Arithmetik Addition Bessere Schaltnetze zur Addition Carry-Look-Ahead-Addierer Multiplikation Wallace-Tree 2/45 Schaltnetze bis jetzt Diskussion (theoretischer) Grundlagen Wo bleibt die Hardware? kommt jetzt Wunsch klar aber immer noch abstrakt Realisierung boolescher Funktionen in Hardware brauchen Realisierung einer funktional-vollständigen Menge boolescher Funktionen Erinnerung Realisierung von NAND reicht aus +V xy Beobachtung x realisiert NAND(x, y ) y 3/45 Gatter Realisierung mit Transistoren . . . falsche Ebene! Grundlage hier einfache logische Bausteine (Gatter) Bausteine für Negation, Konjunktion, Disjunktion, . . . Spielregeln ◮ Eingänge mit Variablen oder Konstanten belegt ◮ nur Verbindungen von Ausgängen zu Eingängen ◮ keine Kreise Ergebnis heißt Schaltnetz 4/45 Symbole für Gatter (1) Funktion DIN 40700 y =x x y y = x1 ∧ x2 ∧ x3 x1 x2 x3 y y = x1 ∧ x2 ∧ x3 x1 x2 x3 y DIN EN 60617 IEEE x 1 y x y x1 x2 x3 & y x1 x2 x3 y x1 x2 x3 & y x1 x2 x3 y 5/45 Symbole für Gatter (2) Funktion DIN 40700 y = x1 ∨ x2 ∨ x3 x1 x2 x3 y y = x1 ∨ x2 ∨ x3 x1 x2 x3 y y = x1 ⊕ x2 x1 y x2 y = x1 x2 ∨ x1 x2 IEEE x1 x2 x3 >1 y x1 x2 x3 y x1 x2 x3 >1 y x1 x2 x3 y =1 y x1 x1 y y x2 x2 x1 x2 DIN EN 60617 x1 x1 y y x2 x2 6/45 Schaltnetz-Bewertung Und jetzt beliebige Schaltnetze entwerfen? mindestens relevant Größe und Geschwindigkeit ◮ Schaltnetzgröße (= Anzahl der Gatter) wegen Kosten, Stromverbrauch, Verlustleistung, Zuverlässigkeit, . . . ◮ Schaltnetztiefe (= Länge längster Weg Eingang wegen Schaltgeschwindigkeit ◮ Fan-In (= max. Anzahl eingehender Kanten) wegen Realisierungsaufwand ◮ Fan-Out (= max. Anzahl ausgehender Kanten) wegen Realisierungsaufwand ◮ . . . (z. B. Anzahl Gattertypen, Testbarkeit, Verifizierbarkeit) Ausgang) 7/45 Was wir schon wissen Jede boolesche Funktion kann mit einem {∧, ∨, ¬}- bzw. einem {⊕, ∧, ¬}-Schaltnetz der Tiefe 3 realisiert werden. Beweis DNF, KNF oder RNF direkt umsetzen Probleme ◮ Fan-In des tiefsten Gatters kann extrem groß sein ◮ Größe des Schaltnetzes oft inakzeptabel 8/45 Beispiel: DNF fbsp : B 3 → B, Wertevektor (1, 0, 0, 0, 1, 1, 1, 1) f (x1 , x2 , x3 ) = x1 x2 x3 ∨ x1 x2 x3 ∨ x1 x2 x3 ∨ x1 x2 x3 ∨ x1 x2 x3 x1 1 & & x2 1 & >1 f bsp & & x3 1 9/45 Beispiel: RNF fbsp : B 3 → B, Wertevektor (1, 0, 0, 0, 1, 1, 1, 1) f (x1 , x2 , x3 ) = x1 x2 x3 ⊕ x1 x2 x3 ⊕ x1 x2 x3 ⊕ x1 x2 x3 ⊕ x1 x2 x3 x1 1 & & x2 1 & =1 f bsp & & x3 1 10/45 Beispiel: KNF fbsp : B 3 → B, Wertevektor (1, 0, 0, 0, 1, 1, 1, 1) f (x1 , x2 , x3 ) = (x1 ∨ x2 ∨ x3 ) ∧ (x1 ∨ x2 ∨ x3 ) ∧ (x1 ∨ x2 ∨ x3 ) x1 >1 x2 1 >1 x3 1 >1 & f bsp 11/45 Multiplexer eine weitere Beispielfunktion . . . aber eine in der Praxis sehr wichtige diesmal! MUXd y1 , y2 , . . . , yd , x0 , x1 , . . . , x2d −1 = x(y1 y2 ··· yd )2 Beispiel y1 y2 0 0 0 0 0 1 0 1 1 0 1 0 1 1 1 1 y3 0 1 0 1 0 1 0 1 MUX3 (y1 , y2 , y3 , x0 , x1 , . . . , x7 ) x0 x1 x2 x3 x4 x5 x6 x7 12/45 Multiplexer Warum ist MUX in der Praxis wichtig? direkte Speicheradressierung OBDD-Realisierung Welche Variablenordnung π? wohl sinnvoll Adressvariablen zuerst denn Wir müssen uns sonst alle Datenvariablen merken! 13/45 OBDD-Realisierung MUX3 Variablenordnung π = (y1 , y2 , y3 , x0 , x1 , x2 , x3 , x4 , x5 , x6 , x7 ) y1 0 1 y2 0 y2 1 0 y3 0 x0 y3 1 x1 0 y3 1 x2 0 x3 0 1 1 x4 1 jeweils xi realisieren y3 x5 0 x6 1 x7 xi 0 0 1 1 14/45 Einfluss von π auf OBDD-Größe Beispiel MUXd gesehen Variablenordnung π = (y1 , y2 , . . . , yd , x0 , x1 , . . . , x2d −1 ) Größe des reduzierten πOBDDs? oben unten vollständiger Binärbaum über y1 , y2 , . . . , yd 20 + 21 + · · · + 2d−1 = 2d − 1 Knoten je ein xi -Knoten und zwei Senken 2d + 2 Knoten zusammen 2d − 1 + 2d + 2 = 2d+1 + 1 Knoten 15/45 Einfluss von π auf OBDD-Größe Beispiel MUXd gesehen Variablenordnung π = (y1 , y2 , . . . , yd , x0 , x1 , . . . , x2d −1 ) Größe des reduzierten πOBDD 2d+1 + 1 Betrachte Variablenordnung π = (x0 , x1 , . . . , x2d −1 , y1 , y2 , . . . , yd ) Größe des reduzierten πOBDDs? Behauptung Beweis d ∀x 6= x ′ ∈ {0, 1}2 : nach Lesen von x bzw. x ′ verschiedene Knoten erreicht durch Widerspruch 16/45 Widerspruchsbeweis zur OBDD-Größe d ∀x 6= x ′ ∈ {0, 1}2 : nach Lesen von x bzw. x ′ verschiedene Knoten erreicht Behauptung Annahme Betrachte Betrachte d für x 6= x ′ ∈ {0, 1}2 gleiche Knoten v erreicht i = min{j | xj 6= xj′ } y1 , y2 , . . . , yd mit (y1 y2 · · · yd )2 = i Beobachtung MUXd (y1 , y2 , . . . , yd , x) = xi 6=xi′ = MUXd (y1 , y2 , . . . , yd , x ′ ) aber OBDD berechnet gleichen Wert, da gleicher Knoten erreicht also minimales OBDD für π = (x0 , x1 , . . . , x2d −1 , y1 , y2 , . . . , yd ) d hat Größe mindestens 22 − 1 (Binärbaum d. Tiefe 2d ) min. OBDD-Größe π = (d, x) min. OBDD-Größe π = (x, d) 9 ≥ 15 33 ≥ 65 535 513 ≥ 1,1579 · 107717/45 d 2 4 8 Schaltnetz für MUX3 x0 & x1 & x2 & x3 & x4 & >1 x5 MUX3 & x6 & x7 & 1 1 1 y1 y2 y3 18/45 Rechner-Arithmetik klar Rechnen zu können ist für Computer zentral. Was wollen wir hier rechnen? hier nur Grundrechenarten, aber keine Division, also ◮ Addition ◮ Subtraktion ◮ Multiplikation Womit wollen wir hier rechnen? ◮ mit ganzen Zahlen ◮ mit rationalen Zahlen (IEEE 754-1985) 19/45 Addition Wie haben wir das in der Schule gelernt? 1. Summand 2. Summand Übertrag Summe 9 + 1 1 1 0 3 9 1 3 8 7 1 6 9 9 1 9 9 8 1 8 8 9 1 8 9 8 0 0 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1 1 7 Übertragung auf Binärzahlen 1. Summand 2. Summand Übertrag Summe + 1 1 1 1 1 0 0 1 0 20/45 Addition von Binärzahlen Beobachtungen zu den Überträgen ◮ ◮ ◮ ◮ 1 + 1“ erzeugt einen Übertrag ” 0 + 0“ eliminiert einen vorhandenen Übertrag ” 0 + 1“ und 1 + 0“ reichen einen vorhandenen Übertrag weiter ” ” Übertrag ist höchstens 1 Kann man Addition als boolesche Funktion ausdrücken? x y 0 0 fHA : {0, 1}2 → {0, 1}2 mit 0 1 1 0 1 1 realisiert Addition mit Summenbit s Beobachtung c =x ∧y c s 0 0 0 1 0 1 1 0 und Übertrag c (Carry) s =x ⊕y 21/45 Halbaddierer c =x ∧y x y s =x ⊕y =1 s & c Größe 2 Tiefe 1 x 0 2 2 Drückt fHA : {0, 1} → {0, 1} mit 0 1 1 wirklich Addition aus? y 0 1 0 1 c 0 0 0 1 s 0 1 1 0 Beobachtung: Nur für isolierte Ziffern, vorheriger Übertrag fehlt! 22/45 Addition als boolesche Funktion calt x y 0 0 0 0 0 1 0 1 0 fVA : {0, 1}3 → {0, 1}2 mit 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 realisiert Addition mit Summenbit s und Beobachtung c s 0 0 0 1 0 1 1 0 0 1 1 0 1 0 1 1 Übertrag c (Carry) s = 1 ⇔ Anzahl der Einsen ungerade s = calt ⊕ x ⊕ y Beobachtung aber c = 1 ⇔ Anzahl Einsen ≥ 2 direkte Realisierung c = x y ∨ x calt ∨ y calt für Realisierung im Schaltnetz Wiederverwendung von Gattern wünschenswert 23/45 Bessere Realisierung Schaltnetz Volladdierer bisher Ziel s = calt ⊕ x ⊕ y c = x y ∨ x calt ∨ y calt für c 1 realisieren für (calt , x, y ) ∈ {011, 101, 110, 111} Beobachtung fehlt noch also x ⊕ y = 1 ⇔ genau eine 1 in x, y also calt (x ⊕ y ) realisiert 101, 110 011, 111 beides durch x y s = calt ⊕ x ⊕ y c = calt (x ⊕ y ) ∨ x y 24/45 Schaltnetz Volladdierer s = x ⊕ y ⊕ calt c = calt (x ⊕ y ) ∨ x y x y calt =1 s =1 & ≥1 c & Größe 5, Tiefe 3 25/45 Vollständiger Addierer + s1 + s2 x0 y0 x0 y0 s0 x1 y1 s1 x0 y0 s0 s0 s1 HA x0 y0 x1 y1 s0 HA VA s1 s2 26/45 Vollständiger Addierer + s2 + s3 x1 y1 s1 x2 y2 s2 x0 y0 x1 y1 x0 y0 s0 x1 y1 s1 x0 y0 s0 s0 HA s1 s2 VA x0 y0 x1 y1 x2 y2 s0 HA s1 s2 VA VA s3 27/45 Realisierung Addition x0 y0 x1 y1 x2 y2 .. . s0 s1 HA VA1 s2 VA2 ··· .. . xn−1 yn−1 .. . .. . sn−1 ··· VAn−1 sn Größe 2 + (n − 1) · 5 = 5n − 3 Tiefe 1 + (n − 1) · 3 = 3n − 2 28/45 Ergebnis: Ripple-Carry Addierer ◮ Realisierung Addition von natürlichen Zahlen“ ” sehr gut strukturiert ◮ Größe 5n − 3 ← sehr klein ◮ Tiefe 3n − 2 ← viel zu tief Warum ist unser Schaltnetz so tief? Überträge brauchen sehr lange offensichtlich Verbesserungsidee Überträge früher berechnen Erinnerung Struktureinsicht (xi , yi ) = (1, 1) (xi , yi ) = (0, 0) (xi , yi ) ∈ {(0, 1), (1, 0)} generiert Übertrag eliminiert Übertrag reicht Übertrag weiter 29/45 Ausnutzen von Einsichten Struktureinsicht (xi , yi ) = (1, 1) (xi , yi ) = (0, 0) (xi , yi ) ∈ {(0, 1), (1, 0)} Beobachtung xi yi ui 0 0 0 0 1 0 1 0 0 1 1 1 also sehr vi 0 1 1 0 generiert Übertrag eliminiert Übertrag reicht Übertrag weiter gut durch Halbaddierer realisierbar Übertrag eliminieren weiterreichen weiterreichen generieren ui = 1 generiert Übertrag vi = 1 reicht Übertrag weiter zentrale Beobachtung alle HA in Tiefe 1 parallel realisierbar 30/45 Realisierung als Schaltnetz Notation fHA (xi , yi ) = (ui , vi ) ui = 1 vi = 1 ci generiert Übertrag ci +1 reicht Übertrag ci +1 weiter = ui −1 ∨ ui −2 vi −1 ∨ ui −3 vi −2 vi −1 ∨ · · · ∨ u0 v1 v2 · · · vi −1 i^ −1 i_ −1 uj ∧ vk = j=0 k=j+1 Gesamttiefe: 4 alle Halbaddierer (ui , vi ) iV −1 alle Und-Gatter uj ∧ vk Tiefe 1 Tiefe 1 k=j+1 großes Oder-Gatter n× ⊕-Gatter f. korr. Summenbits Tiefe 1 Tiefe 1 31/45 Realisierung als Schaltnetz Mit dem Ansatz ui = 1 generiert Übertrag ci +1 vi = 1 reicht Übertrag ci +1 weiter ci = ui −1 ∨ ui −2 vi −1 ∨ ui −3 vi −2 vi −1 ∨ · · · ∨ u0 v1 v2 · · · vi −1 i^ −1 i_ −1 uj ∧ vk = j=0 k=j+1 beliebig lange Zahlen in Tiefe 4 addieren. . . Ist das fair gezählt? Begriff Nein! Anzahl Eingänge eines Gatters heißt Fan-In Problem Wir vergleichen Schaltnetz mit max. Fan-In 2 mit Schaltnetz mit max. Fan-In n. Ziel Vergleichbarkeit herstellen 32/45 Vermeidung von großem Fan-In großen Fan-In systematisch verkleinern x0 x0 x1 x1 ≥ 1 x2 x2 x3 x3 ≥ 1 x4 x4 x5 x5 ≥ 1 x6 x6 x7 x7 ≥ 1 ≥1 x8 x8 x9 x9 ≥ 1 x10 x10 x11 x11 ≥ 1 x12 x12 x13 x13 ≥ 1 x14 x14 x15 x15 ≥ 1 ≥1 ≥1 ≥1 ≥1 ≥1 ≥1 ≥1 Beispiel ODER, Fan-In 16 33/45 Vermeidung von großem Fan-In am Beispiel aus Fan-In 16 wird Fan-In 2 bei Tiefe 1 bei Tiefe 4 (Größe 1) bei Größe 15 Wie ist das allgemein? Größe bei jeder Stufe nur noch halb so viele Gatter n 2 + n 4 + n 8 + ··· + 1 ≈ n Tiefe so oft halbieren, bis man bei 1 Gatter ist ≈ log2 n 34/45 Carry Look-Ahead Addierer (CLA) ◮ Realisierung Addition von natürlichen Zahlen“ ” gut strukturiert ◮ Größe ≈ n2 ◮ Tiefe ≈ 2 log2 n ← ziemlich groß ← ziemlich flach Haben wir jetzt im Vergleich zum Ripple-Carry-Addierer gewonnen? n 8 16 32 64 RippleCarry Größe 37 77 157 317 RippleCarry Tiefe 22 46 94 190 Carry Look-Ahead Größe 64 256 1 024 4 096 Carry Look-Ahead Tiefe 6 8 10 12 35/45 Noch einmal nachdenken. . . Wir wissen doch schon Jede boolesche Funktion in Tiefe 3 realisierbar! (DNF, KNF, RNF) Wieso nicht auf die Addition? ◮ klar geht in Tiefe 3 ◮ aber Größe inakzeptabel (exponentiell) Fazit vorhandenes Vorwissen ausnutzen, Normalformen nur bei kleinen oder unstrukturierten Funktionen 36/45 Multiplikation direkt mit Binärzahlen. . . 1 0 1 also 1 1 0 0 1 0 0 1 1 0 1 1 1 0 1 0 1 0 0 · 1 1 1 0 1 1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1 1 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 0 0 0 Multiplizieren heißt ◮ Nullen passend schreiben ◮ Zahlen passend verschoben kopieren ◮ viele Zahlen addieren 37/45 Multiplikation als Schaltnetz Multiplikation ist ◮ Nullen passend schreiben ◮ Zahlen passend verschoben kopieren ◮ viele Zahlen addieren klar Nullen schreiben einfach und kostenlos, Zahlen verschieben und kopieren einfach und kostenlos, viele Zahlen addieren nicht ganz so einfach 38/45 Addition vieler Zahlen klar Wir haben Addierer für die Addition zweier Zahlen. Wie addieren wir damit n Zahlen? erster Ansatz einfach nacheinander m1 m2 m3 m4 m5 · · · mn Tiefe (n − 1) · Tiefe(+) Schrecklich! + klar sehr naiv + merken + in Schaltnetzen niemals alles nacheinander + Was geht gleichzeitig? .. . + 39/45 Addition von n Zahlen besserer Ansatz paarweise addieren m1 m2 m3 m4 m5 m6 m7 m8 + + + + + + + Anzahl Addierer = n2 + n4 + · · · 1 ≈ n Gesamtgröße ≈ n · Größe(+) Tiefe also auf i -ter Ebene 2log2 (n)−i Addierer ≈ log2 (n) Ebenen Gesamttiefe ≈ log2 (n) · 2 log2 (n) = 2 log2 (n)2 Geht es vielleicht noch schneller? 40/45 Addition von n Zahlen noch schneller (triviale) Beobachtung ◮ ◮ zentral für uns gleiche Summe weniger Zahlen (verrückte?) Idee Addition ersetzt zwei Zahlen durch eine Zahl gleicher Summe Korrektheit Fortschritt“ ” Vielleicht ist es einfacher, drei Zahlen zu ersetzen durch zwei Zahlen gleicher Summe? klar immer noch gleiche Summe ” Korrektheit“ aber 3 2“ statt 2 1“ ” ” weniger Fortschritt Ist das schlimm? 41/45 Wallace-Tree m1 m2 m3 m4 CSA m5 m6 m7 CSA CSA m8 CSA m9 m10 m11 m12 CSA CSA CSA Carry Save Adder (≈ log3/2 (n) Ebenen) klar nur sinnvoll, wenn CSA viel flacher als Addierer CSA CSA CSA + 42/45 Carry Save Adder gesucht Zahlen a, b mit a + b = x + y + z Beobachtung für x, y , z ∈ {0, 1} schon bekannt x + y + z = 2 · u + v (Volladdierer) Beobachtung Es genügt, das parallel für alle Stellen zu tun. + + u3 + x3 y3 z3 (2u3 + v3 ) u2 v3 x2 y2 z2 (2u2 + v2 ) u1 v2 x1 y1 z1 (2u1 + v1 ) u0 v1 x0 y0 z0 (2u0 + v0 ) v0 43/45 Korrektheit der CSA-Realisierung aus Volladdierer x +y +z xi + yi + zi = 2ui + vi = = n−1 X xi · 2i i =0 n−1 X ! + n−1 X i =0 (xi + yi + zi ) · 2i i =0 = = n−1 X (2ui + vi ) · 2i i =0 n−1 X i =0 i +1 ui · 2 yi · 2i ! + ! + i ! n−1 X i =0 zi · 2i ! n−1 X i =0 vi · 2 44/45 Multiplikation mit Wallace-Tree klar für drei n-Bit-Zahlen reichen n Volladdierer also Größe Tiefe 5n 3 Gesamtgröße ∼ n2 Gesamttiefe ≈ 3 · log3/2 (n) + 2 log2 (n) ≈ 7,13 log2 (n) | {z } | {z } Wallace-Tree Fazit Addierer Multiplikation wesentlich teurer“ als Addition, ” aber nicht wesentlich langsamer! 45/45