illegal reference of a signal during a static elaboration, vhdl

I have an entity inside such entity is declare a component, and of course i need to set the port map in the component.

basically i've done something like

port map (x => '0' & signal_id, ...

let's say that x : in std_logic_vector(n - 1 downto 0) while signal signal_id : std_logic_vector(n - 2 downto 0)

so basically i wanted to perform a mapping of a signal sized n - 1 with a signal of size n, so i tried to perform a padding adding one zero. However when i try to run ncvhdl it says:

port map(x => '0' & signal_id,
|
ncvhdl_p: *E,ILSGRD (test.vhd,159|32): illegal reference of a signal (SIGNAL_ID) during static elaboration [12.3].


what's the meaning of static elaboration in this case? i've tried to check if there was a syntax error, however from the ashenden book i've seen that expression as mapping in a port map is legal.

Can anyone explain me what's happening?

• Do you know what VHDL version introduced this? It's not something I've seen; maybe the tool hasn't caught up with the standard. – scary_jeff Oct 30 '15 at 16:18
• Yes it's ncvhdl -v93 the command i've used. So VHDL 93 – user8469759 Oct 30 '15 at 16:18
• Try using vhdl2008 mode if it has one – scary_jeff Oct 30 '15 at 16:25
• It doesn't come out with vhdl2008, just tested. However i need vhdl 93, is there an "elegant way" to do that without declaring auxiliary signals? – user8469759 Oct 30 '15 at 16:29
• How about x(n-1) => '0', x(n-2 downto 0) => signal_id ? – scary_jeff Oct 30 '15 at 16:41

It's helpful when asking VHDL to question to provide a minimal, complete, and verifiable example pointing to an error.

Here's a solution:

library ieee;
use ieee.std_logic_1164.all;

entity some_entity is
generic (n: natural := 9);
port (
x:    in  std_logic_vector (n-1 downto 0)
);
end entity;

architecture foo of some_entity is
begin
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity some_entity_tb is
end entity;

architecture foo of some_entity_tb is
constant n: natural := 9;
signal signal_id:   std_logic_vector (n - 2 downto 0);
begin
INSTANTIATED:
entity work.some_entity
generic map (n)
port map (
x(n-2 downto 0) => signal_id,
x(n-1) => '0'
);
end architecture;


The entire bit analyzes and some_entity_tb elaborates and runs (without actually doing anything useful other than proving connectivity).

You have the ability in VHDL (incl. -93) to associate elements (members) of an array port formal separately.

IEEE Std 1076-1993 4.3.2.2 Association lists, para 14:

A formal may be either an explicitly declared interface object or member (see Section 3) of such an interface object. In the former case,such a formal is said to be associated in whole. In the latter cases,named association must be used to associate the formal and actual; the subelements of such a formal are said to be associated individually. Furthermore, every scalar subelement of the explicitly declared interface object must be associated exactly once with an actual (or subelement thereof)in the same association list, and all such associations must appear in a contiguous sequence within that association list. Each association element that associates a slice or subelement (or slice thereof) of an interface object must identify the formal with a locally static name.

And to explain where the error message:

ncvhdl_p: *E,ILSGRD (test.vhd,159|32): illegal reference of a signal (SIGNAL_ID) during static elaboration [12.3].


came from:

IEEE Std 1076-1993, 12.3 Elaboration of a declarative part, para 3:

In certain cases, the elaboration of a declarative item involves the evaluation of expressions that appear within the declarative item. The value of any object denoted by a primary in such an expression must be defined at the time the primary is read (see 4.3.2 ). In addition, if a primary in such an expression is a function call, then the value of any object denoted by or appearing as a part of an actual designator in the function call must be defined at the time the expression is evaluated.

It's telling you that you can't assign an expression as an actual to a formal unless the value of the object signal_id is known at elaboration time, and a signal's value isn't known until after elaboration:

NOTE--It is a consequence of this rule that the name of a signal declared within a block cannot be referenced in expressions appearing in declarative items within that block, an inner block, or process statement; nor can it be passed as a parameter to a function called during the elaboration of the block. These restrictions exist because the value of a signal is not defined until after the design hierarchy is elaborated. However, a signal parameter name maybe used within expressions in declarative items within a subprogram declarative part, provided that the subprogram is only called after simulation begins,because the value of every signal will be defined by that time.