URL
https://opencores.org/ocsvn/pulse_processing_algorithm/pulse_processing_algorithm/trunk
Subversion Repositories pulse_processing_algorithm
[/] [pulse_processing_algorithm/] [CF_process.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: CF_process.vhd -- Description: - baseline sampling, calculation & correction -- - Constant Fraction pulse construction -- - Zero-crossing detection -- - event-detection -- - baseline_sampling & event_detection gating/inhibition -- - sub_sample timing calculation through interpolation -- - time-stamp generation -- - energy reading/peak-detection -- ----------------------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_SIGNED.ALL; use IEEE.numeric_std.ALL; entity CF_process is generic( WIDTH : natural := 1; MAX_CF_PWR : natural := 1;-- CF_DELAY : natural := 1;-- CF_PWR : natural := 1; MAX_BASELINE_PWR : natural := 1; ZEROX_WINDOW_PWR : natural := 1; ZEROX_THRESHOLD_PWR : natural := 1;-- INTEGRAL_PWR : natural := 1;-- INTEGRAL_THRESHOLD_PWR : natural := 1; INTERP_CYCLES : natural := 1 ); Port ( rst : in STD_LOGIC; clk : in STD_LOGIC; enable : in STD_LOGIC; program : in STD_LOGIC; baseline_enable : in STD_LOGIC; double_CF_in : in STD_LOGIC; data_in : in STD_LOGIC_VECTOR (WIDTH - 1 downto 0); threshold_in : in STD_LOGIC_VECTOR; cf_pwr_in : in STD_LOGIC_VECTOR; cf_integral_pwr_in : in STD_LOGIC_VECTOR; baseline_pwr_in : in STD_LOGIC_VECTOR; baseline_inhibit_cnt_in : in STD_LOGIC_VECTOR; event_inhibit_cnt_in : in STD_LOGIC_VECTOR; baseline_out : out STD_LOGIC_VECTOR; clamped_out : out STD_LOGIC_VECTOR; del_clamp_out : out STD_LOGIC_VECTOR; CFdev_clamp_out : out STD_LOGIC_VECTOR; cf_trace_out : out STD_LOGIC_VECTOR; integral : out STD_LOGIC_VECTOR; sample_nr : out STD_LOGIC_VECTOR; zeroX_out : out STD_LOGIC; event_detect_out : out STD_LOGIC; bl_gate_out : out STD_LOGIC; ed_gate_out : out STD_LOGIC; eventdata_valid : out STD_LOGIC; eventnr_out : out STD_LOGIC_VECTOR; fraction : out STD_LOGIC_VECTOR; energy : out STD_LOGIC_VECTOR ); end CF_process; architecture Behavioral of CF_process is constant MAX_CF_DELAY : natural := 2**MAX_CF_PWR; constant PEAK_DET_BUF_PWR : natural := 4; constant PEAK_DET_BUFSIZE : natural := 2**PEAK_DET_BUF_PWR; -- constant CFWINDOW_SIZE : natural := 2**CF_WINDOW_PWR; -- constant INTEGRAL_SIZE : natural := 2**INTEGRAL_PWR; constant FRACTION_SIZE : natural := INTERP_CYCLES; -- - ZEROX_WINDOW_PWR; --all interp bits are fraction now !! interp between 2 samples -- constant GATE_PWR : natural := BASELINE_PWR; component baseline_follower generic( WINDOW_PWR : natural := 1; -- defines the maximum window in which event disturbance is seen MAX_BASELINE_PWR : natural := 1 -- size of the baseline window ); Port ( rst : in STD_LOGIC; clk : in STD_LOGIC; enable : in STD_LOGIC; program : in STD_LOGIC; gate : in STD_LOGIC; baseline_pwr_in : in STD_LOGIC_VECTOR(7 downto 0); buffer_size_in : in STD_LOGIC_VECTOR(7 downto 0); data_in : in STD_LOGIC_VECTOR; data_out : out STD_LOGIC_VECTOR; buffer_data_valid : out STD_LOGIC ); end component; component SISO_sub_a generic( A_MINUS_B : boolean); port ( dataa : IN STD_LOGIC_VECTOR; datab : IN STD_LOGIC_VECTOR; result : OUT STD_LOGIC_VECTOR ); end component; 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(7 downto 0); data_in : in STD_LOGIC_VECTOR; data_out : out STD_LOGIC_VECTOR; data_valid : out std_logic ); end component; component CF_zeroX generic( BASE_WINDOW_PWR : natural; ZEROX_WINDOW_PWR : natural; ZEROX_THRESHOLD_PWR : natural ); port ( rst : in STD_LOGIC; clk : in STD_LOGIC; enable : in STD_LOGIC; data_in : in STD_LOGIC_VECTOR; zeroX_out : out STD_LOGIC ); end component; component moving_average_programmable generic(MEM_PWR : natural); 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 component; component gate_generator -- generic( BASE_WINDOW_PWR : natural := 1; -- EVENT_INHIB_PWR : natural := 1 -- ); Port ( rst : in STD_LOGIC; clk : in STD_LOGIC; enable : in STD_LOGIC; program : in STD_LOGIC; baseline_enable : in STD_LOGIC; event_in : in STD_LOGIC; baseline_inhibit_cnt_in : in STD_LOGIC_VECTOR; event_inhibit_cnt_in : in STD_LOGIC_VECTOR; bl_gate_out : out STD_LOGIC; -- baseline gate-signal ed_gate_out : out STD_LOGIC -- baseline gating inhibited because of event ); end component; component timing_linear_interp generic( INTERP_CYCLES : natural); Port ( rst : in STD_LOGIC; clk : in STD_LOGIC; enable : in STD_LOGIC; trigger : in STD_LOGIC; data_in : in STD_LOGIC_VECTOR; samplenr_in : in STD_LOGIC_VECTOR; eventnr_out : out STD_LOGIC_VECTOR; fraction_out : out STD_LOGIC_VECTOR; eventdata_valid : out STD_LOGIC ); end component; component sample_counter Port (rst : in STD_LOGIC; clk : in STD_LOGIC; enable : in STD_LOGIC := '1'; sample_nr_out : out STD_LOGIC_VECTOR (63 downto 0) ); end component; component history_max generic( MEM_PWR : natural := 1; DEPTH : natural := 1 ); Port ( rst : in STD_LOGIC; clk : in STD_LOGIC; enable : in STD_LOGIC := '1'; trigger : in STD_LOGIC; data_in : in STD_LOGIC_VECTOR; max_valid : out STD_LOGIC; max_out : out STD_LOGIC_VECTOR ); end component; component event_detector Port ( clk : in STD_LOGIC; enable : in STD_LOGIC := '1'; gate_in : in STD_LOGIC; zeroX_in : in STD_LOGIC; threshold_in : in STD_LOGIC_VECTOR; integral_in : in STD_LOGIC_VECTOR; event_detect_out : out STD_LOGIC ); end component; ----------------------------------------------------------------------- signal rst_S : std_logic := '1'; signal clk_S : std_logic := '0'; signal enable_S : std_logic := '0'; signal program_S : std_logic := '0'; signal baseline_enable_S : STD_LOGIC := '0'; signal double_CF_S : STD_LOGIC := '0'; signal data_in_S : std_logic_vector (WIDTH - 1 downto 0) := (others => '0'); signal baseline_S : STD_LOGIC_VECTOR (WIDTH - 1 downto 0) := (others => '0'); signal clamped_S : STD_LOGIC_VECTOR (WIDTH - 1 downto 0) := (others => '0'); signal CFdev_clamp_S : STD_LOGIC_VECTOR (WIDTH - 1 downto 0) := (others => '0'); signal del_clamp_S : STD_LOGIC_VECTOR (WIDTH - 1 downto 0) := (others => '0'); signal cf_trace_S : STD_LOGIC_VECTOR (WIDTH - 1 downto 0) := (others => '0'); signal threshold_S : STD_LOGIC_VECTOR (WIDTH - 1 downto 0) := (others => '0'); signal integral_S : STD_LOGIC_VECTOR (WIDTH - 1 downto 0) := (others => '0'); signal cf_pwr_S : STD_LOGIC_VECTOR (7 downto 0) := conv_std_logic_vector(4, 8); -- original default value signal cf_integral_pwr_S : STD_LOGIC_VECTOR (7 downto 0) := conv_std_logic_vector(4, 8); -- original default value = (mwd_power - 1) signal cf_delay_S : STD_LOGIC_VECTOR (7 downto 0) := conv_std_logic_vector(16, 8); signal baseline_pwr_S : STD_LOGIC_VECTOR (7 downto 0) := (others => '0'); signal baseline_delay_S : STD_LOGIC_VECTOR (7 downto 0) := (others => '0'); signal baseline_inhibit_cnt_S : STD_LOGIC_VECTOR (7 downto 0) := conv_std_logic_vector(32, 8); -- original default value signal event_inhibit_cnt_S : STD_LOGIC_VECTOR (7 downto 0) := conv_std_logic_vector(16, 8); -- original default value signal event_detect_S : std_logic := '0'; signal zeroX_S : STD_LOGIC := '0'; signal bl_gate_S : STD_LOGIC := '0'; signal ed_gate_S : STD_LOGIC := '0'; signal sample_nr_S : STD_LOGIC_VECTOR (63 downto 0) := (others => '0'); signal eventnr_S : STD_LOGIC_VECTOR (63 downto 0) := (others => '0'); signal time_fraction_S : STD_LOGIC_VECTOR (FRACTION_SIZE - 1 downto 0) := (others => '0'); signal energy_S : STD_LOGIC_VECTOR (WIDTH - 1 downto 0) := (others => '0'); signal eventdata_valid_S : STD_LOGIC := '0'; signal max_valid_S : STD_LOGIC := '0'; ----------------------------------------------------------------------- begin baseline : baseline_follower generic map(WINDOW_PWR => MAX_CF_PWR, MAX_BASELINE_PWR => MAX_BASELINE_PWR ) port map ( rst => rst_S, clk => clk_S, enable => enable_S, program => program_S, gate => bl_gate_S, baseline_pwr_in => baseline_pwr_S, buffer_size_in => baseline_delay_S, data_in => data_in_S, data_out => baseline_S, buffer_data_valid => open ); remove_baseline : SISO_sub_a GENERIC MAP(--WIDTH => data_in_S'length, A_MINUS_B => true) PORT MAP ( dataa => data_in_S, datab => baseline_S, result => clamped_S ); clamped_pipe : progdelay_pipeline generic map(RAM_SIZE_PWR => MAX_CF_PWR, FLEX_RAM_STYLE => "distributed") PORT MAP(rst => rst_S, clk => clk_S, enable => enable_S, program => program_S, delay_in => cf_delay_S, data_in => clamped_S, data_out => del_clamp_S, data_valid => open ); CF_sub : SISO_sub_a GENERIC MAP(--WIDTH => cf_trace_S'length, A_MINUS_B => true) PORT MAP ( dataa => del_clamp_S, datab => CFdev_clamp_S, result => cf_trace_S ); zeroX : CF_zeroX generic map(BASE_WINDOW_PWR => MAX_CF_PWR, -- CF_WINDOW_PWR, ZEROX_WINDOW_PWR => ZEROX_WINDOW_PWR, ZEROX_THRESHOLD_PWR => ZEROX_THRESHOLD_PWR ) port map ( rst => rst_S, clk => clk_S, enable => enable_S, data_in => cf_trace_S, zeroX_out => zeroX_S ); CF_integral : moving_average_programmable generic map(MEM_PWR => MAX_CF_PWR) port map( rst => rst_S, clk => clk_S, enable => enable_S, program => program_S, avg_pwr_in => cf_integral_pwr_S, data_in => clamped_S, data_out => integral_S ); gator : gate_generator -- generic map(BASE_WINDOW_PWR => GATE_PWR, -- EVENT_INHIB_PWR => MAX_CF_PWR --CF_WINDOW_PWR -- ) port map ( rst => rst_S, clk => clk_S, enable => enable_S, program => program_S, baseline_enable => baseline_enable_S, event_in => event_detect_S, baseline_inhibit_cnt_in => baseline_inhibit_cnt_S, event_inhibit_cnt_in => event_inhibit_cnt_S, bl_gate_out => bl_gate_S, ed_gate_out => ed_gate_S ); timing : timing_linear_interp generic map(INTERP_CYCLES => INTERP_CYCLES) Port map( rst => rst_S, clk => clk_S, enable => enable_S, trigger => event_detect_S, data_in => cf_trace_S, samplenr_in => sample_nr_S, eventnr_out => eventnr_S, fraction_out => time_fraction_S, eventdata_valid => eventdata_valid_S ); time_stamp : sample_counter Port map( rst => rst_S, clk => clk_S, enable => enable_S, sample_nr_out => sample_nr_S ); peak_detect : history_max generic map(MEM_PWR => PEAK_DET_BUF_PWR, --CF_WINDOW_PWR, DEPTH => PEAK_DET_BUFSIZE) --CF_WINDOWSIZE -10 port map ( rst => rst_S, clk => clk_S, enable => enable_S, trigger => event_detect_S, data_in => clamped_S, max_valid => max_valid_S, max_out => energy_S ); eventdetect : event_detector Port map( clk => clk_S, enable => enable_S, gate_in => ed_gate_S, zeroX_in => zeroX_S, threshold_in => threshold_S, integral_in => integral_S, event_detect_out => event_detect_S ); rst_S <= rst; clk_S <= clk; enable_S <= enable; program_S <= program; baseline_enable_S <= baseline_enable; double_CF_S <= double_CF_in; data_in_S <= data_in; -- add a sign bit to avoid disaster cf_pwr_S <= cf_pwr_in; cf_delay_S <= conv_std_logic_vector((2**conv_integer(cf_pwr_S)), 8); baseline_delay_S <= conv_std_logic_vector((2**(conv_integer(cf_pwr_S)) + 16), 8); cf_integral_pwr_S <= cf_integral_pwr_in; baseline_pwr_S <= baseline_pwr_in; baseline_inhibit_cnt_S <= baseline_inhibit_cnt_in; event_inhibit_cnt_S <= event_inhibit_cnt_in; baseline_out <= baseline_S; clamped_out <= clamped_S; CF_mux : process(double_CF_S, clamped_S) begin case (double_CF_S) is when '1' => CFdev_clamp_S(CFdev_clamp_S'high) <= clamped_S(clamped_S'high); CFdev_clamp_S(CFdev_clamp_S'high - 1) <= clamped_S(clamped_S'high); CFdev_clamp_S((CFdev_clamp_S'high - 2) downto 0) <= clamped_S((clamped_S'high - 1) downto 1); when '0' => CFdev_clamp_S(CFdev_clamp_S'high) <= clamped_S(clamped_S'high); CFdev_clamp_S(CFdev_clamp_S'high - 1) <= clamped_S(clamped_S'high); CFdev_clamp_S(CFdev_clamp_S'high - 2) <= clamped_S(clamped_S'high); CFdev_clamp_S((CFdev_clamp_S'high - 3) downto 0) <= clamped_S((clamped_S'high - 1) downto 2); when others => CFdev_clamp_S(CFdev_clamp_S'high) <= clamped_S(clamped_S'high); CFdev_clamp_S(CFdev_clamp_S'high - 1) <= clamped_S(clamped_S'high); CFdev_clamp_S(CFdev_clamp_S'high - 2) <= clamped_S(clamped_S'high); CFdev_clamp_S((CFdev_clamp_S'high - 3) downto 0) <= clamped_S((clamped_S'high - 1) downto 2); end case; end process; del_clamp_out <= del_clamp_S; CFdev_clamp_out <= CFdev_clamp_S; cf_trace_out <= cf_trace_S; threshold_S <= threshold_in; integral <= integral_S; sample_nr <= sample_nr_S; zeroX_out <= zeroX_S; event_detect_out <= event_detect_S; bl_gate_out <= bl_gate_S; ed_gate_out <= ed_gate_S; eventdata_valid <= eventdata_valid_S; eventnr_out <= eventnr_S; fraction <= time_fraction_S; energy <= energy_S; end Behavioral;