library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity bpfilterbank_imp is
port ( clk : in std_logic;
   inmod : in signed (31 downto 0);
   outmod1 : out signed(31 downto 0);
   outmod2 : out signed(31 downto 0);
   outmod3 : out signed(31 downto 0);
   outmod4 : out signed(31 downto 0);
   outmod5 : out signed(31 downto 0);
   outmod6 : out signed(31 downto 0);
   outmod7 : out signed(31 downto 0);
   outmod8 : out signed(31 downto 0);
   outmod9 : out signed(31 downto 0);
   outmod10 : out signed(31 downto 0));
--	outp : out signed(0 downto 0)); --TEST
end bpfilterbank_imp;

architecture bpfilterbank_ar of bpfilterbank_imp is



component bpfilter_en
port (  a1 : in signed(31 downto 0);  -- Although 32 bits long,we will only use 8 to store the 
a2 : in signed(31 downto 0);  -- information regarding coefficients
a3 : in signed(31 downto 0);
b1 : in signed(31 downto 0);
b2 : in signed(31 downto 0);
b3 : in signed(31 downto 0);
x0 : in signed(31 downto 0);	-- 32 bit long amplitude input comes from the audio codec
x1 : in signed(31 downto 0);	-- Amplitude input delayed by 1 time unit
x2 : in signed(31 downto 0);	-- Amplitude input delayed by 2 time units
y1 : in signed(31 downto 0);  -- Ampltiude output delayed by 1 time unit
y2 : in signed(31 downto 0);  -- Amplitude output delayed by 2 time units 
--inp : in signed(0 downto 0);
y0 : out signed(31 downto 0));  -- naturally to stay consistent, we have a 32 bit output                                                                                                                                                                                                                                                                
end component;


-- Bandpass filter coefficients
signal a1 : signed(31 downto 0);
signal b2 : signed(31 downto 0);

signal bpf1a2 : signed(31 downto 0);
signal bpf1a3 : signed(31 downto 0);
signal bpf1b1 : signed(31 downto 0);
signal bpf1b3 : signed(31 downto 0);

signal bpf2a2 : signed(31 downto 0);
signal bpf2a3 : signed(31 downto 0);
signal bpf2b1 : signed(31 downto 0);
signal bpf2b3 : signed(31 downto 0);

signal bpf3a2 : signed(31 downto 0);
signal bpf3a3 : signed(31 downto 0);
signal bpf3b1 : signed(31 downto 0);
signal bpf3b3 : signed(31 downto 0);

signal bpf4a2 : signed(31 downto 0);
signal bpf4a3 : signed(31 downto 0);
signal bpf4b1 : signed(31 downto 0);
signal bpf4b3 : signed(31 downto 0);

signal bpf5a2 : signed(31 downto 0);
signal bpf5a3 : signed(31 downto 0);
signal bpf5b1 : signed(31 downto 0);
signal bpf5b3 : signed(31 downto 0);

signal bpf6a2 : signed(31 downto 0);
signal bpf6a3 : signed(31 downto 0);
signal bpf6b1 : signed(31 downto 0);
signal bpf6b3 : signed(31 downto 0);

signal bpf7a2 : signed(31 downto 0);
signal bpf7a3 : signed(31 downto 0);
signal bpf7b1 : signed(31 downto 0);
signal bpf7b3 : signed(31 downto 0);

signal bpf8a2 : signed(31 downto 0);
signal bpf8a3 : signed(31 downto 0);
signal bpf8b1 : signed(31 downto 0);
signal bpf8b3 : signed(31 downto 0);

signal bpf9a2 : signed(31 downto 0);
signal bpf9a3 : signed(31 downto 0);
signal bpf9b1 : signed(31 downto 0);
signal bpf9b3 : signed(31 downto 0);

signal bpf10a2 : signed(31 downto 0);
signal bpf10a3 : signed(31 downto 0);
signal bpf10b1 : signed(31 downto 0);
signal bpf10b3 : signed(31 downto 0);

-- Input signals
signal inmod1 : signed(31 downto 0);
signal inmod2 : signed(31 downto 0);
--
--signal incar1 : signed(31 downto 0);
--signal incar2 : signed(31 downto 0);

signal outputbuffer : signed(63 downto 0);

-- Intermediate Output Signals
signal modbuffer1 : signed(31 downto 0);
signal modbuffer2 : signed(31 downto 0);
signal modbuffer3 : signed(31 downto 0);
signal modbuffer4 : signed(31 downto 0);
signal modbuffer5 : signed(31 downto 0);

signal modbuffer6 : signed(31 downto 0);
signal modbuffer7 : signed(31 downto 0);
signal modbuffer8 : signed(31 downto 0);
signal modbuffer9 : signed(31 downto 0);
signal modbuffer10 : signed(31 downto 0);

