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

Subversion Repositories pulse_processing_algorithm

[/] [pulse_processing_algorithm/] [shaper.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:	mux_sre.vhd
-- Description:	fixed length (=2) MWD module to reshape slopes of MWD-pulses
--
-----------------------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
 
entity shaper is
   Port (rst					: in  STD_LOGIC;
			clk					: in  STD_LOGIC;
			enable				: in  STD_LOGIC;
			program				: in  std_logic;
			data_in				: in  STD_LOGIC_VECTOR;
			correction_in		: in  STD_LOGIC_VECTOR;
			data_out				: out STD_LOGIC_VECTOR
		);
end shaper;
 
architecture Behavioral of shaper is
 
	constant	WIDTH				: natural := data_in'length;
	constant	M_WIDTH			: natural := 18;							-- Multiplier width ; xilinx MULT18x18_SIO
 
 
	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_delay_s		: std_logic := '1';
	signal rst_change_S		: std_logic := '1';
	signal rst_sum_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 program_S			: std_logic := '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 win_diff_S			: std_logic_vector(WIDTH - 1 downto 0)		:= (others => '0');
--	signal del_win_diff_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(M_WIDTH - 1 downto 0)	:= (others	=> '0');
	signal add_result_S		: std_logic_vector(M_WIDTH - 1 downto 0)	:= (others	=> '0');
	signal decay_corr_S		: std_logic_vector(WIDTH - 1 downto 0)		:= (others => '0');
	signal mult_sum_S			: std_logic_vector(M_WIDTH - 1 downto 0)	:= (others => '0');
	signal factor_S			: std_logic_vector(M_WIDTH - 1 downto 0)	:= conv_std_logic_vector(37213, M_WIDTH);
	signal product36			: std_logic_vector(35 downto 0)				:= (others => '0');
	signal data_out_S			: std_logic_vector(WIDTH - 1 downto 0)		:= (others => '0');
 
-----------------------------------------------------------------------
 
	begin
 
		rst_S				<= rst;
		clk_S				<= clk;
		enable_S			<= enable;
		data_in_S		<= data_in;
		data_out			<= data_out_S;
 
 
	program_proc : process (clk_S, rst_S)
	begin
		if rising_edge(clk_S) then
			program_S		<= program;
			if (rst_S = '1') then
				factor_S	<= (others	=> '0');
			else
				program_S	<= program;
				if (program = '1') and (program_S = '0') then
					factor_S		<=	conv_std_logic_vector(conv_integer(correction_in), factor_S'length);
				end if;
			end if;
		end if;
	end process;
 
	diff_proc : process(clk_S, rst_delay_s)
	begin
		if rising_edge(clk_S) then
			if (rst_S = '1') then
				del1_data_S		<=	(others	=> '0');
				del2_data_S		<=	(others	=> '0');
--				win_diff_S		<=	(others	=> '0');
			else
				del1_data_S		<= data_in_S;
				del2_data_S		<= del1_data_S;
--				win_diff_S		<= conv_std_logic_vector((conv_integer(signed(data_in_S)) - conv_integer(signed(del2_data_S))), WIDTH);
--				del_win_diff_S	<= win_diff_S;
			end if;
		end if;
	end process;
 
-------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------
--		below is the 2-stage moving average
-------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------
 
	reset_proc : process(clk_S)
	begin
		if (clk_S'event and clk_S = '1') then
			if (rst_S = '1') then
				rst_delay_s		<= '1';
				rst_change_S	<= '1';
				rst_sum_S		<= '1';
			else
				rst_delay_s		<= rst_S;
				rst_change_S	<= rst_delay_s;
				rst_sum_S		<= rst_change_S;
			end if;
		end if;
	end process;
 
	--	SUB = (a - b) !!
	sub_Msum : SISO_sub_a 
		GENERIC MAP(--WIDTH 		=>WIDTH,
						A_MINUS_B	=>	true)
		PORT MAP(dataa	 => data_in_S,
					datab	 => del2_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
				);
 
	delay_reg : dff_re		-- saving code (and resources ??)
		PORT MAP(rst		=> rst_change_S,
					clk		=>	clk_S,
					enable	=>	enable_S,
					d			=>	change_S,
					q			=>	win_diff_S
				);
 
	wide_change_S		<= conv_std_logic_vector(conv_integer(change_S), M_WIDTH);
 
	add_Msum : SISO_add_a
--		GENERIC MAP (WIDTH => M_WIDTH)
		PORT MAP(dataa	 	=> wide_change_S,
					datab	 	=> mult_sum_S,
					result 	=> add_result_S
				);
 
	msum_reg : dff_re
		PORT MAP(rst		=> rst_sum_S,
					clk		=>	clk_S,
					enable	=>	enable_S,
					d			=>	add_result_S,
					q			=>	mult_sum_S
				);
		-- NOTE !!	below product is effectively divided by 4
		decay_corr_S(16 downto 0) 			<= product36(33 downto 17); 
 
		--	tau = 3.2ns ! dus ln2/(3.2E-9 * 50E6) = 0.693 / 0.16 = 4.332, MWD_size=2 => MWD_PWR=1
 		decay_correction_proc : process(clk_S, rst_S)
		begin
			if (clk_S'event and clk_S = '1') then
				if (rst_S = '1') then
					product36		<= (others => '0');
					data_out_S		<= (others => '0');
				else
					if (enable_S = '1') then
				-- NOTE !!	below factor and product are effectively divided by 4, to be restored in decay_correction
						product36	<= mult_sum_S * ('0' & '0' & factor_S(17 downto 2));
--						data_out_S	<= win_diff_S + decay_corr_S;
						data_out_S	<= conv_std_logic_vector((conv_integer(signed(win_diff_S)) + conv_integer(signed(decay_corr_S))), WIDTH);
					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.