Help with typecasting requested

T

Taylor Hutt

-- I have an ALU which I want to verify. It has a fundamental type
-- 'word_t' which is defined as shown in the package 'types'.
--
-- To verify that the output of the ALU is correct, I want to iterate
-- over each operation, and all the operand values, setting the inputs
-- to the entity with the current 'op_0', 'op_1' and 'operator'
-- values.
--
-- However, being a rank novice VHDL programmer, the only way I can
-- think to do this easily is to declare an integer value for the
-- operands, and then assign this variable to the signal.
--
-- The problem is that I don't now how to cast the variable to the
-- 'word_t' type.
--
-- Can someone point me in the right direction to do one of the
-- following:
--
-- o Cast the 'integer' variable 'oper_0' to be of type 'word_t'.
-- o Declare 'oper_0' as an unsigned variable and assign it to
-- 'op_0'.

library ieee;
use ieee.std_logic_1164.all, ieee.numeric_bit.all;

package types is
subtype word_t is unsigned(31 downto 0);
end package types;

library ieee;
use ieee.std_logic_1164.all, ieee.std_logic_arith.all,
ieee.std_logic_unsigned.all;
use work.types;

entity main is
Port (clk : in std_logic; op_0 : out types.word_t);
end main;

architecture structural of main is
begin
driver : process (clk) is
variable oper_0 : integer := 0;
begin
op_0 <= oper_0;
-- ^^^^^^^^ Error: Type of op_0 is incompatible with type of oper_0.
op_0 <= types.word_t(oper_0);
-- ^^^^^^^^ Error: The expression can not be converted to type word_t.
op_0 <= conv_std_logic_vector(oper_0, 32);
-- ^^^^^^^^ Error: Type of op_0 is incompatible with type of
-- conv_std_logic_vector.
op_0 <= types.word_t(conv_unsigned(oper_0, 32));
-- ^^^^^^^^ Error: The expression can not be converted to type word_t.
end process driver;
end structural;


Thanks for any help,
thutt
 
A

Andy

-- I have an ALU which I want to verify. It has a fundamental type
-- 'word_t' which is defined as shown in the package 'types'.
--
-- To verify that the output of the ALU is correct, I want to iterate
-- over each operation, and all the operand values, setting the inputs
-- to the entity with the current 'op_0', 'op_1' and 'operator'
-- values.
--
-- However, being a rank novice VHDL programmer, the only way I can
-- think to do this easily is to declare an integer value for the
-- operands, and then assign this variable to the signal.
--
-- The problem is that I don't now how to cast the variable to the
-- 'word_t' type.
--
-- Can someone point me in the right direction to do one of the
-- following:
--
-- o Cast the 'integer' variable 'oper_0' to be of type 'word_t'.
-- o Declare 'oper_0' as an unsigned variable and assign it to
-- 'op_0'.

library ieee;
use ieee.std_logic_1164.all, ieee.numeric_bit.all;

package types is
subtype word_t is unsigned(31 downto 0);
end package types;

library ieee;
use ieee.std_logic_1164.all, ieee.std_logic_arith.all,
ieee.std_logic_unsigned.all;
use work.types;

entity main is
Port (clk : in std_logic; op_0 : out types.word_t);
end main;

architecture structural of main is
begin
driver : process (clk) is
variable oper_0 : integer := 0;
begin
op_0 <= oper_0;
-- ^^^^^^^^ Error: Type of op_0 is incompatible with type of oper_0.
op_0 <= types.word_t(oper_0);
-- ^^^^^^^^ Error: The expression can not be converted to type word_t.
op_0 <= conv_std_logic_vector(oper_0, 32);
-- ^^^^^^^^ Error: Type of op_0 is incompatible with type of
-- conv_std_logic_vector.
op_0 <= types.word_t(conv_unsigned(oper_0, 32));
-- ^^^^^^^^ Error: The expression can not be converted to type word_t.
end process driver;
end structural;

Thanks for any help,
thutt