--signal carbuffer1 : signed(31 downto 0);
--signal carbuffer2 : signed(31 downto 0);
--signal carbuffer3 : signed(31 downto 0);
--signal carbuffer4 : signed(31 downto 0);
--signal carbuffer5 : signed(31 downto 0);
--
--signal carbuffer6 : signed(31 downto 0);
--signal carbuffer7 : signed(31 downto 0);
--signal carbuffer8 : signed(31 downto 0);
--signal carbuffer9 : signed(31 downto 0);
--signal carbuffer10 : signed(31 downto 0);

-- State signals of band pass filter banks
signal outmod1_1 : signed(31 downto 0);
signal outmod2_1 : signed(31 downto 0);
--signal outcar1_1 : signed(31 downto 0);
--signal outcar2_1 : signed(31 downto 0);

signal outmod1_2 : signed(31 downto 0);
signal outmod2_2 : signed(31 downto 0);
--signal outcar1_2 : signed(31 downto 0);
--signal outcar2_2 : signed(31 downto 0);

signal outmod1_3 : signed(31 downto 0);
signal outmod2_3 : signed(31 downto 0);
--signal outcar1_3 : signed(31 downto 0);
--signal outcar2_3 : signed(31 downto 0);

signal outmod1_4 : signed(31 downto 0);
signal outmod2_4 : signed(31 downto 0);
--signal outcar1_4 : signed(31 downto 0);
--signal outcar2_4 : signed(31 downto 0);

signal outmod1_5 : signed(31 downto 0);
signal outmod2_5 : signed(31 downto 0);
--signal outcar1_5 : signed(31 downto 0);
--signal outcar2_5 : signed(31 downto 0);

signal outmod1_6 : signed(31 downto 0);
signal outmod2_6 : signed(31 downto 0);
--signal outcar1_6 : signed(31 downto 0);
--signal outcar2_6 : signed(31 downto 0);

signal outmod1_7 : signed(31 downto 0);
signal outmod2_7 : signed(31 downto 0);
--signal outcar1_7 : signed(31 downto 0);
--signal outcar2_7 : signed(31 downto 0);

signal outmod1_8 : signed(31 downto 0);
signal outmod2_8 : signed(31 downto 0);
--signal outcar1_8 : signed(31 downto 0);
--signal outcar2_8 : signed(31 downto 0);

signal outmod1_9 : signed(31 downto 0);
signal outmod2_9 : signed(31 downto 0);
--signal outcar1_9 : signed(31 downto 0);
--signal outcar2_9 : signed(31 downto 0);

signal outmod1_10 : signed(31 downto 0);
signal outmod2_10 : signed(31 downto 0);
--signal outcar1_10 : signed(31 downto 0);
--signal outcar2_10 : signed(31 downto 0);

--signal outp1: signed(0 downto 0);
--signal inp: signed (0 downto 0):= "1";
--signal clockdivider: signed(1 downto 0):= "00";
begin


a1 <= to_signed (8192, 32);
b2 <= to_signed (0, 32);  -- Not really necessary, but helps account for everything

-- centered at 111Hz, 40Hz bandwidth, 32000Hz
bpf1a2 <= to_signed (-16340, 32);
bpf1a3 <= to_signed (8149, 32);
bpf1b1 <= to_signed (21, 32);
bpf1b3 <= to_signed (-21, 32);

-- centered at 250Hz, 50Hz bandwidth, 32000Hz
bpf2a2 <= to_signed (-16322, 32);
bpf2a3 <= to_signed (8139, 32);
bpf2b1 <= to_signed (27, 32);
bpf2b3 <= to_signed (-27, 32);

-- centered at 354Hz, 60Hz bandwidth, 32000Hz
bpf3a2 <= to_signed (-16302, 32);
bpf3a3 <= to_signed (8128, 32);
bpf3b1 <= to_signed (32, 32);
bpf3b3 <= to_signed (-32, 32);

-- centered at 500Hz, 70Hz bandwidth, 32000Hz
bpf4a2 <= to_signed (-16274, 32);
bpf4a3 <= to_signed (8117, 32);
bpf4b1 <= to_signed (38, 32);
bpf4b3 <= to_signed (-38, 32);

-- centered at 707Hz, 80Hz bandwidth, 32000Hz
bpf5a2 <= to_signed (-16229, 32);
bpf5a3 <= to_signed (8107, 32);
bpf5b1 <= to_signed (43, 32);
bpf5b3 <= to_signed (-43, 32);

 -- centered at 1000Hz, 90Hz bandwidth, 32000Hz
bpf6a2 <= to_signed (-16149, 32);
bpf6a3 <= to_signed (8096, 32);
bpf6b1 <= to_signed (48, 32);
bpf6b3 <= to_signed (-48, 32);

 -- centered at 1414Hz, 150Hz bandwidth, 32000Hz
bpf7a2 <= to_signed (-15947, 32);
bpf7a3 <= to_signed (8033, 32);
bpf7b1 <= to_signed (79, 32);
bpf7b3 <= to_signed (-79, 32);

 -- centered at 2000Hz, 250Hz bandwidth, 32000Hz
bpf8a2 <= to_signed (-15571, 32);
bpf8a3 <= to_signed (7928, 32);
bpf8b1 <= to_signed (132, 32);
bpf8b3 <= to_signed (-132, 32);

 -- centered at 2828Hz, 500Hz bandwidth, 32000Hz
