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;