Continue to Site

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.

Width of result vector in VHDL

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,302
Hello,

Consider the following VHDL signals:

Code:
signal x : unsigned ( 7 downto 0 ) ; 
signal y : unsigned ( 7 downto 0 ) ;

From the compiler's point of view:

1. The width of x * y is expected to be x'length + y'length. This makes sense as the highest achievable number is : 1111 1110 0000 0001 (16 bits wide).
2. The width of x + y is expected however to be 8 bits long - and I don't understand why. Clearly, the highest achievable number is 1 1111 1110 (9 bits wide).

Why?
 

Because that's what the vhdl standard says. Pre extend your vectors to get the correct width

- - - Updated - - -

It allows you do multiple additions without bit growth for every addition if you know what the rangers are limited to. You have control over the bit widths
 

Because that's what the vhdl standard says. Pre extend your vectors to get the correct width
Well yeah, I've seen the definition of '+' and sure - it can be easily worked around.

It allows you do multiple additions without bit growth for every addition if you know what the rangers are limited to. You have control over the bit widths
Yet '*' doesn't follow the same logic...

My question - why the inconsistency?
 

Guessing: multiplication always gives bit growth of N+M bits. Addition may or may not grow by a single bit of growth for every addition that occurs. Why bother with compulsory bit growth when it may not happen (and the designer may intend it that way)?

Seems consistent to me.

For a more definitive answer, you'll have to contact the authors of the LRM.

If you care, then do verilog (which does automatically do bit growth)
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
multiplication always gives bit growth of N+M bits
Multiplication will yield bit growth on more occasions then addition - but it isn't guarantied.
Some examples:
"0100" * "0010" = "1000"
"1111" * "0001" = "1111"
 

I'm guessing the argument was that ((A+B)+(C+D)) would have a different width compared to (A+(B+(C+D))) or (((A+B)+C)+D). This makes (A+B+C+D) potentially confusing.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Multiplication will yield bit growth on more occasions then addition - but it isn't guarantied.
Some examples:
"0100" * "0010" = "1000"
"1111" * "0001" = "1111"
An example for what? It has nothing to do with the bit width of an unsigned VHDL multiply operation which doesn't depend on a particular number value.

You'll find the answer in ieee.numeric_std
Code:
variable RESULT: UNSIGNED((L'LENGTH+R'LENGTH-1) downto 0)
 

An example for what? It has nothing to do with the bit width of an unsigned VHDL multiply operation which doesn't depend on a particular number value.
An example for a case when multiplying 2 numbers wouldn't cause bit growth.

The argument in #4 was:
"multiplication always gives bit growth of N+M bits. Addition may or may not grow by a single bit of growth for every addition that occurs."
I just presented a case which this statement won't hold.

My point is: I can't see a real reason for why multiplication and addition should be treated differently when it comes to bit growth.
Both operations may or may not cause bit growth.
 

for multiplcation, you will get bit growth 75% of the time - when X OR Y >= (2**N /2)
For addition, you get bit growth only 49% of the time, when X + Y >= 2**N

So on the basis of statistics, it makes sense to always bit grow multiplication, but not addition.

- - - Updated - - -

for multiplcation, you will get bit growth 75% of the time - when X OR Y >= (2**N /2)
For addition, you get bit growth only 49% of the time, when X + Y >= 2**N

So on the basis of statistics, it makes sense to always bit grow multiplication, but not addition.

The above is slightly wrong:

Actually %age for addition is always less than 50%. If you draw the karnaugh map for bit growth with 2 x 2bit numbers, the bit growth does not occur from one corner to another.
Probability of bit growth :
( (sum(x-1) from 1 to 2**N) / (2**N)**2 ) * 100

This is always less than 50%.

I cant work out the multiplication case as it is rather complicated, and N is a factor in the %age. Eg. for 1 bit x 1bit, there is never any bit growth, for 2 bits bit growth only occurs 25% of the time, but for 3 bits it is 33 / 64, which is just greater than 50%, and this is increased again at 4 bits.
 

As long as you are not starting to define a new hardware description language, the "why" is only of limited interest, I think.

The important point is to know
1. how the commonly used libraries are defining the operation
2. how to supplement it with specific bit assignments to get the operation you need

The most of my multiply use cases are e.g. truncating LS result bits rather than MS bits. A different behavior of the standard signed or unsigned multiply operator won't help at all for it.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
1. The width of x * y is expected to be x'length + y'length. This makes sense as the highest achievable number is : 1111 1110 0000 0001 (16 bits wide).
2. The width of x + y is expected however to be 8 bits long - and I don't understand why. Clearly, the highest achievable number is 1 1111 1110 (9 bits wide).

Why?
The people to answer the question of 'Why' would be the ones who created the numeric_std library...which was released 23 years ago. They have probably long since moved on. Consider using the fixed point package instead which does extend bits as you are expecting them.

Kevin Jennings
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Numeric_std took away most of the Verilog-ism's that std_logic_unsigned/std_logic_arith had -- things that made VHDL more like Verilog. Somehow numeric_std chose something practical even though there could be issues with academic confusion.

(I love the old vs new vs new-old math library debate. numeric_std is clearly the only choice because std_logic_unsigned is too old while the equivalent numeric_std_unsigned is too new.)
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Consider using the fixed point package instead which does extend bits as you are expecting them.
Is the fixed point package well supported in Vivado and Quartus?
 

Is the fixed point package well supported in Vivado and Quartus?

Quartus now includes it as part of 15.1 prime pro and above (only the pro versions afaik).
But the '93 compatability package (if you can find a copy now you cant get it from vhdl.org) has worked in quartus for at least 7 years when I last used it.

Vivado - not tried.
 
  • Like
Reactions: shaiko

    shaiko

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

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top