------------------------------------------------------ -- remove CMC slink status word until the first Header on L0 & L1 before each event -- -- Ver 2.00 -- -- Dominique Gigi Jan 2011 ------------------------------------------------------ -- func(0) bit 0 PCI trigger -- bit 1 Start loop -- bit 2 stop loop -- bit 3 Ena PCI trigger -- bit 4 Start -- bit 5 soft_reset -- func(1) bit23.0 event # -- func(2) bit 0 CRC error gen -- bit 1 BIT error gen -- func(3) bit11.0 Source # -- bit27.11 BX# -- func(4) bit23.0 event lenght -- func(5) bit15..0 wc -- for random distribution of triggers -- bit 31..16 timer between two trigger -- -- correct some variable to be compliant the the old graphical version ------------------------------------------------------ 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 event_generator is port ( reset : IN std_logic; low_clk : IN std_logic; -- frequency of 50 Mhz 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; evt_clk : IN std_logic; wen : OUT std_logic; data : OUT std_logic_vector(63 downto 0); uctrl : OUT std_logic; Back_p : IN std_logic -- Back_p when '0' ); end event_generator; architecture behavioral of event_generator 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; component trigger_gen 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 component; component CRC_generator Port ( D : in std_logic_vector(63 downto 0); CRC_out : out std_logic_vector(15 downto 0); clk : in std_logic; clear : in std_logic; enable : in std_logic); end component; --memory used to store WC and trigger distribution (31..16) WC (words) // (15..0) time between triggers (bit= 20 ns) component memory_rnd port ( RST_lowClk : IN std_logic; low_clk : IN Std_logic; RST_PCIClk : IN Std_logic; PCIe_clk : IN std_logic; PCIe_dt : IN std_logic_vector(31 downto 0); PCIe_func : IN std_logic_vector(15 downto 0); PCIe_cs : IN std_logic; PCIe_wen : IN std_logic; start : IN std_logic; wc : OUT std_logic_vector(15 downto 0); RST_EvtClk : IN std_logic; evt_clk : IN std_logic; trigger : OUT std_logic; end_evt : IN std_logic ); end component; component generate_3 PORT ( clock : IN STD_LOGIC; START : IN STD_LOGIC; LOAD_SEED : IN STD_LOGIC; SEED : IN STD_LOGIC_VECTOR(7 DOWNTO 0); rnd : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END component; component reset_resync is port ( reset : in std_logic; clock : in std_logic; Reset_sync : out std_logic ); end component; signal rnd_dt_O : std_logic_vector(63 downto 0); signal rnd_dt_L : std_logic_vector(63 downto 0); signal ena_rnd_dt : std_logic; signal LFF_D : std_logic; signal BX : std_logic_vector(11 downto 0); signal SOURCE : std_logic_vector(11 downto 0); signal evt_lenght : std_logic_vector(23 downto 0); --(byte--) signal crc_error : std_logic_vector(2 downto 0); signal bit_error : std_logic_vector(2 downto 0); signal hd_error : std_logic_vector(2 downto 0); signal tr_error : std_logic_vector(2 downto 0); signal HD_ena : std_logic; signal TR_ena : std_logic_vector(3 downto 0); signal PL_ena : std_logic_vector(1 downto 0); signal HD_dt : std_logic_vector(63 downto 0); signal TR_dt : std_logic_vector(63 downto 0); signal PL_dt : std_logic_vector(63 downto 0); signal evt_run : std_logic_vector(3 downto 0); signal pre_TR : std_logic_vector(63 downto 0); signal WC_size : std_logic_vector(20 downto 0); signal end_WC : std_logic_vector(1 downto 0); signal run_mode : std_logic; signal ena_PCIe : std_logic; signal trig_nb : std_logic_vector(23 downto 0); signal trigger : std_logic; signal end_evt : std_logic; signal soft_rst : std_logic; signal wc_rnd : std_logic_vector(15 downto 0); signal trigger_rnd : std_logic; signal pseudo_reset : std_logic_vector(0 downto 0); signal CRC_OUT : std_logic_vector(15 downto 0); signal CRC_val : std_logic_vector(15 downto 0); signal CRC_cmp : std_logic; signal CRC_reg : std_logic_vector(63 downto 0); signal wen_reg : std_logic; signal data_reg : std_logic_vector(63 downto 0); signal uctrl_reg : std_logic; signal PCIe_dto_trg : std_logic_vector(31 downto 0); signal PCIe_dto_local: std_logic_vector(31 downto 0); signal Byte_rnd : std_logic_vector(7 downto 0); signal Rst_PCIclk : std_logic; signal Rst_Evtclk : std_logic; signal Rst_lowclk : std_logic; --*********************************************************************** --**********************<< BEGIN >>************************* --*********************************************************************** begin --/***************** resync reset to clocks domain****************** rst_pci_i1:reset_resync port map( reset => reset, clock => PCIe_clk, Reset_sync => Rst_PCIclk ); rst_evt_i1:reset_resync port map( reset => reset, clock => evt_clk, Reset_sync => Rst_Evtclk ); rst_low_i1:reset_resync port map( reset => reset, clock => low_clk, Reset_sync => Rst_lowclk ); --*************** Sync Back_pressure ************************ process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then LFF_D <= '1'; elsif rising_edge(evt_clk) then LFF_D <= Back_p; -- Back_p when '0' end if; end process; ena_rnd_dt <= '1' when LFF_D = '1' and evt_run(2) = '1' else '0'; --################## Pseudo random data with 8 times same bytes ################### i3:generate_3 PORT MAP ( clock => evt_clk, START => ena_rnd_dt, LOAD_SEED => evt_run(0), SEED => x"00", rnd => Byte_rnd ); rnd_dt_L(63 downto 56) <= Byte_rnd; rnd_dt_L(55 downto 48) <= Byte_rnd; rnd_dt_L(47 downto 40) <= Byte_rnd; rnd_dt_L(39 downto 32) <= Byte_rnd; rnd_dt_L(31 downto 24) <= not(Byte_rnd); rnd_dt_L(23 downto 16) <= not(Byte_rnd); rnd_dt_L(15 downto 08) <= not(Byte_rnd); rnd_dt_L(07 downto 00) <= not(Byte_rnd); --********************************************************************************* --***********************<< error generator >> *********************************** --******** decoding PCIe functions process(Rst_PCIclk,PCIe_clk) begin if Rst_PCIclk = '0' then crc_error(0) <= '0'; bit_error(0) <= '0'; hd_error(0) <= '0'; tr_error(0) <= '0'; elsif rising_edge(PCIe_clk) then crc_error(0) <= '0'; bit_error(0) <= '0'; hd_error(0) <= '0'; tr_error(0) <= '0'; if PCIe_cs = '1' AND PCIe_func(6) = '1' AND PCIe_wen = '1' then crc_error(0) <= PCIe_dti(0); bit_error(0) <= PCIe_dti(1); hd_error(0) <= PCIe_dti(2); tr_error(0) <= PCIe_dti(3); end if; end if; end process; crc_err_resync:resync port map( reset => Rst_PCIclk, Free_clki => '1', clocki => PCIe_clk, clocko => evt_clk, input => crc_error(0), output => crc_error(1) ); bit_err_resync:resync port map( reset => Rst_PCIclk, Free_clki => '1', clocki => PCIe_clk, clocko => evt_clk, input => bit_error(0), output => bit_error(1) ); hd_err_resync:resync port map( reset => Rst_PCIclk, Free_clki => '1', clocki => PCIe_clk, clocko => evt_clk, input => hd_error(0), output => hd_error(1) ); tr_err_resync:resync port map( reset => Rst_PCIclk, Free_clki => '1', clocki => PCIe_clk, clocko => evt_clk, input => tr_error(0), output => tr_error(1) ); process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then crc_error(2) <= '0'; bit_error(2) <= '0'; hd_error(2) <= '0'; tr_error(2) <= '0'; elsif rising_edge(evt_clk) then if crc_error(1) = '1' then crc_error(2) <= '1'; elsif TR_ena(3) = '1' then crc_error(2) <= '0'; end if; if bit_error(1) = '1' then bit_error(2) <= '1'; elsif evt_run(3) = '1' and LFF_D = '1' then bit_error(2) <= '0'; end if; if hd_error(1) = '1' then hd_error(2) <= '1'; elsif TR_ena(3) = '1' and LFF_D = '1' then hd_error(2) <= '0'; end if; if tr_error(1) = '1' then tr_error(2) <= '1'; elsif TR_ena(3) = '1' and LFF_D = '1' then tr_error(2) <= '0'; end if; end if; end process; end_evt <= TR_ena(3); --******************************************************************************* --**************************<< event gener. >>*********************************** trig:trigger_gen port map( Rst_Pciclk => Rst_Pciclk, PCIe_clk => PCIe_clk, PCIe_func => PCIe_func, PCIe_wen => PCIe_wen, PCIe_dti => PCIe_dti, PCIe_dto => PCIe_dto_trg, PCIe_cs => PCIe_cs, ttc_trigger => trigger_rnd, Rst_Evtclk => Rst_Evtclk, evt_clk => evt_clk, ena_PCIe => ena_PCIe, run_mode => run_mode, trig_nb => trig_nb, trigger => trigger, end_evt => end_evt, Back_p => LFF_D ); process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then evt_run <= (others => '0'); elsif rising_edge(evt_clk) then if evt_run(1) = '1' then evt_run(2) <= '1'; elsif LFF_D = '1' AND end_WC(0) = '1' then evt_run(2) <= '0'; end if; if evt_run(2) = '1' then evt_run(3) <= '1'; elsif end_WC(1) = '1' then evt_run(3) <= '0'; end if; evt_run(1) <= evt_run(0); evt_run(0) <= trigger; end if; end process; rnd_mem_trig:memory_rnd port map( RST_lowClk => RST_lowClk, low_clk => low_clk, RST_PCIClk => RST_PCIClk, PCIe_clk => PCIe_clk, PCIe_dt => PCIe_dti, PCIe_func => PCIe_func, PCIe_cs => PCIe_cs, PCIe_wen => PCIe_wen, start => run_mode, wc => wc_rnd, RST_EvtClk => RST_EvtClk, evt_clk => evt_clk, trigger => trigger_rnd, end_evt => end_evt ); --******************************************************************************* --************************** << Header >> *********************************** process(Rst_PCIclk,PCIe_clk) begin if Rst_PCIclk = '0' then BX <= (others => '0'); SOURCE <= (others => '0'); evt_lenght <= (others => '0'); elsif rising_edge(PCIe_clk) then if PCIe_cs = '1' and PCIe_func(3) = '1' AND PCIe_wen = '1' then BX <= PCIe_dti(27 downto 16); SOURCE <= PCIe_dti(11 downto 00); end if; if PCIe_cs = '1' and PCIe_func(4) = '1' AND PCIe_wen = '1' then evt_lenght <= PCIe_dti(23 downto 00); end if; PCIe_dto_local <= (others => '0'); if PCIe_func(3) = '1' then PCIe_dto_local(11 downto 0) <= BX; PCIe_dto_local(27 downto 16) <= SOURCE; elsif PCIe_func(4) = '1' then PCIe_dto_local(23 downto 00) <= evt_lenght; end if; end if; end process; PCIe_dto <= PCIe_dto_local when PCIe_func(4) = '1' or PCIe_func(3) = '1' else PCIe_dto_trg; process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then HD_ena <= '0'; elsif rising_edge(evt_clk) then HD_ena <= evt_run(0); HD_dt(63 downto 56) <= x"50"; HD_dt(55 downto 32) <= trig_nb; HD_dt(31 downto 20) <= BX; HD_dt(19 downto 08) <= SOURCE; HD_dt(07 downto 00) <= x"00"; end if; end process; --******************************************************************************* --************************** << PayLoad >> *********************************** pseudo_reset(0) <= '0' when (end_WC(0) = '1' AND LFF_D = '1') else '1'; process(pseudo_reset(0),evt_clk) begin if pseudo_reset(0) = '0' then PL_ena(0) <= '0'; elsif rising_edge(evt_clk) then if reset = '0' then PL_ena(0) <= '0'; elsif evt_run(2) = '1' and LFF_D = '1' then PL_ena(0) <= '1'; end if; end if; end process; process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then PL_ena(1) <= '0'; elsif rising_edge(evt_clk) then if PL_ena(0) = '1' and LFF_D = '1' and end_WC(0) = '0' then PL_ena(1) <= '1'; elsif end_WC(0) = '1' and LFF_D = '1' then PL_ena(1) <= '0'; end if; end if; end process; process(evt_run(0),evt_clk) begin if evt_run(0) = '1' then PL_dt <= (others => '0'); elsif rising_edge(evt_clk) then if evt_run(2) = '1' and LFF_D = '1' then PL_dt <= rnd_dt_L; end if; end if; end process; --******************************************************************************* --************************** << Trailer >> *********************************** process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then pre_TR <= (others => '0'); TR_ena <= (others => '0'); elsif rising_edge(evt_clk) then if trigger = '1' then pre_TR(63 downto 56) <= x"A0"; if ena_PCIe = '1' then pre_TR(55 downto 53) <= (others => '0'); pre_TR(52 downto 32) <= evt_lenght(23 downto 3); -- value send by PCIe (in bytes) wc used in 63-bit words , it's why we start by bit '3' else pre_TR(55 downto 48) <= "00000000"; pre_TR(47 downto 32) <= wc_rnd; end if; pre_TR(31 downto 00) <= x"00000000"; end if; TR_ena(3 downto 1) <= TR_ena(2 downto 0); TR_ena(0) <= '0'; if evt_run(2) = '1' and end_WC(0) = '1' and LFF_D = '1' then TR_ena(0) <= '1' ; end if; end if; end process; TR_dt(63 downto 32) <= pre_TR(63 downto 32); TR_dt(31 downto 16) <= CRC_val; TR_dt(15 downto 00) <= pre_TR(15 downto 00); --******************************************************************************* --**************************<< Event size >>*********************************** process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then WC_size <= (others => '0'); elsif rising_edge(evt_clk) then if evt_run(0) = '1' then WC_size(20 downto 0) <= pre_TR(52 downto 32); elsif evt_run(2) = '1' and LFF_D = '1' then WC_size <= WC_size - "1"; end if; end if; end process; process(trigger,evt_clk) begin if trigger = '1' then end_WC <=(others => '0'); elsif rising_edge(evt_clk) then end_WC(1) <= '0'; if end_WC(0) = '1' AND LFF_D = '1' AND evt_run(1) = '1' then end_WC(1) <= '1'; end if; if WC_size = "000000000000000000010" AND evt_run(2) = '1' AND LFF_D = '1' then -- WC include Header and trailer (in 64-bit words) end_WC(0) <= '1'; end if; end if; end process; --******************************************************************************* --**************************<< CRC compute >>*********************************** process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then CRC_cmp <= '0'; elsif rising_edge(evt_clk) then if HD_ena = '1' then CRC_reg <= HD_dt; elsif PL_ena(1) = '1' then CRC_reg <= PL_dt; elsif TR_ena(0) = '1' then CRC_reg <= pre_TR; end if; CRC_cmp <= '0'; if HD_ena = '1' OR (PL_ena(1) = '1' AND LFF_D = '1') OR TR_ena(0) = '1' then CRC_cmp <= '1'; end if; end if; end process; crc_cmp_comp:CRC_generator Port map ( D => CRC_reg, CRC_out => CRC_OUT, clk => evt_clk, clear => evt_run(0), enable => CRC_cmp ); CRC_val <= not(CRC_OUT) when crc_error(2) = '1' else CRC_OUT; --********************************************************************************** --******************** << registers output >> ************************************ process(Rst_Evtclk,evt_clk) begin if Rst_Evtclk = '0' then wen_reg <= '0'; uctrl_reg <= '0'; elsif rising_edge(evt_clk) then uctrl_reg <= '0'; if (HD_ena = '1' and hd_error(2) = '0') OR (TR_ena(2) = '1' and tr_error(2) = '0') then uctrl_reg <= '1'; end if; wen_reg <= '0'; if HD_ena = '1' OR (PL_ena(1) = '1' AND LFF_D = '1') OR TR_ena(2) = '1' then wen_reg <= '1'; end if; if HD_ena = '1' then data_reg <= HD_dt; elsif TR_ena(2) = '1' then data_reg <= TR_dt; elsif LFF_D = '1' and evt_run(2) = '1' then data_reg(63 downto 43) <= PL_dt(63 downto 43); if bit_error(2) = '1' then data_reg(42) <= not(PL_dt(42)); else data_reg(42) <= PL_dt(42); end if; data_reg(41 downto 00) <= PL_dt(41 downto 00); end if; end if; end process; wen <= wen_reg; data <= data_reg; uctrl <= not(uctrl_reg); end behavioral;