library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use ieee.numeric_std.all; use work.reg_pack.ALL; entity FIRFilter is generic( NBTAP : natural := 16; DSIZE : natural := 16 ); port ( clk_100_MHz : in std_logic; clk_8_192_MHz : in std_logic; datain : in std_logic_vector(DSIZE - 1 downto 0); firout : out std_logic_vector(DSIZE - 1 downto 0); hphone_valid : in std_logic ); end FIRFilter; architecture Behavioral of FIRFilter is COMPONENT blk_mem_gen_0 PORT ( clka : IN STD_LOGIC; addra : IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- Adresse douta : OUT STD_LOGIC_VECTOR(15 DOWNTO 0) -- Koeffizienten an der jeweiligen Adresse ); END COMPONENT; COMPONENT xbip_multadd_0 PORT ( CLK : IN STD_LOGIC; CE : IN STD_LOGIC; -- Clock Enable (active-HIGH) SCLR : IN STD_LOGIC; -- Synchronous Clear (active-High) A : IN STD_LOGIC_VECTOR( DSIZE - 1 DOWNTO 0); -- A Input bus (multiplier operand 1) B : IN STD_LOGIC_VECTOR( DSIZE - 1 DOWNTO 0); -- B Input bus (multiplier operand 2) C : IN STD_LOGIC_VECTOR( 3*DSIZE - 1 DOWNTO 0); -- C Input bus (operand 1 of add/sub operation) SUBTRACT : IN STD_LOGIC; -- Controls Add/Subtract operation (High = subtraction, Low = addition) P : OUT STD_LOGIC_VECTOR(3*DSIZE - 1 DOWNTO 0); -- Output bus PCOUT : OUT STD_LOGIC_VECTOR(3*DSIZE - 1 DOWNTO 0) -- Cascade Output ); END COMPONENT; component reg_par is generic(reg_width : natural := 16); port( ck : in std_logic; ld_par : in std_logic; data_in : in std_logic_vector(reg_width - 1 downto 0); data_out : out std_logic_vector(reg_width - 1 downto 0) ); end component; component fsm_fir_get_data is port( ck : in std_logic; start_fs_tic_f : in std_logic; reg_ready_f : out std_logic ); end component; signal s_ready_1 : std_logic := '0'; -- startet die Berechnung der MulAdd-Blöcke signal s_ready_2 : std_logic := '0'; signal s_activate : std_logic := '0'; signal temp : std_logic_vector(3*DSIZE - 1 downto 0) := x"000000000000"; signal s_filtered_data : std_logic_vector(DSIZE - 1 downto 0) := x"0000"; signal s_filter_data : std_logic_vector(DSIZE - 1 downto 0) := x"0000"; ***************************************************************** constant s_rounding : std_logic_vector(3*DSIZE - 1 downto 0) := x"000000004000"; ***************************************************************** signal ADR_C : std_logic_vector(3 downto 0) := b"0000"; constant MAX : std_logic_vector(3 downto 0) := b"1111"; signal COEF : std_logic_vector(DSIZE - 1 downto 0) := x"0000"; shared variable shvar_enable : boolean := false; --****************************************************************** signal SCLR : std_logic := '0'; -- Synchronous Clear (active-HIGH) signal SUBTRACT : std_logic := '0'; -- LOW = Addition, HIGH = Subtraction type ASOP is array (0 to NBTAP - 1) of std_logic_vector(3 * DSIZE - 1 downto 0); -- 48 Bit Accumulator signal a_sop : ASOP := ( others => x"000000000000" ); type ACOEF is array (0 to NBTAP - 1) of std_logic_vector(0 to DSIZE - 1); signal a_coeff : ACOEF := ( others => x"0000" ); begin blk_mem_gen : blk_mem_gen_0 PORT MAP ( clka => clk_100_MHz, --brd_clk, addra => ADR_C(3 downto 0), douta => COEF ); ADR_CNT_COEF : process(clk_100_MHz) --(brd_clk) variable i : integer := 0; begin if(rising_edge(clk_100_MHz)) then --brd_clk)) then if(ADR_C = MAX) then a_coeff(NBTAP - 1) <= COEF; ADR_C <= (others => '0'); i := 0; shvar_enable := TRUE; else a_coeff(i) <= COEF; ADR_C <= ADR_C + 1; if i < NBTAP - 1 then i := i + 1; end if; end if; end if; end process ADR_CNT_COEF; reg_par_read_data : reg_par generic map(reg_width => DSIZE) port map ( ck => clk_100_MHz, --brd_clk, ld_par => hphone_valid, data_in => datain, data_out => s_filter_data ); reg_par_write_data : reg_par generic map(reg_width => DSIZE) port map ( ck => clk_100_MHz, ld_par => s_ready_2, data_in => s_filtered_data, data_out => firout ); fsm_get_input_data : fsm_fir_get_data port map ( ck => clk_100_MHz, start_fs_tic_f => hphone_valid, reg_ready_f => s_ready_1 ); fsm_write_output_data : fsm_fir_get_data port map ( ck => clk_100_MHz, start_fs_tic_f => s_ready_1, reg_ready_f => s_ready_2 ); gen : for I in 0 to NBTAP - 1 generate begin g0 : if I = 0 generate element_u0 : xbip_multadd_0 port map( CLK => clk_100_MHz, CE => s_ready_1, SCLR => SCLR, A => s_filter_data, B => std_logic_vector(a_coeff(NBTAP - 1)), C => s_rounding, SUBTRACT => SUBTRACT, P => a_sop(NBTAP - 1), PCOUT => open ); end generate g0; gi : if ( (I < (NBTAP - 1)) and (I > 0) ) generate element_ui : xbip_multadd_0 port map( CLK => clk_100_MHz, CE => s_ready_1, SCLR => SCLR, A => s_filter_data, B => std_logic_vector(a_coeff(NBTAP - 1 - I)), C => a_sop(NBTAP - I), SUBTRACT => SUBTRACT, P => a_sop(NBTAP - I - 1), PCOUT => open ); end generate gi; glast : if I = (NBTAP - 1) generate element_ui : xbip_multadd_0 port map( CLK => clk_100_MHz, CE => s_ready_1, SCLR => SCLR, A => s_filter_data, B => std_logic_vector(a_coeff(0)), C => a_sop(1), SUBTRACT => SUBTRACT, P => a_sop(0), PCOUT => open ); end generate glast; end generate gen; temp <= a_sop(0) when ( ( a_sop(0)(47 downto 30) = "000000000000000000") or (a_sop(0)(47 downto 30) = "111111111111111111" ) ) else x"00003FFFFFFF" when ( ( a_sop(0)(47) = '0' ) and (a_sop(0)(46 downto 30) /= "00000000000000000" ) ) else x"000040000001"; -- ( ( a_sop(0)(47) = '1' ) and (a_sop(0)(46 downto 30) /= "11111111111111111" ) ); s_filtered_data <= temp(30 downto 15); end Behavioral;