size of std_logic_vector to unsigned

  • Thread starter Frank van Eijkelenburg
  • Start date
F

Frank van Eijkelenburg

Hi,

I have a std_logic_vector with size 2 and I want to use it in a function call
(which requires two unsigned parameters) like this:

signal offset : std_logic_vector(1 downto 0);
signal base : std_logic_vector(31 downto 0);

bus_write(unsigned(base) + unsigned(offset) * 4, write_data);

I see it's not working in simulation. It looks like the multiply of 4 is not
working. I assume the temporary result of 4 * unsigned(offset) is stored in an
unsigned with size 2 and than added to base?

I also get a warning about truncation. Do I have to store the result of the
operation in a larger unsigned explicitly or is there another way to do this?

TIA,
Frank
 
N

Nicolas Matringe

Frank van Eijkelenburg a écrit :
Hi,

I have a std_logic_vector with size 2 and I want to use it in a function
call (which requires two unsigned parameters) like this:

signal offset : std_logic_vector(1 downto 0);
signal base : std_logic_vector(31 downto 0);

bus_write(unsigned(base) + unsigned(offset) * 4, write_data);

I see it's not working in simulation. It looks like the multiply of 4 is
not working. I assume the temporary result of 4 * unsigned(offset) is
stored in an unsigned with size 2 and than added to base?

I also get a warning about truncation. Do I have to store the result of
the operation in a larger unsigned explicitly or is there another way to
do this?

I think you are right, the result is 2 bits long because offset is 2
bits long, thus resulting in a null vector.
Just extend offset :
bus_write(unsigned(base) + unsigned("00" & offset) * 4, write_data);

Nicolas
 
J

Jim Lewis

Frank
I think you are right, the result is 2 bits long because offset is 2
bits long, thus resulting in a null vector.
Just extend offset :
bus_write(unsigned(base) + unsigned("00" & offset) * 4, write_data);

Wrenching on Nicolas' solution a little can avoid the multiply:
bus_write(unsigned(base) + unsigned(offset & "00"), write_data);

Of course, his is a little more readable.

Cheers,
Jim

BTW, size_of( unsigned(offset) * 4) = 2 * offset'length
 
A

Andy

Frank


Wrenching on Nicolas' solution a little can avoid the multiply:
bus_write(unsigned(base) + unsigned(offset & "00"), write_data);

Of course, his is a little more readable.

Cheers,
Jim

BTW, size_of( unsigned(offset) * 4) = 2 * offset'length

This kind of stuff reminds me why I like working with integer
subtypes! And also how frustrated I get remembering that unsigned
integers are limited to a paltry 31 bits!

You could also use the new fixed point types, but then you'd have to
whack the MS bit off the final result.

Pick your poison...

Andy
 
F

Frank van Eijkelenburg

Nicolas said:
Frank van Eijkelenburg a écrit :

I think you are right, the result is 2 bits long because offset is 2
bits long, thus resulting in a null vector.
Just extend offset :
bus_write(unsigned(base) + unsigned("00" & offset) * 4, write_data);

Nicolas

Thanks for your help. I found some extra information:

-- Id: A.17
function "*" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
-- Result subtype: UNSIGNED((L'LENGTH+L'LENGTH-1) downto 0).
-- Result: Multiplies an UNSIGNED vector, L, with a non-negative
-- INTEGER, R. R is converted to an UNSIGNED vector of
-- SIZE L'LENGTH before multiplication.

So it is not the temporary result which is too small, but the natural of 4
doesn't fit in a 2 bits wide unsigned.

BTW, your solution doesn't compile: Illegal type conversion to unsigned
(operand type is not known).

constant c_test : std_logic_vector := "01";
signal address : unsigned(31 downto 0);

address <= unsigned("00" & c_test) * 4;
 
N

Nicolas Matringe

Frank van Eijkelenburg a écrit :
So it is not the temporary result which is too small, but the natural of
4 doesn't fit in a 2 bits wide unsigned.

Right
I don't have the numeric_std source code at home so I could not check
easily.

BTW, your solution doesn't compile: Illegal type conversion to unsigned
(operand type is not known).

Right too, litteral constant "00" can be of several types (though it
seems obvious from the context, at least to a human reader)

address <= resize(unsigned(c_test), 4) * 4;

Jim Lewis's solution is quite nice too, though it can not be generalized
to any multiplier.

Nicolas
 

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

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,115
Latest member
JoshuaMoul
Top