Rechnerstrukturen - LS12

Werbung
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
Herunterladen