Showing results for 
Show  only  | Search instead for 
Did you mean: 
Registered: ‎06-30-2020

Is this a bug is Vivado's handling of VHDL? (resize() function in numeric_std)

While working on a project, I found a strange behavior which I believe to be a bug. But I'm not sure. Here are the code snippets in question. The first snippet does not work as expected, the second does:


s3 <=   resize(unsigned(subtrahend(15 downto 12)) * 1000, s3'length);
--Expected result is subtrahend*1000 resized to s3's length, where 1000 is a natural number




constant thousand : unsigned(11 downto 0) := x"3E8";
s3 <=   resize(unsigned(subtrahend(15 downto 12)) * thousand, s3'length);
--Expected result is subtrahend*1000, where 1000 is a natural number (but in this case is presented as unsigned type of 12 bits)

For background, according to the numeric_std package, the resize function supports unsigned, signed, and natural numbers in various configurations. In this case, resize(unsigned, natural) should return a vector of length natural of the unsigned type. s3'length should be a natural number, I believe.

Secondly, the "*" operator supports unsigned and natural inputs. From this, looking at the first code snippet (which doesn't work), we would expect the result to be a vector of length s3'length containing the value subtrahend(15 downto 12)*1000 where 1000 is one thousand, a natural number. In fact, the function returns subtrahend(15 downto 12) * 8, interpreting 1000 as 8 instead of 1000. This means something is treating 1000 as a vector of 1s and 0s, even though nothing about it presents as a binary vector. Meanwhile, the other version, with the unsigned constant thousand, works exactly as the code suggests it would.


This is quite bizarre, imo. Normally, to interpret a string of 1s and 0s as a vector of any type would require the quotation marks, or a typecast, or something like that. So the behavior I'm seeing seems like an error. It may be (I have not tested this) that the argument requires parentheses around, a la


s3 <=   resize(unsigned((subtrahend(15 downto 12)) * 1000), s3'length);

because of some sort of grouping precedence issue in the resize function. But, on the other hand, I don't see how VHDL should ever treat 1000 as anything other than a natural number in this context. Therefore, I would expect an error here.

Altogether, the issue is quite minor, but I thought it was strange when I realized what was going on, and I'm wondering if it's a bug, or there's some other reason for these disparate outcomes.



2 Replies
Registered: ‎11-06-2018

Was this happening in synthesis or simulation? I agree, 1000 is 1000 and not "1000" and it must have taken you rather a while to figure out what it is doing.

I've seen that Vivado makes integers into 32-bit structures even when 3 bits would suffice, so I've learnt to be very explicit with how I treat integers and naturals to make sure it does what I intend.
I would have used "to_unsigned(1000, 12)"

0 Kudos
Registered: ‎06-20-2012

When multiplying a vector by an integer, the integer is converted into a vector of the same width as the other operand !!!

As a consequence, the result’s width is forced to two times the width of the signed/unsigned vector.

== If this was helpful, please feel free to give Kudos, and close if it answers your question ==