Rechnerstrukturen Michael Engel und Peter Marwedel TU Dortmund, Fakultät für Informatik SS 2013 Hinweis: Folien a. d. Basis von Materialien von Gernot Fink und Thomas Jansen Boole. Fkt. 23. April 2013 1 Boolesche Funktionen und Schaltnetze Schaltnetze Rechner-Arithmetik Addition Bessere Schaltnetze zur Addition Carry-Look-Ahead-Addierer Multiplikation Wallace-Tree Boole. Fkt. 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 y Boole. Fkt. realisiert NAND(x, y ) 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 Boole. Fkt. 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 Boole. Fkt. 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 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 Boole. Fkt. 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 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) Boole. Fkt. Ausgang) 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 Boole. Fkt. 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 & & & x3 Boole. Fkt. 1 >1 f bsp 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 & & & x3 Boole. Fkt. 1 =1 f bsp 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 Boole. Fkt. & f bsp 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 Boole. Fkt. y3 0 1 0 1 0 1 0 1 MUX3 (y1 , y2 , y3 , x0 , x1 , . . . , x7 ) x0 x1 x2 x3 x4 x5 x6 x7 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! Boole. Fkt. 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 y3 1 x4 jeweils xi realisieren Boole. Fkt. 1 x5 xi 0 0 1 1 0 x6 1 x7 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 Boole. Fkt. 2d − 1 + 2d + 2 = 2d+1 + 1 Knoten 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 Boole. Fkt. d ∀x 6= x ′ ∈ {0, 1}2 : nach Lesen von x bzw. x ′ verschiedene Knoten erreicht durch Widerspruch 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 · 1077 d 2 4 8 Boole. Fkt. Schaltnetz für MUX3 x0 & x1 & x2 & x3 & x4 & >1 x5 & x6 & x7 Boole. Fkt. & 1 1 1 y1 y2 y3 MUX3 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) Boole. Fkt. 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 Boole. Fkt. + 1 1 1 1 1 0 0 1 0 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 Boole. Fkt. c =x ∧y c s 0 0 0 1 0 1 1 0 und Übertrag c (Carry) s =x ⊕y 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! Boole. Fkt. Realisierung von Addition als boolesche Funktion calt x y 0 0 0 0 0 1 0 1 0 3 2 fVA : {0, 1} → {0, 1} mit 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 realisiert Addition mit Summenbit s und Beobachtung Beobachtung aber Boole. Fkt. 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 c = 1 ⇔ Anzahl Einsen ≥ 2 direkte Realisierung c = x y ∨ x calt ∨ y calt für Realisierung im Schaltnetz 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 Boole. Fkt. 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 Schaltnetz Volladdierer s = x ⊕ y ⊕ calt c = calt (x ⊕ y ) ∨ x y x y calt =1 s =1 & ≥1 & Größe 5, Tiefe 3 Boole. Fkt. c Vollständiger Addierer + s1 + s2 Boole. Fkt. x0 y0 x0 y0 s0 x1 y1 s1 x0 y0 s0 s0 s1 HA x0 y0 x1 y1 s0 HA VA s1 s2 Vollständiger Addierer + s2 + s3 Boole. Fkt. 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 Realisierung Addition x0 y0 x1 y1 x2 y2 .. . s0 s1 HA VA1 s2 VA2 ··· .. . xn−1 yn−1 Größe 2 + (n − 1) · 5 = 5n − 3 Tiefe 1 + (n − 1) · 3 = 3n − 2 Boole. Fkt. .. . .. . sn−1 ··· VAn−1 sn 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)} Boole. Fkt. generiert Übertrag eliminiert Übertrag reicht Übertrag weiter 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 Boole. Fkt. 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 Boole. Fkt. Tiefe 1 Tiefe 1 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 Boole. Fkt. 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 Beispiel ODER, Fan-In 16 Boole. Fkt. ≥1 ≥1 ≥1 ≥1 ≥1 ≥1 ≥1 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 Boole. Fkt. 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 Boole. Fkt. 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 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 Boole. Fkt. vorhandenes Vorwissen ausnutzen, Normalformen nur bei kleinen oder unstrukturierten Funktionen 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 Multiplizieren heißt ◮ Nullen passend schreiben ◮ Zahlen passend verschoben kopieren ◮ viele Zahlen addieren Boole. Fkt. 0 0 0 Multiplikation als Schaltnetz Multiplikation ist ◮ Nullen passend schreiben ◮ Zahlen passend verschoben kopieren ◮ viele Zahlen addieren klar Boole. Fkt. Nullen schreiben einfach und kostenlos, Zahlen verschieben und kopieren einfach und kostenlos, viele Zahlen addieren nicht ganz so einfach 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? Boole. Fkt. .. . + 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? Boole. Fkt. 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 ” aber 3 2“ statt 2 1“ ” ” weniger Fortschritt Ist das schlimm? Boole. Fkt. Korrektheit Wallace-Tree m1 m2 m3 m4 CSA m5 m6 m7 CSA CSA CSA CSA CSA Carry Save Adder (≈ log3/2 (n) Ebenen) klar nur sinnvoll, wenn CSA viel flacher als Addierer CSA CSA CSA + Boole. Fkt. m8 m9 m10 m11 CSA m12 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 + Boole. Fkt. 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 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 Boole. Fkt. i +1 ui · 2 yi · 2i ! + ! + i ! i =0 n−1 X i =0 vi · 2 n−1 X zi · 2i ! 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 } Wallce-Tree Fazit Boole. Fkt. Addierer Multiplikation wesentlich teurer“ als Addition, ” aber nicht wesentlich langsamer!