(:requiretuid:)
Die Grundelemente digitaler Schlatungen sind: Gatter, Multiplexer, Decoder, Register, Arithmetische Schaltungen, Zähler, Speicher und programmierbare Logikfelder.
Diese veranschaulicht man durch:
Diese Grundelemente werden für den Aufbau eines eigenen Mikroprozessors verwendet (dazu in Kapitel 7 mehr)
Diese werden auch Carry-propagate adder (CPA) genannt. Dabei gibt es verschiedene Typen:
Der Carry-Lookahead und Prefix-Addierer sind schneller bei breiteren Datenworten, benötigen dafür aber auch mehr Fläche.
Der Ripple-Carry-Addierer besteht aus einer Kette von 1-bit-Addierern. Die Überträge werden von niedrigen zu hohen Bits weitergegeben. Sie ripplen sich durch die Schaltung.
Dadurch ist der Ripple-Carry-Addierer langsam.
Die Verzögerung durch einen N-bit Ripple-Carry-Addierer berechnet sich durch
dabei ist die Verzögerung durch einen Volladdierer.
Statt Bit-zu-Bit Einzelberechnungen, wird nun der Carry jeweils für Blöcke von k-Bits berechnet. Dazu werden 2 Signale eingeführt:
Wie vorher beim Ripple-Carry-Addierer werden die Bits in Spalten organisiert, jetzt gibt es aber mehrere Zeilen.
Eine Spalte (Bit i) produziert einen Übertrag an ihrem Ausgang Ci
Eine Spalte (Bit i) erzeugt einen Übertrag falls Ai und Bi beide 1 sind.
Eine Spalte (Bit i) leitet einen eingehenden Übertrag weiter falls Ai oder Bi 1 ist.
Damit ist der Übertrag Ci aus der Spalte i heraus:
Als Beispiel wollen wir dieses Verfahren nun an einem 4b Block (CLA für 2 4b Zahlen) durchgehen. Dazu müssen wir die Signale P3:0 und G3:0 bestimmen.
Wir überlegen uns zunächst, wann ein ein 4b Block einen Übertrag erzeugt. Dies ist der Fall, wenn:
Der 4b Block leitet einen Übertrag direkt weiter, wenn alle Spalten den Übertrag weiterleiten.
Damit ist der Übertrag durch einen i:j Bit breiten Block Ci
Wir können die 4b Blöcke nun verwenden, um aus ihnen einen breiteren CLA zusammenzusetzen. Zum Beispiel verwenden wir acht Stück, um einen 32-bit CLA zu konstruieren.
Dabei gilt Gi = Ai Bi und Pi = Ai + Bi. Wir schließen also immer den Cout eines 4b Blocks an den Cin des darauffolgenden Blockes an.
Die Verzögerung durch einen N-bit CLA mit k-bit Blöcken berechnet sich nach
wobei
Für N > 16 ist ein CLA oftmals schneller als ein Ripple-Carry-Addierer. Aber die Verzögerung hängt immer noch von N ab und ist im wesentlichen linear.
Der Präfix-Addierer führt die Ideen des CLA weiter. Er berechnet den Übertrag Ci-1 in jede Spalte i so schnell wie möglich. Dabei berechnet sich die Summe jeder Spalte folgendermaßen.
Um alle Ci schnell zu berechnen, berechnet ein Präfix-Addierer P und G für größer werdende Blöcke. Also Blöcke der Größe 1b, 2b, 4b, 8b usw. Solange bis die Eingangsüberträge für alle Spalten bereitstehen.
Dadurch besteht der Präfix-Addierer nicht mehr aus N/k Stufen, sondern nur noch log2N Stufen. Die Breite der Operanden geht also nur noch logarithmisch in die Verzögerung ein.
Der Preis für die geringe Verzögerung ist, dass für einen Präfix-Addierer sehr viel Hardware erforderlich ist.
Bei einem Präfix-Addierer wird ein Übertrag...
Definition: Der Eingangsübertrag Cin in den ganzen Addierer kommt aus Spalte -1
Der Eingangsübertrag in eine Spalte i ist der Ausgangsübertrag Ci-1 der Spalte i-1
Gi-1:-1 ist das Generate-Signal von Spalte -1 bis Spalte i-1
Interpretation: Ein Ausgangsübertrag aus Spalte i-1 entsteht...
Damit ist die Summenformel für die Spalte i umschreibbar zu
Deshalb ist nun das Ziel der Hardware-Realisierung, so schnell wie möglich G0:-1, G1:-1, G2:-1, G3:-1, G4:-1, G5:-1 usw. zu bestimmen. Die sogenannten Präfixe.
Die Berechnung von P und G für einen variabel großen Block funktioniert folgendermaßen.
Es gelte:
So ergibt sich für einen Block i:j
Bedeutung:
Ein Block erzeugt einen Ausgabeübertrag, falls
Ein Block leitet einen Eingabeübertrag als Ausgabeübertrag weiter, falls sowohl der untere als auch der obere Teil den Übertrag weiterleiten.
wobei
Als Beispiel berechnen wir hier die Verzögerung bei einer 32b Addition mit einem Ripple-Carry, einem Carry-Lookahead (4-bit Blöcke) und einem Präfix-Addierer. Dabei haben die Volladdierer eine Verzögerung von tFA = 300 ps und die Zwei-Eingangs Gatter eine Verzögerung von tAND = tOR = tXOR = 100ps.
Für vorzeichenlose Zahlen
In diesem Beispiel konfigurieren wir die 32b ALU für eine SLT-Berechnung. Wir nehmen dabei an, dass A = 25 und B = 32 ist. Als Ausgabe erwarten wir A < B, also Y = 32'b1. Wir setzen den Steuereingang entsprechend der Tabelle für SLT: F2:0 = 3'b111. Aus dem Schaltplan wird dabei ersichtlich, dass das Signal F2 = 1'b1 den Addierer als Subtrahierer konfiguriert. Somit ergibt sich für das Signal S = A - B = 25 - 32 = -7. Da der Wert von S im Zweierkomplement vorliegt, also S = -7 = 32'h0xfffffff9, ist, das msb von S, S31 = 1. Mit F1:0 = 2'b11 wählen wir Y = S31 mit einem Zero Extend als Ausgabe. Insgesamt ergibt sich Y = S31 (zero extend) = 32'h00000001.
Der Wert wird um eine Bitposition verschoben. Leere Stellen werden mit 0 aufgefüllt.
Beispiele:
11001
>> 2 = 00110
11001
<< 2 = 00100
Der Wert wird, wie beim logischen Schieben, um eine Bitposition verschoben. Beim Rechtsschieben wird jedoch der alte Wert des msb zum Auffüllen leerer Stellen verwendet.
Beispiele:
11001
>>> 2 = 11110
11001
<<< 2 = 00100
Hierbei werden Bits im Kreis rotiert, d.h. herausgeschobene Bits tauchen am anderen Ende wieder auf.
Beispiele:
11001
ROR 2 = 01110
11001
ROL 2 = 00111
Logisches Schieben um N Stellen nach links multipliziert den Zahlenwert mit
Arithmetisches Schieben um N Stellen nach rechts dividiert den Zahlenwert durch
Schrittweise Multiplikation in Dezimal- und Binärdarstellung:
Sobald die Division einfach dargestellt wird, wird sie leider sehr langsam. Demnach wird sie etwas schneller, wenn sie kompliziert wird. Die Division ist aber immer deutlich langsamer als z.B. die Multiplikation.
Deshalb ist sie für eine Einführungsverantstaltung eher ungeeignet, die Beschreibung im Buch ist auch leider ziemlich schlecht... Deswegen wird die Division hier nur gestreift.
Dividiere vorzeichenlose Zahlen:
Dividend z (2k Bit breit) durch Divisor d (k Bit breit)
Ergebnis:
Quotient q (k Bit breit) und Rest s (k Bit breit)
Es gilt: z = q d + s
Beispiel: k=8, ergo 16b Dividend, 8b Divisor, 8b Quotient, 8b Rest.
Problem: nicht alle Ergebnisse sind repräsentierbar!
Operanden: z = 65534, d = 2
Ergebnis: q = 32767 ist nicht mehr in 8b darstellbar, Überlauf! s = 0
Vorgehensweise: Vorher auf darstellbares Ergebnis prüfen
Maximalwert für Dividenden:
Damit ergibt sich :
impliziert: Wenn , dann kein ÜberlaufHier ein einfaches (aber langsames) Vorgehen:
Optimierung: Schiebe nicht Divisor nach rechts sondern partiellen Rest nach links
Falls Differenz >= 0: , sonst
Wir haben bisher verscheidene Zahlensysteme kennen gelernt:
Es fehlen also noch Brüche, rationale Zahlen und reelle Zahlen.
Es gibt zwei gängige Darstellungen:
Die Position des Kommas bleibt konstant.
Beispiel: Dezimalsystem, 2 Vorkomma-, 3 Nachkommastellen
Die Position des Kommas kann wandern, ist stets rechts der höchstwertigen Stelle <>0. Die Position des Kommas wird durch die Exponentenschreibweise angegeben.
Beispiele: Dezimalsystem, insgesamt 5 Stellen
nicht:
Es gibt eine Obergrenze für Exponenten. Man kann keine beliebig großen Zahlen darstellen.
Die Darstellung von 6,75 mit 4b für den ganzen Anteil und 4b für den Binärbruch:
0110110 -> 0110 , 1100
Das Binärkomma wird nicht explizit dargestellt. Die Position wird durch das Format impliziert (hier: 4,4).
Dies hat den Nachteil, dass alle Leser und Schreiber von Festkommadaten das selbe Format verwenden müssen.
in 8b im binären 4,4 - Festkommaformat: 0111 1000Wie bei ganzen Zahlen sind auch hier zwei Darstellungen möglich. Auch hier gibt es die Vorzeichen-/Betragsform und das Zweierkomplement.
in 8b im binären 4,4 - Festkommaformat Vorzeichen/Betrag: 11111000 in 8b im binären 4,4 - Festkommaformat Zweierkomplement: +7,5 = 0111 1000, invertiert: 1000 0111, +1 -> 1000 1000Das Binärkomma liegt immer genau rechts von der höchswertigen 1. Dies ist ähnlich zur wissenschaftlichen Darstellung von Dezimalbrüchen. Die 4,387263 in wissenschaftlicher Darstellung ist .
Die Allgemeine Schreibweise ist:
dabei ist:
Im Beispiel haben wir hier: M = 4,387263, B = 10 und E = 6
Beispiel: Stelle den Wert 288 als 32b-Gleitkommazahl dar.
Wir stellen hier drei Versionen dar, dabei ist aber nur die letzte davon eine Standarddarstellung!
Wandle die Dezimalzahl in die Binärdarstellung um:
Trage nun die Daten in die Felder des 32b Wortes ein:
Wir beobachten, dass das erste Bit der Mantisse immer eine 1 ist.
Man kann sich das explizite Abspeichern der führenden 1 also sparen, da sie immer implizit als präsent angenommen wird.
Stattdessen speichert man nur den Bruchanteil (die "Nachkommastellen") explizit ab.
Der Exponent kann auch negativ sein. Hier ist aber die Idee des Zweierkomplements möglich, sie hat aber praktische Nachteile. Besser ist es den Exponent relativ zu einem konstanten Grundwert (Exzess, Biaswert) anzugeben.
Hier ist der Biaswert = 127 (0111 1111)
Der Exponent mit Bias = Biaswert + Exponent
Der Exponent 7 wird also gespeichert als:
Damit hat man die IEEE 754 32-bit Gleitkommadarstellung von 288
Wir stellen hier -58,25 gemäß dem IEEE 754 32-bit Gleitkommastandard dar.
1. Wir wandeln in die Binärdarstellung um:
2. Wir tragen die Felder des 32b Gleitkommawortes ein:
In Hexadezimalschreibweise ist dies 0xC2690000
.
Nicht alle benötigten Werte sind nach dem Schema darstellbar.
Zum Beispiel hat die 0 keine führende 1.
Beispiel: Runde 1,100101 (1,578125) auf 3 Bits Bruchanteil
1. Exponenten- und Bruchanteilfelder aus Gleitkommawort extrahieren
2. Bruchanteil um die führende 1 erweitern, um die Mantisse zu bilden
3. Vergleiche den Exponenten
4. Schiebe die Mantisse von der Zahl mit dem kleineren Exponenten nach rechts (bis die Exponenten gleich sind)
5. Addiere die Mantissen
6. Normalisiere die Mantissen und passe den Exponenten falls nötig an
7. Runde das Ergebnis entsprechend dem gewählten Rundungsmodus
8. Baue das Gleitkommawort aus Exponenten und Bruchanteil des Ergebnisses
Wir addieren hier die beiden Gleitkommazahlen 0x3fC00000
und 0x40500000
.
1. Extrahiere den Exponenten und den Bruchanteil aus 32b Worten
2. Erweitere den Bruchanteil um die führende 1, um die Mantisse zu bilden
M1: 1,1 M2: 1,101
3. Vergleiche die Exponenten
E2 - E1 = 128 -127 = 1, N1 muss also um ein Bit geschoben werden.
4. Die Mantisse der Zahl mit dem kleineren Exponenten entsprechend nach recht schieben
M1: 1,1 >> 0,11
5. Mantissen addieren (haben jetzt den gleichen Exponenten)
6. Normalisiere die Mantisse und passe den Exponenten an, falls nötig
7. Runde das Ergebnis entsprechend dem Rundungsmodus
Dies ist hier nicht nötig, da unser Ergebnis in 23Bit passt.
8. Baue aus Exponent und Mantisse ein neues Gleitkommawort für das Ergebnis
S = 0
E = 2 + 127 = 129 = 1000 0001
F = 001 1000 ... 0000
Das Ergebnis in Hexadezimalschreibweise ist 0x40980000
.
Im einfachsten Fall wird ein Zähler zu jeder positiven Taktflanke inkrementiert.
Es wird durch einen Zyklus von Werten gezählt. Zum Beispiel bei 3b Breite: 000,
001, 010, 011, 100, 101, 110, 111, 000, 001,...
Beispielanwendungen sind Digitaluhren oder ein Programmzähler (zeigt auf die
nächste auszuführende Instruktion).
Bei einem Schieberegister (auch: FIFO, first-in first-out) wird jeden Takt ein neuer Wert eingeschoben und ein alter Wert ausgeschoben. Dadurch kann man es auch als Seriell-nach-Parallel-Konverter verwenden. D.h. eine serielle Eingabe (Sin) wird in eine parallele Ausgabe (Q0:N-1) konvertiert.
Ist das Signal Load = 1, agiert die Schaltung als normales N-bit Register. Ist Load = 0, agiert die Schaltung als Schieberegister. Dadurch ist sie verwendbar als Seriell-nach-Parallelkonverter (Sin nach Q0:N-1) und Parallel-nach-Seriellkonverter (D0:N-1 nach Sout).
Speicherfelder können effizient größere Datenmengen speichern. Dabei gibt es drei weitverbreitete Typen:
An jede N-bit Adresse kann ein M-bit breites Datum geschrieben werden.
Speicherfelder sind zweidimensionale Felder von Bit-Zellen, wobei jede Bit-Zelle genau 1 Bit speichert.
Ein Feld hat N Adressbits und M Datenbits
Wordline:
Zwei wesentliche Typen:
Verwenden unterschiedliche Speichertechniken für die Bit-Zellen:
Datenbit wird als Ladung eines Kondensators interpretiert. Dynamisch, da der Speicherwert periodisch neu geschrieben werden muss.
Implementierung der folgenden logischen Funktionen auf einem Bit ROM:
Implementierung der folgenden logischen Funktionen durch Bit ROM:
Ändere Funktion nur durch Ändern der Speicherinhalte!
Speicherfelder speichern Wertetabellen
Wort aus Eingangsvariablen bildet Adresse
Für jede Kombination von Eingangswerten ist der Funktionswert gespeichert.
Ein Port besteht aus zusammengehörigen Anschlüssen für Adresse und Datum. Dabei besteht ein Drei-Port Speicher aus
Kleine Multi-Port-Speicher werden als Registerfelder bezeichnet. Diese werden z.B. in Prozesooren eingesetzt.
FPGAs bestehen grundsätzlich aus:
CLBs bestehen im wesentlichen aus:
Ein Spartan 3 CLB enthält:
* 2 LUTs:
* 2 sequentielle Ausgänge:
* 2 kombinatorische Ausgänge:
Berechnung der folgenden Funktionen mit dem Spartan 3 CLB
Der Enwurfsfluss wird in der Regel durch Entwurfswerkzeuge wie Xilinx ISE unterstützt. Dies ist in der Regel ein iterativer Prozess, bestehend aus:
Der Entwickler denkt nach, gibt einen Entwurf als Schaltplan oder HDL-Beschreibung ein und wertet die Simulationsergebnisse aus. Wenn die Simulation zufriedenstellend ist, dann wird der Entwurf als Netzliste synthetisiert (eine textuelle Beschreibung der elektrischen Verbindungen zwischen Bauelementen). Die Netzliste wird auf die FPGA-Konfiguration abgebildet (CLBs, IOBs, Verbindungsnetz). Danach werden die Konfigurationsdaten (bit streams) auf den FPGA geladen und zum Schluss in realer Hardware getestet.