Electronic – VHDL – range direction of variable length generic

vhdl

I would like to have some variable length generic in my entity however it looks like the default range direction is to what collides with internal signals ranges that are declared with downto.

entity my_entity is
    generic (
        GEN: std_ulogic_vector := b"100_0000_0000_0000_0000_1000" &
                                  b"0000_0000_0000_0000_0000_0000" &
                                  b"0000_0000_0001"
    );
    port (
        clk: in std_ulogic;
        reset: in std_ulogic;
        a: in std_ulogic_vector(63 downto 0);
        b: out std_ulogic_vector(63 downto 0)
    );
end;

Is there any language specific mechanism to inform VHDL tools that range direction of GEN is downto not to? Right now, the only solution I can think of is to use some extra constant in declarative part of architecture with the same value but different range direction.

Best Answer

Because there's almost always more than one way:

library ieee;
use ieee.std_logic_1164.all;
entity my_entity is
    generic (
        UNBOUND_GEN: std_ulogic_vector := b"100_0000_0000_0000_0000_1000" &
                                  b"0000_0000_0000_0000_0000_0000" &
                                  b"0000_0000_0001"
    );
    port (
        clk: in std_ulogic;
        reset: in std_ulogic;
        a: in std_ulogic_vector(63 downto 0);
        b: out std_ulogic_vector(63 downto 0)
    );
    alias  GEN: std_ulogic_vector (UNBOUND_GEN'length - 1 downto 0) 
              is UNBOUND_GEN;
end entity;

The alias can also be declared as an architecture declarative item or in the immediately enclosing declarative region of where it is used in an architecture.

In a -2008 compliant VHDL tool implementation the alias can be dispensed with and a second generic declaration depending on the first can be used:

library ieee;
use ieee.std_logic_1164.all;
entity my_entity1 is
    generic (
        UNBOUND_GEN: std_ulogic_vector := b"100_0000_0000_0000_0000_1000" &
                                  b"0000_0000_0000_0000_0000_0000" &
                                  b"0000_0000_0001";
        GEN: std_ulogic_vector (UNBOUND_GEN'length - 1 downto 0) := UNBOUND_GEN

    );
    port (
        clk: in std_ulogic;
        reset: in std_ulogic;
        a: in std_ulogic_vector(63 downto 0);
        b: out std_ulogic_vector(63 downto 0)
    );
    -- alias  GEN: std_ulogic_vector (UNBOUND_GEN'length - 1 downto 0)
    --           is UNBOUND_GEN;
end entity;