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


von Ron N. (blitzgeist)


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?
1
library IEEE;
2
use IEEE.numeric_std.all;
3
...
4
5
6
process(rst, clk)
7
 variable product : std_logic_vector(13 downto 0);
8
 begin
9
  if(rst = '1')then
10
   first_product <= (others => '0');
11
  elsif(rising_edge(clk))then
12
   product := numeric_std.signed(x1) * numeric_std.signed(x2)    
13
   frist_product <= std_logic_vector(product(13) & product(11 downto 0));
14
  end if;
15
end process


Ist diese Zuweisung so korrekt?
1
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

von Matthias (Gast)


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

von Ron N. (blitzgeist)


Lesenswert?

Ich habe hier einen Link gefunden:

[http://www.vhdl.org/vhdl-200x/vhdl-200x-ft/proposals/numeric_packages/n008_fixed_point.html]


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... :)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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.
1
signal product : std_logic_vector(13 downto 0);
2
signal x1, x2 : std_logic_vector(6 downto 0);
3
:
4
process(rst, clk)
5
 begin
6
  if(rst = '1')then
7
     first_product <= (others => '0');
8
  elsif(rising_edge(clk))then
9
     frist_product <= std_logic_vector(signed(x1) * signed(x2));
10
  end if;
11
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?

von Ron N. (blitzgeist)


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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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

von Ron N. (blitzgeist)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.