4
\$\begingroup\$

My design has a entity for configuration which returns std_logic_vectors (length defined by generic - normally 32 bit)

entity CenterConfig is
generic (
    -- Width of S_AXI data bus
    C_S_AXI_DATA_WIDTH  : integer   := 32;
    -- Width of S_AXI address bus
    C_S_AXI_ADDR_WIDTH  : integer   := 4
);
port (
    ...
    ...
    center_height: out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
    center_width: out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0)
);
end CenterConfig;

During instantiation I want to connect only the used pins and declare the others as OPEN.

Config: CenterConfig 
generic map(
    C_S_AXI_DATA_WIDTH => C_S_AXI_DATA_WIDTH,
    C_S_AXI_ADDR_WIDTH => C_S_AXI_ADDR_WIDTH
)
port map(
    ...
    ...
    center_height(std_center_height'range) => std_center_height,
    center_height(C_S_AXI_DATA_WIDTH-1 downto std_center_height'length) => open, 
    -- not working, not elegant

    center_width(std_center_width'range) => std_center_width
);

ERROR: [VRFC 10-1225] partially associated formal center_height cannot have actual OPEN [/home/mir3/Compute/ip_repo/Starburst/src/Starburst.vhd:306]

The length of std_center_height is also define by generics. How can I declare the others a OPEN in an elegant way?

Is there something like (others => open)?

\$\endgroup\$
3
  • \$\begingroup\$ Is 32 the maximum width that these vectors will ever be? \$\endgroup\$
    – scary_jeff
    Commented Apr 1, 2016 at 15:02
  • \$\begingroup\$ In my usecase yes. \$\endgroup\$
    – Botnic
    Commented Apr 1, 2016 at 15:04
  • 1
    \$\begingroup\$ It's not possible to mix connected and open signals in a port map. You could introduce a *_float signal as an intermediate signal. The advantage is that you can filter for warnings related to these signal names and ignore all "unconnected signal" warnings. \$\endgroup\$
    – Paebbels
    Commented Apr 1, 2016 at 17:19

2 Answers 2

3
\$\begingroup\$

The length of std_center_height is also define by generics. How can I declare the others a OPEN in an elegant way?

There's a basic issue with your associations:

center_height(std_center_height'range) => std_center_height,
center_height(C_S_AXI_DATA_WIDTH-1 downto std_center_height'length) => open, 
-- not working, not elegant

center_width(std_center_width'range) => std_center_width

You specified that std_center_height and std_center_width depended on generics, which means the specified slices are locally static names.

IEEE Std 1076-2008 6.5.7.1 Association lists paragraph 16 (in part):

...Furthermore, every scalar subelement of the explicitly declared interface object shall be associated exactly once with an actual (or subelement thereof) in the same association list, and all such associations shall 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 shall identify the formal with a locally static name.

The first of these two sentences gives the reason why, you can't determine every subelement is connected at analysis time for a slice that's dependent on a generic.

There's a long chain of references on what makes up a locally static name (8.1 para 6, locally static name, 9.4.2 para 2 locally static range, para 1 g), 16.2.3 Predefined attributes of arrays ('LENGTH is a function).

You can't have a locally static name dependent on a subtype that isn't locally static. That means all three of those associations won't work. You could declare local constants or use a package whose declaration are visible to both the architecture instantiating CenterConfig and the entity declaration for CenterConfig but that doesn't help with the OPEN issue.

Is there something like (others => open)?

Nope. 6.5.7.1 Association lists paragraph 18:

It is an error if an actual of open is associated with a formal interface object that is associated individually. An actual of open counts as the single association allowed for the corresponding formal interface object, but does not supply a constant, signal, or variable (as is appropriate to the object class of the formal) to the formal.

You can't do individual association with some association subelements open it's all or nothing.

We know you can use a non slice name as a formal, the port name itself is a locally static name. We can use actuals that matches the length of the formals, and because you wanted elegant:

library ieee;
use ieee.std_logic_1164.all;

entity CenterConfig is
    generic (
        C_S_AXI_DATA_WIDTH  : integer   := 32;
        C_S_AXI_ADDR_WIDTH  : integer   := 4
    );
    port (
        center_height: out std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0);
        center_width: out std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0)
    );
end entity CenterConfig;

architecture foo of centerconfig is

begin
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity instance is
    generic (
           CENTERHEIGHT: integer := 16;      -- because 42 is out or range
           CENTERWIDTH:  integer := 16; 
           C_S_AXI_DATA_WIDTH: integer   := 32;
           C_S_AXI_ADDR_WIDTH: integer   := 4
    );
end entity;

architecture fum of instance is 

    component centerconfig is
        generic (
            C_S_AXI_DATA_WIDTH  : integer   := 32;
            C_S_AXI_ADDR_WIDTH  : integer   := 4
        );
        port (
            center_height: 
                out std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0);
            center_width: 
                out std_logic_vector(C_S_AXI_DATA_WIDTH - 1 downto 0)
        );
    end component;

    signal full_center_height: std_logic_vector 
                        (C_S_AXI_DATA_WIDTH - 1 downto 0);
    signal full_center_width:  std_logic_vector
                        (C_S_AXI_DATA_WIDTH - 1 downto 0);

    alias std_center_height: std_logic_vector(CENTERHEIGHT - 1  downto 0) is
        full_center_height (CENTERHEIGHT - 1  downto 0);
    alias std_center_width: std_logic_vector(CENTERWIDTH - 1  downto 0) is
        full_center_height (CENTERWIDTH - 1  downto 0);
begin

Config: 
    CenterConfig 
        generic map (
            C_S_AXI_DATA_WIDTH => C_S_AXI_DATA_WIDTH,
            C_S_AXI_ADDR_WIDTH => C_S_AXI_ADDR_WIDTH
        )
        port map (
            center_height => full_center_height,
            center_width => full_center_width
        );
 Monitor:
     process (std_center_height, std_center_width) 
     begin
         report "std_center_height length = " & 
                 integer'image(std_center_height'length);
         report "std_center_width length = " & 
                 integer'image(std_center_width'length);
     end process;
