--======================================================================================= -- TITLE : Calibration and pedestal triggers generation -- DESCRIPTION : Generate LP1, LP2 and PEDESTAL pulses for calibration runs -- FILE : calibration_pedestal.vhd -- COMPANY : Micro-Cameras & Space Exploration SA --======================================================================================= -- CREATION -- DATE AUTHOR PROJECT REVISION -- 11/03/2011 JGi 110311a --======================================================================================= -- MODIFICATION HISTORY -- DATE AUTHOR PROJECT REVISION COMMENTS -- 11/03/2011 JGi 110311a Description -- 13/04/2011 JGi 110413a Update pulse enable management to allow the -- same pulse to be enabled if no others are. --======================================================================================= -- Library Definition library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library ftm_definitions; use ftm_definitions.ftm_array_types.all; use ftm_definitions.ftm_constants.all; -- Entity Definition entity calibration_pedestal is port( --clock clk_50MHz : in std_logic; --control new_config : in std_logic; --settings general_settings : in std_logic_vector(7 downto 0); LP_and_PED_freq : in std_logic_vector(9 downto 0); LP1_LP2_PED_ratio : in std_logic_vector(14 downto 0); --outputs LP1_pulse : out std_logic; --send start signal to light pulser 1 LP2_pulse : out std_logic; --send start signal to light pulser 2 PED_pulse : out std_logic); end calibration_pedestal; -- Architecture Definition architecture RTL of calibration_pedestal is type t_reg is record -- Internal register declaration new_config : std_logic; general_settings : std_logic_vector(7 downto 0); LP_and_PED_freq : std_logic_vector(9 downto 0); LP1_LP2_PED_ratio : std_logic_vector(14 downto 0); ms_counter : unsigned(MAX_MS_COUNTER_WIDTH-1 downto 0); ms_tick : std_logic; tick_counter : unsigned(9 downto 0); trigger_tick : std_logic; trigger_counter : unsigned(4 downto 0); enable_LP1 : std_logic; enable_LP2 : std_logic; enable_PED : std_logic; -- Ouput register declaration LP1_pulse : std_logic; LP2_pulse : std_logic; PED_pulse : std_logic; end record; signal i_next_reg : t_reg := (new_config => '0', general_settings => (others => '0'), LP_and_PED_freq => (others => '0'), LP1_LP2_PED_ratio => (others => '0'), ms_counter => (others => '0'), ms_tick => '0', tick_counter => (others => '0'), trigger_tick => '0', trigger_counter => (others => '0'), enable_LP1 => '0', enable_LP2 => '0', enable_PED => '0', LP1_pulse => '0', LP2_pulse => '0', PED_pulse => '0'); signal i_reg : t_reg := (new_config => '0', general_settings => (others => '0'), LP_and_PED_freq => (others => '0'), LP1_LP2_PED_ratio => (others => '0'), ms_counter => (others => '0'), ms_tick => '0', tick_counter => (others => '0'), trigger_tick => '0', trigger_counter => (others => '0'), enable_LP1 => '0', enable_LP2 => '0', enable_PED => '0', LP1_pulse => '0', LP2_pulse => '0', PED_pulse => '0'); begin -- Combinatorial logic process(new_config, general_settings, LP_and_PED_freq, LP1_LP2_PED_ratio, i_reg) variable v_reg : t_reg := (new_config => '0', general_settings => (others => '0'), LP_and_PED_freq => (others => '0'), LP1_LP2_PED_ratio => (others => '0'), ms_counter => (others => '0'), ms_tick => '0', tick_counter => (others => '0'), trigger_tick => '0', trigger_counter => (others => '0'), enable_LP1 => '0', enable_LP2 => '0', enable_PED => '0', LP1_pulse => '0', LP2_pulse => '0', PED_pulse => '0'); begin v_reg := i_reg; --=================================================================================== --=================================================================================== -- Milliseconds counter --=================================================================================== v_reg.ms_tick := '0'; -- Counter management -- Count until 1ms is reached if i_reg.ms_counter = to_unsigned(MAX_MS_COUNTER_VAL, MAX_MS_COUNTER_WIDTH)-1 then v_reg.ms_counter := (others => '0'); v_reg.ms_tick := '1'; else v_reg.ms_counter := i_reg.ms_counter+1; end if; --=================================================================================== --=================================================================================== -- Triggers counter --=================================================================================== v_reg.trigger_tick := '0'; -- Generate a tick each time the pulse generation period is reached if i_reg.tick_counter = unsigned(i_reg.LP_and_PED_freq(9 downto 0)) then v_reg.tick_counter := (others => '0'); v_reg.trigger_tick := '1'; elsif i_reg.ms_tick = '1' then v_reg.tick_counter := i_reg.tick_counter+1; end if; --=================================================================================== --=================================================================================== -- Triggers management --=================================================================================== v_reg.new_config := new_config; -- Register parameters when new configuration is set if new_config = '1' and i_reg.new_config = '0' then v_reg.general_settings := general_settings; v_reg.LP_and_PED_freq := LP_and_PED_freq; v_reg.LP1_LP2_PED_ratio := LP1_LP2_PED_ratio; end if; -- Manages pulses if i_reg.enable_LP1 = '1' then -- Wait for set number of pulse of LP1 if i_reg.trigger_tick = '1' then v_reg.trigger_counter := i_reg.trigger_counter+1; -- If number of pulse reached elsif i_reg.trigger_counter = unsigned(i_reg.LP1_LP2_PED_ratio(4 downto 0)) then v_reg.trigger_counter := (others => '0'); v_reg.enable_LP1 := '0'; -- Switch to next pulse enable if i_reg.general_settings(5) = '1' then v_reg.enable_LP2 := '1'; elsif i_reg.general_settings(6) = '1' then v_reg.enable_PED := '1'; elsif i_reg.general_settings(4) = '1' then v_reg.enable_LP1 := '1'; end if; end if; elsif i_reg.enable_LP2 = '1' then -- Wait for set number of pulse of LP2 if i_reg.trigger_tick = '1' then v_reg.trigger_counter := i_reg.trigger_counter+1; -- If number of pulse reached elsif i_reg.trigger_counter = unsigned(i_reg.LP1_LP2_PED_ratio(9 downto 5)) then v_reg.trigger_counter := (others => '0'); v_reg.enable_LP2 := '0'; -- Switch to next pulse enable if i_reg.general_settings(6) = '1' then v_reg.enable_PED := '1'; elsif i_reg.general_settings(4) = '1' then v_reg.enable_LP1 := '1'; elsif i_reg.general_settings(5) = '1' then v_reg.enable_LP2 := '1'; end if; end if; elsif i_reg.enable_PED = '1' then -- Wait for set number of pulse of PED if i_reg.trigger_tick = '1' then v_reg.trigger_counter := i_reg.trigger_counter+1; -- If number of pulse reached elsif i_reg.trigger_counter = unsigned(i_reg.LP1_LP2_PED_ratio(14 downto 10)) then v_reg.trigger_counter := (others => '0'); v_reg.enable_PED := '0'; -- Switch to next pulse enable if i_reg.general_settings(4) = '1' then v_reg.enable_LP1 := '1'; elsif i_reg.general_settings(5) = '1' then v_reg.enable_LP2 := '1'; elsif i_reg.general_settings(6) = '1' then v_reg.enable_PED := '1'; end if; end if; else v_reg.trigger_counter := (others => '0'); end if; -- Enable first selected pulse when new configuration is registered -- It's made after ratio counter to avoid error if new configuration -- is done on the same time pulse enables change in the ratio counter if new_config = '0' and i_reg.new_config = '1' then v_reg.enable_LP1 := '0'; v_reg.enable_LP2 := '0'; v_reg.enable_PED := '0'; if i_reg.general_settings(4) = '1' then v_reg.enable_LP1 := '1'; elsif i_reg.general_settings(5) = '1' then v_reg.enable_LP2 := '1'; elsif i_reg.general_settings(6) = '1' then v_reg.enable_PED := '1'; end if; end if; -- Set enabled pulse on output if i_reg.trigger_tick = '1' then if i_reg.enable_LP1 = '1' then v_reg.LP1_pulse := '1'; elsif i_reg.enable_LP2 = '1' then v_reg.LP2_pulse := '1'; elsif i_reg.enable_PED = '1' then v_reg.PED_pulse := '1'; end if; -- Once set, pulse is reset else v_reg.LP1_pulse := '0'; v_reg.LP2_pulse := '0'; v_reg.PED_pulse := '0'; end if; --=================================================================================== --=================================================================================== -- Drive register input i_next_reg <= v_reg; --=================================================================================== -- Output assignation LP1_pulse <= i_reg.LP1_pulse; LP2_pulse <= i_reg.LP2_pulse; PED_pulse <= i_reg.PED_pulse; --=================================================================================== end process; -- Sequential logic process(clk_50MHz) begin if rising_edge(clk_50MHz) then i_reg <= i_next_reg; end if; end process; end RTL;