problem with unsigned vs std_logic_vector

J

jlodman

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.
 
S

Sean Durkin

Am 25.02.2014 19:14, schrieb (e-mail address removed):
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
 
D

Daniel Kho

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
 
H

HT-Lab

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
 
G

Gerhard Hoffmann

Am 25.02.2014 19:14, schrieb (e-mail address removed):
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
 
J

jlodman

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 ifnot 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.
 
D

Daniel Kho

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.
 
D

Daniel Kho

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
 
D

Dio Gratia

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 reportis 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 todescribe 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 representationsin 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 anarray 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?
 
A

Andy

...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
 
D

Dio Gratia

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.
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.
 
A

Andy

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top