library ieee;
use ieee.Std_logic_1164.all;
use IEEE.NUMERIC_std.all;
use ieee.STD_LOGIC_UNSIGNEd.all;
use IEee.MATH_REAL.all;
use WORK.SYSTEM_PACK.all;
use WORK.duc_cf_coeffpack.all;
entity DUC_Multi_channel_fir is
port (CLOCK_I: in STD_LOGIC;
NRESET_I: in STD_logic;
DATA_VLD_I: in STD_LOGIC;
CHAN_IN_I: in std_logic_vector(G_CHAN_Width-1 downto 0);
DATA_I: in STD_LOGIC_vector(g_datain_width-1 downto 0);
DATA_O: out std_logic_vector(g_dataout_width-1 downto 0);
chAN_OUT_O: out std_logic_vector(g_chan_width-1 downto 0);
data_VLD_O: out STD_LOGIc);
end duc_multi_channel_fIR;

architecture O of DUC_MULTI_CHANNEL_FIR is

attribute syn_PRESERVE: BOOLEAN;

attribute syn_preserve of O: architecture is TRUE;

signal L: STD_logic;

signal I: std_logic_vector(g_datain_width-1 downto 0);

signal ol: std_logic_vector(G_DATAIn_width-1 downto 0);

signal LL: STD_LOGIC_VECTOR(g_accwidth-1 downto 0);

signal il: std_logic_vector(G_FINALADDWIDTH-1 downto 0);

signal oi: std_logic_vector(g_datain_width-1 downto 0);

signal li: sTD_LOGIC_VECTOR(G_Dataout_width-1 downto 0);

type ii is array (1 to G_MACC_DELAYS) of std_logic_vectOR((G_CHAN_WIDTh-1) downto 0);

signal O0: II;

type L0 is array (1 to G_MACC_DELAYS) of STD_LOGIC;

signal I0: L0;

type o1 is array (0 to g_dspcount-1) of std_logic_vector(0 downto 0);

signal l1: o1;

signal i1: o1;

type OOL is array (0 to 0) of std_logic_vectOR(0 downto 0);

type lol is array (0 to G_DSPCOUNT-1) of STD_LOGIC_VECTOR((g_datain_width-1) downto 0);

signal IOL: lol;

signal Oll: LOL;

signal LLL: LOL;

signal ILL: LOL;

type oil is array (0 to g_dspcount-1) of std_logic_vector((G_COEFF_WIDth-1) downto 0);

signal LIL: oil;

type iil is array (0 to G_dspcount-1) of STD_LOGIC_VECTOR((G_ACCWIDTH-1) downto 0);

type O0L is array (0 to G_DSPCOUNT-2) of STD_LOgic_vector((g_accwidth-1) downto 0);

signal l0l: o0l;

signal i0l: STD_LOGIC_vector((g_accwidth-1) downto 0);

signal O1L: iil;

attribute syn_maxfan: INTEGer;

attribute SYN_Maxfan of i1: signal is 1;

component DATA_SHIFTER
generic (G_DATA_WIDth: INTeger := 16;
G_SHIFT_DELAY: INTEGER := 3);
port (CLOCK_I: in sTD_LOGIC;
NREset_i: in STD_LOgic;
shift_en_i: in STD_LOGIC;
DATA_I: in std_logic_vector((G_DATA_WIDth-1) downto 0);
data_o: out STD_LOGIC_VECTOR((G_DATA_WIDTH-1) downto 0));
end component;

component mult_adDSUB is
generic (g_a_width: integer := 16;
g_b_width: integer := 16;
g_d_width: integer := 16;
G_c_width: integer := 37;
g_cin_width: integER := 37;
g_p_wIDTH: integer := 37);
port (CLOCK_I: in STD_LOGIC;
nRESET_I: in std_logic;
A_i: in STD_LOGIC_VECTOR(G_A_WIDTH-1 downto 0);
B_I: in std_logic_vector(g_b_width-1 downto 0);
D_I: in std_LOGIC_VECTOR(G_D_WIDTH-1 downto 0);
c_i: in STD_logic_vector(g_c_width-1 downto 0);
cin_i: in std_logic_vector(G_CIN_WIDTH-1 downto 0);
CDIN_FDBK_SEL_I: in std_logic_vector(1 downto 0);
CDOUT_O: out STD_LOGIC_VECTOR(G_P_WIDTH-1 downto 0);
P_o: out stD_LOGIC_VECTOR(G_p_width-1 downto 0));
end component;

