Forum: FPGA, VHDL & Co. Multiplizieren 2 bit fehlen beim Target


von Peter (Gast)


Lesenswert?

Hallo,

ich möchte 2 Zahlen Multiplizieren und verstehe nicht, warum das Target 
2 Bit weniger hat, als angegeben.
1
signal ADC  : std_logic_vector(11 downto 0) := (others=>'0');
2
signal ADCx : std_logic_vector(25 downto 0) := (others=>'0');
3
4
ADCx <= std_logic_vector(unsigned(ADC(ADC'Length-1 downto 0)) * 15125);

-> width mismatch in assignment; target has 26 bits, source has 24

Warum ist das so?
15125 sind 14 bit + die 12 Bit komme ich auf 26 Bit

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


Lesenswert?

Peter schrieb:
> -> width mismatch in assignment; target has 26 bits, source has 24
Probiers mal so:
1
    ADCx <= std_logic_vector(unsigned(ADC) * to_unsigned(15125,14));

> Warum ist das so?
Weil der Operator * so definiert ist... ;-)
Die Ergebnisbreite wird bei unsigned*integer aus dem "linken" 
unsigned-Wert zu ((L'length+L'length-1) downto 0) berechnet:
https://www.csee.umbc.edu/portal/help/VHDL/packages/numeric_std.vhd
1
     -- Id: A.17
2
  function "*" ( L: UNSIGNED; R: NATURAL) return UNSIGNED;
3
     -- Result subtype: UNSIGNED((L'length+L'length-1) downto 0).
4
     -- Result: Multiplies an UNSIGNED vector, L, with a non-negative 
5
     --         INTEGER, R. R is converted to an UNSIGNED vector of 
6
     --         SIZE L'length before multiplication.
Wenn ich aber unsigned*unsigned mache, dann greift die Formel 
((L'length+R'length-1) downto 0):
1
     -- Id: A.15
2
  function "*" (L,R: UNSIGNED ) return UNSIGNED;
3
     -- Result subtype: UNSIGNED((L'length+R'length-1) downto 0).
4
     -- Result: Performs the multiplication operation on two UNSIGNED vectors
5
     --         that may possibly be of different lengths.

Und um die ganze Hin- und Herwandlerei zu sparen, kannst du den ADC 
gleich als unsigned deklarieren:
1
 signal ADC  : unsigned(11 downto 0) := (others=>'0');
2
 signal ADCx : unsigned(25 downto 0) := (others=>'0');
3
 
4
 ADCx <= ADC * to_unsigned(15125,14);

: Bearbeitet durch Moderator
von Peter (Gast)


Lesenswert?

Lothar M. schrieb:
> Und um die ganze Hin- und Herwandlerei zu sparen, kannst du den ADC
> gleich als unsigned deklarieren:
Ja, nur irgendwo muss ich es konvertieren, da es nur die eine Stelle ist 
belasse ich es in dem Fall so.

Lothar M. schrieb:
> ADCx <= ADC * to_unsigned(15125,14);
Das war es, Vivado scheint die Bitbreite von dem integer anders zu 
interpretieren.

in meinem Fall funktioniert es mit
1
ADCx <= std_logic_vector(unsigned(ADC(ADC'Length-1 downto 0)) * to_unsigned(15125,14));

Peter

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


Lesenswert?

Peter schrieb:
> Das war es, Vivado scheint die Bitbreite von dem integer anders zu
> interpretieren.
Ein Integer hat keine Bitbreite. Er hat lediglich einen Wertebereich. 
Und das Problem hat nichts mit Vivado zu tun. Es hat mit der Definition 
des Multiplikationsoperators zu tun.
Lies nochmal langsam und genau, was ich gepostet habe, und versuche es 
zu verstehen. Setz dir einen Link auf den Quellcode der numeric_std. Du 
wirst ihn immer wieder brauchen.

: Bearbeitet durch Moderator
von C. A. Rotwang (Gast)


Lesenswert?

Peter schrieb:

> 15125 sind 14 bit

Sicher? (Vorsicht Fangfrage!)

Falls das numerische Literal 15125 ein integer und damit 
vorzeichenbehaftet ist, dann musst du noch ein bit für das Vorzeichen 
'+' einrechnen das bitweise als '0'-bit ganz links dargestellt wird, 
weil andernfalls  11101100010101 = - 6933. Beim type natural dagegen 
würden 14 bit reichen, natural is ja als subtype von Integer eingeführt.

> Ein Integer hat keine Bitbreite. Er hat lediglich einen Wertebereich.

Njein. Ein Integer hat ab VHDL'87 32 bit, da gab es mal die Diskussion 
das auf 64 per Standard-revision hochzusetzen.
Welchen typ jetzt eine 'nackte Zahl' hat ist wieder eine andere Frage 
und um diese Frage nicht zu stellen, gibt man eigentlich immer den Typ 
der nackten Zahl an. Entweder explizite Konvertierung, casz operator und 
man definiert es gleich als Konstante (weil auch in VHDL sind 'magic 
numbers' wegen schlechter Wartbarkeit und geringer Verständlichkeit 
nicht gerne gesehen).

Und wenn man nicht will das für einen integer nicht 32 bit für den 
vollen Bereich von -2147483648 bis +2147483647 'verheizt' werden, gibt 
man den tatsächlichen Wertebereich an (range). Das nennt sich 
unglücklichwerweise 'constrained subtype', obwohl es nichts mit 'timing 
constraints' zu tun hat.

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


Lesenswert?

C. A. Rotwang schrieb:
> unglücklichwerweise 'constrained subtype', obwohl es nichts mit 'timing
> constraints' zu tun hat.
Das hat mit Glück oder Unglück nicht so sehr zu tun, denn "to constrain" 
bedeutet ja lediglich "einschränken": einmal wird der Wertebereich 
eingeschränkt und einmal das Timing.

> Falls das numerische Literal 15125 ein integer und damit
> vorzeichenbehaftet ist, dann musst du noch ein bit für das Vorzeichen
> '+' einrechnen
Im Kontext der Multiplikation wird ist die Zeichenkette 15125 als ein 
auf natürliche Integerzahlen eingeschränkter Natural betrachtet, weil 
die Multiplikation ja mit einem "linken" Unsigned und einem "rechten" 
Natural durchgeführt wird:
function "*" ( L: UNSIGNED; R: NATURAL) return UNSIGNED;

> Beim type natural dagegen würden 14 bit reichen, natural is ja als
> subtype von Integer eingeführt.
Und genau um so eine Multiplikation geht es hier zweifelsohne. Denn es 
ist in der numeric_std keine Multiplikation eines Unsigned mit einem 
Integer vorgesehen. Siehe im oben verlinkten Quelltext die Deklarationen 
A.15 bis A.20:
1
--========================================================================
2
 
3
     -- Id: A.15
4
  function "*" (L,R: UNSIGNED ) return UNSIGNED;
5
     -- Result subtype: UNSIGNED((L'length+R'length-1) downto 0).
6
     -- Result: Performs the multiplication operation on two UNSIGNED vectors
7
     --         that may possibly be of different lengths.
8
 
9
     -- Id: A.16
10
  function "*" ( L,R: SIGNED) return SIGNED;
11
     -- Result subtype: SIGNED((L'length+R'length-1) downto 0)
12
     -- Result: Multiplies two SIGNED vectors that may possibly be of
13
     --         different lengths.
14
 
15
     -- Id: A.17
16
  function "*" ( L: UNSIGNED; R: NATURAL) return UNSIGNED;
17
     -- Result subtype: UNSIGNED((L'length+L'length-1) downto 0).
18
     -- Result: Multiplies an UNSIGNED vector, L, with a non-negative 
19
     --         INTEGER, R. R is converted to an UNSIGNED vector of 
20
     --         SIZE L'length before multiplication.
21
 
22
     -- Id: A.18
23
  function "*" ( L: NATURAL; R: UNSIGNED) return UNSIGNED;
24
     -- Result subtype: UNSIGNED((R'length+R'length-1) downto 0).
25
     -- Result: Multiplies an UNSIGNED vector, R, with a non-negative 
26
     --         INTEGER, L. L is converted to an UNSIGNED vector of 
27
     --         SIZE R'length before multiplication.
28
 
29
     -- Id: A.19
30
  function "*" ( L: SIGNED; R: INTEGER) return SIGNED;
31
     -- Result subtype: SIGNED((L'length+L'length-1) downto 0)
32
     -- Result: Multiplies a SIGNED vector, L, with an INTEGER, R. R is
33
     --         converted to a SIGNED vector of SIZE L'length before 
34
     --         multiplication.
35
 
36
     -- Id: A.20
37
  function "*" ( L: INTEGER; R: SIGNED) return SIGNED;
38
     -- Result subtype: SIGNED((R'length+R'length-1) downto 0)
39
     -- Result: Multiplies a SIGNED vector, R, with an INTEGER, L. L is
40
     --         converted to a SIGNED vector of SIZE R'length before 
41
     --         multiplication.
42
  --========================================================================

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.