First of all, get rid of std_logic_arith and std_logic_unsigned. They
are non-standard, impostor packages created by Synopsys, and subject
to different implementations by different tool vendors. Use
ieee.numeric_std instead.

Why can't you declare oper_0 as word_t?

To assign an integer value to a word_t (a subtype of unsigned), use
to_unsigned() out of numeric_std package.

oper_0 := to_unsigned(int_val, oper_0'length);

Or if you'd really rather have an integer for oper_0, you have to
convert it similarly to assign to op_0:

op_0 <= to_unsigned(oper_0, op_0'length);

Now, numeric_std.unsigned is convertible to/from std_logic_vector via
"cast" (not a vhdl term, but it gets the point across):

my_unsigned <= unsigned(my_std_logic_vector);
my_std_logic_vector <= std_logic_vector(my_unsigned);

Or, I often declare the unconstrained subtype:

subtype slv is std_logic_vector; -- abbreviation

then I can use the shorter slv type name instead of
"std_logic_vector":

my_slv <= slv(my_unsigned);

Hope this helps,

Andy
 
T

Taylor Hutt

Andy said:
On Apr 17, 6:31 pm, Taylor Hutt <[email protected]>
wrote:


First of all, get rid of std_logic_arith and
std_logic_unsigned. They are non-standard, impostor packages created
by Synopsys, and subject to different implementations by different
tool vendors. Use ieee.numeric_std instead.

Thanks, that's good information. Where can I find such information?
I'm too cheap to buy the IEEE VHDL LRM, and I don't want to read it
anyway as I've not heard anything interesting about it. "Cure for
insomnia..."
Why can't you declare oper_0 as word_t?

In simple terms, because I want to increment it with each iteration
through a loop. I want to verify that the output of my ALU for each
operator and all operands produces the expected value.

If there's a simple way to increment a 'word_t' type by one, then I'd
be happy to do that instead of converting an integer to a 'word_t'.
To assign an integer value to a word_t (a subtype of unsigned), use
to_unsigned() out of numeric_std package.

oper_0 := to_unsigned(int_val, oper_0'length);

I tried creating oper_0 as a 'word_t' and applying this, but the
Xlinix tool produces an error. Since it's not the current code that I
have, I'll move on....
Or if you'd really rather have an integer for oper_0, you have to
convert it similarly to assign to op_0:

op_0 <= to_unsigned(oper_0, op_0'length);

Ok, this fails under Xilinx's XST too.

'Type of op_0 is incompatible with type of to_unsigned.'

I won't be surprised if Xilinx's tool is wrong -- heck, they don't
even support the enumeration attribute 'val'!

Don't I need to convert it to some sort of vector?

Would be be too much trouble to ask you to verify that this works with
whatever tool you're using? I don't want to file a case against
Xilinx's tools if their behavior is correct, but I certainly do enjoy
filing the reports when their defects really bite me.

On tangent, what's the advantage of defining 'word_t' as I have versus
something like:

type word_t is std_logic_vector(31 downto 0)

or

type word_t is std_ulogic_vector(31 downto 0)

or

type word_t is bit(31 downto 0)?

(Syntax may be wrong, but you get the picture.)

I've copied the ideas for the ALU from a book, and the book
conveniently doesn't talk about 'unsigned' subtypes, so I don't know
the relative merits of one form or the other. (I understand that bit
doesn't give information about electrical signals, but I can't imagine
I'd need that capability for an ALU)

Thanks for the information, I appreciate it, as I'm stuck on this
right now,

thutt
 
M

Magne

Taylor said:
-- I have an ALU which I want to verify. It has a fundamental type
-- 'word_t' which is defined as shown in the package 'types'.
--
-- To verify that the output of the ALU is correct, I want to iterate
-- over each operation, and all the operand values, setting the inputs
-- to the entity with the current 'op_0', 'op_1' and 'operator'
-- values.
--
-- However, being a rank novice VHDL programmer, the only way I can
-- think to do this easily is to declare an integer value for the
-- operands, and then assign this variable to the signal.
--
-- The problem is that I don't now how to cast the variable to the
-- 'word_t' type.
--
-- Can someone point me in the right direction to do one of the
-- following:
--
-- o Cast the 'integer' variable 'oper_0' to be of type 'word_t'.
-- o Declare 'oper_0' as an unsigned variable and assign it to
-- 'op_0'.

library ieee;
use ieee.std_logic_1164.all, ieee.numeric_bit.all;

package types is
subtype word_t is unsigned(31 downto 0);
end package types;

Here you define word_t as a subtype of unsigned from the
ieee.numeric_bit library. That will make it an array of bits not
std_logics. It looks to me like you would like to use
ieee.numeric_std.all instead.

Also, I think there might be a difference between type and subtype
declarations. My theory is that if you declare it as a subtype you will
need a conversion function to go from unsigned to word_t but not the
other way around.
library ieee;
use ieee.std_logic_1164.all, ieee.std_logic_arith.all,
ieee.std_logic_unsigned.all;
use work.types;

You should include numeric_std here aswell and get rid of
std_logic_arith and std_logic_unsigned. Call the function from
numeric_std to convert the integer to a unsigned. (I don't recall the
name of it right now :) You might need to typecast it to a word_t aswell.

You could try this:
op_0 <= word_t(to_unsigned(oper_0, 32));
entity main is
Port (clk : in std_logic; op_0 : out types.word_t);
end main;

architecture structural of main is
begin
driver : process (clk) is
variable oper_0 : integer := 0;
begin
op_0 <= oper_0;
-- ^^^^^^^^ Error: Type of op_0 is incompatible with type of oper_0.
op_0 <= types.word_t(oper_0);
-- ^^^^^^^^ Error: The expression can not be converted to type word_t.
op_0 <= conv_std_logic_vector(oper_0, 32);
-- ^^^^^^^^ Error: Type of op_0 is incompatible with type of
-- conv_std_logic_vector.
op_0 <= types.word_t(conv_unsigned(oper_0, 32));
-- ^^^^^^^^ Error: The expression can not be converted to type word_t.
end process driver;
end structural;


Thanks for any help,
thutt

Hope this helps

Mamu
 
B

Brian Drummond

<I wrote it, I can snip it>

In simple terms, because I want to increment it with each iteration
through a loop. I want to verify that the output of my ALU for each
operator and all operands produces the expected value.

If there's a simple way to increment a 'word_t' type by one, then I'd
be happy to do that instead of converting an integer to a 'word_t'.

If word_t is unsigned (numeric_std.unsigned, that is!) you can add 1 to
it directly.

- Brian
 
A

Andy

Here you define word_t as a subtype of unsigned from the
ieee.numeric_bit library. That will make it an array of bits not
std_logics. It looks to me like you would like to use
ieee.numeric_std.all instead.

Also, I think there might be a difference between type and subtype
declarations. My theory is that if you declare it as a subtype you will
need a conversion function to go from unsigned to word_t but not the
other way around.




You should include numeric_std here aswell and get rid of
std_logic_arith and std_logic_unsigned. Call the function from
numeric_std to convert the integer to a unsigned. (I don't recall the
name of it right now :) You might need to typecast it to a word_t aswell.

You could try this:
op_0 <= word_t(to_unsigned(oper_0, 32));








Hope this helps

Mamu

Good catch Mamu! (on the numeric_bit usage).

Subtypes and their parent types can be interchanged without
conversions, in either direction. Sometimes it involves an invisible
bounds check, but that has nothing to do with the coding.

Taylor,

The LRM, as of yet, does not cover the numeric_std packages. Most
tools will have a copy of at least the package declaration, if not the
body as well. Search through your tool suite's libraries.

I believe your compilation errors will go away if you use the
conversion functions from numeric_std, and standardize all packages
and entity/architectures on numeric_std as well.

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

Forum statistics

Threads
473,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top