component roUND_SAT
generic (G_UNRND_DATA_WIDTh: positive := 33;
G_RND_DATA_WIDth: positive := 16;
g_unrnd_fraCT_BITS: POSITIVE := 30;
G_RND_FRact_bits: positive := 15);
port (CLOCK_I: in sTD_LOGIC;
NRESET_I: in std_logic;
DATA_I: in std_logic_vector(g_unrnd_data_WIDTH-1 downto 0);
data_o: out std_logic_vector(G_RND_DATA_WIDTh-1 downto 0));
end component;

begin
L1L:
process (nreset_i,CLOck_i)
begin
if (nreset_i = '0') then
l <= '0';
OL <= ( others => '0');
I <= ( others => '0');
elsif (RISING_EDGE(clock_i)) then
L <= data_VLD_I;
OL <= data_i;
i <= OL;
end if;
end process l1l;
I1L:
for OOI in 0 to (G_DSPCOUNT-1)
generate
begin
p_fWD_DELAY_SHIFT: DATA_SHIFTER
generic map (g_data_width => 1,
G_SHIFT_DELAY => 1)
port map (clock_i => clOCK_I,
NRESET_I => Nreset_i,
shift_EN_I => '1',
data_I => L1(OOI),
data_o => I1(ooi));
end generate I1l;
L1(0)(0) <= L;
LOI:
for ooi in 0 to (G_DSPCount-2)
generate
begin
l1(OOI+1) <= i1(ooi);
end generate Loi;
IOI:
for ooi in 0 to (G_DSPCOUnt-1)
generate
begin
p_fwd_delay_RAM: data_shifter
generic map (G_DATA_width => G_datain_width,
G_SHIFT_DELAY => g_CHANCOUNT+1)
port map (CLOCK_I => CLOCK_I,
NREset_i => NREset_i,
SHIFT_EN_I => I1(OOI)(0),
DATA_I => iol(ooi),
data_o => OLL(OOI));
end generate IOI;
IOL(0) <= I;
oli:
for OOI in 0 to (g_dspcoUNT-2)
generate
begin
ioL(ooi+1) <= oll(OOI);
end generate oli;
lli:
if (g_has_symm = 1)
generate
ili:
if (g_symm = 0)
generate
lll(0) <= OLL(G_DSPCOUNT-1);
end generate ili;
oii:
if (G_SYMM = 1)
generate
LII:
process (NRESET_I,clock_I)
begin
if (nreset_i = '0') then
LLl(0) <= ( others => '0');
elsif (RISING_EDGE(clock_i)) then
lll(0) <= OLL(g_dspcounT-1);
end if;
end process Lii;
end generate oii;
iLL(0) <= LLL(0);
iii:
for ooi in 1 to (G_DSPCOUNT-1)
generate
begin
P_REv_delay_ram: DATA_shifter
generic map (G_DATA_WIDTH => g_datain_width,
g_shift_dELAY => G_chancount-1)
port map (clocK_I => CLOCK_I,
NRESET_i => NRESET_I,
shIFT_EN_I => i1(G_DSpcount-ooi-1)(0),
data_i => lll(OOI),
DATA_O => ill(ooi));
end generate iii;
O0I:
for ooi in 0 to (G_DSPCOUNT-2)
generate
begin
LLL(ooi+1) <= ill(ooi);
end generate O0I;
end generate LLI;
L0I:
for ooi in 0 to (g_DSPCOUNT-1)
generate
begin
I0I:
process (NRESET_I,cloCK_I)
begin
if (nreSET_I = '0') then
lil(OOI) <= ( others => '0');
elsif RISING_EDGE(CLOCK_I) then
lil(ooi) <= g_coeff(ooi);
end if;
end process i0i;
end generate L0I;
P_MULT_ACC0: MULT_ADDSUB
generic map (g_a_width => g_coeff_width,
g_b_width => G_DATAIN_WIDTh,
g_d_width => g_datain_width,
g_c_width => G_ACCWIDTH,
g_cin_width => G_ACCWidth,
g_p_width => g_accwidth)
port map (CLOCK_i => CLOCK_I,
nreset_i => nreset_i,
A_I => Lil(0),
b_i => oll(0),
D_I => ill(g_dspcount-1),
C_i => LL,
cin_i => O1L(0),
cdIN_FDBK_SEL_I => "00",
CDOUT_O => l0l(0),
p_o => open );
O1I:
for ooi in 1 to (g_dspcount-2)
generate
begin
p_mult_acc: mult_addsub
generic map (g_a_width => g_coeff_width,
g_b_width => G_DATAIN_width,
g_d_width => g_datain_width,
G_C_WIDth => g_accwidth,
G_CIN_WIDTH => g_accwidth,
g_p_widtH => G_ACCWIDTH)
port map (CLOCK_I => CLOCK_I,
nreset_i => nreset_i,
a_i => lil(OOi),
b_i => oll(OOI),
d_i => ILL(G_DSPCOUNT-1-ooi),
C_I => LL,
CIN_I => o1l(ooi),
cDIN_FDBK_SEL_I => "11",
cdout_o => L0L(ooi),
p_o => open );
end generate O1i;
p_mULT_ACC_LAST: MULT_ADDSUB
generic map (g_a_width => G_COeff_width,
g_b_width => G_datain_width,
g_D_WIDTH => g_dATAIN_WIDTH,
G_C_width => g_ACCWIDTH,
G_CIN_WIDTH => G_ACCWIDTH,
G_p_width => g_accwidth)
port map (CLOCK_I => CLOCK_I,
nreset_i => Nreset_i,
A_I => LIL(g_dspcount-1),
b_i => oLL(G_DSPCOUNT-1),
d_i => oi,
C_I => ll,
CIN_I => o1l(g_dspcount-1),
Cdin_fdbk_sel_i => "11",
CDOUT_O => open ,
P_O => i0l);
LL <= ( others => '0');
OI <= ( others => '0');
L1i:
for OOI in 0 to (G_dspcount-2)
generate
begin
o1l(0) <= ( others => '0');
o1l(OOI+1) <= l0l(ooi);
end generate l1i;
il <= STD_LOGIC_VECTOr(resize(signed(i0l),
G_FINALaddwidth));
U_ROUND_SAT: ROUND_SAT
generic map (G_UNRnd_data_width => g_finaladdwidth,
g_rnd_DATA_WIDTH => g_dataout_width,
G_UNRND_Fract_bits => g_unrnd_fracwidth,
G_RND_FRACT_BITS => g_dataout_fracwidTH)
port map (CLOCK_I => clock_i,
nreset_i => NRESET_I,
DATA_I => il,
data_o => LI);
I1I:
process (nreset_I,clock_i)
begin
if (nreset_i = '0') then
i0 <= ( others => '0');
elsif (RISINg_edge(CLOCK_I)) then
I0 <= data_vld_i&i0(1 to G_MACC_DELAYS-1);
end if;
end process I1i;
oo0:
process (NRESET_I,CLOCK_I)
begin
if (NRESET_I = '0') then
o0 <= ( others => ( others => '0'));
elsif (rISING_EDGE(CLOCK_I)) then
o0 <= chan_in_i&O0(1 to g_macc_delays-1);
end if;
end process OO0;
DATA_O <= li;
Data_vld_o <= i0(G_macc_delays);
CHAN_OUT_O <= o0(g_macc_delays);
end O;
