-- 31..6 waittime, 5 Endmarker 4..0, Pattern auf T0..T4 -- Trigger selector 8 outputs, -- 9 from trigger multiplicity classes -- 3 from coincidence matrices -- 5 from sequencer -- -- -- 17 = 5 Bits for each output -- -- -- Trigger Sequencer, Base Addres 0x3000 -- Memory area of 512 32 Bit words for trigger sequences has address -- range 512 to 1023 (0x200..0x3ff), write only from CPU -- Address 0: Runcontrol -- 0: sequencer off -- 1: single run from address 512 to endmarker -- 2: cyclic run -- Memory content bit description: -- 31..6 : timer val in 25ns steps -- 5: 1=last word, 0: next present -- 4..0. Trigger pattern for 5 outputs -- library ieee; use ieee.std_logic_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity trigger_sequencer is port ( clk40 : in std_logic; cpuclk : in std_logic; reset_n : in std_logic; tseq_IBO : in std_logic_vector(31 downto 0); tseq_OBI : out std_logic_vector(31 downto 0); we : in std_logic; address : in std_logic_vector(9 downto 0); Tout : out std_logic_vector(4 downto 0)); -- Trigger out end trigger_sequencer; architecture behv of trigger_sequencer is component mempipe port ( clk40 : in std_logic; cpuclk : in std_logic; reset_n : in std_logic; cpuaddr : in std_logic_vector(8 downto 0); cpudata : in std_logic_vector(31 downto 0); cpuwe : in std_logic; init : in std_logic; done : out std_logic; inca : in std_logic; q : out std_logic_vector(31 downto 0)); end component; -- register for runcontrol signal runctrl_cpuclk : std_logic_vector(1 downto 0); signal runctrl_clk40 : std_logic_vector(1 downto 0); signal last_runctrl0 : std_logic; signal cyclic : std_logic; signal start_puls : std_logic; -- Pausetimer signal pausecounter : std_logic_vector(25 downto 0); signal pc_en : std_logic; -- Enable = Run, noEN=clear -- Control Memory mempipe containig addresscounter signal mem_done : std_logic; signal acnt_clr : std_logic; signal acnt_en : std_logic; -- data from memory to processing sequence signal memdata : std_logic_vector(31 downto 0); signal pausval : std_logic_vector(25 downto 0); signal endmarker : std_logic; signal ltp,triggerpattern : std_logic_vector(4 downto 0); -- write enable to mem signal wemem : std_logic; -- FSM states type STATE_TYPE is (idle, pipeprep, pipewait, runpause, incaddr, lastpattern); signal state,nextstate : STATE_TYPE; -- Signals to activate Trigger output signal en_out : std_logic; begin -- behv -- control register runctrl_cpu_r : process (cpuclk, reset_n) begin -- process en_cpu_r if reset_n = '0' then -- asynchronous reset (active low) runctrl_cpuclk <= "00"; elsif cpuclk'event and cpuclk = '1' then -- rising clock edge if we = '1' and address = "0000000000" then runctrl_cpuclk <= tseq_IBO(1 downto 0); end if; end if; end process runctrl_cpu_r; runctrl_40_r : process (clk40) begin -- process en_cpu_r if clk40'event and clk40 = '1' then -- rising clock edge runctrl_clk40 <= runctrl_cpuclk; end if; end process runctrl_40_r; cyclic <= runctrl_clk40(1); start_puls_r : process (clk40, reset_n) begin -- process start_puls_r if reset_n = '0' then -- asynchronous reset (active low) last_runctrl0 <= '0'; elsif clk40'event and clk40 = '1' then -- rising clock edge last_runctrl0 <= runctrl_clk40(0); end if; end process start_puls_r; -- start puls only on positive edge; start_puls <= '1' when last_runctrl0 = '0' and runctrl_clk40(0) = '1' else '0'; -- Map piped Memory mempipe_1 : mempipe port map ( clk40 => clk40, cpuclk => cpuclk, reset_n => reset_n, cpuaddr => address(8 downto 0), cpudata => tseq_IBO, cpuwe => wemem, init => acnt_clr, done => mem_done, inca => acnt_en, q => memdata); wemem <= '1' when we = '1' and address(9) = '1' else '0'; pausval <= memdata(31 downto 6); endmarker <= memdata(5); triggerpattern <= memdata(4 downto 0); -- Pausetimer, controlled by FSM pc_p : process (clk40, reset_n) begin -- process pc_p if reset_n = '0' then -- asynchronous reset (active low) pausecounter <= (others => '0'); elsif clk40'event and clk40 = '1' then -- rising clock edge if pc_en = '1' then pausecounter <= pausecounter +1; else pausecounter <= (others => '0'); end if; end if; end process pc_p; -- -------- -- FSM fsm_sp : process (clk40, reset_n) begin -- process fsm_sp if reset_n = '0' then -- asynchronous reset (active low) state <= idle; elsif clk40'event and clk40 = '1' then -- rising clock edge state <= nextstate; end if; end process fsm_sp; -- -- idle, pipeprep, pipewait, runpause, incaddr, lastpattern fsm_comb: process (state, start_puls, cyclic, pausecounter, pausval, endmarker, mem_done) begin -- process fsm_comb case state is when idle => -- reset acnt, pc if start_puls = '1' or cyclic = '1' then nextstate <= pipeprep; else nextstate <= idle; end if; when pipeprep => nextstate <= pipewait; when pipewait => if mem_done = '1' then if (pausval = conv_std_logic_vector(0,26)) then nextstate <= incaddr; else nextstate <= runpause; end if; else nextstate <= pipewait; end if; when runpause => if pausecounter = pausval - 1 then if endmarker = '1' then nextstate <= lastpattern; else nextstate <= incaddr; end if; else nextstate <= runpause; end if; when incaddr => if (pausval = conv_std_logic_vector(0,26)) then if endmarker = '1' then nextstate <= lastpattern; else nextstate <= incaddr; end if; else nextstate <= runpause; end if; when lastpattern => nextstate <= idle; when others => nextstate <= idle; end case; end process fsm_comb; acnt_clr <= '1' when state = pipeprep else '0'; acnt_en <= '1' when state = incaddr else '0'; pc_en <= '1' when state = runpause else '0'; with state select en_out <= '1' when incaddr | lastpattern, '0' when others; Tout_register: process (clk40, reset_n) begin -- process Tout_register if reset_n = '0' then -- asynchronous reset (active low) Tout <= (others => '0'); ltp <= (others => '0'); elsif clk40'event and clk40 = '1' then -- rising clock edge ltp <= triggerpattern; if en_out = '1' then Tout <= ltp; else Tout <= "00000"; end if; end if; end process Tout_register; -- Address demultiplex with address select tseq_OBI <= ((31 downto 2 => '0') & runctrl_cpuclk) when "0000000000", (others => '0') when others; end behv;