Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL rules for arithmetic operations

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,300
Hello,

1.When multiplying 2 unsigned vectors in VHDL, must they be at the same length?
2.Is it legal to multiply an unsigned vector with an integer? Or both operands must be of the same type?
 

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,827
Helped
1,811
Reputation
3,632
Reaction score
1,773
Trophy points
1,393
Location
USA
Activity points
59,100
I'm pretty sure for 1. the inputs to a multiply can be different lengths and the result will be the two lengths added together.
For 2. the numeric_std package for 97 shows unsigned-natural and signed-integer, which makes sense as integer can have negative values.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,300
Thanks,
I verified #1 (modelim compilation + Quartus synthesis). Works as you said.
Regarding #2 - what about multiplying an unsigned vector with type natural (or positive)?
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,520
Helped
14,272
Reputation
28,807
Reaction score
12,976
Trophy points
1,393
Location
Bochum, Germany
Activity points
280,612
To answer the question yourself, why don't you review the source of numeric_std.vhd?
 

TrickyDicky

Advanced Member level 5
Joined
Jun 7, 2010
Messages
7,069
Helped
2,078
Reputation
4,173
Reaction score
2,031
Trophy points
1,393
Activity points
39,155
  • Like
Reactions: shaiko and FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating

    shaiko

    Points: 2
    Helpful Answer Positive Rating

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,827
Helped
1,811
Reputation
3,632
Reaction score
1,773
Trophy points
1,393
Location
USA
Activity points
59,100
numeric_std defines * for unsigned/signed * integer and integer * unisnged/signed.
natural and positive are subtypes of integer, so will work just fine.
You really need a good reference book - this is basic stuff.

https://www.doulos.com/content/products/golden_reference_guides.php
Tricky are you sure you aren't mistaken, I just looked at the package on the IEEE site and the 1076.2-1996 package doesn't define * for unsigned/signed.

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-- Id: A.15
  function "*" (L, R: UNSIGNED) return UNSIGNED;
  -- Result subtype: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0)
  -- Result: Performs the multiplication operation on two UNSIGNED vectors
  --         that may possibly be of different lengths.
 
  -- Id: A.16
  function "*" (L, R: SIGNED) return SIGNED;
  -- Result subtype: SIGNED((L'LENGTH+R'LENGTH-1) downto 0)
  -- Result: Multiplies two SIGNED vectors that may possibly be of
  --         different lengths.
 
  -- Id: A.17
  function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
  -- Result subtype: UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0)
  -- Result: Multiplies an UNSIGNED vector, L, with a nonnegative
  --         INTEGER, R. R is converted to an UNSIGNED vector of
  --         SIZE L'LENGTH before multiplication.
 
  -- Id: A.18
  function "*" (L: NATURAL; R: UNSIGNED) return UNSIGNED;
  -- Result subtype: UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0)
  -- Result: Multiplies an UNSIGNED vector, R, with a nonnegative
  --         INTEGER, L. L is converted to an UNSIGNED vector of
  --         SIZE R'LENGTH before multiplication.
 
  -- Id: A.19
  function "*" (L: SIGNED; R: INTEGER) return SIGNED;
  -- Result subtype: SIGNED((L'LENGTH+L'LENGTH-1) downto 0)
  -- Result: Multiplies a SIGNED vector, L, with an INTEGER, R. R is
  --         converted to a SIGNED vector of SIZE L'LENGTH before
  --         multiplication.
 
  -- Id: A.20
  function "*" (L: INTEGER; R: SIGNED) return SIGNED;
  -- Result subtype: SIGNED((R'LENGTH+R'LENGTH-1) downto 0)
  -- Result: Multiplies a SIGNED vector, R, with an INTEGER, L. L is
  --         converted to a SIGNED vector of SIZE R'LENGTH before
  --         multiplication.


https://standards.ieee.org/downloads/1076/1076.2-1996/numeric_std.vhdl

It has been change to the following in the 1076-2008, which also doesn't define * for signed/unsigned. :???:

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-- Id: A.15
  function "*" (L, R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED;
  -- Result subtype: UNRESOLVED_UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0)
  -- Result: Performs the multiplication operation on two UNRESOLVED_UNSIGNED vectors
  --         that may possibly be of different lengths.
 
  -- Id: A.16
  function "*" (L, R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED;
  -- Result subtype: UNRESOLVED_SIGNED((L'LENGTH+R'LENGTH-1) downto 0)
  -- Result: Multiplies two UNRESOLVED_SIGNED vectors that may possibly be of
  --         different lengths.
 
  -- Id: A.17
  function "*" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED;
  -- Result subtype: UNRESOLVED_UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0)
  -- Result: Multiplies an UNRESOLVED_UNSIGNED vector, L, with a nonnegative
  --         INTEGER, R. R is converted to an UNRESOLVED_UNSIGNED vector of
  --         SIZE L'LENGTH before multiplication.
 
  -- Id: A.18
  function "*" (L : NATURAL; R : UNRESOLVED_UNSIGNED) return UNRESOLVED_UNSIGNED;
  -- Result subtype: UNRESOLVED_UNSIGNED((R'LENGTH+R'LENGTH-1) downto 0)
  -- Result: Multiplies an UNRESOLVED_UNSIGNED vector, R, with a nonnegative
  --         INTEGER, L. L is converted to an UNRESOLVED_UNSIGNED vector of
  --         SIZE R'LENGTH before multiplication.
 
  -- Id: A.19
  function "*" (L : UNRESOLVED_SIGNED; R : INTEGER) return UNRESOLVED_SIGNED;
  -- Result subtype: UNRESOLVED_SIGNED((L'LENGTH+L'LENGTH-1) downto 0)
  -- Result: Multiplies an UNRESOLVED_SIGNED vector, L, with an INTEGER, R. R is
  --         converted to an UNRESOLVED_SIGNED vector of SIZE L'LENGTH before
  --         multiplication.
 
  -- Id: A.20
  function "*" (L : INTEGER; R : UNRESOLVED_SIGNED) return UNRESOLVED_SIGNED;
  -- Result subtype: UNRESOLVED_SIGNED((R'LENGTH+R'LENGTH-1) downto 0)
  -- Result: Multiplies an UNRESOLVED_SIGNED vector, R, with an INTEGER, L. L is
  --         converted to an UNRESOLVED_SIGNED vector of SIZE R'LENGTH before
  --         multiplication.

 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,520
