size of std_logic_vector to unsigned

  • Thread starter Frank van Eijkelenburg
  • Start date
F

Frank van Eijkelenburg

Guest
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
 
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
 
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
 
On May 3, 4:38 pm, Jim Lewis <j...@synthworks.com> wrote:
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
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
 
Nicolas Matringe wrote:
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
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;
 
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
 

Welcome to EDABoard.com

Sponsor

Back
Top