URL
https://opencores.org/ocsvn/pulse_processing_algorithm/pulse_processing_algorithm/trunk
Subversion Repositories pulse_processing_algorithm
[/] [pulse_processing_algorithm/] [moving_average_programmable.vhd] - Rev 2
Compare with Previous | Blame | View Log
----------------------------------------------------------------------------------------------- -- -- Copyright (C) 2011 Peter Lemmens, PANDA collaboration -- p.j.j.lemmens@rug.nl -- http://www-panda.gsi.de -- -- As a reference, please use: -- E. Guliyev, M. Kavatsyuk, P.J.J. Lemmens, G. Tambave, H. Loehner, -- "VHDL Implementation of Feature-Extraction Algorithm for the PANDA Electromagnetic Calorimeter" -- Nuclear Inst. and Methods in Physics Research, A .... -- -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU Lesser General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Lesser General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA -- ----------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------- -- Company : KVI (Kernfysisch Versneller Instituut -- Groningen, The Netherlands -- Author : P.J.J. Lemmens -- Design Name : Feature Extraction -- Module Name : moving_average_programmable -- Description : Moving/running average over a programmable number (power of 2) of samples -- ----------------------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_SIGNED.ALL; entity moving_average_programmable is generic( MEM_PWR : natural := 1); port ( rst : in std_logic ; clk : in std_logic ; enable : in std_logic; program : in std_logic; avg_pwr_in : in std_logic_vector(7 downto 0); data_in : in std_logic_vector; data_out : out std_logic_vector ); end moving_average_programmable; architecture Behavioral of moving_average_programmable is constant WIDTH : natural := data_in'length; constant E_WIDTH : natural := WIDTH + MEM_PWR; -- data_out'length; component progdelay_pipeline generic (RAM_SIZE_PWR : natural := 1; FLEX_RAM_STYLE : string := "distributed"); Port (clk : in STD_LOGIC; rst : in STD_LOGIC; enable : in STD_LOGIC; program : in STD_LOGIC; delay_in : in STD_LOGIC_VECTOR; data_in : in STD_LOGIC_VECTOR; data_out : out STD_LOGIC_VECTOR; data_valid : out std_logic ); end component; component SISO_add_a -- generic( WIDTH : natural); port ( dataa : IN STD_LOGIC_VECTOR; datab : IN STD_LOGIC_VECTOR; result : OUT STD_LOGIC_VECTOR ); end component; component SISO_sub_a generic( --WIDTH : natural; A_MINUS_B : boolean ); port ( dataa : IN STD_LOGIC_VECTOR; datab : IN STD_LOGIC_VECTOR; result : OUT STD_LOGIC_VECTOR ); end component; component dff_re port (rst : in STD_LOGIC; clk : in STD_LOGIC; enable : IN STD_LOGIC := '1'; d : in STD_LOGIC_VECTOR; q : out STD_LOGIC_VECTOR ); end component; ------------------------------------------------------ signal rst_S : std_logic := '1'; signal rst_change_S : std_logic := '1'; signal rst_sum_S : std_logic := '1'; signal clk_S : std_logic := '1'; signal enable_S : std_logic := '0'; signal enable_change_S : std_logic := '0'; signal enable_sum_S : std_logic := '0'; signal program_S : std_logic := '0'; signal avg_pwr_S : std_logic_vector(7 downto 0) := x"04"; signal delay_S : STD_LOGIC_VECTOR(9 downto 0) := conv_std_logic_vector(16, 10); -- default delay = 16 signal data_in_S : std_logic_vector(WIDTH - 1 downto 0) := (others => '0'); signal del_data_S : std_logic_vector(WIDTH - 1 downto 0) := (others => '0'); signal sub_result_S : std_logic_vector(WIDTH - 1 downto 0) := (others => '0'); signal change_S : std_logic_vector(WIDTH - 1 downto 0) := (others => '0'); signal wide_change_S : std_logic_vector(E_WIDTH - 1 downto 0) := (others => '0'); signal msum_S : std_logic_vector(E_WIDTH - 1 downto 0) := (others => '0'); signal add_result_S : std_logic_vector(E_WIDTH - 1 downto 0) := (others => '0'); signal data_out_S : std_logic_vector(WIDTH - 1 downto 0) := (others => '0'); begin mavg_pipe : progdelay_pipeline generic map(RAM_SIZE_PWR => MEM_PWR, FLEX_RAM_STYLE => "distributed") PORT MAP(rst => rst_S, clk => clk_S, enable => enable_S, program => program_S, delay_in => delay_S, data_in => data_in_S, data_out => del_data_S, data_valid => open ); -- SUB = (a - b) !! sub_Msum : SISO_sub_a GENERIC MAP(--WIDTH =>WIDTH, A_MINUS_B => true) PORT MAP(dataa => data_in_S, datab => del_data_S, result => sub_result_S ); change_reg : dff_re PORT MAP(rst => rst_change_S, clk => clk_S, enable => enable_S, d => sub_result_S, q => change_S ); wide_change_S <= conv_std_logic_vector(conv_integer(change_S), E_WIDTH); add_Msum : SISO_add_a -- GENERIC MAP (WIDTH => E_WIDTH) PORT MAP(dataa => wide_change_S, datab => msum_S, result => add_result_S ); msum_reg : dff_re PORT MAP(rst => rst_sum_S, clk => clk_S, enable => enable_sum_S, d => add_result_S, q => msum_S ); clk_S <= clk; -- connect clk PORT to internal clk-signal rst_S <= rst; enable_S <= enable; program_S <= program; avg_pwr_S <= avg_pwr_in; delay_S <= conv_std_logic_vector(((2**conv_integer(avg_pwr_S))), 10); data_in_S <= data_in; data_out <= data_out_S; reset_proc : process(clk_S) begin if rising_edge(clk_S) then if (rst_S = '1') or (program_S = '1') then rst_change_S <= '1'; rst_sum_S <= '1'; else rst_change_S <= (rst_S or program_S); --rst_delay_s; rst_sum_S <= rst_change_S; enable_sum_S <= enable_S; --rst_delay_s; end if; end if; end process; data_out_S <= msum_S((conv_integer(avg_pwr_S) + WIDTH - 1) downto conv_integer(avg_pwr_S)); end Behavioral;