library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity my_bandpass is generic ( filter_length : integer := 4); port ( reset : in std_logic; clk : in std_logic; enable_my_bandpass : in std_logic; data_clk : in std_logic; data_in : in std_logic_vector (15 downto 0); data_out : out std_logic_vector (23 downto 0)); end entity; architecture my_bandpass_arc of my_bandpass is --FIR-Filter is constructed by Taps which responsible to Multiply and Accumulate the data at each Tap. --For this tutorial, we start with 2-Tap FIR-Filter to describe the following : y[n] = x[n]-0.5*x[n-1]+0.25*x[n-2]-0.125*x[n-3] --Here we have the following filter coefficients C = (0, -0.5, 0.25, -0.125) --We Scale those coefficients such that we have only integer values; More practically, scaling by 8 we have C = (8, -4, 2, -1) --The max value is 8 => we need 4-bits to represent all the signed values. -- --Here is the point to state that scaling doesn't matter anything to the final result since it represented by std_logic_vector. type bandpass_taps is array (filter_length-1 downto 0) of std_logic_vector(15 downto 0); signal fir_filter_taps : bandpass_taps; constant coeff0 : signed := to_signed(8, 4); constant coeff1 : signed := to_signed(-4, 4); constant coeff2 : signed := to_signed(2, 4); constant coeff3 : signed := to_signed(-1, 4); signal product0 : signed (23 downto 0); signal product1 : signed (23 downto 0); signal product2 : signed (23 downto 0); signal product3 : signed (23 downto 0); signal debugger : signed (19 downto 0); begin u1 : process(reset, data_clk) -- Data Streaming begin if (reset = '1') then fir_filter_taps <= (others => x"0000"); elsif (rising_edge(data_clk)) then fir_filter_taps(0) <= data_in; fir_filter_taps(filter_length-1 downto 1) <= fir_filter_taps(filter_length-2 downto 0); end if; end process; debugger <= signed(fir_filter_taps(0))*coeff0; product0 <= resize(signed(fir_filter_taps(0))*coeff0, 24); product1 <= resize(signed(fir_filter_taps(1))*coeff1, 24); product2 <= resize(signed(fir_filter_taps(2))*coeff2, 24); product3 <= resize(signed(fir_filter_taps(3))*coeff3, 24); data_out <= std_logic_vector(product0+product1+product2+product3); end architecture;