OpenCores
URL https://opencores.org/ocsvn/pulse_processing_algorithm/pulse_processing_algorithm/trunk

Subversion Repositories pulse_processing_algorithm

[/] [pulse_processing_algorithm/] [CF_zeroX.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_zeroX
-- Description	:	Zero-crossing detection
--	Inputs		:	
--	Outputs		:	
-----------------------------------------------------------------------------------------------
--	Generics		:	
--	Parameters	:
-----------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
 
entity CF_zeroX is
	generic(	BASE_WINDOW_PWR		:	natural	:=	1;
				ZEROX_WINDOW_PWR		:	natural	:=	1;
				ZEROX_THRESHOLD_PWR	:	natural	:=	1
				);
	Port (	rst			: in  STD_LOGIC;
				clk			: in  STD_LOGIC;
				enable		: in  STD_LOGIC := '1';
				data_in		: in  STD_LOGIC_VECTOR;
				zeroX_out	: out	STD_LOGIC
			);
end CF_zeroX;
 
architecture Behavioral of CF_zeroX is
 
	constant	WIDTH						: natural := data_in'length;
	constant	ZEROX_WINDOW			: natural := 2**ZEROX_WINDOW_PWR;
	constant	INHIBIT_COUNT			: natural := ZEROX_WINDOW;						-- gating period after zero-cross-detection
 
	component pipeline
		generic(	RAM_SIZE_PWR	: natural;
					DEPTH				:	natural);
		port (	rst		: IN STD_LOGIC ;
					clk		: IN STD_LOGIC ;
					enable	: IN  STD_LOGIC := '1';
					data_in	: IN STD_LOGIC_VECTOR;
					data_out	: OUT STD_LOGIC_VECTOR
				);
	end component;
 
	component compare_a2b is
		Port (	clk	: std_logic;
					a		: in	STD_LOGIC_VECTOR;
					b		: in	STD_LOGIC_VECTOR;
					lt	 	: out	STD_LOGIC;
					gt	 	: out	STD_LOGIC
				);
	end component;
 
-----------------------------------------------------------------------
 
	signal rst_S				: std_logic := '1';
	signal clk_S				: std_logic := '0';
	signal enable_S			: std_logic := '0';
	signal data_in_S			: std_logic_vector(WIDTH - 1 downto 0) := (others => '0');
	signal del1_data_S		: std_logic_vector(WIDTH - 1 downto 0) := (others => '0');
	signal del2_data_S		: std_logic_vector(WIDTH - 1 downto 0) := (others => '0');
	signal zeroX_S				: std_logic := '0';
	signal front1_hi_enuf_S	: std_logic := '0';
	signal front2_hi_enuf_S	: std_logic := '0';
	signal end_lo_enuf_S		: std_logic := '0';
	signal inhibited_S		: std_logic := '0';
	signal inhibit_cnt_S		: std_logic_vector(ZEROX_WINDOW_PWR + 1 downto 0) := conv_std_logic_vector(INHIBIT_COUNT,ZEROX_WINDOW_PWR + 2);
 
	signal p1_threshold_S		: std_logic_vector(WIDTH - 1 downto 0) := conv_std_logic_vector(2,WIDTH);	-- add a SIGN bit !!!
	signal p2_threshold_S		: std_logic_vector(WIDTH - 1 downto 0) := conv_std_logic_vector(1,WIDTH);	-- add a SIGN bit !!!
	signal n_threshold_S		: std_logic_vector(WIDTH - 1 downto 0) := conv_std_logic_vector(-1,WIDTH);	-- add a SIGN bit !!!
 
---------------------------------------------------------------------------------------------------------
	begin
 
		zerox_win_proc : process(rst_S, clk_S, enable_S, data_in_S)
			begin
				if (clk_S'event and clk_S = '1') then
					if (rst_S = '1') then
						del1_data_S	<=	(others	=> '0');
						del2_data_S	<=	(others	=> '0');
					else
						if (enable_S = '1') then
							del1_data_S	<= data_in_S;
							del2_data_S	<= del1_data_S;
						end if;
					end if;
				end if;
		end process;
 
		p1_threshold	: compare_a2b							-- check if data at the front of the zerox-window exceeds the positive threshold
			port map	(	clk	=> clk_S,
							a		=>	data_in_S,
							b		=>	p1_threshold_S,
							lt		=>	open,
							gt		=>	front1_hi_enuf_S
						);
 
		p2_threshold	: compare_a2b							-- check if data at the front of the zerox-window exceeds the positive threshold
			port map	(	clk	=> clk_S,
							a		=>	del1_data_S,
							b		=>	p2_threshold_S,
							lt		=>	open,
							gt		=>	front2_hi_enuf_S
						);
 
		n_threshold	: compare_a2b							-- check if data at the end of the zerox-window goes below the 1st negative threshold
			port map	(	clk	=> clk_S,
							a		=>	del2_data_S,
							b		=>	n_threshold_S,
							lt		=>	end_lo_enuf_S,
							gt		=>	open
						);
 
		inhibit	: compare_a2b							-- check if data at the end of the zerox-window stays above the 2nd negative threshold
			port map	(	clk	=> clk_S,
							a		=>	inhibit_cnt_S,
							b		=>	conv_std_logic_vector(0, inhibit_cnt_S'length),
							lt		=>	open,
							gt		=>	inhibited_S
						);
 
 
		clk_S			<= clk;													-- connect clk PORT to internal clk-signal
		rst_S			<= rst;
		enable_S 	<= enable;
		data_in_S	<= data_in;
--		zeroX_S		<=	front1_hi_enuf_S and front2_hi_enuf_S and end_lo_enuf_S and not(inhibited_S);
		zeroX_out	<= zerox_S;
		-- positive threshold = 4*negative threshold... constant-fraction of 4
		p1_threshold_S	<= conv_std_logic_vector(2**(ZEROX_THRESHOLD_PWR + 1), WIDTH);
		p2_threshold_S	<= conv_std_logic_vector(2**(ZEROX_THRESHOLD_PWR), WIDTH);
		n_threshold_S	<= conv_std_logic_vector(-(2**ZEROX_THRESHOLD_PWR), WIDTH);
 
		zeroX_inhibit : process (clk_S, rst_S, enable_S)
		begin
			if (clk_S'event and clk_S = '1') then
				if (rst_S = '1') then
					zeroX_S	<= '0';
				else 
					if  (enable_S = '1') then
						--zeroX_out <= zeroX_S;
						zeroX_S		<=	front1_hi_enuf_S and front2_hi_enuf_S and end_lo_enuf_S and not(inhibited_S);
					end if;
 
					if  (enable_S = '1') then
						if (zeroX_S = '1') then
							inhibit_cnt_S <= conv_std_logic_vector(INHIBIT_COUNT,ZEROX_WINDOW_PWR + 2);
						else
							if (inhibit_cnt_S > 0) then
								inhibit_cnt_S <= inhibit_cnt_S - 1;
							end if;
						end if;
					end if;
				end if;
			end if;
		end process;
 
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.