Electronic – Understanding type conversion in expression in vhdl

typecastvhdl

i've a source code where basically there's this expression:

unsigned( '1' & unsigned(((17-10-1) downto 0 => '0'))))

ncvhdl 93 returns

ncvhdl: 14.10-E460: (c) Copyright 1995-2015 Cadence Design Systems, Inc.
        unsigned( '1' & unsigned(((17-10-1) downto 0 => '0'))));
                                                           |

illegal type conversion operand [7.3.5].
        unsigned( '1' & unsigned(((17-10-1) downto 0 => '0'))));
                               |

can not make sense of P(...) [6.4] [6.5] [7.3.3] [7.3.5] 87[8.5] 93[8.6]

There's clearly a problem when i write expression like this… so basically i was wandering what's the return type of expression like:

(a downto b => c)?

I thought it was a std_logic_vector and in my mind the conversion to unsigned shouldn't give any problem…

Best Answer

An aggregate gets it's type from context. You don't type convert an unknown type to type unsigned.

You can use a qualified expression to specify the type of the aggregate:

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

entity foo is
end entity;

architecture fum of foo is
    signal some_unsigned: unsigned (7 downto 0);
begin
    some_unsigned <= unsigned( '1' & unsigned'(((17-10-1) downto 0 => '0')));
end architecture;

(You also had one too many ')' closing parenthesis).

This analyzes, elaborates and simulates (while doing nothing interesting simulation tells us the length on the left hand and right hand side of the assignment matches).

And unless I'm mistaken the added apostrophe goes exactly where the vertical bar shows up in your ncvhdl error message:

illegal type conversion operand [7.3.5].
        unsigned( '1' & unsigned'(((17-10-1) downto 0 => '0')));
                               |

(with added apostrophe for qualified expression shown)

And to simplify the entire expression:

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

entity foo is
end entity;

architecture fum of foo is
    signal some_unsigned: unsigned (7 downto 0);
begin
    some_unsigned <= ( '1' & unsigned'(((17-10-1) downto 0 => '0')));
end architecture;

This also works, because there's only one "&" function as an operator overload defined that will take a std_ulogic ('1') and an unsigned.

Lukkio asks:

So for example an expression like b <= a + (3 downto 0 => '1') where both 'b' and 'a' are unsigned it is valid?

I can add another architecture to the foo entity code example:

architecture fie of foo is 
    signal a,b: unsigned (3 downto 0); 
begin 
    b <= a + (3 downto 0 => '1'); 
end architecture; 

(and it works).

The aggregate gets it's type from context. IEEE 1076-1993, 7.3.2 Aggregates, para 7:

The type of an aggregate shall be determinable solely from the context in which the aggregate appears, excluding the aggregate itself but using the fact that the type of the aggregate shall be a composite type. The type of an aggregate in turn determines the required type for each of its elements.

The context here is the "+" function with a left operand that is unsigned and a return value that is unsigned and knowing it has to be an array type.

The type of the left hand operand a is unsigned. The type of the result is determined by the type of the assignment target b. We can determine from the aggregate that it's a single dimensional array.

There's only one operator overload available in the only package provided in the context clause that's eligible. That's "+"[unsigned, unsigned, return unsigned] in package numeric_std.

With no ambiguity as to which overload operator and the types of it's arguments and result the type of the aggregate expression must be unsigned, determined from context.

Also note we can determine it's subtype by the index constraint provided in the aggregate's choice.

Related Topic