I am trying to define a type inside a package whose size is dependent on the component generics. Here is what I am trying to do, but synthesis is complaining:
package DcoPack is
component SinCosDco
generic
(
g_LUT_DEPTH : integer := 2**10;
g_LUT_BIT_RES : integer := 15
);
port
(
reset : in std_logic;
lClk : in std_logic;
InFreqCtrl : in std_logic_vector(31 downto 0) := X"028F5C28";
InStartPhse : in std_logic_vector(31 downto 0) := X"00000000";
OutDco : out signed((g_LUT_BIT_RES - 1) downto 0)
);
type LutSinT is array(0 to g_LUT_DEPTH - 1) of
std_logic_vector(g_LUT_BIT_RES-1 downto 0);
function f_QuantizationSgn(nbit : integer; max_abs : real; dval : real)
return std_logic_vector;
function f_InitLutSin
return LutSinT;
end package DcoPack;
package body DcoPack is
function f_QuantizationSgn(nbit : integer; max_abs : real; dval : real)
return std_logic_vector is
<function body>
end function;
function f_InitLutSin return LutSinT is
<function body>
end function;
end package body DcoPack;
and my component
library DCO_lib;
use DCO_lib.DcoPack.all;
entity Dco is
generic
(
g_LUT_DEPTH : integer := 2**10;
g_LUT_BIT_RES : integer := 15
);
port
(
reset : in std_logic;
lClk : in std_logic;
InDcoEn : in std_logic;
InFreqCtrl : in std_logic_vector(31 downto 0) := X"028F5C28";
InStartPhse : in std_logic_vector(31 downto 0) := X"00000000";
OutDco : out signed((g_LUT_BIT_RES - 1) downto 0)
);
end entity Dco;
architecture zDco of Dco is
-- want to reference LutSinT in numerous components, it varies depending
-- on generics
constant c_SinCosLut : LutSinT := f_InitLutSin;
... <rest of code is irrelevant
As the code above shows, I am trying to reference this type inside each component. However, I need to be able to easily vary the generic parameters depending on the project, so is there a way for VHDL to infer the correct array size? Or am I locked into defining the g_LUT_DEPTH/g_LUT_BIT_RES in the package or hard-coding the type inside each component?
EDIT: Added clarifying code snippets and explanation.
Yes there now is. VHDL-2008 supports package generics. So you can write
library ieee;
use ieee.numeric_std.all;
entity SinCosDco is
generic (
g_LUT_DEPTH : positive;
g_LUT_BIT_RES : positive
);
port (
OutDco : out signed((g_LUT_BIT_RES - 1) downto 0)
);
end entity;
architecture tmp of SinCosDco is
use ieee.std_logic_1164.all;
begin
OutDco <= to_signed(-1, g_LUT_BIT_RES);
end architecture;
library ieee;
package DcoPack is
generic (
g_LUT_DEPTH : positive := 2**10;
g_LUT_BIT_RES : positive := 15
);
use ieee.numeric_std.all;
component SinCosDco
generic (
g_LUT_DEPTH : positive := g_LUT_DEPTH;
g_LUT_BIT_RES : positive := g_LUT_BIT_RES
);
port (
OutDco : out signed((g_LUT_BIT_RES - 1) downto 0)
);
end component;
use ieee.std_logic_1164.all;
type LutSinT is array(0 to g_LUT_DEPTH - 1) of std_logic_vector(g_LUT_BIT_RES-1 downto 0);
end package DcoPack;
entity e is end entity;
library ieee;
architecture a of e is
constant g_LUT_DEPTH: positive := 2**7; -- remember integer is only 32 bits
constant g_LUT_BIT_RES : positive := 8;
package myDcoPack is new work.DcoPack
generic map (
g_LUT_DEPTH => g_LUT_DEPTH,
g_LUT_BIT_RES => g_LUT_BIT_RES);
-- use work.myDcoPack.all; -- optional
use ieee.numeric_std.all;
signal output : signed((g_LUT_BIT_RES - 1) downto 0);
use ieee.std_logic_1164.all;
signal lut : myDcoPack.LutSinT;
begin
comp_inst : myDcoPack.SinCosDco
port map ( OutDco => output );
lut(0) <= std_logic_vector(output);
end architecture;
However, this was not supported in Vivado 2 years ago. Don't know if it's supported now.