Electronic – Identifier not declared in generic map, vhdl

vhdl

Following a previous suggestion in this post i tried to write by my self an example, but it doesn't work.

Top entity

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

entity topEntity is
    generic(m : natural);
    port(x : in std_logic_vector(m - 1 downto 0));
end topEntity;

architecture rtl of topEntity is
    component componentEntity is
        generic(n : natural);
        port(x : in std_logic_vector(n - 1 downto 0));
    end component;
begin
    INSTANCE : componentEntity
        generic map(n => m)
        port map(x(n - 1) => '0', x(n - 2 downto 0) => x(m - 2 downto 0));
end architecture rtl;

Component entity

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

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

architecture foo of componentEntity is
begin
end architecture foo;

when i run ncvhdl -v93 it says:

ncvhdl: 15.10-s008: (c) Copyright 1995-2015 Cadence Design Systems, Inc.
                port map(x(n - 1) => '0', x(n - 2 downto 0) => x(m - 2 downto 0));
                           |
ncvhdl_p: *E,IDENTU (topEntity.vhd,19|13): identifier (N) is not declared [10.3].

why it's not declared? it's a generic parameter properly initialized.

Update:

I putted:
port map(x(m - 1) => '0', x(m - 2 downto 0) => x(m - 2 downto 0));

The result is

ncvhdl: 15.10-s008: (c) Copyright 1995-2015 Cadence Design Systems, Inc.
                port map(x(m - 1) => '0', x(m - 2 downto 0) => x(m - 2 downto 0));
                          |
ncvhdl_p: *E,FMLNLS (topEntity.vhd,19|12): formal must be identified a locally static name 87[4.3.3.2] 93[4.3.2.2].
                port map(x(m - 1) => '0', x(m - 2 downto 0) => x(m - 2 downto 0));
                                           |
ncvhdl_p: *E,FMLNLS (topEntity.vhd,19|29): formal must be identified a locally static name 87[4.3.3.2] 93[4.3.2.2].
                port map(x(m - 1) => '0', x(m - 2 downto 0) => x(m - 2 downto 0));
                                           |
ncvhdl_p: *E,UFPTID (topEntity.vhd,19|29): port (X) must be associated [1.1.1.2].

Updated 2…

Still trying to figure out what it is the problem with all these kind of declaration/mapping in vhdl… my new attempt is:

The error report that formal must be identified a locally static name

I found a glossary where each term of interest for this error is explained it also refers to the language standard:

 locally static name: A name in which every expression is locally static (if every discrete range that appears as part of the name denotes a locally static range or subtype and if no prefix within the name is either an object or value of an access type or a function call). (§6.1)

locally static expression: An expression that can be evaluated during the analysis of the design unit in which it appears. (§7.4, §7.4.1)

analysis: The syntactic and semantic analysis of source code in a VHDL design file and the insertion of intermediate form representations of design units into a design library. (§1 1.1, §11.2, §11.4)

There's also the error with the
port (X) must be associated

So i guess the problem could be that the name of the top entity input is x which is the same name as the component input. However i'm not sure about this because in general with port mapping like x => x don't cause any trouble to me…

Looking at the standard as static name it spits out that:

A name is said to be a static name if and only if one of the following conditions holds:
— The name is a simple name or selected name (including those that are expanded names) that does not
denote a function call, an object or value of an access type, or an object of a protected type and (in
the case of a selected name) whose prefix is a static name.
— The name is an indexed name whose prefix is a static name, and every expression that appears as part
of the name is a static expression.
— The name is a slice name whose prefix is a static name and whose discrete range is a static discrete
range.

Futhermore a specification is given for locally static name, which should help me to figure out the problem with the name:

a name is said to be a locally static name if and only if one of the following conditions hold:
— The name is a simple name or selected name (including those that are expanded names) that is not an
alias and that does not denote a function call, an object or value of an access type, or an object of a
protected type and (in the case of a selected name) whose prefix is a locally static name.
— The name is a simple name or selected name (including those that are expanded names) that is an
alias, and that the aliased name given in the corresponding alias declaration (see 4.3.3) is a locally
static name, and (in the case of a selected name) whose prefix is a locally static name.
— The name is an indexed name whose prefix is a locally static name, and every expression that appears
as part of the name is a locally static expression.
— The name is a slice name whose prefix is a locally static name and whose discrete range is a locally
static discrete range

So the issue should be that the name x doesn't fall in any of the categories listed, but why?

Best Answer

Try to replace your component instantiation with this:

INSTANCE : componentEntity
        generic map(n => m)
        port map(x(m - 1) => '0', x(m - 2 downto 0) => x(m - 2 downto 0));

Since n is not declared inside topEntity you can't use it. Your misconception is that the named generic n of componentEntity should be directly visible inside the port assignments region (that is port map (...)). This is not the case.
Since m and n are going to hold the same value (due to n => m) you can just use m when doing port assignments.