neg. Zahlen multiplizieren

OP #1320486
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
Gast #1320526
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
OP #1320538
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... :)
Moderator (Firma: Titel) Persönliche Seite #1320607
> 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?
OP #1320644
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?
Moderator (Firma: Titel) Persönliche Seite #1320694
> 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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.