problem with unsigned vs std_logic_vector

Guest
I'm having a problem with a VHDL signal I hadn't expected. Simulator is Modelsim.

When I declare a signal

signal A : unsigned(31 downto 0);

or

signal A : std_logic_vector(31 downto 0);

I get unexpected results from the unsigned case specifically when I try to set the 31st bit. I don't expect there would be a difference but I could be wrong.

I am using numeric_std

Thanks for any insight.
 
Am 25.02.2014 19:14, schrieb jlodman@gmail.com:
I'm having a problem with a VHDL signal I hadn't expected. Simulator
is Modelsim.

When I declare a signal

signal A : unsigned(31 downto 0);

or

signal A : std_logic_vector(31 downto 0);

I get unexpected results from the unsigned case specifically when I
try to set the 31st bit. I don't expect there would be a difference
but I could be wrong.

You need to be more specific. What "unexpected results"? What exactly
are you trying to do, what are you expecting to happen, and what does
actually happen?

Greetings,
Sean
 
You need to be more specific. What "unexpected results"? What exactly

are you trying to do, what are you expecting to happen, and what does

actually happen?



Greetings,

Sean

Yes, also how did you assign your signal A? Did you try forcing A(31) to some hard-coded value and see what happens?

regards, daniel
 
On Wed, 26 Feb 2014 20:30:21 -0800, Daniel Kho wrote:

You need to be more specific. What "unexpected results"? What exactly

are you trying to do, what are you expecting to happen, and what does

actually happen?



Greetings,

Sean


Yes, also how did you assign your signal A? Did you try forcing A(31) to
some hard-coded value and see what happens?

Actually, the 31st bit would be either A(30) or A(1) depending on how the
OP counted; as a little-endian guy I would consider A(31) to be the 32nd
bit...

I agree the question as posted is hopelessly unclear.

- Brian
 
On 25/02/2014 18:14, jlodman@gmail.com wrote:
I'm having a problem with a VHDL signal I hadn't expected. Simulator is Modelsim.

When I declare a signal

signal A : unsigned(31 downto 0);

or

signal A : std_logic_vector(31 downto 0);

I get unexpected results from the unsigned case specifically when I try to set the 31st bit. I don't expect there would be a difference but I could be wrong.

I am using numeric_std

Thanks for any insight.

I suspect the longest static prefix manage to trip another user ;-)

Hans
www.ht-lab.com
 
Am 25.02.2014 19:14, schrieb jlodman@gmail.com:
I'm having a problem with a VHDL signal I hadn't expected. Simulator is Modelsim.

When I declare a signal

signal A : unsigned(31 downto 0);

or

signal A : std_logic_vector(31 downto 0);

I get unexpected results from the unsigned case specifically when I try to set the 31st bit. I don't expect there would be a difference but I could be wrong.

I am using numeric_std

Thanks for any insight.

Probably your code breaks when you try to convert to integer.
Integers are only + / - 2 Giga and you would also need sth. between
+2Giga and slightly less than +4Giga for full 32 bit unsigneds.
0x8000 0000 is also forbidden.

That's not your fault, that's brain damage built into the language.
It's fun testing a 64 bit design if you cannot formulate the numbers
for your test cases in a readable way.

I was thinking about a BCD arithmetic package that provides at least
the equivalent of 256 bits. 4 bits stored per char. Should give fast
conversion to/from int/string/signed/unsigned/fixed etc. and
implementation could be an easy table-driven version of paper & pencil.

Google summer of code?

Still could not be used for long loops & synthesis.
I really want int64 and int128.


regards, Gerhard
 
On Tuesday, February 25, 2014 10:14:23 AM UTC-8, jlo...@gmail.com wrote:
I'm having a problem with a VHDL signal I hadn't expected. Simulator is Modelsim.



When I declare a signal



signal A : unsigned(31 downto 0);



or



signal A : std_logic_vector(31 downto 0);



I get unexpected results from the unsigned case specifically when I try to set the 31st bit. I don't expect there would be a difference but I could be wrong.



I am using numeric_std



Thanks for any insight.

I did try and force it to a hardcoded value of '1' by "or" with x"8000_0000". It ended up as x"0000_0003"

It's become clear that unsigned really can't handle a value large than 2^31-1, even when declaring a large range (I tried it). With everything else identical, when I changed the unsigned(31 downto 0) to std_logic_vector(31 downto 0) everything worked perfectly. I simply wasn't expecting this. Reading on-line it seems that even though the simulator/compiler accepts it, an unsigned bigger than an integer don't work right even when not using it to work with integers.

As Gerhard indicates, this restriction on integers is becoming a Not Fun if not a serious problem in the language that should have been fixed in the last standard. Unsigned and signed should work regardless of the range specified, even if they would kick out now when trying to convert to a 32 bit integer.

