Skip to content
Snippets Groups Projects
Commit ded96861 authored by David Cussans's avatar David Cussans
Browse files

* Created SyncGenerator_rtl.vhd , which generates trigger veto and shutter...

* Created SyncGenerator_rtl.vhd , which generates trigger veto and shutter signals. (needs to be wrapped in IPBus interface)
* Created counter with preload to top bit as well as reset
parent 9029f9da
Branches
Tags
No related merge requests found
--=============================================================================
--! @file syncGenerator_rtl.vhd
--=============================================================================
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------
-- unit name: syncGenerator
--
--============================================================================
--! Entity declaration for syncGenerator
--============================================================================
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
use IEEE.math_real.all;
--! @brief Generates a sync signal for, eg. KPix
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date April 2018
--
--! @version v0.1
--
-------------------------------------------------------------------------------
--! @details
--! Starts sequence with trigger_veto_o high and shutter_o low.
--! If enable_sequence_i is high then when trigger_sources_i(trigger_source_select_i) goes high
--! then sequence starts.
--! At time T1 after Emin signal shutter_o goes higher
--! At time T2 after Emin veto_o goes low
--! At time T3 after Emin shutter_o goes low and veto_o goes high.
--
--! \n\n<b>Last changes:</b>\n
--!
ENTITY syncGenerator IS
GENERIC (g_COUNTER_WIDTH : integer := 32; --! Number of bits in counter
g_IPBUS_WIDTH : integer := 32;
g_NUM_TRIG_SOURCES : integer := 4 --! Number of input trigger sources.
);
PORT
(
-- Input signals
clock_i: IN STD_LOGIC; --! rising edge active clock
reset_i: IN STD_LOGIC; --! Active high. syncronous with rising clk
strobe_i: IN STD_LOGIC; --! one strobe pulse per 4 clock cycles
trigger_sources_i: IN STD_LOGIC_VECTOR(g_NUM_TRIG_SOURCES-1 downto 0); --! array of possible trigger trigger_sources
trigger_source_select_i : IN STD_LOGIC_VECTOR(g_IPBUS_WIDTH-1 downto 0); --! Selects which input to use
threshold_t1_i, threshold_t2_i, threshold_t3_i : IN STD_LOGIC_VECTOR(g_IPBUS_WIDTH-1 downto 0); --! Times at which sequence changes state.
enable_sequence_i : in std_logic ; --! take high to enable sequence
--! Output Signals
shutter_o: OUT STD_LOGIC;
trigger_veto_o: OUT STD_LOGIC
);
END syncGenerator;
ARCHITECTURE rtl OF syncGenerator IS
constant c_SELWIDTH : integer := integer(ceil(log2(real(g_NUM_TRIG_SOURCES))));
signal s_sel : integer := 0;
signal s_counter_value: std_logic_vector(g_COUNTER_WIDTH downto 0); -- One wider that comparator values.
signal s_trigger, s_counter_enable, s_reset_counter: std_logic :='0';
-- constant c_SELWIDTH : integer := 4; --! Up to 16 different trigger sources
signal s_trigger_source_select: std_logic_vector(c_SELWIDTH-1 downto 0);
signal s_counter_lt_t1 , s_counter_lt_t2 , s_counter_lt_t3 : std_logic := '0';
signal s_shutter , s_veto : std_logic := '0';
signal s_threshold_t1,s_threshold_t3,s_threshold_t2: unsigned(g_COUNTER_WIDTH-1 downto 0);
BEGIN
-- Instantiate a counter
cmp_Counter: ENTITY work.counterWithResetPreset
GENERIC MAP (g_COUNTER_WIDTH => g_COUNTER_WIDTH+1
)
PORT MAP
(
clock_i => clock_i,
reset_i => s_reset_counter,
preset_i => reset_i, --! Preload top bit to halt counter
enable_i => s_counter_enable,
result_o => s_counter_value); --! std_logic_vector output
--! Process to generate a reset signal for counter
--! Will reset ( and hence start to count ) if input trigger is high and
--! the sequence isn't running.
p_generateReset: PROCESS (clock_i)
BEGIN
IF rising_edge(clock_i) THEN
if (s_trigger = '1') and
(s_counter_lt_t3 = '0') and
(enable_sequence_i = '1') then
s_reset_counter<= '1';
else
s_reset_counter <= '0';
end if;
END IF;
END PROCESS p_generateReset;
--! Process to stop counter before it wraps round
--! and only count when strobe_i is high.
p_generateStrobe: PROCESS (clock_i)
BEGIN
IF rising_edge(clock_i) THEN
if ((s_counter_value(s_counter_value'left) = '0') and (strobe_i = '1')) then
s_counter_enable <= '1';
else
s_counter_enable <= '0';
end if;
END IF;
END PROCESS p_generateStrobe;
-- Trim the source select value and convert to integer.
s_trigger_source_select <= trigger_source_select_i(s_trigger_source_select'range);
s_sel <= to_integer(unsigned(s_trigger_source_select));
--! Process to register trigger input
p_inputSelect: PROCESS (clock_i)
BEGIN
IF rising_edge(clock_i) and (strobe_i='1') THEN
s_trigger <= trigger_sources_i( s_sel);
END IF;
END PROCESS p_inputSelect;
-- Trim threshold values and convert to unsigned.
s_threshold_t1 <= unsigned(threshold_t1_i(s_threshold_t1'range));
s_threshold_t2 <= unsigned(threshold_t2_i(s_threshold_t2'range));
s_threshold_t3 <= unsigned(threshold_t3_i(s_threshold_t3'range));
--! Process to drive s_counter_lt_t1 , s_counter_lt_t2, s_counter_lt_t3
p_comparators: PROCESS (clock_i)
BEGIN
IF rising_edge(clock_i) and (strobe_i='1') THEN
if unsigned(s_counter_value) < s_threshold_t1 THEN
s_counter_lt_t1 <= '1';
else
s_counter_lt_t1 <= '0';
end if;
if unsigned(s_counter_value) < s_threshold_t2 THEN
s_counter_lt_t2 <= '1';
else
s_counter_lt_t2 <= '0';
end if;
if unsigned(s_counter_value) < s_threshold_t3 THEN
s_counter_lt_t3 <= '1';
else
s_counter_lt_t3 <= '0';
end if;
END IF;
END PROCESS p_comparators;
-- sequence: Emin --> Shutter-on --> Veto-off --> (shutter-off,veto-on)
-- NB. Need to ensure T1 < T2 < T3
s_veto <= '0' when (s_counter_lt_t3 ='1') and (s_counter_lt_t2 = '0') else '1';
s_shutter <= '1' when (s_counter_lt_t3 ='1') and (s_counter_lt_t1 = '0') else '0';
--! Process to set output signals
p_setOutput: PROCESS (clock_i)
BEGIN
IF rising_edge(clock_i) and (strobe_i='1') THEN
trigger_veto_o <= s_veto;
shutter_o <= s_shutter;
END IF;
END PROCESS p_setOutput;
END rtl;
--=============================================================================
--! @file counterWithResetPreset_rtl.vhd
--=============================================================================
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- unit name: counterWithResetPreset (counterWithResetPreset / rtl)
--
--============================================================================
--! Entity declaration for counterWithResetPreset
--============================================================================
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
--! @brief Simple counter with synchronous reset and top-bit preload
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date Feb\2012
--
--! @version v0.1
--
-------------------------------------------------------------------------------
--! @details
--! \n\n<b>Last changes:</b>\n
--! 5/Mar/12 DGC Changed to use numeric_std\n
--! 26/Feb/14 DGC Added registers to output to aid timing closure.
--!
ENTITY counterWithResetPreset IS
GENERIC (g_COUNTER_WIDTH : integer := 32; --! Number of bits
g_OUTPUT_REGISTERS : integer := 4 --! Number of output registers. Minumum =1. Aids timing closure.
);
PORT
(
clock_i: IN STD_LOGIC; --! rising edge active clock
reset_i: IN STD_LOGIC; --! Active high. synchronous with rising clk. Takes output to 0
preset_i: IN STD_LOGIC; --! Active high. synchronous with rising clk. Takes highest bit to 1
enable_i: IN STD_LOGIC; --! counts when enable=1
result_o: OUT STD_LOGIC_VECTOR ( g_COUNTER_WIDTH-1 downto 0) --! Unsigned integer output
);
END counterWithResetPreset;
ARCHITECTURE rtl OF counterWithResetPreset IS
type t_register_array is array(natural range <>) of UNSIGNED ( g_COUNTER_WIDTH-1 downto 0) ; -- --! Array of arrays for output register...
signal s_output_registers : t_register_array(g_OUTPUT_REGISTERS downto 0) := ( others => ( others => '0')); -- --! Output registers.
BEGIN
--! Process to count up from zero when enable_i is high.
p_counter: PROCESS (clock_i)
BEGIN
IF rising_edge(clock_i) THEN
IF (reset_i = '1') THEN
s_output_registers(0) <= (others => '0');
ELSIF (preset_i='1') THEN
s_output_registers(0)(g_COUNTER_WIDTH-1) <= '1'; -- Preload highest bit to '1'
ELSIF (enable_i='1') THEN
s_output_registers(0) <= s_output_registers(0) + 1;
END IF;
END IF;
END PROCESS p_counter;
--! Generate some output registers. Number controlled by g_OUTPUT_REGISTERS
generate_registers: for v_register in 1 to g_OUTPUT_REGISTERS generate
--! An individual register
p_outputRegister: process (clock_i)
begin -- process p_outputRegister
if rising_edge(clock_i) then
s_output_registers( v_register) <=
s_output_registers( v_register-1);
end if;
end process p_outputRegister;
end generate generate_registers; -- v_register
--! Copy the (registered) result to the output
result_o <= STD_LOGIC_VECTOR(s_output_registers(g_OUTPUT_REGISTERS));
END rtl;
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment