Ambiguous type in infix expression

J

jens

The code listed below yields the following errors in ModelSim:

Ambiguous type in infix expression; ieee.numeric_std.unsigned or
work.test_package.unsigned8_array.
Illegal type conversion to ieee.numeric_std.signed (operand type is
not known).

The original code does something a little more useful, I just whittled
it down. Commenting out the seemingly unrelated type definition fixes
the problem, as does changing the typedef to a signed array. Moving
the "000" outside of the type conversion also works ("000" &
signed(...)). Various other attempts to remove the error typically
didn't work (including using a type qualifier for the "000").

In the meantime I've avoided the problem by using shift_left, but it
seems like there's nothing ambiguous here and that it should work.
Note that nothing's actually using the typedef. Any ideas?

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

package test_package is

type unsigned8_array is array (natural range <>) of unsigned(7
downto 0); -- here's what causes the error

end package test_package;

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

entity test is
port
(
input_unsigned: in unsigned(15 downto 0);
output_signed: out signed(15 downto 0)
);
end entity test;

architecture arch of test is
begin

output_signed <= signed("000" & input_unsigned(15 downto 3)); --
this is the line with the error

end architecture arch;
 
S

sandeep

The code listed below yields the following errors in ModelSim:

Ambiguous type in infix expression; ieee.numeric_std.unsigned or
work.test_package.unsigned8_array.
Illegal type conversion to ieee.numeric_std.signed (operand type is
not known).

The original code does something a little more useful, I just whittled
it down.  Commenting out the seemingly unrelated type definition fixes
the problem, as does changing the typedef to a signed array.  Moving
the "000" outside of the type conversion also works ("000" &
signed(...)).  Various other attempts to remove the error typically
didn't work (including using a type qualifier for the "000").

In the meantime I've avoided the problem by using shift_left, but it
seems like there's nothing ambiguous here and that it should work.
Note that nothing's actually using the typedef.  Any ideas?

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

package test_package is

    type unsigned8_array is array (natural range <>) of unsigned(7
downto 0); -- here's what causes the error

end package test_package;

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

entity test is
port
(
    input_unsigned: in  unsigned(15 downto 0);
    output_signed:  out signed(15 downto 0)
);
end entity test;

architecture arch of test is
begin

    output_signed <= signed("000" & input_unsigned(15 downto 3)); --
this is the line with the error

end architecture arch;

I tried to compile above code and didnot get any errors or warnings. I
am using
Cadence 5.8. And for me code looks ok.
 
G

Guest

The code listed below yields the following errors in ModelSim:

Ambiguous type in infix expression; ieee.numeric_std.unsigned or
work.test_package.unsigned8_array.
Illegal type conversion to ieee.numeric_std.signed (operand type is
not known). [...]
type unsigned8_array is array (natural range <>) of unsigned(7
downto 0); -- here's what causes the error

I would need to do a bit of digging in the LRM to be totally
sure, but I think Modelsim is probably right here. Your
expression
"000" & input_signed(...)
has the function signature
"&"[UNSIGNED, UNSIGNED] return <something>
and, because it's inside a type conversion, VHDL has
no hints about what "something" might be. So it looks
for all the various forms of "&" it knows about, and
it finds
--- the one you want, and we all know and love
"&"[UNSIGNED, UNSIGNED] return UNSIGNED;
--- an implicit & operator provided by your new
--- array-of-signed type
"&"[UNSIGNED, UNSIGNED] return unsigned8_array;

I'd be happy to be corrected about this; anything
to do with the implicit operators created by a type
definition is a reliable way of confusing me.

If I'm right, the following rather ugly arrangement
should fix it, by forcing the "&" operator to return
UNSIGNED as you require:

output_signed <= signed(
unsigned'(
"000" & input_unsigned(15 downto 3)
)
);

Note the inner type QUALIFICATION, not conversion.

However, I would have thought that this version would
probably be nicer, and closer to your intent:

output_signed <= signed (
resize (
input_unsigned(15 downto 3),
output_signed'length
)
);

Or maybe something with a shift operator:

output_signed <= signed ( input_unsigned srl 3 );

Finally, a custom conversion function would probably
be best of all, especially if you're using it in more
than one place; hide away all the ugliness inside a
function with a nice sensible name!
Obviously, it depends on the details of what you're
really doing.

HTH
 
J

James Unterburger

If Cadence compiled this, then they are not LRM compliant.

The problem is with the type conversion expression:
signed("000" & input_unsigned(15 downto 3))

Well actually, since we can't use the target type of the conversion
when determining the type of the operand of the type conversion,
the problem is with the operand, which is the concatenation expression,
the infix expression mentioned in the error message from
ModelSim:

"000" & input_unsigned(15 downto 3)


Any compliant compiler must choose which "&" operator to use
from the overloading rules, which allow only types (not
subtypes) to be considered.

Since the slice of input_unsigned is of type unsigned, there
are two "&" operators which could be used, hence the error
since this is ambiguous:

"&"[unsigned, unsigned RETURN unsigned]
"&"[unsigned, unsigned RETURN unsigned8_array]

So the concatenation is either an [array&array=>longer array]
concatenation, or a [elem&elem=>2-element array] concatenation
(which would be an error in this example since neither element
is an 8-element array). Again, only types, not subtypes are
allowed when attempting to disambiguate overloaded operators
and/or functions.

Use a qualified expression to tell the compiler the type
of the result of the concatenation:

output_signed <= signed(unsigned'("000" & input_unsigned(15 downto 3)));

In the above, the "&" operator is being "told", via the qualified
expression, what its return type must be, so the array-of-array
implicit "&" operator is no longer considered.

This will also work:

output_signed <= ("000" & signed(input_unsigned(15 downto 3)));

In the above, the type conversion of input_unsigned to type signed
removes the array-of-array type's implicit "&" operators from
consideration (since the element type is unsigned, not signed),
so the ambiguity disappears.
 

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,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top