-- -- Detect external triggers. -- -- Joris van Rantwijk 2024 -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.puzzlefw_pkg.all; entity trigger_detector is port ( -- Main clock, active on rising edge. clk: in std_logic; -- Reset, active high, synchronous to main clock. reset: in std_logic; -- High to enable automatic (continuous) triggering. trig_auto_en: in std_logic; -- High to enable external triggering. trig_ext_en: in std_logic; -- High to force a trigger event (if the acquisition chain is ready). trig_force: in std_logic; -- Select external input signal to use as trigger. trig_select: in std_logic_vector(1 downto 0); -- High to trigger on falling edge, low to trigger on rising edge. trig_falling: in std_logic; -- Digital input signals. trig_ext_in: in std_logic_vector(3 downto 0); -- High in the clock cycle following the occurrence of a trigger. trig_out: out std_logic ); end entity; architecture arch of trigger_detector is type regs_type is record prev_level: std_logic; ext_trig: std_logic; trig_out: std_logic; end record; constant regs_init: regs_type := ( prev_level => '0', ext_trig => '0', trig_out => '0' ); signal r: regs_type := regs_init; signal rnext: regs_type; begin -- Drive output. trig_out <= r.trig_out; -- -- Combinatorial process. -- process (all) is variable v: regs_type; variable v_trig: std_logic; begin -- Load current register values. v := r; -- Select external input signal. v.prev_level := trig_ext_in(to_integer(unsigned(trig_select))); -- Detect active edge. v.ext_trig := (not (r.prev_level xor trig_falling)) and (v.prev_level xor trig_falling); -- Combine trigger sources. v.trig_out := trig_auto_en or (trig_ext_en and r.ext_trig) or trig_force; -- Synchronous reset. if reset = '1' then v.ext_trig := '0'; v.trig_out := '0'; end if; -- Drive new register values to synchronous process. rnext <= v; end process; -- -- Synchronous process. -- process (clk) is begin if rising_edge(clk) then r <= rnext; end if; end process; end architecture;