Helped
14,272
Reputation
28,807
Reaction score
12,976
Trophy points
1,393
Location
Bochum, Germany
Activity points
280,612
In contrast to legacy std_logic_arith, ieee.numeric_std has no automatic type conversion from unsigned to signed, thus unsigned*signed or unsigned*negative_integer isn't supported.

But I don't hear that Tricky is suggesting anything different.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

TrickyDicky

Advanced Member level 5
Joined
Jun 7, 2010
Messages
7,069
Helped
2,078
Reputation
4,173
Reaction score
2,031
Trophy points
1,393
Activity points
39,155
Ok - I stand a little corrcted. You can never multipliy an unsigned and signed as it wouldnt make sense.
Neither would multiplying unsigned with an integer (as it can have negative values).

Ok multiplicates:

us * us
s *s
s * integer (and other way around - this covers positives and naturals)
us * natural (and other way around - this also covers positives).

The 2008 definition uses unresolved_signed by default as this was how std_logic was changed - std_logic_vector became a subtype of std_ulogic_vector, rather than an array of std_logic. So they did the same change in numeric_std.

As unsigned/signed are just subtypes of unresolved_(un)signed, you can use the functions you quoted.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,300
The length of us * us will be the sum of both - simple enough.
But what about:
us * natural (in case the natural is unconstrained)
Will the tool simply assume that the natural number is 32 bits long ?
Or will it treat it as a constrained unsigned exactly the length of its binary equivalent?
 

axcdd

Full Member level 3
Joined
Jan 29, 2012
Messages
155
Helped
58
Reputation
116
Reaction score
57
Trophy points
1,308
Activity points
2,133
Code:
  function "*" (L : UNRESOLVED_UNSIGNED; R : NATURAL) return UNRESOLVED_UNSIGNED;
  -- Result subtype: UNRESOLVED_UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0)
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,300
ads-ee,

post #6 is VERY helpful.
I couldn't find this package on IEEE site.
I found it on another site, but I'd like to have the original reference.

Can you please post the link ?

- - - Updated - - -

I stumbled upon this definition of the "+" function:
Code:
  -- Id: A.3
  function "+" (L, R: UNSIGNED) return UNSIGNED;
  -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
  -- Result: Adds two UNSIGNED vectors that may be of different lengths.
Can't find the scene behind it.
I'd expect the function to take into consideration the possibility of an overflaw and the result to be defined as one bit longer than the longest of operands - yet I see the length of the result is simply defined as the length of the longest operand without any extra bits.

Am I missing something?
 

TrickyDicky

Advanced Member level 5
Joined
Jun 7, 2010
Messages
7,069
Helped
2,078
Reputation
4,173
Reaction score
2,031
Trophy points
1,393
Activity points
39,155
ads-ee,

post #6 is VERY helpful.
I couldn't find this package on IEEE site.
I found it on another site, but I'd like to have the original reference.

Can you please post the link ?

- - - Updated - - -

I stumbled upon this definition of the "+" function:
Code:
  -- Id: A.3
  function "+" (L, R: UNSIGNED) return UNSIGNED;
  -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0).
  -- Result: Adds two UNSIGNED vectors that may be of different lengths.
Can't find the scene behind it.
I'd expect the function to take into consideration the possibility of an overflaw and the result to be defined as one bit longer than the longest of operands - yet I see the length of the result is simply defined as the length of the longest operand without any extra bits.

Am I missing something?

Nope. No overflow is done
If you want overflow you need to extend the inputs by a bit - which is common:

op <= ('0' & a) + ('0' & b);
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

K-J

Advanced Member level 2
Joined
Jan 26, 2012
Messages
658
Helped
308
Reputation
620
Reaction score
301
Trophy points
1,343
Activity points
7,053
Can't find the scene behind it.
I'd expect the function to take into consideration the possibility of an overflaw and the result to be defined as one bit longer than the longest of operands - yet I see the length of the result is simply defined as the length of the longest operand without any extra bits.
Am I missing something?
If you want overflow taken into consideration, then you should consider using the fixed point package instead.
Kevin Jennings
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,520
Helped
14,272
Reputation
28,807
Reaction score
12,976
Trophy points
1,393
Location
Bochum, Germany
Activity points
280,612
Code:
op <= ('0' & a) + ('0' & b);
It's sufficient to extend one of both operands to avoid result truncation. And you can use numeric_std resize(), which also performs the necessary sign extension of signed numbers.
Code:
op <= resize(a, op'length) + b;
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top