Search code examples
vhdlmodelsim

Using configuration specification in VHDL/ModelSim


I'm trying to use a VHDL configuration specification to pre-set

This should be possible, as shown in IEEE1076-2008, section 7.3.2.1, which gives the following example:

entity AND_GATE is
    generic (I1toO, I2toO: DELAY_LENGTH := 4 ns);
    port (I1, I2: in BIT; O: out BIT);
end entity AND_GATE;

entity XOR_GATE is
    generic (I1toO, I2toO: DELAY_LENGTH := 4 ns);
    port (I1, I2: in BIT; O: out BIT);
end entity XOR_GATE;

package MY_GATES is
    component AND_GATE is
        generic (I1toO, I2toO: DELAY_LENGTH := 4 ns);
        port (I1, I2: in BIT; O: out BIT);
    end component AND_GATE;
    component XOR_GATE is
        generic (I1toO, I2toO: DELAY_LENGTH := 4 ns);
        port (I1, I2: in BIT; O: out BIT);
    end component XOR_GATE;
end package MY_GATES;

entity Half_Adder is
    port (X, Y: in BIT; Sum, Carry: out BIT);
end entity Half_Adder;

use WORK.MY_GATES.all;

architecture Structure of Half_Adder is
    for L1: XOR_GATE use
        entity WORK.XOR_GATE(Behavior) -- The primary binding
            generic map (3 ns, 3 ns) -- indication for instance L1.
            port map (I1 => I1, I2 => I2, O => O);
    for L2: AND_GATE use
        entity WORK.AND_GATE(Behavior) -- The primary binding
            generic map (3 ns, 4 ns) -- indication for instance L2.
            port map (I1, open, O);
begin
    L1: XOR_GATE port map (X, Y, Sum);
    L2: AND_GATE port map (X, Y, Carry);
end architecture Structure;

use WORK.GLOBAL_SIGNALS.all;

configuration Different of Half_Adder is
    for Structure
        for L1: XOR_GATE
            generic map (2.9 ns, 3.6 ns); -- The incremental binding
        end for; -- indication of L1; rebinds its generics.
        for L2: AND_GATE
            generic map (2.8 ns, 3.25 ns) -- The incremental binding
            port map (I2 => Tied_High); -- indication of L2; rebinds
        end for; -- its generics and binds its open port.
    end for;
end configuration Different;

Even If I add the package missing from the example myself

package GLOBAL_SIGNALS is
    constant Tied_High : bit := '1';
end package GLOBAL_SIGNALS;

Elaboration is still failing in Modelsim.

Error: [...]/half_adder.vhd(36): (vcom-1035) Formal port "I2" has OPEN or no actual associated with it.

Caused by the line

port map (I1, open, O);

Which already seems to indicate that Modelsim doesn't properly support these configuration statements.

I would like to use this configuration specifications to ease my design entry.

Example:

entity comp is
    generic(step : time; defined: boolean);
    port(clk, data : in bit);
end entity;

entity e is end entity e;

architecture a of e is
    component comp is
        generic(step : time; defined: boolean);
        port(clk, data : in bit);
    end component;
    
    signal clk1, clk2 : bit;
    
    for a : comp use
        entity work.comp
            generic map(step => 1 ns)
            port map(clk => clk1);
    for b : comp use
        entity work.comp
            generic map(step => 100 ns)
            port map(clk => clk2);
    for all : comp use
        entity work.comp
            generic map(defined => true);

    signal sig_a, sig_b : bit;
    
begin
    a: comp
        port map(data => sig_a);

    b_gen : for i in 0 to 2 generate
        b: comp
            port map(data => sig_b);
    end generate;
end architecture;

This code throws a large number of errors:

Error: [...]/e.vhd(19): (vcom-1031) Formal generic "defined" has OPEN or no actual associated with it.

Error: [...]/e.vhd(19): (vcom-1035) Formal port "data" has OPEN or no actual associated with it.

Error: [...]/e.vhd(23): (vcom-1031) Formal generic "defined" has OPEN or no actual associated with it.

Error: [...]/e.vhd(23): (vcom-1035) Formal port "data" has OPEN or no actual associated with it.

Error: [...]/e.vhd(26): (vcom-1031) Formal generic "step" has OPEN or no actual associated with it.

Error: [...]/e.vhd(24): ALL configuration specification for component "comp" attempts to re-bind instances already bound.

Error: [...]/e.vhd(24): ALL configuration specification for component "comp" attempts to re-bind instances already bound.

