Carry-Ripple, Conditional-Sum und Carry-Lookahead-Ad
Transcription
Carry-Ripple, Conditional-Sum und Carry-Lookahead-Ad
Praktikum Grundlagen von Hardwaresystemen Wintersemester 2012/13 Versuch 5: Carry-Ripple, Conditional-Sum und Carry-Lookahead-Addierer 10. Dezember 2012 Fachbereich 12: Informatik und Mathematik Institut für Informatik Professur für Eingebettete Systeme Prof. Dr. Uwe Brinkschulte unter Mitarbeit von Benjamin Betting Michael Bauer Daniel Lohn Johann Wolfgang Goethe-Universität Frankfurt am Main Inhaltsverzeichnis 1 Einleitung 2 2 Grundlagen 2.1 Erzeugung regulärer Strukturen mittels Schemata . . 2.1.1 Verwendung von Schemata im ISE Webpack . 2.2 Addierer . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Carry-Ripple-Addierer . . . . . . . . . . . . . 2.2.2 Conditional-Sum-Addierer . . . . . . . . . . . 2.2.3 Carry-Lookahead-Addierer . . . . . . . . . . 2.3 Laufzeiteffekte in Schaltnetzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 4 11 11 11 12 14 3 Anmerkungen und Tipps 15 4 Vorbereitungsaufgaben 16 5 Praktikumsaufgaben 18 1 Kapitel 1 Einleitung Dieser Versuch behandelt im wesentlichen zwei Addierertypen (Carry-Ripple-Addierer und Carry-Lookahead-Addierer). In den Aufgaben werden die folgenden Punkte ausführlich behandelt: • Notwendigkeit der strukturellen Beschreibung • Verwendung des Schemata Konzepts zur strukturellen Beschreibung von Architekturen • Implementierung und Vergleich zweier Addierertypen (Carry-Ripple-Addierer und CarryLookahead-Addierer) • Betrachtung von Laufzeiteffekten in Schaltnetzen • Implementierung der Verzögerung in VHDL 2 Kapitel 2 Grundlagen 2.1 Erzeugung regulärer Strukturen mittels Schemata Bei den bisherigen Praktikumsaufgaben ging es hauptsächlich darum, einfache Komponenten in algorithmischer oder Datenflussbeschreibung zu modellieren, sowie diese Komponenten mittels struktureller Verknüpfung zu komplexeren Schaltungen zu verbinden. Die strukturelle Verknüpfung ist allerdings zur vollständigen Beschreibung von Entwürfen heutzutage nicht mehr adäquat, da z.B. moderne Prozessoren mittlerweile aus einigen Millionen Gattern bestehen. Beim modernen Schaltungsdesign beschreibt man den Entwurf deshalb hauptsächlich algorithmisch, und extrahiert aus dieser Beschreibung mittels einer automatischen Synthese eine strukturelle Beschreibung mit Gattern, Flipflops und Registern, die dann weiterverarbeitet werden kann. Es gibt aber durchaus noch Gründe für eine strukturelle Beschreibung in VHDL: • zur Verbindung von großen Bausteinen, die algorithmisch beschrieben sind. Heutzutage werden solche Bausteine auch als sog. IP-Cores (intellectual property cores) gehandelt, d.h. Chiphersteller kaufen bestimmte Komponenten für ihren Entwurf als VHDLBeschreibung von Drittanbietern. • bei regulären Strukturen wie z.B. Speichern ist eine strukturelle Beschreibung durchaus sinnvoll. Um solche großen Strukturen zu beschreiben, bietet das ISE Webpack das Schemata-Konzept, mit dem sich strukturelle Beschreibungen, bestehend aus beliebig vielen Einzelkomponenten, einfach per Drag & Drop erzeugen lassen. • es kann sein, dass algorithmische Konstrukte vom Synthesewerkzeug nicht oder nur ungenügend umgesetzt werden, so dass man hier auf eine bessere selbstdefinierte strukturelle Beschreibung zurückgreifen muss. 3 KAPITEL 2. GRUNDLAGEN 4 Für die Erzeugung komplexerer und aufwendiger struktureller Beschreibungen, bieten VHDL und die Entwicklungsumgebung ISE Webpack zwei Konzepte an. Ziel dieser ist es, eine möglichst einfache Erzeugung der Netzliste (Instanziierung und Vernetzung der Komponenten/Entities), also die eigentliche Beschreibung der strukturellen Zielarchitektur, dem Entwickler bereitzustellen. Diese sind: • generate-Anweisung • Schemata (Schaltsymbole) Die generate-Anweisung ist ein Konzept von VHDL selbst und wird in diesem Praktikum aufgrund des zeittechnischen Aufwands und der Komplexität nicht betrachtet. Dennoch ist das Prinzip und die Funktionsweise die, dass durch die Verwendung von Schleifen eine parametrisierte iterative Instanziierung der Komponenten durchgeführt werden kann. Das zweite Konzept ist Teil der Entwicklunsgumbegung. Im ISE Webpack ist es möglich eine visualisierte Darstellung der VHDL Entwürfe in Form von Schemata zu erzeugen. Schemata sind, auf diesen Kontext bezogen, technische Schaltsymbole die den jeweiligen Entities zugeordnet sind. Unter Verwendung dieser Symbole kann der Entwickler den Entwurf dann visuell per Drag & Drop aus den jeweiligen Schaltsymbolen erstellen. Der zugehörige VHDLQuellcode wird automatisch über die verknüpften Komponenten/Entites generiert, welcher später auch eingesehen und verwendet werden kann. 2.1.1 Verwendung von Schemata im ISE Webpack Um Ihnen das Prinzip einfach zu verdeutlichen, wird hier ein Beispiel ausgeführt, welches die strukturelle Beschreibung eines XOR-Gatters basierend, auf vier NAND-Gattern (Aufgabe 5 aus Praktikumsversuch 1), verwendet. Bevor Sie Entities schematisch im ISE Webpack visuell per Drag & Drop instanziieren und verschalten können, müssen zunächst für die benötigten Entities die zugehörigen Schaltsymbole (Schematic Symbols) erzeugt werden. Dazu gehen Sie wie folgt vor: • Im Drop Down Menü Sources for: des Design-Fensters den Vorgang Implementation auswählen. KAPITEL 2. GRUNDLAGEN 5 • Auswahl der entsprechenden Entity im Design-Fenster. Dabei ist es wichtig, dass sich die Datei der Entity im Verzeichnis des aktuellen Projekts befindet. Sollte die Entity nicht bereits Teil des Projekts sein, so fügen Sie diese dem Projekt zuvor hinzu (Rechtsklick auf FPGA-Design (xc3s200) → Add Copy of Source). Die Erzeugung des Schaltsymbols starten Sie im Prozess-Fenster unter dem Punkt Design Utilities → Create Schematic Symbol. Wiederholen Sie diesen Vorgang gegebenenfalls für alle Entity Dateien, die für die strukturelle Beschreibung der Zielentity notwendig sind. KAPITEL 2. GRUNDLAGEN 6 Nachdem alle Schaltsymbole erstellt wurden, kann die eigentliche strukturelle Beschreibung begonnen werden. Erzeugen Sie dazu eine neue VHDL Schematic Datei, mit welcher die Beschreibung einer Entity schematisch erfolgen kann. Dazu gehen Sie wie folgt vor: • Anlegen einer neuen VHDL Schematics Datei mit Rechtsklick auf das FPGA-Design (xc3s200). Aus dem Kontextmenü wählen Sie New Source. Der create new File Wizard wird geöffnet. • Als Dateiformat wählen Sie auf der linken Seite Schematic. Im Namensfeld geben Sie den Namen der Entity ein. Mit Next gelangen Sie zur Zusammenfassung. Klicken Sie dort auf Finish um die Datei zu erzeugen. • Anschließend wird die schematische Ansicht der Entity geöffnet. Alternativ öffnet sich durch einen Doppelklick auf die Schemata-Datei im Design-Fenster ebenfalls diese Ansicht. Um wieder zur normalen Ansicht (Design-Fenster) zu wechseln, wählen Sie den Reiter Design unterhalb des Symbol-Fensters aus. KAPITEL 2. GRUNDLAGEN 7 • Nun können Sie die strukturelle Bechreibung schematisch mittels Drag & Drop vornehmen. Um eine Entity zu instanziieren, wählen Sie das zugehörige Schaltsymbol aus dem Symbol-Fenster auf der linken Seite aus. Damit Sie nicht lange suchen müssen, wählen Sie aus dem darüberliegenden Kategorie-Fenster ihr aktuelles Projekt aus (zweite Position). Somit werden lediglich ihre Entitäten angezeigt. • Nachdem Sie die gewünschte Entity ausgewählt haben, klicken Sie einfach im SchemataPlan auf der rechten Seite auf eine freie Fläche. Das Schaltbild wird dann dort platziert. Mit der Platzierung wird die Entity instanziiert. Wiederholen Sie diesen Vorgang gegebenenfalls für alle weiteren Entitäten, die benötigt werden. KAPITEL 2. GRUNDLAGEN 8 • Um die erzeugten Entity-Instanzen miteinander zu vernetzen, wählen Sie aus der WerkzeugToolbar in der Mitte den Punkt Add Wire (dritte Position von oben) aus. Um nun zwei IO-Ports miteinander zu verbinden, klicken Sie auf einen der beiden Ports und ziehen Sie eine Linie (Verdrahtung) zum anderen. • Um ein IO-Port als Ein- bzw. Ausgangssignal der aus dem Schemata resultierenden Entity zu deklarieren, wählen Sie aus der Werkzeug-Toolbar in der Mitte den Punkt Add I/O Marker (siebte Position von oben) aus und klicken Sie auf den Pin, der als I/O-Port deklariert werden soll. Das Verhalten bzw. die Polarität des Ports ist wählbar, indem Sie auf dessen Symbol doppelklicken und im sich öffnenden Eigenschafts-Fenster unter Nets die PortPolarity auf In- bzw. Output stellen. • Um einen Bus zu erstellenm klicken Sie auf Add Wire und erstellen Sie einen einfachen Draht. Diese Leitung hat zunächst nur eine Breite von einem Bit. Durch einen Doppelklick auf den neuen Draht öffnet sich sein Eigenschafts-Fenster. Durch einen Namenszusatz können Sie jetzt den Draht zu einem Bus machen. Schreiben Sie in Klammern KAPITEL 2. GRUNDLAGEN 9 hinter dem Namen, welche Bits verwendet werden, z.B. ist Test(3:0) ein 4-Bit breiter Bus. Mit Add Bus Tap können von einem Bus einzelne Bit ausgewählt werden. Verbinden Sie dazu das Bus Tap mit dem gewünschten Bus. Über den Namen kann ein bestimmtes Bit ausgewählt werden, z.B. wird über den Namen Test(3) das höchstwertige Bit des Busses Test ausgewählt. Nachdem Sie ihre Schaltung fertiggestellt haben, kann die resultierende Entity wie folgt verwendet werden. • Wechseln Sie wieder zum Design-Fenster des Projekts (Reiter Design unterhalb des Symbol-Fensters), wo die Entitäten und Dateien ihres aktuellen Projekts angezeigt werden. Es gibt nun zwei Arten den VHDL-Quellcode der Schemata-Datei einzusehen. KAPITEL 2. GRUNDLAGEN 10 – Die Erste umfasst den gesamten Code, also Entity und Architektur. – Die Zweite bietet eine Ansicht des zugehörigen Instanz-Templates, d.h. den ComponentBlock welcher benötigt wird, wenn Sie die Entity in einer höheren Entity instanziieren möchten, wie zum Beispiel in einer Testumgebung (SimBox). Das InstanzTemplate wird dann wie gewohnt in die Architektur der Simbox eingefügt und instanziiert. Für die Ansicht des gesamten Quellcodes gehen Sie wie folgt vor: – Auswahl der schematisch beschriebenen Entity aus dem Design-Fenster – Im Prozess-Fenster wählen Sie dann den Punkt Design Utilities → View HDL Functional Model Für die Ansicht des Instanz-Templates gehen Sie wie folgt vor: – Auswahl der schematisch beschriebenen Entity aus dem Design-Fenster – Im Prozess-Fenster wählen Sie dann den Punkt Design Utilities → View HDL Instantiation Template Wichtig: In beiden Varianten ist nur eine Einsicht des Codes möglich und keine Bearbeitung. Dazu muss der Code kopiert und in einer neuen Datei abgelegt werden (in den Praktikumsversuchen ist dies allerdings nicht notwendig). KAPITEL 2. GRUNDLAGEN 2.2 11 Addierer Addierglieder sind Schaltnetze, die zwei Dualzahlen addieren. Dualzahlen werden wie Dezimalzahlen stellenweise addiert, beginnend bei der Stelle mit dem niedrigsten Wert. Die Addition von zwei mehrstelligen Dualzahlen kann bitseriell oder bitparallel ausgeführt werden. Man spricht daher von Serienaddierer und Paralleladdierer. Beide Addiernetze unterscheiden sich wesentlich im Hardwareaufwand und in der Addierzeit. Der Serienaddierer führt während eines Taktschrittes die Addition von nur einer Stelle aus. Der Paralleladdierer führt während einem Taktschritt die Addition aller Stellen aus. Der Serienaddierer besteht aus einem VA-Schaltnetz (beim ersten Praktikumsversuch haben wir Halbaddierer und Volladdierer kennengelernt), zwei Registern zur Aufnahme der Summanden und der Summe und einem Speicherglied für die Zwischenspeicherung des Übertrages. Der Serienaddierer ist deshalb ein Schaltwerk. Paralleladdierer können nach drei Strategien realisiert werden: • Paralleladdierer in Normalformlösung • Ripple-Carry-Addierer • Carry-Look-Ahead-Addierer (Paralleladdierer mit Übertragsvorausberechnung) 2.2.1 Carry-Ripple-Addierer Der Carry-Ripple-Addierer (Abbildung 2.1) realisiert ein mehrstufiges Schaltnetz. Die Addition der ersten oder wertniedrigsten Stelle wird von einem HA ausgeführt. Für jede weitere zu addierende Stelle wird ein VA nachgeschaltet, der aus den Stellenbits und dem Übertrag der vorangehenden Stelle wiederum einen Übertrag und eine Summe bildet. B3 Cout A3 VA S3 B2 C3 A2 VA S2 B1 C2 A1 VA S1 B0 C1 A0 VA Cin S0 Abbildung 2.1: Aufbau eines 4-Bit Ripple-Carry Addierers 2.2.2 Conditional-Sum-Addierer Bei einem Carry-Ripple-Addierer ist die Berechnung der Carry-Signale zeitkritisch, da bei entsprechenden Eingangswerten ein Carry vom ersten bis zum letzten Volladdierer durchpropagiert werden muss, bevor das entsprechende Summen-Bit korrekt berechnet werden kann. In zeitkritischen Schaltungen können solche Addierer bei aktuellen Bitbreiten zwischen 32 KAPITEL 2. GRUNDLAGEN 12 bis 64 Bit zu langsam werden. Ein Conditional-Sum-Addierer nutzt den Vorteil einer gleichzeitigen Voraus-Berechnung der Summen-Bits. Dies erfolgt durch die Annahme beider Werte von 0 und 1 eines entsprechenden Carry-Signals in der jeweiligen Addierer-Stufe. Die Addition zweier Bits erfolgt somit doppelt, jedoch mit unterschiedlichem Carry-Eingangssignal. Sobald das tatsächliche Carry-Signal aus der vorangegangen Stufe propagiert wurde, wird das korrekte Ergebnis selektiert. Mittels dieses Verfahrens werden Latenzen dies bis zum Eintreffen eines Carry-Signals entstehen können, durch eine vorzeitige Berechnung beider Ergebnismöglichkeiten effektiv ausgenutzt. Das Auswahlschaltnetz welches die Selektion des richtigen Teilergebnisses durchführt, wird durch den Einsatz gewöhnlicher Multiplexer realisiert. Je nach Wortbreite und Eingabe wird eine deutliche kürzere Rechenzeit gegenüber dem Ripple-Carrry-Addierer erzielt. B3 A3 B2 0 VA VA MUX A2 MUX Cout 0 VA 1 VA MUX MUX B1 A1 B0 0 VA 1 VA A0 VA Cin 1 MUX MUX MUX MUX MUX S3 S2 S1 S0 Abbildung 2.2: Realisierung eines 4-Bit Conditional-Sum Addierers mittels 2:1 Multiplexern 2.2.3 Carry-Lookahead-Addierer Da der bereits vorgestellte Ripple-Carry wie auch Conditional-Sum-Addierer eine Addition stehts in Abhängigkeit des vorangehenden Carry-Signals berechnen, werden Latenzen die durch das Propagieren dieses Signals entstehen nicht vermieden. Dies stellt vor allem bei großen Wortbreiten (> 64 Bit) ein Problem dar. Um jedoch auch bei einer hohen Anzahl von Bits kurze Rechenzeiten zu erhalten, bedient man sich in solch einem Fall der CarryLookahead-Addierer (CLA). Diese Addierer berechnen die Überträge der einzelenen Volladdierer wesentlich schneller. Die Funktionsweise der CLA basiert auf folgenden Überlegungen zum Carry-Ripple-Addierer: • Der Volladdierer k generiert ein Carry-Signal genau dann, wenn KAPITEL 2. GRUNDLAGEN 13 – beide Summanden ak und bk den Wert 1 haben oder – ein Volladdierer j < k ein Carry produziert und alle Volladdierer (j + 1)...k dieses Carry propagieren. • Ein Volladdierer propagiert ein eingehendes Carry, wenn genau einer der beiden Summanden den Wert 1 hat. Diese Überlegungen führen zu einem erweiterten Volladdierer, dem Carry-Lookahead-fähigen Volladdierer (Abb. 2.3). a b c_in CVA c_p s c_g Abbildung 2.3: Ein Carry-Lookahead-fähiger Volladdierer Dieser hat neben dem Summen-Ausgang einen Ausgang c g (Carry-generate) und einen Ausgang c p (Carry-propagate). Aus diesen beiden Ausgangssignalen wird dann mit einem Schaltnetz, in das auch die Carry-generates und -propagates der vorherigen Volladdierer eingehen, das Carry-in des nächsten Volladdierers berechnet. a1 b1 a0 b0 c_out CVA S1 S0 p s c_in CVA g p s c_in g c_in AND OR OR AND AND Abbildung 2.4: Ein 2-Bit-Carry-Lookahead Addierer Das zusätzliche Carry-in auf der rechten Seite nimmt dabei die Rolle eines Carry-generate ein. KAPITEL 2. GRUNDLAGEN 2.3 14 Laufzeiteffekte in Schaltnetzen Bisher haben wir nur verzögerungsfreie Schaltungen simuliert, d.h. wenn zum Zeitpunkt t eine Signaländerung am Eingang einer Schaltung anlag, hat diese auch zum Zeitpunkt t darauf am Ausgang reagiert. Dies ist natürlich kein reales Verhalten, denn jedes Gatter braucht eine gewisse Zeitspanne, um eine Signaländerung zu verarbeiten. Es gibt hierbei zwei Modelle: • ideale Verzögerung um die Zeitspanne t: Jede Signaländerung wirkt sich erst nach der Zeitspanne t am Ausgang aus. • träge Verzögerung um die Zeitspanne t: Signaländerungen, die nur eine Zeitspanne s < t andauern, werden verschluckt. Nur Signaländerungen, die mindestens die Zeitspanne t überstehen, werden ideal verzögert. Auch VHDL kennt ideale und träge Verzögerung. Dies ist wichtig für die Simulation, da diese Verzögerungen in der Realität auftreten und deshalb auch modellierbar sein müssen. Kennt man die Verzögerungswerte der Technologie, in der man sein Design implementiert, kann man dies bei der Simulation berücksichtigen. In VHDL gibt es jedoch keine Laufzeitglieder, die Verzögerung wird durch Sprachkonstrukte bei der Signalzuweisung implementiert. Die Architektur eines AND-Gatters mit einer trägen Verzögerung von 10 Nanosekunden sieht so aus: Listing 2.1: AND mit Verzögerung architecture d a t a f l o w of AND gate i s begin c <= a and b a f t e r 10 ns ; end Dataflow ; Das Schlüsselwort after beschreibt eine träge Verzögerung. Für eine ideale Verzögerung sieht die Signalzuweisung dagegen wie folgt aus: Listing 2.2: Signalzuweisung bei einer idealen Verzögerung c <= transport a and b a f t e r 10 ns ; Kapitel 3 Anmerkungen und Tipps • carry generate sagt aus, wann ein Übertrag gebildet wird. • carry propagate sagt aus, wann ein Übertrag weitegeleitet wird. • Die Tatktfrequenz eines Addierers in MHz lässt sich anhand der worst-case Rechenzeit in Nanosekunden wie folgt berechnen: F requenz = 103 W C−Zeit 15 Kapitel 4 Vorbereitungsaufgaben Die folgenden Aufgaben dienen der Vorbereitung der Praktikumsaufgaben und sind teilweise Ausgangsbasis für eine VHDL-Implementierung. Bearbeiten Sie diese Aufgaben vor dem Praktikumstermin. Aufgabe 1. Worin liegt der Unterschied zwischen Schaltnetzen und Schaltwerken? Nennen Sie jeweils ein konkretes Beispiel. Aufgabe 2. Welche ist die kleinste Zahl, die einen Überlauf des 6-Bit-Carry-Ripple-Addierers verursacht, wenn sie zu sich selbst addiert wird? Aufgabe 3. Unter welchen Bedingungen, bezüglich der Eingabevektoren A und B, benötigt ein 6-Bit Carry-Ripple, Conditional Sum und Carry-Lookahead Addierer die maximale Rechenzeit? Aufgabe 4. Was ist ein Hazard und welche Hazardarten haben Sie in der Vorlesung Hardwarear” chitekturen und Rechensysteme“ kennengelernt? Aufgabe 5. Geben Sie die booleschen Ausdrücke für das Carry-generate c g und das Carry-propagate c p eines einzelnen Carry-Lookahead-fähigen Volladdierers an. Aufgabe 6. Geben Sie einen zweistufigen booleschen Ausdruck für das Carry-in aller Addierer und das Carry-out eines 6-Bit-Carry-Lookahead-Addierers an. Aufgabe 7. Erstellen Sie eine Tabelle mit der notwendigen Anzahl an Gattern für einen CarryRipple (RCA), Conditional-Sum (CSA) und einen Carry-Lookahead-Addierer (CLA) in Abhängigkeit von der Anzahl der zu addierenden Bits 6, 16, 32 und 64. Betrachten Sie hierzu den Volladdierer (VA) und Multiplexer (MUX) als eigenständiges Gatter und gehen Sie davon aus, dass die verwendeten Volladdierer (VA) auch die Signale carry generate und carry propagate erzeugen. Des Weiteren ist zu berücksichtigen, dass die ODER und UND-Gatter beliebig viele Eingänge besitzen können. Die Tabelle soll demnach wie folgt aufgebaut sein: CLA CSA RCA VA ? ? ? 6-Bit OR AND ? ? ? ? ? ? MUX ? ? ? 16-Bit OR AND ? ? ? ? ? ? VA ? ? ? 16 MUX ? ? ? KAPITEL 4. VORBEREITUNGSAUFGABEN CLA CSA RCA VA ? ? ? 32-Bit OR AND ? ? ? ? ? ? MUX ? ? ? VA ? ? ? 64-Bit OR AND ? ? ? ? ? ? 17 MUX ? ? ? Kapitel 5 Praktikumsaufgaben Aufgabe 1. Legen Sie ein neues Projekt an und fügen Sie dem Projekt eine Kopie der Quelldateien vom Halb- und Volladdierer aus dem letzten Versuch hinzu. Erzeugen Sie für diese beiden Bausteine die zugehörigen Schaltsymbole. Erstellen Sie einen Carry-Ripple-Addierer mit 6 Bit mit Hilfe von Schemata. Fügen Sie dazu eine neue Datei vom Typ Schematic“ mit dem Namen carry ripple 6 Ihrem ” Projekt hinzu. Als Bausteine für den Addierer verwenden Sie den Volladdierer aus dem vorangegangenen Versuch. Als Eingabe soll der Addierer zwei 6-Bit-Vektoren sowie ein zusätzliches Carry-Bit haben. Als Ausgabe soll ein 7-Bit-Vektor dienen. Schreiben Sie die Stimuli zur Simulation der Schaltung in eine neue VHDL-Datei. Das benötigte Instanz-Template (Component-Block) des Carry-Ripple-Addierers erhalten Sie aus der Schemata-Datei (wie in Abschnitt2.1.1 beschrieben). Führen Sie bei der Simulation 20 Additionen aus, wobei insgesamt jeder 1-Bit-Volladdierer mindestens einmal ein Carry produziert. Aufgabe 2. Versehen Sie den bereits konstruierten Volladdierer mit einer idealen Verzögerung von jeweils drei Nanosekunden. Wiederholen Sie anschließend die Simulation des CarryRipple-Addierers und beachten Sie die Unterschiede in den Simulationen. Unter welchen Bedingungen, bezüglich der Eingabevektoren A und B, erreicht ihr Addierer seine maximale Rechenzeit? Können Sie laufzeitbedingte Phänomene wie Hazards beobachten und wenn ja, erklären Sie um welche Hazardart es sich handelt? Aufgabe 3. Implementieren Sie einen 6-Bit-Conditional-Sum-Addierer auf der Basis des gezeigten Multiplexer-Ansatzes in Abschnitt 2.2.2. Ändern Sie hierzu die bereits von Ihnen erstellte 4:1 mux gate Entity aus dem vorangegangen Versuch 1 in einen 2:1 Multiplexer ab. Anschließend setzen Sie die Vernetzung der Komponenten mittels Schemata um. Der Addierer soll zwei 6-Bit Vektoren und ein Carry-Bit für die Eingabe haben. Für die Ausgabe soll ein 7-Bit Vektor dienen. Simulieren Sie den Entwurf mit den gleichen Testfällen aus Aufgabe 1. Aufgabe 4. Realisieren Sie nun eine Verzögerung von drei Nanosekunden für die Volladdierer und jeweils einer für jeden Multiplexer. Anschließend simulieren Sie den Entwurf erneut. Untersuchen Sie das Schaltungsverhalten auf Hazards. Aufgabe 5. Entwerfen Sie einen Carry-Lookahead-fähigen Volladdierer in VHDL (mit der Bezeichnung CLAVA) auf der Basis des schon entwickelten Volladdierers. Verwenden Sie die 18 KAPITEL 5. PRAKTIKUMSAUFGABEN 19 Variante ohne Verzögerung. Testen Sie Ihren Entwurf für alle möglichen Belegungen der Eingangssignale. Aufgabe 6. Erweitern Sie Ihr Projekt und entwerfen Sie einen 6-Bit-Carry-Lookahead-Addierer mittels Schemata. Verknüpfen Sie dazu 6 CLAVAs mit der Lookahead-Logik zu einem Carry-Lookahead-Addierer. Der Lookahead Generator (CLAG) steht Ihnen als Quellcode (Entity der Schaltung) auf der Praktikumswebseite zur Verfügung. Um diesen mittels Schemata zu verknüpfen, müssen Sie die Datei in das bestehende Projekt einbinden und das Schaltsymbol erzeugen. Anschließend vernetzen Sie die CLAVAs mit dem CLAG wie in Abbildung 5.1 gezeigt. Der Addierer soll zwei 6-Bit-Vektoren, ein zusätzliches Carry-Bit als Eingang und einen 7-Bit-Vektor als Ausgang haben. Simulieren Sie ihre Schaltung mit den Testfällen aus Aufgabe 1. B5 A5 VA p_5 A4 VA S5 C_out B4 S4 g_5 B3 A3 B2 VA VA S3 p_4 g_4 p_3 A2 CLAG p_2 A1 VA S2 g_3 B1 A0 VA S1 g_2 B0 S0 p_1 g_1 p_0 g_0 C_in Abbildung 5.1: Ein 6-Bit-Carry-Lookahead Addierer Aufgabe 5. Versehen Sie jetzt die CLAVAs mit einer idealen Verzögerung von drei Nanosekunden und alle anderen Gatter innerhalb des CLAG-Schaltnetzes mit einer idealen Verzögerung von einer Nanosekunde. Behandeln Sie dabei, unabhängig von der Anzahl der Eingänge, alle Und- sowie Oder-Gatter gleich. Simulieren Sie die Schaltung erneut und vergleichen Sie die worst-case Rechenzeit des Carry-Lookahead-Addierer gegenüber dem ConditionalSum und Ripple-Carry-Addierer.