Since I have 36 bit addresses, I now have to do more work to get them out.
 
On Fri, 28 Feb 2014 10:42:04 -0800, jlodman wrote:

On Tuesday, February 25, 2014 10:14:23 AM UTC-8, jlo...@gmail.com wrote:
I'm having a problem with a VHDL signal I hadn't expected. Simulator is
Modelsim.

signal A : unsigned(31 downto 0);

I did try and force it to a hardcoded value of '1' by "or" with
x"8000_0000". It ended up as x"0000_0003"

It's become clear that unsigned really can't handle a value large than
2^31-1, even when declaring a large range (I tried it).

Unsigned can handle any required range. Integer (and Natural) can't.
Yes this does cause difficulty in current implementations of VHDL.
Fortunately you can create Unsigned literal values without using Integer.

- Brian
 
On Fri, 28 Feb 2014 10:42:04 -0800, jlodman wrote:

On Tuesday, February 25, 2014 10:14:23 AM UTC-8, jlo...@gmail.com wrote:
I'm having a problem with a VHDL signal I hadn't expected. Simulator is
Modelsim.

signal A : unsigned(31 downto 0);

I did try and force it to a hardcoded value of '1' by "or" with
x"8000_0000". It ended up as x"0000_0003"

It's become clear that unsigned really can't handle a value large than
2^31-1, even when declaring a large range (I tried it).

Unsigned can handle any required range. Integer (and Natural) can't.
Yes this does cause difficulty in current implementations of VHDL.
Fortunately you can create Unsigned literal values without using Integer.

- Brian
 
Unsigned can handle any required range. Integer (and Natural) can't.

Yes, (un)signed and any array types such as std_(u)logic_vector can handle any required range. Scalar types such as integer can't as mentioned by Brian.

You should try with a simple testcase:

architecture test of design is
signal A : unsigned(31 downto 0);
begin
A<=x"8000_0000";
end architecture test;

Try changing the value from x"8000_0000" to x"0", resimulate, and notice if there are any changes in the simulated waveform.

Also, you could try with just driving a single bit to different values and resimulate to notice the difference:
A(31)<='1';
A(31)<='0';


Actually, the 31st bit would be either A(30) or A(1) depending on how the
OP counted; as a little-endian guy I would consider A(31) to be the 32nd
bit...

Yes, I'm a little-endian guy myself, though I have the (bad) habit of referring A(0) as the zeroth bit instead of the first bit. Sorry about that.
 
Try changing the value from x"8000_0000" to x"0", resimulate, and notice if there are any changes in the simulated waveform.

I meant to say change x"8000_0000" to x"0000_0000" or 32x"0".

-daniel
 
On Saturday, March 1, 2014 7:42:04 AM UTC+13, jlo...@gmail.com wrote:
Since I have 36 bit addresses, I now have to do more work to get them out..

You're statement that an unsigned can deal with greater than 31 bits is unfounded for VHDL in general. There's also not an arithmetic operator defined for std_logic_vector by default in VHDL unless you're also using synopsys's package std_logic_unsigned. You should consider it anathema to mix numeric_std (which provides unsigned) with synopsys's packages.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity test is
end entity;

