------------------------------------------------------ -- remove CMC slink status word until the first Header on L0 & L1 before each event -- -- Ver 1.00 -- -- Dominique Gigi Jan 2011 ------------------------------------------------------ -- -- -- -- ------------------------------------------------------ LIBRARY ieee; --LIBRARY altera_mf; --LIBRARY altera; USE ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.std_logic_unsigned.all; --LIBRARY lpm; --USE lpm.lpm_components.all; --USE altera_mf.altera_mf_components.all; --USE altera.altera_primitives_components.all; entity trigger_gen is port ( Rst_Pciclk : IN std_logic; PCIe_clk : IN std_logic; PCIe_func : IN std_logic_vector(15 downto 0); PCIe_wen : IN std_logic; PCIe_dti : IN std_logic_vector(31 downto 0); PCIe_dto : OUT std_logic_vector(31 downto 0); PCIe_cs : IN std_logic; ttc_trigger : IN std_logic; Rst_Evtclk : IN std_logic; evt_clk : IN std_logic; ena_PCIe : OUT std_logic; run_mode : OUT std_logic; trig_nb : OUT std_logic_vector(23 downto 0); trigger : OUT std_logic; end_evt : IN std_logic; Back_p : IN std_logic ); end trigger_gen; architecture behavioral of trigger_gen is component resync port ( reset : in std_logic; Free_clki : in std_logic; clocki : in std_logic; clocko : in std_logic; input : in std_logic; output : out std_logic ); end component; signal delay_end_evt : std_logic_vector(3 downto 0); signal pre_trig_loop : std_logic; signal pre_trig_TTC : std_logic; signal delay_pre_trg_TTC : std_logic; signal trigger_mux : std_logic; signal trig_sync : std_logic; signal trigger_cnt : std_logic_vector(8 downto 0); signal evt_cnt : std_logic_vector(63 downto 0); signal check_trig : std_logic; signal evt_working : std_logic; signal pulse_trigger : std_logic; signal mem_evt_num : std_logic_vector(23 downto 0); signal pcie_ld : std_logic; signal ld_evt_nm : std_logic; signal start : std_logic; signal ena_PCI_trigger : std_logic; signal go_round : std_logic; signal reset_func : std_logic; signal PCI_trig : std_logic; signal Start_rsync : std_logic_vector(1 downto 0); signal Loop_rsync : std_logic; --********************************************************************* --**********************<< BEGIN >>*********************************** --********************************************************************* begin -- PCIe decoding function process(Rst_Pciclk,PCIe_clk) begin if Rst_Pciclk = '0' then go_round <= '0'; ena_PCI_trigger <= '0'; start <= '0'; pre_trig_loop <= '0'; pre_trig_TTC <= '0'; elsif rising_edge(PCIe_clk) then -- set the loop trigger mode if PCIe_cs = '1' and PCIe_func(0) = '1' and PCIe_dti(1) = '1' AND PCIe_wen = '1' then go_round <= '1'; elsif PCIe_cs = '1' and PCIe_func(0) = '1' and PCIe_dti(2) = '1' AND PCIe_wen = '1' then go_round <= '0'; end if; -- select the trigger if PCIe_cs = '1' and PCIe_func(0) = '1' AND PCIe_wen = '1' then ena_PCI_trigger <= PCIe_dti(3); end if; -- generate a PCI trigger PCI_trig <= '0'; if PCIe_cs = '1' and PCIe_func(0) = '1' and PCIe_dti(0) = '1' AND PCIe_wen = '1' then PCI_trig <= '1'; end if; -- start to generate triggers if PCIe_cs = '1' and PCIe_func(0) = '1' AND PCIe_wen = '1' then start <= PCIe_dti(4); end if; pre_trig_loop <= '0'; -- pre trigger when loop mode if PCIe_cs = '1' and PCIe_func(0) = '1' and PCIe_dti(1) = '1' AND PCIe_wen = '1' then pre_trig_loop <= '1'; end if; delay_pre_trg_TTC <= pre_trig_TTC; pre_trig_TTC <= '0'; -- pre trigger when TTC trigger used if PCIe_cs = '1' and PCIe_func(0) = '1' and PCIe_dti(4) = '1' AND PCIe_wen = '1' then pre_trig_TTC <= '1'; end if; pcie_ld <= '0'; if PCIe_cs = '1' and PCIe_func(1) = '1' AND PCIe_wen = '1' then pcie_ld <= '1'; mem_evt_num <= PCIe_dti(23 downto 0); end if; end if; end process; process(PCIe_clk) begin if rising_edge(PCIe_clk) then PCIe_dto <= (others => '0'); if PCIe_func(0) = '1' then PCIe_dto(0) <= '0'; PCIe_dto(1) <= go_round; PCIe_dto(2) <= go_round; PCIe_dto(3) <= ena_PCI_trigger; PCIe_dto(4) <= start; PCIe_dto(5) <= '0'; PCIe_dto(7 downto 6) <= (others => '0'); PCIe_dto(8) <= evt_working; PCIe_dto(9) <= Back_p; PCIe_dto(31 downto 10) <= (others => '0'); elsif PCIe_func(1) = '1' then PCIe_dto(31 downto 0) <= evt_cnt(31 downto 0); elsif PCIe_func(2) = '1' then PCIe_dto(31 downto 0) <= evt_cnt(63 downto 32); elsif PCIe_func(7) = '1' then PCIe_dto(8 downto 0) <= trigger_cnt; -- pending triggers end if; end if; end process; -- if '1' the trigger and wc are from PCIe access (if '0' trigger s and WC comes form FIFO memory_RND) ena_PCIe <= ena_PCI_trigger; -- specify that the event can be generated (all parametes should be set before going to this mode run_mode <= start ; trigger_mux <= '1' when start = '1' and ((PCI_trig = '1' AND ena_PCI_trigger= '1') or ( (ttc_trigger = '1' or delay_pre_trg_TTC = '1') AND ena_PCI_trigger= '0')) else '0'; trg_gen:resync port map( reset => Rst_Pciclk, Free_clki => '1', clocki => PCIe_clk, input => trigger_mux, clocko => evt_clk, output => trig_sync ); -- resync two signals to Evt_CK Process(evt_clk) begin if rising_edge(evt_clk) then Start_rsync(1) <= Start_rsync(0); Start_rsync(0) <= start; end if; end process; -- trigger counter process(Rst_Evtclk,Start_rsync(1),evt_clk) begin if Rst_Evtclk = '0' or Start_rsync(1) = '0' then trigger_cnt <= (others => '0'); elsif rising_edge(evt_clk) then if trig_sync = '1' and end_evt = '0' then trigger_cnt <= trigger_cnt + "1"; elsif trig_sync = '0' and end_evt = '1' then trigger_cnt <= trigger_cnt - "1"; end if; end if; end process; pre_trig_loop_i1:resync port map( reset => Rst_PCIclk, Free_clki => '1', clocki => PCIe_clk, input => pre_trig_loop, clocko => evt_clk, output => Loop_rsync ); -- create a delay at the end of the event before starting the new one's process(evt_clk) begin if rising_edge(evt_clk) then delay_end_evt(3 downto 1) <= delay_end_evt(2 downto 0); delay_end_evt(0) <= end_evt or Loop_rsync; end if; end process; process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then check_trig <= '0'; evt_working <= '0'; pulse_trigger <= '0'; elsif rising_edge(evt_clk) then check_trig <= '0'; if start = '1' AND check_trig = '0' AND evt_working = '0' AND trigger_cnt /= "000000000" AND Back_p = '1' then check_trig <= '1'; end if; pulse_trigger <= evt_working; if (delay_end_evt(3) = '1' AND go_round = '1' AND start = '1' ) OR (go_round = '0' AND check_trig = '1' ) then evt_working <= '1' ; elsif end_evt = '1' then evt_working <= '0' ; end if; end if; end process; ld_evt_sync:resync port map( reset => Rst_Pciclk, Free_clki => '1', clocki => PCIe_clk, input => pcie_ld, clocko => evt_clk, output => ld_evt_nm ); -- event counter managment process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then evt_cnt <= (others => '0'); elsif rising_edge(evt_clk) then if ld_evt_nm = '1' then evt_cnt(63 downto 24) <= (others => '0'); evt_cnt(23 downto 00) <= mem_evt_num; elsif end_evt = '1' then evt_cnt <= evt_cnt + "1"; end if; end if; end process; trigger <= '1' when evt_working = '1' AND pulse_trigger = '0' else '0'; trig_nb <= evt_cnt(23 downto 0); end behavioral;