OpenCores
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;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.