architecture foo of test is
function unsigned_to_string (inp: unsigned) return string is
variable tmp: string (1 to inp'LENGTH) := "";
variable eval: character;
variable index: positive;
begin
for i in inp'RANGE loop
if inp(i) = 'U' then eval := 'U';
elsif inp(i) = 'X' then eval := 'X';
elsif inp(i) = '0' then eval := '0';
elsif inp(i) = '1' then eval := '1';
elsif inp(i) = 'Z' then eval := 'Z';
elsif inp(i) = 'W' then eval := 'W';
elsif inp(i) = 'L' then eval := 'L';
elsif inp(i) = 'H' then eval := 'H';
else eval := '-';
end if ;
tmp(index) := eval;
index := index + 1;
end loop;
return tmp;
end function;

signal A: unsigned (31 downto 0);
signal B: unsigned (35 downto 0);
signal C: unsigned (35 downto 0);

begin
A <= x"80000000" after 1 ns;
B <= x"800000000" after 1 ns;
C <= A + B;

MONITOR:
assert C = x"FFFFFFFFF"
report LF & "A = " & unsigned_to_string(A) & LF &
"B = " & unsigned_to_string(B) & LF &
"C = " & unsigned_to_string(C)
severity NOTE;
end architecture;

%% ghdl -a unsigned.vhdl
%% ghdl -e test
%% ghdl -r test
.../../../src/ieee/numeric_std-body.v93:1613:7:mad:0ms:(assertion warning): NUMERIC_STD."=": metavalue detected, returning FALSE
unsigned.vhdl:40:1:mad:0ms:(assertion note):
A = UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
B = UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
C = UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
.../../../src/ieee/numeric_std-body.v93:1613:7:mad:0ms:(assertion warning): NUMERIC_STD."=": metavalue detected, returning FALSE
unsigned.vhdl:40:1:mad:0ms:(assertion note):
A = UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
B = UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
C = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
unsigned.vhdl:40:1:mad:1ns:(assertion note):
A = 10000000000000000000000000000000
B = 100000000000000000000000000000000000
C = 100010000000000000000000000000000000
%%

All the 'U's are expected from the default assignment to the left most value of std_ulogic for each element of the unsigned arrays. The second report is due to no delay in the assignment of C. You get all 'X's adding two arrays of 'U's. The third report shows the results of C <= A + B;

unsigned is an array of std_logic which uses a nine value representation to describe bit values ('U','X','0','1','Z','W','L','H','-'). The function "+" (an adding operator) is defined in package numeric_std.

You could note I was too lazy to convert unsigned to string representations in base 16, they are shown by std_logic element (i.e. bit by bit).

There's also useful information derived from familiarity with the packages, for example the array length of the result for the function "+" (an operator) is derived from the MAX of the length of it's two arguments. C is a an array of the std_ulogic nine level (MVL9 originally from Synopsys) representation of an array of bits that has a range of 35 downto 0 (36 bits).

Perhaps you could show us an example VHDL description that exhibits your problem?
 
On Sunday, March 2, 2014 4:05:44 PM UTC-6, Dio Gratia wrote:
...There's also not an arithmetic operator defined for std_logic_vector by
default in VHDL unless you're also using synopsys's package
std_logic_unsigned.

VHDL-2008 includes the package ieee.numeric_standard_unsigned, which defines arithmetic operators with std_logic_vector operands for unsigned arithmetic.

You should consider it anathema to mix numeric_std (which provides unsigned)
with synopsys's packages.

Amen. If your synthesis/simulation vendor does not support VHDL-2008, tell them you need it, or switch tools.

Even with the two ieee packages, I doubt there is an operator defined to add an SLV to an unsigned. Just don't go there...

Andy
 
On Tuesday, March 4, 2014 5:39:28 AM UTC+13, Andy wrote:
On Sunday, March 2, 2014 4:05:44 PM UTC-6, Dio Gratia wrote:

...There's also not an arithmetic operator defined for std_logic_vector by

default in VHDL unless you're also using synopsys's package

std_logic_unsigned.



VHDL-2008 includes the package ieee.numeric_standard_unsigned, which defines arithmetic operators with std_logic_vector operands for unsigned arithmetic.

Technically it's by inheritance. numeric_std_unsigned defines arithemetic and other operators for std_ulogic_vector which the 2008 std_logic_1164 package defines standard_logic_vector as a resolved subtype of.

You should consider it anathema to mix numeric_std (which provides unsigned)

with synopsys's packages.



Amen. If your synthesis/simulation vendor does not support VHDL-2008, tell them you need it, or switch tools.



Even with the two ieee packages, I doubt there is an operator defined to add an SLV to an unsigned. Just don't go there...

See the bit above about standard_logic_vector being a subtype of std_ulogic_vector. In 2008 unsigned is a resolved UN_RESOLVED_UNSIGNED which is an array type of STD_ULOGIC.

They two array types (standard_logic_vector and UNSIGNED) aren't closely related. Their elements do have the same base type.
>

And imagine how few religious arguments over types we'd have today if unsigned had been an alias for std_logic_vector originally. They're all just bags of bits (arrays) and the hardware (the 'H' in VHDL) really doesn't care.
 
On Monday, March 3, 2014 12:34:00 PM UTC-6, Dio Gratia wrote:
They two array types (standard_logic_vector and UNSIGNED) aren't closely
related. Their elements do have the same base type.

This is not true. The BASE TYPES of std_logic_vector and unsigned are both arrays of std_ulogic. That makes them closely related.

And imagine how few religious arguments over types we'd have today if unsigned
had been an alias for std_logic_vector originally. They're all just bags of
bits (arrays) and the hardware (the 'H' in VHDL) really doesn't care.

How do you specify that you want SLV to have an unsigned numeric representation? VHDL lets you (or other users before you) write packages that do that for you, or define the SLV representation as twos-complement, signed or unsigned fixed point, or floating point. When you want to mix them, VHDL wants to know explicitly how you want them mixed, so it can accurately model the behavior you want. From an accurate model, accurate hardware can be synthesized, rather than guessed at.

If all you want to do is describe HW structure/implementation instead of behavior, use edif. It doesn't care either.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top