Ambiguous type in infix expression

Discussion in 'VHDL' started by jens, Oct 15, 2008.

  1. jens

    jens 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).

    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;
     
    jens, Oct 15, 2008
    #1
    1. Advertising

  2. jens

    sandeep Guest

    On Oct 15, 12:22 pm, jens <> wrote:
    > 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.
     
    sandeep, Oct 15, 2008
    #2
    1. Advertising

  3. jens

    Guest

    On Oct 15, 5:22 am, jens <> wrote:
    > 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
    --
    Jonathan Bromley
     
    , Oct 15, 2008
    #3
  4. 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.


    sandeep wrote:
    > On Oct 15, 12:22 pm, jens <> wrote:
    >
    >>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.
     
    James Unterburger, Oct 15, 2008
    #4
  5. Mike Treseler, Oct 15, 2008
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. senthil
    Replies:
    1
    Views:
    3,346
    Egbert Molenkamp
    Feb 27, 2004
  2. KidLogik
    Replies:
    5
    Views:
    7,093
    David Rubin
    Feb 3, 2004
  3. Vladimir

    Ambiguous Expression

    Vladimir, Dec 28, 2004, in forum: C++
    Replies:
    17
    Views:
    2,120
    Attila Feher
    Dec 30, 2004
  4. Trit
    Replies:
    8
    Views:
    3,160
  5. tomer
    Replies:
    0
    Views:
    2,138
    tomer
    Jul 28, 2011
Loading...

Share This Page