VHDL: is there a way to create an entity into which constants can be passed?
Add a generic clause to your entity. It allows you to pass in e.g. constants:
entity counterTst is
generic (
constant COUNTER_LEN : integer -- := 4
);
port (
enable: in STD_LOGIC;
clk: in STD_LOGIC;
rst: in STD_LOGIC;
output: out STD_LOGIC_VECTOR(COUNTER_LEN - 1 downto 0)
);
end counterTst;
architecture rtl of counterTst is
-- constant COUNTER_LEN: integer := 4;
Moreover generic values can be used in you port clause to size ports. A generic can have a default value, thus the user doesn't need to apply it in a generic map. In you case, you shouldn't apply a default value to force the user to think about his choice :).
And here is the usage:
cnt : entity work.counterTst
generic map (
COUNTER_LEN => 4
)
port map (
-- ...
);
Like in a port map, you map generics in a generic map.
Yes, it is called a 'generic':
I could show an example here, but there are plenty of example on the WWW once you know what to look for: https://www.nandland.com/vhdl/examples/example-generic.html
Since VHDL 2008, you can also make output
an unconstrained port and then infer the counter length from that port, as given during instantiation:
entity counterTst is
port(
enable: in std_logic;
clk: in std_logic;
rst: in std_logic;
output: out std_logic_vector
);
end entity;
architecture rtl of counterTst is
constant counter_len: natural := output'length;
-- ...
end architecture;
Just one thing to be careful about: The instantiation will define the full range of output
, so it might be an std_logic_vector(counter_len downto 1)
or even a dreaded to
range. Since you assign output
from a local signal, this is not an issue, but it could be problematic if you try to index output
directly.