In VHDL we can constrain the length of an std_logic_vector in port map as follows:
entity fdct_coeff_rom is
generic (
data_len : integer range 1 to 8
);
port (
i_clk : in std_logic;
i_rst_n : in std_logic;
i_data : in std_logic_vector(data_len-1 downto 0);
i_we : in std_logic;
i_re : in std_logic;
o_data : out std_logic_vector(data_len-1 downto 0)
);
I have an array of std_logic_vectors in the port map. The ports are 8 std_logic_vectors, the length of which can change. Now I am not sure how to use generic to change the length of each std_logic_vector. Is this possible?
entity fdct_coeff_rom is
generic (
data_len : integer range 1 to 8
);
port (
i_clk : in std_logic;
i_rst_n : in std_logic;
i_data : in data_arr_t; -- 8 std_logic_vector, each data_len-1 downto 0
i_we : in std_logic;
i_re : in std_logic;
o_data : out data_arr_t -- 8 std_logic_vector, each data_len-1 downto 0
);
The data_arry_t is defined in a package as an array of std_logic_vector. I am not sure how I can specify the size of the std_logic_vector using a generic such that, each instance of the module has a different length of the std_logic_vector.
Please note that the module I am dealing with is complex, the example in this question is just to illustrate what I am trying to do.
Now, if this is not at all possible in VHDL, can this be done in SystemVerilog?
1 Answer 1
VHDL 2008 allows all dimensions to be unconstrained when a type is defined. So, first create a package with the type:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package my_pkg is
type slv_array_t is array(natural range <>) of std_logic_vector;
end package;
Now define the entity:
-- use VHDL-2008
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.my_pkg.all;
entity my_entity is
generic(
N : natural := 8;
WW : natural := 16
);
port (
i_clk : in std_logic;
i_data : in slv_array_t(0 to N-1)(WW-1 downto 0);
o_data : out slv_array_t(0 to N-1)(WW-1 downto 0)
);
end entity;
architecture rtl of my_entity is
begin
process(i_clk)
begin
if rising_edge(i_clk) then
o_data <= i_data;
end if;
end process;
end architecture;
Take note of how the 2D array is being constrained in both dimensions, inner and outer.
i_data : in slv_array_t(0 to N-1)(WW-1 downto 0);
o_data : out slv_array_t(0 to N-1)(WW-1 downto 0)
This must be compiled with VHDL-2008 enabled. This will synthesize in Intel Quartus Prime, Xilinx Vivado and also Microsemi Libero SoC as long as the VHDL-2008 setting is specifie.
-
1\$\begingroup\$ In my_pkg composite array type slv_array_t has a single index, it's not a multidimensional array type while it's element type happens to be a composite array type with a single index. An object of type slv_array_t is not a 2D array. An indexed name specifies a specific element, a slice name a range of elements. A multidimensional (2D) array type can't be sliced. You can have an indexed name whose prefix is an indexed name and designates an element of a std_logic_vector and is a subelement of a slv_array_t. See Std 1076-2008 5.3.2 Array types and 8. Names. \$\endgroup\$user16145658– user161456582022年08月12日 20:27:00 +00:00Commented Aug 12, 2022 at 20:27
-
1\$\begingroup\$ I do not understand what you said, is there an example of what you are referring to? \$\endgroup\$quantum231– quantum2312022年08月13日 13:48:40 +00:00Commented Aug 13, 2022 at 13:48