vhdl

Can an embedded configuration be used for an instance inside a generate?


In the VHDL architecture declarative region I sometimes use embedded configurations like for and_gate_inst : and_gate use entity work.and_gate(rtl); But I don't know how to write this embedded configuration when the instance is inside a generate. Perhaps this is not supported. The embedded configuration statement inside my code example produces an error and is not correct:

library ieee;
use ieee.std_logic_1164.all;
entity and_gate is
    port (
        inp1_i, inp2_i : in std_logic;
        out_o  : out std_logic
    );
end entity;
architecture rtl of and_gate is
begin
    out_o <= inp1_i and inp2_i;
end architecture;

library ieee;
use ieee.std_logic_1164.all;
entity embedded_conf is
end entity embedded_conf;
library work;
architecture struct of embedded_conf is
    signal inp1, inp2, out1  : std_logic;
    component and_gate is
        port (
            inp1_i : in  std_logic;
            inp2_i : in  std_logic;
            out_o  : out std_logic
        );
    end component;
    for dummy_g for and_gate_inst : and_gate use entity work.and_gate(rtl); -- Not correct!!!
begin
    dummy_g: if true generate
        and_gate_inst : and_gate
            port map (
                inp1_i => inp1,
                inp2_i => inp2,
                out_o  => out1
            );
    end generate dummy_g;
end architecture;

Does anybody know how this embedded configuration has to look like?


Solution

  • Can an embedded configuration be used for an instance inside a generate?

    The simple answer to the title question for the code example error is no. The reason why depends on where a configuration specification for an instantiated component can appear.

    1. Specifications

    7.1 General, second paragraph:

    A specification always relates to named entities that already exist; thus a given specification shall either follow or (in certain cases) be contained within the declaration of the entity to which it relates. Furthermore, a specification shall always appear either immediately within the same declarative part as that in which the declaration of the named entity appears, or (in the case of specifications that relate to design units or the interface objects of design units, subprograms, or block statements) immediately within the declarative part associated with the declaration of the design unit, subprogram body, or block statement.

    The block statement here is elaborated from the generate statement:

    14.5.3 Generate statements

    Elaboration of a generate statement consists of the replacement of the generate statement with zero or more copies of a block statement whose declarative part consists of declarative items contained within the generate statement and whose statement part consists of concurrent statements contained within the generate statement. These block statements are said to be represented by the generate statement. Each block statement is then elaborated.

    A configuration specification (e.g. IEEE 1076-2008 7.3 Configuration specification) is a block declarative item which can be found in an architecture declarative part (3.3.2 Architecture declarative part) or a generate statement body (11.8 Generate statements):

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity and_gate is
        port (
            inp1_i, inp2_i:  in std_logic;
            out_o:   out std_logic
        );
    end entity;
    
    architecture rtl of and_gate is
    begin
        out_o <= inp1_i and inp2_i;
    end architecture;
    
    library ieee;
    use ieee.std_logic_1164.all;
    
    entity embedded_conf is
    end entity embedded_conf;
    
    -- library work;
    architecture struct of embedded_conf is
        signal inp1, inp2, out1:   std_logic;
        component and_gate is
            port (
                inp1_i:  in  std_logic;
                inp2_i:  in  std_logic;
                out_o:   out std_logic
            );
        end component;
        -- for dummy_g
        --     for and_gate_inst  and_gate
        --         use entity work.and_gate(rtl); -- Not correct!!!
    begin
    
    dummy_g:
        if true generate
            for and_gate_inst: and_gate
                use entity work.and_gate(rtl);
        begin
    and_gate_inst:
            and_gate
                port map (
                    inp1_i => inp1,
                    inp2_i => inp2,
                    out_o  => out1
                );
        end generate dummy_g;
    end architecture;
    

    7.3 Configuration specifications
    7.3.1 General

    A configuration specification associates binding information with component labels representing instances of a given component declaration.
    ...
    The elaboration of a configuration specification results in the association of binding information with the labels identified by the instantiation list. ...

    The elaboration of a configuration specification results in the association of binding information with the labels identified by the instantiation list.

    There is no ability to specify hierarchy in a configuration specification, it doesn't contain a block configuration. For that you would need a configuration declaration (3.4 Configuration declaration) which is a primary unit and would be the target of elaboration (-e) and simulation (-r) with ghdl.

    In a configuration declaration there's only one binding indication possible when the reserved word entity is used:

    -- library work;
    architecture struct of embedded_conf is
        signal inp1, inp2, out1:   std_logic;
        component and_gate is
            port (
                inp1_i:  in  std_logic;
                inp2_i:  in  std_logic;
                out_o:   out std_logic
            );
        end component;
        -- for dummy_g
        --     for and_gate_inst  and_gate
        --         use entity work.and_gate(rtl); -- Not correct!!!
    begin
    
    dummy_g:
        if true generate
            -- for and_gate_inst: and_gate
            --     use entity work.and_gate(rtl);
        -- begin
    and_gate_inst:
        and_gate
            port map (
                inp1_i => inp1,
                inp2_i => inp2,
                out_o  => out1
            );
        end generate dummy_g;
    end architecture;
    
    configuration embedded_conf_configuration of embedded_conf is
        for struct
            for dummy_g
                for and_gate_inst: and_gate
                    use entity work.and_gate(rtl);
                end for;
            end for;
        end for;
    end embedded_conf_configuration;
    

    The configuration would be invoked for simulation by:

    %: ghdl -e embedded_conf_configuration
    %: ghdl -r embedded_conf_configuration
    %: 
    

    Using ghdl with a gcc or llvm backend.

    For the mcode version just the -r command after all the design units have been analyzed into one or more design libraries.

    Note few if any synthesis tool chains for FPGA synthesis support declarations while that was a requirement in IEEE Std 1076.6-2004 RTL Synthesis (withdrawn due to lack of vendor participation).

    Unlike configuration specifications block configurations found in configuration declarations can be nested to describe an elaborated design hierarchy:

    configuration test_config of des_test is
        for behave
            for des_chip: des
                use configuration work.behave_config;
            end for;
        end for;
    end test_config;