Error: [...]/e.vhd(32): (vcom-1031) Formal generic "step" has OPEN or no actual associated with it.

Error: [...]/e.vhd(32): (vcom-1031) Formal generic "defined" has OPEN or no actual associated with it.

Error: [...]/e.vhd(32): (vcom-1035) Formal port "clk" has OPEN or no actual associated with it.

Error: [...]/e.vhd(36): (vcom-1031) Formal generic "step" has OPEN or no actual associated with it.

Error: [...]/e.vhd(36): (vcom-1031) Formal generic "defined" has OPEN or no actual associated with it.

Error: [...]/e.vhd(36): (vcom-1035) Formal port "clk" has OPEN or no actual associated with it.

Warning: [...]/e.vhd(24): (vcom-1263) Configuration specification "all : comp" applies to no component instantiation statements.

Error: [...]/e.vhd(20): No statement with label "b" was found.

So it seems this is not the supported way to use configuration specifications. Too bad, because it would ease my design entry.

I this just a Modelsim bug, or will configurations specifications never help with these default bindings this way?


Solution

  • The question has changed and so has this answer.

    Elaboration is still failing in Modelsim.

    Error: [...]/half_adder.vhd(36): (vcom-1035) Formal port "I2" has OPEN or no actual associated with it.

    Caused by the line

    port map (I1, open, O);
    

    Which already seems to indicate that Modelsim doesn't properly support these configuration statements.

    There is no 'properly' that can be applied to your conclusion, which isn't supported by the VHDL standard.

    The error appears to have been caused by an attempt to elaborate Half_Adder when I2 is not bound. The configuration specification associates I2 with open, which is not allowed.

    If you create a Minimal, Complete and Verifiable example:

    -- IEEE Std 1076-1993 5.2.1 Binding Indication (example)
    -- -2008 7.3.2.1
    
    package global_signals is   -- THIS PACKAGE MISSING IN THE EXAMPLE
        signal Tied_High:   bit := '1';
    end package;
    
    entity AND_GATE is           -- ADDED entity and architecture
        generic (I1toO, I2toO: DELAY_LENGTH := 4 ns);
        port        (I1, I2: in BIT;   O: out BIT);
    end entity AND_GATE;
    
    architecture Behavior of AND_GATE is  -- ADDED
        signal In1, In2:    BIT;
    begin
        In1 <= I1 after I1toO;
        In2 <= I2 after I2toO;
    
        O <= In1 and In2;
    
        process
        begin
            report
                LF & HT & "I1to0 = " & time'image(I1toO) &
                LF & HT & "I2to0 = " & time'image(I2toO);
            wait;
        end process;
    end architecture Behavior;
    
    entity XOR_GATE is            -- ADDED entity and architecture
        generic (I1toO, I2toO : DELAY_LENGTH := 4 ns);
        port        (I1, I2: in BIT;    O : out BIT);
    end entity XOR_GATE;
    
    architecture Behavior of XOR_GATE is  -- ADDED
        signal In1, In2:    BIT;
    begin
        In1 <= I1 after I1toO;
        In2 <= I2 after I2toO;
    
        O <= In1 xor In2;
    
        process
        begin
            report
                LF & HT & "I1to0 = " & time'image(I1toO) &
                LF & HT & "I2to0 = " & time'image(I2toO);
            wait;
        end process;
    end architecture Behavior;
    
    package MY_GATES is
       component AND_GATE is
          generic  (I1toO, I2toO: DELAY_LENGTH := 4 ns);
          port       (I1, I2: in BIT;   O: out BIT);
       end component AND_GATE;
    
       component XOR_GATE is
          generic  (I1toO, I2toO: DELAY_LENGTH := 4 ns);
          port       (I1, I2: in BIT;   O : out BIT);
       end component XOR_GATE;
    end package MY_GATES;
    
    entity Half_Adder is
        port    (X, Y: in BIT;
                   Sum, Carry: out BIT);
    end entity Half_Adder;
    
    use WORK.MY_GATES.all;
    architecture Structure of Half_Adder is
        signal O:   bit;            -- Added
        for L1: XOR_GATE use
            entity WORK.XOR_GATE(Behavior)      --  The primary binding indication
                 generic map (3 ns, 3 ns)       --  for instance L1.
                 port map (I1 => I1, I2 => I2, O => O);
    
        for L2: AND_GATE use
            entity WORK.AND_GATE(Behavior)      --  The primary binding indication
                 -- generic map (3 ns, 4 ns)       --  for instance L2.
                 port map (I1, open, O);
    
    begin
        L1: XOR_GATE    port map (X, Y, Sum);
        L2: AND_GATE    port map (X, Y, Carry);
    end architecture Structure;
    
    use WORK.GLOBAL_SIGNALS.all;
    
    configuration Different of Half_Adder is
        for Structure
            for L1: XOR_GATE
                generic map (2.9 ns, 3.6 ns); --  The  incremental binding
            end for;               --  indication of L1; rebinds its generics.
    
            for L2: AND_GATE
                generic map (2.8 ns, 3.25 ns)  -- The incremental binding
                port map (I2 => Tied_High); -- indication L2; rebinds its generics
            end for;                          -- and binds its open port.
        end for;
    end configuration Different;
    

    in this case all in one design file it analyzes, elaborates and simulates:

    ghdl -a Half_Adder.vhdl
    ghdl -e different
    ghdl -r different
    Half_Adder.vhdl:44:9:@0ms:(report note): I1to0 = 2900000 fs I2to0 = 3600000 fs Half_Adder.vhdl:22:9:@0ms:(report note): I1to0 = 2800000 fs I2to0 = 3250000 fs

    while demonstrating the incremental binding expressed in the code functions properly.

    Note this requires the a ghdl implementation built from source code containing a recent Github commit.

    Commit : 9e0cf4af3cf2141002b37db9803c15afec8ea2f4 [9e0cf4a]
    Parents : b801510561
    Author : Tristan Gingold
    Date : October 30, 2017 at 7:19:41 AM GMT+13

    Analyzing, elaborating and running the above Half_Adder requires a ghdl built from the Github repository after October 30, 2017, the ability to incrementally bind accidentally lost in a change to how semantic analysis was applied, recently restored. The capability will be in ghdl-0.35 when released.

    No one noticed the lack for a period of a couple of years. The feature is likely less enthusiastically received than the authors of incremental binding might have hoped. You could also note the example in the standard is not complete and additional typo's have shown up in later revisions. The MCVe is now incorporated in ghdl's test suite.

    Your second example code (e.vhdl) you generated doesn't provide a configuration declaration.

    Annex I (Informative) Glossary

    incremental binding: A binding indication in a configuration declaration that either reassociates a previously associated local generic constant or that associates a previously unassociated local port is said to incrementally rebind the component instance or instances to which the binding indication applies. (7.3.2.1)

    How this 'restriction' comes about is a matter of semantic requirements.

    An understanding of incremental binding can be garnered from it's authors in the book 'VHDL'92' by Jean-Michel Bergé, Alain Fonkoua, Serge Maginot and Jacques Rouillard. See VHDL'92, 6. Incremental Binding, pages 47 through 56.

    (Incremental binding can also be found published in IEEE Std P1076-1992c, and was subsequently incorporated in the IEEE Std 1076-1993 revision).

    There are various semantic shortcomings in your second example:

    e.vhdl:

    entity comp is
        generic(step : time; defined: boolean);
        port(clk, data : in bit);
    end entity;
    
    entity e is end entity e;
    
    architecture a of e is
        component comp is
            generic(step : time; defined: boolean);
            port(clk, data : in bit);
        end component;
    
        signal clk1, clk2 : bit;
    
        for a : comp use                          -- Line 15
            entity work.comp
                generic map(step => 1 ns)
                port map(clk => clk1);
        for b : comp use                          -- Line 20
            entity work.comp
                generic map(step => 100 ns)
                port map(clk => clk2);
        for all : comp use                        -- Line 24
            entity work.comp
                generic map(defined => true);
    
        signal sig_a, sig_b : bit;
    
    begin
        a: comp                                   -- Line 31
            port map(data => sig_a);
    
        b_gen : for i in 0 to 2 generate
            b: comp                              -- Line 35
                port map(data => sig_b);
        end generate;
    end architecture;
    

    in addition to the lack of a configuration declaration, the example demonstrates those shortcomings by the Modelsim errors and warnings as well as ghdl:

    ghdl -a e.vhdl
    e.vhdl:31:5:error: no actual for constant interface "step"
    e.vhdl:35:9:error: no actual for constant interface "step"
    e.vhdl:20:9:error: no component instantation with label "b"
    e.vhdl:24:5:error: component instance "a" is already bound by a configuration specification
    e.vhdl:16:5:error: (previous is configuration specification)
    ghdl:error: compilation error
    

    Synthesis tools generally support configuration specifications but not configuration declarations. Incremental binding is of no real practical use when applied to designs destined for silicon.