bpf9a2 <= to_signed (-14790, 32);
bpf9a3 <= to_signed (7673, 32);
bpf9b1 <= to_signed (260, 32);
bpf9b3 <= to_signed (-260, 32);

-- centered at 5187Hz, 1000Hz bandwidth, 32000Hz
bpf10a2 <= to_signed (-11966, 32);
bpf10a3 <= to_signed (7184, 32);
bpf10b1 <= to_signed (504, 32);
bpf10b3 <= to_signed (-504, 32);



--bpf1 : bpfilter_en port map -- centered at 250Hz, 40Hz bandwidth, 32000Hz
----(a1, bpf1a2, bpf1a3, bpf1b1, b2, bpf1b3, input, input1, input2, output1, output2, inp, y0buffer1);
--(a1, bpf1a2, bpf1a3, bpf1b1, b2, bpf1b3, input, input1, input2, output1, output2, y0buffer1);

-- Modulating voice signal filtering
bpf1 : bpfilter_en port map
(a1, bpf1a2, bpf1a3, bpf1b1, b2, bpf1b3, inmod, inmod1, inmod2, outmod1_1, outmod2_1, modbuffer1);
bpf2 : bpfilter_en port map
(a1, bpf2a2, bpf2a3, bpf2b1, b2, bpf2b3, inmod, inmod1, inmod2, outmod1_2, outmod2_2, modbuffer2);
bpf3 : bpfilter_en port map
(a1, bpf3a2, bpf3a3, bpf3b1, b2, bpf3b3, inmod, inmod1, inmod2, outmod1_3, outmod2_3, modbuffer3);
bpf4 : bpfilter_en port map
(a1, bpf4a2, bpf4a3, bpf4b1, b2, bpf4b3, inmod, inmod1, inmod2, outmod1_4, outmod2_4, modbuffer4); 
bpf5 : bpfilter_en port map
(a1, bpf5a2, bpf5a3, bpf5b1, b2, bpf5b3, inmod, inmod1, inmod2, outmod1_5, outmod2_5, modbuffer5);

bpf6 : bpfilter_en port map
(a1, bpf6a2, bpf6a3, bpf6b1, b2, bpf6b3, inmod, inmod1, inmod2, outmod1_6, outmod2_6, modbuffer6);
bpf7 : bpfilter_en port map
(a1, bpf7a2, bpf7a3, bpf7b1, b2, bpf7b3, inmod, inmod1, inmod2, outmod1_7, outmod2_7, modbuffer7);
bpf8 : bpfilter_en port map
(a1, bpf8a2, bpf8a3, bpf8b1, b2, bpf8b3, inmod, inmod1, inmod2, outmod1_8, outmod2_8, modbuffer8);
bpf9 : bpfilter_en port map
(a1, bpf9a2, bpf9a3, bpf9b1, b2, bpf9b3, inmod, inmod1, inmod2, outmod1_9, outmod2_9, modbuffer9); 
bpf10 : bpfilter_en port map
(a1, bpf10a2, bpf10a3, bpf10b1, b2, bpf10b3, inmod, inmod1, inmod2, outmod1_10, outmod2_10, modbuffer10);


process(clk)
begin
if rising_edge(clk) then
--inp <= clockdivider(1 downto 1);
inmod1 <= inmod;
inmod2 <= inmod1;

outmod1_1 <= modbuffer1;
outmod2_1 <= outmod1_1;

outmod1_2 <= modbuffer2;
outmod2_2 <= outmod1_2;

outmod1_3 <= modbuffer3;
outmod2_3 <= outmod1_3;

outmod1_4 <= modbuffer4;
outmod2_4 <= outmod1_4;

outmod1_5 <= modbuffer5;
outmod2_5 <= outmod1_5;

outmod1_6 <= modbuffer6;
outmod2_6 <= outmod1_6;

outmod1_7 <= modbuffer7;
outmod2_7 <= outmod1_7;

outmod1_8 <= modbuffer8;
outmod2_8 <= outmod1_8;

outmod1_9 <= modbuffer9;
outmod2_9 <= outmod1_9;

outmod1_10 <= modbuffer10;
outmod2_10 <= outmod1_10;

outmod1 <= modbuffer1;
outmod2 <= modbuffer2;
outmod3 <= modbuffer3;
outmod4 <= modbuffer4;
outmod5 <= modbuffer5;
outmod6 <= modbuffer6;
outmod7 <= modbuffer7;
outmod8 <= modbuffer8;
outmod9 <= modbuffer9;
outmod10 <= modbuffer10;


--output <= modbuffer1 + modbuffer2 + modbuffer3 + modbuffer4 + modbuffer5 + modbuffer6 + modbuffer7 + modbuffer8 + modbuffer9 + modbuffer10;   -- We cannot read outputs directly, so this is the best solution

--outp <= clockdivider(1 downto 1);
--clockdivider <= clockdivider + "1";
end if;
end process;

end bpfilterbank_ar;

