mikrocontroller.net

Forum: FPGA, VHDL & Co. neg. Zahlen multiplizieren


Autor: Ron Napp (blitzgeist)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich zwei negative Zahlen mit numeric_std. multipliziere, was 
geschieht dann mit den beiden VZ's?

x1 = x2 sind zwei vorzeichenbehaftete 6Bit Zahlen
x1 * x2 => VZ VZ 12Bit <- stimmt das?
library IEEE;
use IEEE.numeric_std.all;
...


process(rst, clk)
 variable product : std_logic_vector(13 downto 0);
 begin
  if(rst = '1')then
   first_product <= (others => '0');
  elsif(rising_edge(clk))then
   product := numeric_std.signed(x1) * numeric_std.signed(x2)    
   frist_product <= std_logic_vector(product(13) & product(11 downto 0));
  end if;
end process


Ist diese Zuweisung so korrekt?
frist_product <= std_logic_vector(product(13) & product(11 downto 0));
MSB ist das VZ (product(13)).
MSB-1 wird verworfen.
MSB-2 bis LSB, product(11 downto 0), ist der Betrag der Zahl (bei neg. 
natürlich im 2er-Komp)


Danke für die Hilfe.
LG

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke nicht. Das Zweierkomplement funktioniert nicht so, dass du ein 
Vorzeichenbit hast und danach folgt der Betrag der Zahl. Erklären kann 
ich es nicht, ich habe es auch nur durch aufzeichnen und nachdenken 
verstanden.

Jedenfalls solltest du die Zahlen gleich mal mit dem Typ "signed" 
anlegen oder wenigstens auf den hincasten vor der Multiplikation. Dann 
bekommst du ein Ergebnis, dessen Breite die Summe der Breiten der beiden 
Eingangsvektoren ist. Das ist dann aber auch wieder eine 
Zweierkomplementzahl, hat also nicht zwei Vorzeichen.

Am besten mal mit zb 4 bit Zahlen und Papier und Bleistift ein wenig 
damit rumspielen, dann kommt das Verständnis von selber.

LG
Matthias

Autor: Ron Napp (blitzgeist)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe hier einen Link gefunden:

[http://www.vhdl.org/vhdl-200x/vhdl-200x-ft/proposa...]


Zitat aus dem Link:
...
SummaryBit sizing rules for multiplication and division

For a multiply in numeric_std:
   signed (a downto 0) * signed (c downto 0) = signed (a+c+1 downto 0)
   unsigned (a downto 0) * unsigned (c downto 0) = unsigned (a+c+1 
downto 0)
...

Laut diesem ist:
x1 = VZ 6 Bit => 7 Bit, 6 downto 0
x2 = VZ 6 Bit => 7 Bit, 6 downto 0

erg = x1 * x2

erg := 6 + 6 + 1 = 13, 13 downto 0, also 14 Bit

MSB ist VZ.
MSB-1 bis LSB ist Wert.

Wenn nun das erg eine pos. Zahl ist, ist VZ = 0 und der Wert hätte 13 
Bit.
Wie kann eine Multiplikation von zwei 6 Bit Zahlen eine 13 Bit Zahl 
ergeben?

Oder hilft da nur Papir und Bleistift... :)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> x1 * x2 => VZ VZ 12Bit <- stimmt das?
Nein.
Wieso schreibst du nicht einfach eine integer-Operation hin und 
konvertierst das Ganze wieder zurück? numeric_std gibt dir die Werkzeuge 
an die Hand.
signal product : std_logic_vector(13 downto 0);
signal x1, x2 : std_logic_vector(6 downto 0);
:
process(rst, clk)
 begin
  if(rst = '1')then
     first_product <= (others => '0');
  elsif(rising_edge(clk))then
     frist_product <= std_logic_vector(signed(x1) * signed(x2));
  end if;
end process

> Wie kann eine Multiplikation von zwei 6 Bit Zahlen eine 13 Bit Zahl
> ergeben?
Es sind zwei 7-Bit Zahlen (Vorzeichen + 6 Ziffern), und multipliziert 
ergibt das eine 14-Bit-Zahl. Das ist der Trick. Das vorderste Bit ist 
eben nicht "nur" das Vorzeichen, sondern es erweitert den Zahlenbereich 
um den Faktor 2.

> Oder hilft da nur Papir und Bleistift... :)
Schaden kann das nicht ;-)

BTW:
Warum vermischt du (unnötig) Signale und Variable?

Autor: Ron Napp (blitzgeist)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Lothar, für deinen Beitrag.

> Warum vermischt du (unnötig) Signale und Variable?
Habe ich in einem Beispiel gelesen...

> Das vorderste Bit ist
> eben nicht "nur" das Vorzeichen, sondern es erweitert den Zahlenbereich
> um den Faktor 2.

Du meinst, das VZ (MSB) IST das VZ (und wird nur als VZ interpretiert) 
und das MSB-1, das erweitert den Zahlenbereich.

Verstehe ich das richtig?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Du meinst, das VZ (MSB) IST das VZ
Ja, und jedes Bit in einer Dezimalzahl erweitert den 
Zahlendarstellungsbereich theoretisch um den Faktor 2.

Allerdings:
Nimm mal eine 7-Bit-Zahl von -64 (=100 0000) bis +63 (=011 1111).
So, und jetzt rechne mal
-64*-64 = +4096 = 01 0000 0000 0000
-64*-63 = +4032 = 00 1111 1100 0000
 -1* -1 = +1    = 00 0000 0000 0001
  0* 0  = 0     = 00 0000 0000 0000
 -1* +1 = -1    = 11 1111 1111 1111
-64*+63 = -4032 = 11 0000 0100 0000

Das Vorzeichen ist das vorderste Bit
     |
     01 0000 0000 0000
      |
Das zweitvorderste Bit wird nur für das Ergebnis -64*-64 gebraucht  :-o

Autor: Ron Napp (blitzgeist)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja super, jetzt ist es geklärt! Vielen Dank und schönen Abend noch.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.