# VHDL - range direction of variable length generic

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.

• The used "default" direction comes from the declaration of std_ulogic_vector. It uses a positive index, that in turn is defined from 0 to integer'high. So you could enforce another "default direction" by creating another integer subtype and a new vector type :). This ascend function can be used to enforce an ascending range. See desend for the opposite direction. – Paebbels Oct 29 '17 at 17:21

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;

• I haven't ever seen an alias used in the entity declaration like that. Good to know. – Lincoln Oct 26 '17 at 14:09

As far as I know there is not a way to inform the tools of a direction without also specifying the range.

Typically if I needed a variable length generic I would use a second generic to define its length. Using your example it would look like this:

entity my_entity is
generic (
GEN_LEN: positive := 59; -- positive forces len >= 1
GEN: std_ulogic_vector(GEN_LEN-1 downto 0) :=
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;


I understand that this is probably not nearly as pretty as what you were hoping for. It does handle your use case though.