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.ddc_cf_coeffpack.all;
entity DDC_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 ddC_MULTI_CHANNEL_FIR;

architecture o of ddc_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;
