Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

- Community Forums
- :
- Forums
- :
- Vivado RTL Development
- :
- Design Methodologies and Advanced Tools
- :
- Is this a bug is Vivado's handling of VHDL? (resiz...

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Navindaxon

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-08-2021 07:28 AM

443 Views

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

and

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

mvisser

Observer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

04-06-2021 01:21 AM

285 Views

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)"

calibra

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

04-06-2021 01:56 AM

275 Views

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 ==