Vortrag: Praktikum Technische Informatik Sommersemester 2007 Gruppe 2 Thema: Multiplikations- und Divisionseinheit in VHDL Von Jonas Zaddach, Johannes Kohl und Marco Volbracht
Vorstellung der Teilnehmer Vorstellung der Aufgabe Inhalt Vorstellung der Teilnehmer Vorstellung der Aufgabe Erläuterung Multiplizierer Grobe Übersicht Erläuterung der einzelnen Zustände Feine Übersicht Eckdaten
Erläuterung Dividierer Inhalt (2) Erläuterung Dividierer Grobe Übersicht Erläuterung ausgewählter Zustände Feine Übersicht Eckdaten Zeiteinteilung Organisation Probleme
Vorstellung der Teilnehmer Marco Antonio Volbracht (Projektleiter) Jonas Zaddach (Vortrag) Johannes Michael Kohl (Dokumentation)
Vorstellung der Aufgabe Es ist eine Multiplikations- und Divisionseinheit zu implementieren, welche Binärzahlen in einer vorgegebenen Zahlendarstellung miteinander verrechnen. Die Schaltung wird in VHDL realisiert und mit Hilfe des Programms Altera Quartus II entworfen und getestet.
Grobe Funktionsweise des Multiplizierers
Reset Warte darauf, dass ena = Reset auf High gesetzt wird Setze alle Flags und internen Signale zurück
Einlesen Berechung des Vorzeichens Prüfen, ob eine der Eingabezahlen Null ist Setzen des Zero-Flags und Wechsel in Endzustand Speichern der Eingabewerte in internen Signalen (als positive Zahlen) -- Hoechstwertiges Bit des -- ersten Einganges (Vorzeichen) in1_msb: IN std_logic; -- Vorkommastellen des ersten -- Einganges bis auf MSB in1_vk: IN std_logic_vector(14 downto 0); -- Nachkommastellen des ersten Einganges in1_nk: IN std_logic_vector(7 downto 0);
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 , , , 1 1 1 1 , , , Ergebnis ist doppelt so lang wie Eingabe Bit zur Überlauferkennung
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 1 1 , , , 1 1 1 1 1 1 , , , Wenn niedrigstes Bit von In2 gesetzt ist, addiere In1 zu Ergebnis (von links)
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 1 , , , 1 1 1 1 1 , , , Shift Logical Right Shift Logical Right Verschiebe In2 nach rechts Verschiebe Ergebnis nach rechts
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 1 , , , 1 1 1 1 1 , , , Fange wieder von vorne an (führe Addition hier 4 mal, bei VHDL-Einheit insgesamt 23 Mal aus) Keine Addition wenn In2(0) = 0
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 1 , , , 1 1 1 1 1 , , , Shift Logical Right Shift Logical Right
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 1 1 1 , , ,
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 1 1 , , , 1 1 1 1 1 1 , , , Shift Logical Right Shift Logical Right
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 1 1 , , ,
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 1 1 , , , 1 1 1 1 1 1 , , , Shift Logical Right Shift Logical Right
Multiplizieren In1 In2 Ergebnis * = 1 1 1 1 1 1 , , , 1 1 1 1 1 1 , , , Effektive Ausgabe
Ausgabe anpassen Falls Ergebnis negativ ist, Bildung des Zweierkomplements
Ausgabe Anlegen des internen Ergebnissignals an äußere Pins Anlegen der Flagsignale (Overflow) Setzen des Ready-Flags
Eckdaten Multiplizieren Rechendauer Genau 23 Takte für die eigentliche Multiplikation 2 Takte für Wechsel Reset-Zustand Einlesen und Multiplizieren Ausgabe 3 Takte für Einlesen, Ausgabe anpassen und Ausgabe Es werden genau 28 Takte benötigt (außer wenn In = 0 oder In2 = 0) (≈ 280 ns bei Taktdauer von 10 ns) Es können Zahlen zwischen –32‘767,99609375 = -(215-2-8) und 32‘767,99609375 = 215-2-8 ein- und ausgegeben werden
Eckdaten Multiplizieren (2) Flags zero: Zeigt an, dass das Ergebnis echt Null ist (weil eine der Eingabezahlen Null war) ovr: Ergebnis hat nicht in Ausgabevektor gepasst, es ist ein Überlauf aufgetreten rdy: Wird gesetzt, wenn Chip Rechnung beendet hat
Divisionsbaustein
Divisionsbaustein
Nenner anpassen Sicherungskopie des ursprünglichen Nenners anlegen Nenner wird so lange nach links geschoben, bis es keine führenden Nullen mehr gibt In2 1 1 ,
Nenner anpassen Nenner wird so lange nach links geschoben, bis es keine führenden Nullen mehr gibt In2 1 1 , Auf 1 testen
Nenner anpassen Nenner wird so lange nach links geschoben, bis es keine führenden Nullen mehr gibt In2 1 1 , Shift Logical Left
Nenner anpassen Nenner wird so lange nach links geschoben, bis es keine führenden Nullen mehr gibt In2 1 1 , Test auf 1 erfolgreich, fertig
Dividieren In1 ist ein Bit länger, um festzustellen ob Subtraktion Überlauf verursacht hat In1 In2 Ergebnis 1 1 1 / 1 1 = , , , - 1 1 , In1 und In2 sind haben doppelt so viele Nachkommastellen, damit das Ergebnis bis in die letzte Stelle genau ist Bei der Subtraktion wird eine 0 an In2 angehängt, um gleiche Breite wie In1 zu haben
Dividieren In1 In2 Ergebnis 1 1 1 / 1 1 = 1 , , , - 1 1 , 1 1 1 / 1 1 = 1 , , , - 1 1 , Ergebnisbit setzen 1 , Übertragsbit ist 0 Subtraktion erfolgreich
Dividieren In1 In2 Ergebnis 1 / 1 1 = 1 , , , - 1 1 , 1 / 1 1 = 1 , , , - 1 1 , Vergleichen von untersten Bits von In2 mit Original-Eingabevektor In2 Ungleich weiter machen 1 1
Dividieren In1 In2 Ergebnis 1 / 1 1 = 1 , , , - 1 1 , 1 / 1 1 = 1 , , , - 1 1 , Ergebnis links schieben In2 rechts schieben
Dividieren In1 In2 Ergebnis 1 / 1 1 = 1 , , , - 1 1 , 1 / 1 1 = 1 , , , - 1 1 , Ergebnisbit löschen 1 1 1 1 1 , Übertragsbit ist 1 Subtraktion nicht erfolgreich In1 in ursprünglichem Zustand belassen
Dividieren In1 In2 Ergebnis 1 / 1 1 = 1 , , , 1 1 , 1 / 1 1 = 1 , , , - 1 1 , Vergleichen von untersten Bits von In2 mit Original-Eingabevektor In2 Ungleich Weiter machen 1 1
Dividieren In1 In2 Ergebnis 1 / 1 1 = 1 , , , - 1 1 , 1 / 1 1 = 1 , , , - 1 1 , Ergebnis links schieben In2 rechts schieben
Dividieren In1 In2 Ergebnis 1 / 1 1 = 1 1 , , , - 1 1 , 1 / 1 1 = 1 1 , , , - 1 1 , Ergebnisbit setzen 1 1 , Übertragsbit ist 0 Subtraktion erfolgreich
Dividieren In1 In2 Ergebnis 1 / 1 1 = 1 1 , , , 1 1 , 1 / 1 1 = 1 1 , , , - 1 1 , Vergleichen von untersten Bits von In2 mit Original-Eingabevektor In2 Gleich Fertig 1 1
Eckdaten Dividieren Rechendauer Max. 23 Takte um den Nenner nach links zu schieben Max. 3 * (22 + 8+1) Takte für die Subtraktionen und Vergleiche 4 Takte für Einlesen externer Signale und Ausgabe interner Signale Es werden für die Division maximal 121 Takte benötigt (≈ 1,21 µs bei Taktdauer von 10 ns) Es können Zahlen zwischen –32‘767,99609375 = -(215-2-8) und 32‘767,99609375 = 215-2-8 ein- und ausgegeben werden
Eckdaten Dividieren (2) Flags zero: Zeigt an, dass das Ergebnis echt Null ist (weil Zähler Null war) dze: Fehlerflag für Null im Nenner ovr: Ergebnis hat nicht in Ausgabevektor gepasst, es ist ein Überlauf aufgetreten (kann vorkommen, da mit Brüchen gerechnet wird) rdy: Wird gesetzt, wenn Chip Rechnung beendet hat
Zeiteinteilung 15 Treffen Grobanalyse Feinanalyse Pflichtenheft Spezifikation Implementierung Multiplikationseinheit Implementierung Divisionseinheit Testdokumentation Vortrag Ausarbeitung
Organisation mittels eigener Webseite Titel und Datum Kurze Erläuterung Weitere Informationen Versionsverwaltung mittels CVS
Probleme Zahlendarstellung Zero-Flag
Fragen? ? ? ? ?