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

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.