end architecture;

You can use aliases of slices of the used signal with the intended name.

And this example analyzes, elaborates and simulates:

ghdl -a center_config.vhdl
ghdl -e instance
ghdl -r instance
center_config.vhdl:71:10:@0ms:(report note): std_center_height length = 16
center_config.vhdl:73:10:@0ms:(report note): std_center_width length = 16

And this avoids the requirement for locally static names using slices or trying to specify open associations based on generics.

\$\endgroup\$
2
\$\begingroup\$

I think if it was me, and since the data in this case is just a vector with no direct meaning (as in, it is not a signed or unsigned number), I would make std_center_height have a width of C_S_AXI_DATA_WIDTH, so that it could be connected to the instantiation in a 'normal' way. I would then only use the constant that defines the width of std_center_height when using this vector. Something like:

constant C_STD_CENTER_HEIGHT_WIDTH : integer := 19;
signal std_center_height : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal some_other_vector : std_logic_vector(C_STD_CENTER_HEIGHT_WIDTH-1 downto 0);

...

port map (
  center_height => std_center_height
);

some_other_vector <= std_center_height(C_STD_CENTER_HEIGHT_WIDTH-1 downto 0);

Note that some_other_vector is not an alias of std_center_height, but is just used as an example of 'making use of std_center_height in some other bit of logic'.

\$\endgroup\$
6
  • \$\begingroup\$ Yes that si exactly what I did: --center_height(8 downto 0) => std_center_height, center_height => dummy_center_height, center_width => dummy_center_width ); std_center_height <= dummy_center_height(std_center_height'range); std_center_width <= dummy_center_width(std_center_width'range); It works, but I hoped for a "nicer" solution ;-) \$\endgroup\$
    – Botnic
    Commented Apr 1, 2016 at 15:19
  • \$\begingroup\$ @Botnic Per my clarification, the other vector is not just another name for the same thing, it is showing an example of this vector being used in some other logic. If you added an example of how std_center_height is actually used, I could make the example more representative. \$\endgroup\$
    – scary_jeff
    Commented Apr 1, 2016 at 15:22
  • \$\begingroup\$ Haha, I know what you mean. I made just made up another name for the same vector \$\endgroup\$
    – Botnic
    Commented Apr 1, 2016 at 15:38
  • \$\begingroup\$ @Botnic if you have a vector with the word 'dummy' in the name then you are not implementing what I have suggested. \$\endgroup\$
    – scary_jeff
    Commented Apr 1, 2016 at 15:42
  • \$\begingroup\$ I think it was not a good idea to enlarge std_center_height because this signal is presumably used at a lot of other places in the code. Thus, the name of the intermediate signal should be a new one instead, like dummy_center_height as posted in the first commment from @Botnic. \$\endgroup\$ Commented Apr 6, 2016 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.