library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library unisim; use unisim.vcomponents.all; entity cbb_top is generic ( trg_cnt_width : integer := 12; no_delays : integer := 8 ); port ( -- clock inputs CLK40n : in std_logic; CLK40p : in std_logic; CLK120n : in std_logic; CLK120p : in std_logic; -- SCSN I/O to DCS board SCSNINn : in std_logic; SCSNINp : in std_logic; SCSNOUTn : out std_logic; SCSNOUTp : out std_logic; SCSNFEBINn : in std_logic; -- pass through to TLMU SCSNFEBINp : in std_logic; SCSNFEBOUTn : out std_logic; SCSNFEBOUTp : out std_logic; -- SCSN I/O to TLMU IF17x_SCSN_IN : in std_logic; IF17x_SCSN_OUT : out std_logic; -- TTCrx L1ACCEPTn : in std_logic; L1ACCEPTp : in std_logic; B_Channel : in std_logic; IO_C0 : in std_logic; -- SOR/EOR signal from DCS board -- TTCex A_ECL : out std_logic; B_ECL : out std_logic; BC_ECL : out std_logic; -- PIM PIMLINK : out std_logic_vector(2 downto 0); -- GTU BUSY : in std_logic; -- TLMU interface CLK40T : out std_logic; RESET_TOFFPGA : out std_logic; CNRRL : out std_logic; -- enable for TLMU interface -- used for primary/backup switching SPA : out std_logic; -- spare: used for SOR/EOR signalling -- TLMU trigger inputs TLMU_trg : in std_logic_vector(7 downto 0); -- input from CB-A/C CB_A : in std_logic; CB_C : in std_logic; -- Front-Panel LEDs LED1 : out std_logic; LED2 : out std_logic; -- unused CB_TOF : out std_logic; -- ??? SPB : out std_logic; -- spare to TLMU S1_IN1 : in std_logic; -- spare I/O to TLMU S1_OUT1 : out std_logic; S1_OUT2 : out std_logic; S2_OUT1 : out std_logic; S2_OUT2 : out std_logic ); end cbb_top; architecture default of cbb_top is -- Clocks and Reset signal CLK120_in : std_logic; signal clk40 : std_logic; signal clk40_90 : std_logic; signal clk40_180 : std_logic; signal clk40_ps : std_logic; signal clk40_ps_180 : std_logic; signal clk80 : std_logic; signal clk_scsn : std_logic; signal clk_scsn_180 : std_logic; signal clk160 : std_logic; signal rst_request : std_logic; -- asynchr. reset request signal rst_request_n : std_logic; signal rst40 : std_logic; signal rst40_n : std_logic; signal rst40_tlmu : std_logic; signal rst80 : std_logic; signal rst_scsn : std_logic; signal rst_scsn_n : std_logic; signal rst160 : std_logic; -- I/O signal led1_i : std_logic; signal led2_i : std_logic; -- SCSN signal scsn_in : std_logic; signal scsn_out : std_logic; signal scsn_feb_in : std_logic; signal scsn_feb_out : std_logic; -- SCSN bus signal scsn_bus_addr : std_logic_vector(15 downto 0); signal scsn_bus_din : std_logic_vector(31 downto 0); signal scsn_bus_dout : std_logic_vector(31 downto 0); signal scsn_bus_we : std_logic; signal scsn_bus_req : std_logic; signal scsn_bus_ack : std_logic; signal scsn_bus_din_i : std_logic_vector(31 downto 0); -- bus registers signal scsn_bus_din_ta : std_logic_vector(31 downto 0); signal scsn_bus_din_ramcnt : std_logic_vector(31 downto 0); signal scsn_bus_din_lut : std_logic_vector(31 downto 0); signal scsn_bus_din_bctrg : std_logic_vector(31 downto 0); signal scsn_bus_din_tlrec : std_logic_vector(31 downto 0); signal scsn_bus_dout_r : std_logic_vector(31 downto 0); signal scsn_bus_addr_r : std_logic_vector(15 downto 0); signal scsn_bus_we_r : std_logic; signal scsn_bus_we_ramcnt : std_logic; signal scsn_bus_we_lut : std_logic; signal scsn_bus_we_ta : std_logic; signal scsn_bus_we_bctrg : std_logic; signal scsn_bus_we_tlrec : std_logic; signal scsn_bus_req_ramcnt : std_logic; signal scsn_bus_req_lut : std_logic; signal scsn_bus_req_ta : std_logic; signal scsn_bus_req_bctrg : std_logic; signal scsn_bus_req_tlrec : std_logic; signal scsn_bus_ack_i : std_logic; signal scsn_bus_ack_ramcnt : std_logic; signal scsn_bus_ack_lut : std_logic; signal scsn_bus_ack_ta : std_logic; signal scsn_bus_ack_bctrg : std_logic; signal scsn_bus_ack_tlrec : std_logic; -- TTC input (from TTCrx) signal ttc_a_channel : std_logic; signal ttc_b_channel : std_logic; signal ttc_a_channel_r : std_logic; -- trigger inputs/requests signal cba_in : std_logic; signal cbc_in : std_logic; signal cba_sampling : std_logic_vector(1 downto 0); signal cba_sampling_r : std_logic_vector(1 downto 0); signal cbc_sampling : std_logic_vector(1 downto 0); signal cbc_sampling_r : std_logic_vector(1 downto 0); signal cba_lut : std_logic_vector(1 downto 0); signal cbc_lut : std_logic_vector(1 downto 0); signal cba_lut_r : std_logic_vector(1 downto 0); signal cbc_lut_r : std_logic_vector(1 downto 0); signal tlmu_trg_r : std_logic_vector(7 downto 0); signal lut_trg_r : std_logic_vector(1 downto 0); signal pt_req : std_logic; signal pt_req_r : std_logic; signal pt_trg_src : std_logic_vector(15 downto 0); type pt_trg_array is array(15 downto 0) of std_logic_vector(no_delays-1 downto 0); signal pt_trg_aligned : pt_trg_array; signal pt_trg_ctb : std_logic_vector(15 downto 0); signal pt_trg_ctb_r : std_logic_vector(15 downto 0); -- LUT signal pattern_cba : std_logic_vector(1 downto 0); signal pattern_cbc : std_logic_vector(1 downto 0); signal pattern_tof : std_logic_vector(4 downto 0); signal pattern_match_cba : std_logic; signal pattern_match_cbc : std_logic; signal pattern_match_tof : std_logic; signal lut_mon : std_logic_vector(12 downto 0); signal lut_trg : std_logic_vector(1 downto 0); -- trigger pulses signal trg_bc : std_logic; signal rnd_trg : std_logic; signal pt_to_sm : std_logic; signal l0_to_sm : std_logic; signal l1_to_sm : std_logic; signal l0_ctb : std_logic; signal l0_to_ctp : std_logic; signal l0_to_ctp_r : std_logic; -- to trigger generation signal pt_pre_gen : std_logic; signal pt_ctp_pre_gen : std_logic; signal l0_pre_gen : std_logic; signal l1_pre_gen : std_logic; -- output to TTCex signal a_channel_out : std_logic; signal a_channel_out_r : std_logic_vector(1 downto 0); signal a_channel_out_masked : std_logic; signal b_channel_out : std_logic; signal a_channel_ttcex_trggen : std_logic; signal ttcex_ctrl : std_logic_vector(1 downto 0); signal ttcex_status : std_logic_vector(9 downto 0); -- GTU signal gtu_busy : std_logic; signal gtu_busy_ddr : std_logic_vector(1 downto 0); signal gtu_busy_ctrl : std_logic_vector(3 downto 0); -- output to PIM signal pim_out : std_logic_vector(2 downto 0); signal tin1_out : std_logic; signal tin1_opt_code : std_logic_vector(1 downto 0); signal tin2_out : std_logic; signal tin2_opt_code : std_logic_vector(1 downto 0); -- configuration settings signal cbb_ctrl : std_logic_vector(1 downto 0); signal ptrg_to_l0_acc : std_logic_vector(trg_cnt_width-1 downto 0); signal ptrg_to_l0_send : std_logic_vector(trg_cnt_width-1 downto 0); signal ptrg_to_l1_acc : std_logic_vector(trg_cnt_width-1 downto 0); signal ptrg_to_l1_send : std_logic_vector(trg_cnt_width-1 downto 0); signal ptrg_to_idle : std_logic_vector(trg_cnt_width-1 downto 0); signal ptrg_to_idle_nol0 : std_logic_vector(trg_cnt_width-1 downto 0); signal ptrg_to_idle_nol1 : std_logic_vector(trg_cnt_width-1 downto 0); signal ptrg_to_l0_delay : std_logic_vector(trg_cnt_width-1 downto 0); signal a_channel_out_dis : std_logic; signal pt_trg_mask : std_logic_vector(15 downto 0); signal pt_trg_mask_r : std_logic_vector(15 downto 0); signal pt_trg_delays : std_logic_vector(63 downto 0); type pt_trg_delays_array is array(15 downto 0) of std_logic_vector(3 downto 0); signal pt_trg_delays_r : pt_trg_delays_array; -- std_logic_vector(63 downto 0); signal rnd_trg_thr : std_logic_vector(31 downto 0); signal tana_trg_mask : std_logic_vector(31 downto 0); signal tana_arm : std_logic; signal tana_postcnt : std_logic_vector(8 downto 0); -- testing only signal clk_counter : std_logic_vector(27 downto 0); signal zero : std_logic_vector(31 downto 0); signal clk_tick : std_logic; signal ttc_channel_ctrl : std_logic_vector(15 downto 0); signal ttc_channel_ctrl_r : std_logic_vector(15 downto 0); signal ttc_pulse_cnt : std_logic_vector(15 downto 0); -- BC signal bc : std_logic_vector(11 downto 0); signal bc_rst_val : std_logic_vector(11 downto 0) := std_logic_vector(to_unsigned(0, 12)); signal bc_max_val : std_logic_vector(11 downto 0) := std_logic_vector(to_unsigned(3563, 12)); signal bc_l0 : std_logic_vector(11 downto 0); signal bc_msg : std_logic_vector(11 downto 0); signal bc_offset : std_logic_vector(11 downto 0); -- TTC receiver signal l0_ttcrx : std_logic; signal l1_ttcrx : std_logic; signal l2a_ttcrx : std_logic; signal l2r_ttcrx : std_logic; signal l1m_ttcrx : std_logic; signal l2m_ttcrx : std_logic; signal sod_ttcrx : std_logic; signal eod_ttcrx : std_logic; signal rst_bunch_counter_ttcrx : std_logic; signal rst_event_counter_ttcrx : std_logic; signal l1_message_ttcrx : std_logic_vector(59 downto 0); signal l1_message_rdy_ttcrx : std_logic; signal l2a_message_ttcrx : std_logic_vector(95 downto 0); signal l2r_message_ttcrx : std_logic_vector(11 downto 0); -- from emulator signal pt_emu : std_logic; signal pt_ctp : std_logic; signal l0_emu : std_logic; signal l1_emu : std_logic; -- trigger counters signal ram_cnt_clr : std_logic; signal ram_cnt_capt : std_logic; signal trg_cnt_clr : std_logic; signal trg_cnt_l0 : std_logic_vector(15 downto 0); signal trg_cnt_l1 : std_logic_vector(15 downto 0); signal trg_cnt_l2a : std_logic_vector(15 downto 0); signal trg_cnt_l2r : std_logic_vector(15 downto 0); signal ram_cnt_input : std_logic_vector(127 downto 0); signal clk_cba_prebuf: std_logic; signal clk_cbc_prebuf: std_logic; signal clk_cba: std_logic; signal clk_cbc: std_logic; signal tlmu_trg_a_c : std_logic_vector(7 downto 0); signal tlmu_trg_nota_c : std_logic_vector(7 downto 0); signal tlmu_trg_a_notc : std_logic_vector(7 downto 0); signal tlmu_trg_nota_notc : std_logic_vector(7 downto 0); signal cba_coinc_cnt_en : std_logic_vector(7 downto 0); signal cbc_coinc_cnt_en : std_logic_vector(7 downto 0); signal coinc_cnt_ctrl : std_logic_vector(31 downto 0); signal ac_short: std_logic_vector(1 downto 0); signal ac_short_in: std_logic_vector(1 downto 0); signal ac_long: std_logic_vector(1 downto 0); signal ac_allow: std_logic_vector(1 downto 0); type ac_in_array is array(1 downto 0) of std_logic_vector(6 downto 0); signal ac_in_r: ac_in_array; begin -- default -- -- dummy signal & mappings zero <= (others => '0'); rst_request <= not rst_request_n; process (clk40) begin if rst40 = '1' then clk_tick <= '0'; elsif rising_edge(clk40) then clk_tick <= clk_counter(26); end if; end process; CNRRL <= cbb_ctrl(0); -- enable signal for TLMU LVDS buffers SPB <= cbb_ctrl(0); -- enable signal for TLMU LVDS buffers -- -- clock & reset generation clock_generation : entity work.clock_gen port map ( CLK120_N => CLK120n, CLK120_P => CLK120p, CLK40_N => CLK40n, CLK40_P => CLK40p, rst_req => rst_request, clk40 => clk40, clk40_90 => clk40_90, clk40_180 => clk40_180, clk80 => clk80, clk120 => open, -- clk_scsn, clk120_180 => open, -- clk_scsn_180, clk160 => clk160, clk120dcs => open, ps_adjust => ttcex_ctrl(1 downto 0), ps_state => ttcex_status(9 downto 0), clk40_ps => clk40_ps, clk40_ps_180 => clk40_ps_180, rst40 => rst40, rst40_n => rst40_n, rst80 => rst80, rst120 => open, -- rst_scsn, rst120_n => open, -- rst_scsn_n, rst160 => rst160 ); clk_scsn <= clk40; clk_scsn_180 <= clk40_180; rst_scsn <= rst40; rst_scsn_n <= rst40_n; rst40_tlmu <= rst40 when cbb_ctrl(1) = '0' else rst40_n; -- SCSN forwarding scsn_feb_out <= IF17x_SCSN_IN; IF17x_SCSN_OUT <= scsn_feb_in; -- -- SCSN interface scsn_inst : entity work.mcm_network_interface port map ( ser0_din => scsn_in, ser0_dout => scsn_out, ser1_din => '0', ser1_dout => open, bus_din => scsn_bus_din, bus_dout => scsn_bus_dout, bus_addr => scsn_bus_addr, bus_req => scsn_bus_req, bus_we => scsn_bus_we, bus_ack => scsn_bus_ack, chipRST_n => rst_request_n, reset_n => rst_scsn_n, clk => clk_scsn, clk_buf => clk_scsn, clk_buf_disable => open ); -- -- System configuration -- connected to SCSN bus interface sys_config0: entity work.sys_config generic map ( trg_cnt_width => trg_cnt_width ) port map( clk => clk_scsn, rst => rst_scsn, cbb_ctrl => cbb_ctrl, ttc_channel_ctrl => ttc_channel_ctrl, ttc_pulse_cnt => ttc_pulse_cnt, ram_cnt_clr => ram_cnt_clr, ram_cnt_capt => ram_cnt_capt, trg_cnt_clr => trg_cnt_clr, trg_cnt_l0 => trg_cnt_l0, trg_cnt_l1 => trg_cnt_l1, trg_cnt_l2a => trg_cnt_l2a, trg_cnt_l2r => trg_cnt_l2r, ptrg_to_l0_acc => ptrg_to_l0_acc, ptrg_to_l0_send => ptrg_to_l0_send, ptrg_to_l1_acc => ptrg_to_l1_acc, ptrg_to_l1_send => ptrg_to_l1_send, ptrg_to_idle => ptrg_to_idle, ptrg_to_idle_nol0 => ptrg_to_idle_nol0, ptrg_to_idle_nol1 => ptrg_to_idle_nol1, ptrg_to_l0_delay => ptrg_to_l0_delay, a_channel_out_dis => a_channel_out_dis, gtu_busy_ctrl => gtu_busy_ctrl, pt_trg_mask => pt_trg_mask, pt_trg_delays => pt_trg_delays, cba_sampling => cba_sampling, cbc_sampling => cbc_sampling, pattern_cba => pattern_cba, pattern_cbc => pattern_cbc, pattern_tof => pattern_tof, bc_offset => bc_offset, bc_l0 => bc_l0, bc_msg => bc_msg, bc_rst_val => bc_rst_val, tin1_opt_code => tin1_opt_code, tin2_opt_code => tin2_opt_code, tim_ana_trg_mask => tana_trg_mask, tim_ana_arm => tana_arm, tim_ana_postcnt => tana_postcnt, rnd_trg_thr => rnd_trg_thr, coinc_cnt_ctrl => coinc_cnt_ctrl, ttcex_ctrl => ttcex_ctrl, ttcex_status => ttcex_status, -- syscfg_addr => scsn_bus_addr_r, -- syscfg_wdata => scsn_bus_dout_r, -- syscfg_rdata => scsn_bus_din_i, -- syscfg_req => scsn_bus_req_r, -- syscfg_ack => scsn_bus_ack_i, -- syscfg_we => scsn_bus_we_r, scsn_addr => scsn_bus_addr, scsn_dout => scsn_bus_dout, scsn_din => scsn_bus_din, scsn_req => scsn_bus_req, scsn_ack => scsn_bus_ack, scsn_we => scsn_bus_we, scsn_dout_com => scsn_bus_dout_r, scsn_addr_com => scsn_bus_addr_r, scsn_we_ta => scsn_bus_we_ta, scsn_req_ta => scsn_bus_req_ta, scsn_ack_ta => scsn_bus_ack_ta, scsn_din_ta => scsn_bus_din_ta, scsn_we_ramcnt => scsn_bus_we_ramcnt, scsn_req_ramcnt => scsn_bus_req_ramcnt, scsn_ack_ramcnt => scsn_bus_ack_ramcnt, scsn_din_ramcnt => scsn_bus_din_ramcnt, scsn_we_lut => scsn_bus_we_lut, scsn_req_lut => scsn_bus_req_lut, scsn_ack_lut => scsn_bus_ack_lut, scsn_din_lut => scsn_bus_din_lut, scsn_we_bctrg => scsn_bus_we_bctrg, scsn_req_bctrg => scsn_bus_req_bctrg, scsn_ack_bctrg => scsn_bus_ack_bctrg, scsn_din_bctrg => scsn_bus_din_bctrg, scsn_we_tlrec => scsn_bus_we_tlrec, scsn_req_tlrec => scsn_bus_req_tlrec, scsn_ack_tlrec => scsn_bus_ack_tlrec, scsn_din_tlrec => scsn_bus_din_tlrec ); -- -- TTC input process (clk40) begin if rising_edge(clk40) then if rst40 = '1' then ttc_pulse_cnt <= (others => '0'); elsif ttc_a_channel = '1' then ttc_pulse_cnt <= ttc_pulse_cnt + '1' ; end if; ttc_a_channel_r <= ttc_a_channel; end if; end process; -- -- CB-A/C sampling cba_sample: entity work.cb_ac_sample port map( clk40 => clk40, rst40 => rst40, clk_s => clk160, rst_s => rst160, cb_sample_par => cba_sampling_r, cb_in => cba_in, cb_out => cba_lut ); cbc_sample: entity work.cb_ac_sample port map( clk40 => clk40, rst40 => rst40, clk_s => clk160, rst_s => rst160, cb_sample_par => cbc_sampling_r, cb_in => cbc_in, cb_out => cbc_lut ); process (clk40) begin if rst40 = '1' then cba_sampling_r <= (others => '0'); cbc_sampling_r <= (others => '0'); cba_lut_r <= (others => '0'); cbc_lut_r <= (others => '0'); elsif rising_edge(clk40) then cba_sampling_r <= cba_sampling; cbc_sampling_r <= cbc_sampling; cba_lut_r <= cba_lut; cbc_lut_r <= cbc_lut; end if; end process; -- -- TLMU input process (clk40) begin if rst40 = '1' then tlmu_trg_r <= (others => '0'); elsif rising_edge(clk40) then tlmu_trg_r <= TLMU_trg; end if; end process; -- -- GTU busy input process (clk40) begin if rst40 = '1' then gtu_busy <= '1'; elsif rising_edge(clk40) then if gtu_busy_ctrl(0) = '1' then gtu_busy <= gtu_busy_ddr(1); else gtu_busy <= gtu_busy_ddr(0); end if; end if; end process; -- -- LUT trg_lut_inst: entity work.trg_lut port map( clk40 => clk40, rst40 => rst40, tlmu_in => pt_trg_ctb(9 downto 2), -- tlmu_trg_r, cbc_in => pt_trg_ctb(13 downto 12), -- cbc_lut, cba_in => pt_trg_ctb(15 downto 14), -- cba_lut, bc_in => pt_trg_ctb(10), pattern_tof => pattern_tof, pattern_cba => pattern_cba, pattern_cbc => pattern_cbc, pattern_match_tof => pattern_match_tof, pattern_match_cba => pattern_match_cba, pattern_match_cbc => pattern_match_cbc, lut_mon => lut_mon, trigger => lut_trg, scsn_addr => scsn_bus_addr_r, scsn_din => scsn_bus_dout_r, scsn_we => scsn_bus_we_lut, scsn_req => scsn_bus_req_lut, scsn_dout => scsn_bus_din_lut, scsn_ack => scsn_bus_ack_lut ); process (clk40) begin if rst40 = '1' then lut_trg_r <= (others => '0'); pt_trg_mask_r <= (others => '0'); elsif rising_edge(clk40) then lut_trg_r <= lut_trg; pt_trg_mask_r <= pt_trg_mask; end if; end process; -- -- pretrigger source alignment pt_trg_src <= cba_lut & cbc_lut & rnd_trg & trg_bc & tlmu_trg & lut_trg; pt_delay_gen : for i in 0 to 15 generate process (clk40) begin if rst40 = '1' then pt_trg_aligned(i) <= (others => '0'); pt_trg_delays_r(i) <= (others => '0'); elsif rising_edge(clk40) then pt_trg_delays_r(i) <= pt_trg_delays(4*i+3 downto 4*i); pt_trg_aligned(i)(0) <= pt_trg_src(i); tlmu_delay_shift : for ii in 1 to 7 loop pt_trg_aligned(i)(ii) <= pt_trg_aligned(i)(ii-1); end loop; end if; end process; end generate; pt_delay_mux : for i in 0 to 15 generate with pt_trg_delays_r(i) select pt_trg_ctb(i) <= pt_trg_src(i) when x"0", pt_trg_aligned(i)(0) when x"1", pt_trg_aligned(i)(1) when x"2", pt_trg_aligned(i)(2) when x"3", pt_trg_aligned(i)(3) when x"4", pt_trg_aligned(i)(4) when x"5", pt_trg_aligned(i)(5) when x"6", pt_trg_aligned(i)(6) when x"7", pt_trg_src(i) or pt_trg_aligned(i)(0) when x"8", pt_trg_aligned(i)(0) or pt_trg_aligned(i)(1) when x"9", pt_trg_aligned(i)(1) or pt_trg_aligned(i)(2) when x"a", pt_trg_aligned(i)(2) or pt_trg_aligned(i)(3) when x"b", pt_trg_aligned(i)(3) or pt_trg_aligned(i)(4) when x"c", pt_trg_aligned(i)(4) or pt_trg_aligned(i)(5) when x"d", pt_trg_aligned(i)(5) or pt_trg_aligned(i)(6) when x"e", pt_trg_aligned(i)(6) or pt_trg_aligned(i)(7) when x"f", pt_trg_src(i) when others; end generate; -- -- Pretrigger request -- delaying direct trigger inputs to be aligned with LUT trigger pt_req <= '1' when ((pt_trg_ctb_r(15 downto 2) & pt_trg_ctb(1 downto 0)) and pt_trg_mask_r) /= x"0000" else '0'; process (clk40) begin if rst40 = '1' then pt_req_r <= '0'; pt_trg_ctb_r <= (others => '0'); elsif rising_edge(clk40) then pt_req_r <= pt_req; pt_trg_ctb_r <= pt_trg_ctb; end if; end process; -- -- trigger emulation (insert missing pretrigger) trg_emu : entity work.trg_emulator generic map ( cnt_width => trg_cnt_width ) port map ( clk40 => clk40, rst40 => rst40, pt_in => pt_req, l0_in => l0_ttcrx, l1_in => l1_ttcrx, pt_out => pt_emu, pt_ctp => pt_ctp, l0_out => l0_emu, l1_out => l1_emu, trg_delay => ptrg_to_l0_delay ); process (clk40) begin if rising_edge(clk40) then ttc_channel_ctrl_r <= ttc_channel_ctrl; end if; end process; pt_pre_gen <= pt_req_r when ttc_channel_ctrl_r(8) = '0' else pt_emu; pt_ctp_pre_gen <= pt_req_r when ttc_channel_ctrl_r(8) = '0' else pt_ctp; l0_pre_gen <= l0_ttcrx when ttc_channel_ctrl_r(8) = '0' else l0_emu; l1_pre_gen <= l1_ttcrx when ttc_channel_ctrl_r(8) = '0' else l1_emu; l0_to_ctp <= pt_req_r when ttc_channel_ctrl_r(9) = '0' else l0_ctb; -- -- trigger sequence generation trg_gen : entity work.trg_generator generic map ( cnt_width => trg_cnt_width ) port map ( clk40 => clk40, rst40 => rst40, pt_in => pt_pre_gen, pt_ctp => pt_ctp_pre_gen, l0_in => l0_pre_gen, l1_in => l1_pre_gen, pt_to_sm => pt_to_sm, l0_to_sm => l0_to_sm, l1_to_sm => l1_to_sm, l0_to_ctp => l0_ctb, ptrg_to_l0_acc => ptrg_to_l0_acc, ptrg_to_l0_send => ptrg_to_l0_send, ptrg_to_l1_acc => ptrg_to_l1_acc, ptrg_to_l1_send => ptrg_to_l1_send, ptrg_to_idle_nol0 => ptrg_to_idle_nol0, ptrg_to_idle_nol1 => ptrg_to_idle_nol1, ptrg_to_idle => ptrg_to_idle ); a_channel_ttcex_trggen <= (pt_to_sm or l0_to_sm or l1_to_sm) when ttc_channel_ctrl(4) = '0' else (l0_ttcrx or l1_ttcrx); -- -- random trigger pulse generator rnd_trg_inst : entity work.random_pulser port map ( clk40 => clk40, rst40 => rst40, thr => rnd_trg_thr, pulse => rnd_trg ); -- -- output to TTCex a_channel_out_masked <= a_channel_ttcex_trggen and not a_channel_out_dis; -- a_channel_out <= ttc_channel_ctrl_r(1) when ttc_channel_ctrl_r(0) = '0' else a_channel_out_masked; -- b_channel_out <= ttc_channel_ctrl_r(3) when ttc_channel_ctrl_r(2) = '1' else '1'; reg_a_out : process (clk40) begin if rst40 = '1' then a_channel_out <= '0'; elsif rising_edge(clk40) then if ttc_channel_ctrl_r(0) = '0' then a_channel_out <= ttc_channel_ctrl_r(1); else a_channel_out_r(1) <= a_channel_out_masked; a_channel_out_r(0) <= a_channel_out_r(1); a_channel_out <= a_channel_out_r(0); end if; end if; end process; reg_b_out : process (clk40) begin if rst40 = '1' then b_channel_out <= '1'; elsif rising_edge(clk40) then if ttc_channel_ctrl_r(2) = '1' then b_channel_out <= ttc_channel_ctrl_r(3); else b_channel_out <= '1'; end if; end if; end process; process (clk40) begin if rst40 = '1' then l0_to_ctp_r <= '0'; elsif rising_edge(clk40) then l0_to_ctp_r <= l0_to_ctp; end if; end process; -- -- output to CTP via PIM tin1_inst : entity work.ctp_tin generic map ( signature => conv_std_logic_vector(83, 7) ) port map ( clk40 => clk40, rst40 => rst40, opt_code => tin1_opt_code, trg_ctb => l0_to_ctp, rnd_trg => rnd_trg, trg_out => tin1_out ); tin2_inst : entity work.ctp_tin generic map ( signature => conv_std_logic_vector(83, 7) ) port map ( clk40 => clk40, rst40 => rst40, opt_code => tin2_opt_code, trg_ctb => tlmu_trg(1), -- tlmu_trg(1) only for testing!!! rnd_trg => rnd_trg, trg_out => tin2_out ); pim_out(0) <= clk40; pim_out(1) <= tin1_out xor clk40; pim_out(2) <= tin2_out xor clk40; -- -- debugging process (clk_scsn_180) begin if (clk_scsn_180'event and clk_scsn_180 = '1') then clk_counter <= clk_counter + 1; end if; if (clk_counter(26) = '1') then led2_i <= '1'; else led2_i <= '0'; end if; end process; -- -- TTC receiver ttc_receiver0 : entity work.ttc_receiver_top port map ( -- general signals clk => clk40, reset_n => rst40_n, -- -- ttc event logging & communication -- clk_ppc : in std_logic; -- ttc_events_addr : in std_logic_vector(9 downto 0); -- ttc_events_data : out std_logic_vector(17 downto 0); -- ttc_events_log_ctrl : in std_logic_vector(19 downto 0); -- ttc_events_log_mon : out std_logic_vector(15 downto 0); -- ttc_events_log_halt : in std_logic; channelA => ttc_a_channel, channelB => ttc_b_channel, -- triggers l0trigger => l0_ttcrx, l1trigger => l1_ttcrx, l2atrigger => l2a_ttcrx, l2rtrigger => l2r_ttcrx, -- strobes l1m_strobe => l1m_ttcrx, l2m_strobe => l2m_ttcrx, -- sod/eod sod => sod_ttcrx, eod => eod_ttcrx, sod_eod_debug_up => open, -- resets reset_bc => rst_bunch_counter_ttcrx, reset_ec => rst_event_counter_ttcrx, error_ttc_rcv => open, -- message outputs l1_message => l1_message_ttcrx, l1_message_rdy => l1_message_rdy_ttcrx, l2a_message => l2a_message_ttcrx, l2r_message => l2r_message_ttcrx ); -- BC -- reset comes via TTC process (clk40) begin if rst40 = '1' then bc <= (others => '0'); bc_offset <= (others => '0'); bc_l0 <= (others => '0'); bc_msg <= (others => '0'); elsif rising_edge(clk40) then if rst_bunch_counter_ttcrx = '1' then bc <= bc_rst_val; elsif bc = bc_max_val then bc <= (others => '0'); else bc <= bc + '1'; end if; -- capture BC at L0 if l0_ttcrx = '1' then bc_l0 <= bc; end if; -- determine offset in BC w.r.t. the one sent by CTP if l2a_ttcrx = '1' then -- L2a message valid after L2a seen bc_msg <= l2a_message_ttcrx(95 downto 84); bc_offset <= bc_l0 - l2a_message_ttcrx(95 downto 84); end if; end if; end process; -- -- BC trigger bc_trigger_inst : entity work.bc_trigger port map ( clk40 => clk40, rst40 => rst40, clk_scsn => clk_scsn, rst_scsn => rst_scsn, scsn_addr => scsn_bus_addr_r, scsn_din => scsn_bus_dout_r, scsn_dout => scsn_bus_din_bctrg, scsn_req => scsn_bus_req_bctrg, scsn_ack => scsn_bus_ack_bctrg, scsn_we => scsn_bus_we_bctrg, bc => bc, trg => trg_bc ); -- -- Temporary trigger counters process(clk40) begin if rising_edge(clk40) then if rst40 = '1' or trg_cnt_clr = '1' then trg_cnt_l0 <= (others => '0'); trg_cnt_l1 <= (others => '0'); trg_cnt_l2a <= (others => '0'); trg_cnt_l2r <= (others => '0'); else if l0_ttcrx = '1' then trg_cnt_l0 <= trg_cnt_l0 + '1'; end if; if l1_ttcrx = '1' then trg_cnt_l1 <= trg_cnt_l1 + '1'; end if; if l2a_ttcrx = '1' then trg_cnt_l2a <= trg_cnt_l2a + '1'; end if; if l2r_ttcrx = '1' then trg_cnt_l2r <= trg_cnt_l2r + '1'; end if; end if; end if; end process; -- Timing Coinc Counters cba_coinc_cnt: entity del_coinc_cnt_en generic map ( depth => 8, ref_offset => 6 ) port map ( clk40 => clk40, rst40 => rst40, enable => coinc_cnt_ctrl(0), ref =>trg_bc, sig => ac_short(0), cnt_en=>cba_coinc_cnt_en(7 downto 0) ); cbc_coinc_cnt: entity del_coinc_cnt_en generic map ( depth => 8, ref_offset => 6 ) port map ( clk40 => clk40, rst40 => rst40, enable => coinc_cnt_ctrl(1), ref =>trg_bc, sig => ac_short(1), cnt_en=>cbc_coinc_cnt_en(7 downto 0) ); ac_short_in <= pt_trg_ctb_r(13) & pt_trg_ctb_r(15); ac_short_gen : for i in 0 to 1 generate process (clk40) begin if rst40 = '1' then ac_in_r(i) <= (others => '0'); elsif rising_edge(clk40) then ac_in_r(i) <= ac_in_r(i)(5 downto 0) & ac_short_in(i); end if; end process; ac_long(i) <= ac_short_in(i) or ac_in_r(i)(0) or ac_in_r(i)(1) or ac_in_r(i)(2) or ac_in_r(i)(3) or ac_in_r(i)(4) or ac_in_r(i)(5) or ac_in_r(i)(6); process (clk40) begin if rst40 = '1' then ac_allow(i) <= '0'; elsif rising_edge(clk40) then ac_allow(i) <= not ac_long(i); end if; ac_short(i) <= ac_short_in(i) and ac_allow(i); end process; end generate; -- -- counters ram_cnt_inst : entity work.ram_cnt port map ( clk40 => clk40, rst40 => rst40, capture => ram_cnt_capt, clear => ram_cnt_clr, inputs => ram_cnt_input, input_mask => x"ffffffffffffffffffffffffffffffff", scsn_addr => scsn_bus_addr_r, scsn_dout => scsn_bus_din_ramcnt, scsn_req => scsn_bus_req_ramcnt, scsn_ack => scsn_bus_ack_ramcnt ); ram_cnt_input(3 downto 0) <= l1_ttcrx & l0_ttcrx & '0' & "1"; ram_cnt_input(7 downto 4) <= ttc_b_channel & ttc_a_channel & rst_bunch_counter_ttcrx & rst_event_counter_ttcrx; ram_cnt_input(11 downto 8) <= l2r_ttcrx & l2a_ttcrx & l1_ttcrx & l0_ttcrx ; ram_cnt_input(15 downto 12) <= cba_in & cba_in & '0' & '0'; ram_cnt_input(19 downto 16) <= lut_mon(3 downto 0); ram_cnt_input(23 downto 20) <= lut_mon(7 downto 4); ram_cnt_input(27 downto 24) <= tlmu_trg_r(3 downto 0); ram_cnt_input(31 downto 28) <= tlmu_trg_r(7 downto 4); ram_cnt_input(35 downto 32) <= '0' & pattern_match_tof & pattern_match_cbc & pattern_match_cba; ram_cnt_input(39 downto 36) <= '0' & pt_pre_gen & l0_pre_gen & l1_pre_gen; ram_cnt_input(43 downto 40) <= '0' & pt_emu & l0_emu & l1_emu; ram_cnt_input(47 downto 44) <= "00" & '1' & a_channel_out_masked; ram_cnt_input(51 downto 48) <= l0_to_ctp & pim_out(1) & rnd_trg & trg_bc; ram_cnt_input(55 downto 52) <= l1_to_sm & l0_to_sm & pt_to_sm & a_channel_ttcex_trggen; ram_cnt_input(59 downto 56) <= '0' & pt_req & lut_trg_r(0) & lut_trg_r(1); ram_cnt_input(63 downto 60) <= (clk_counter(26) and not clk_tick) & clk_counter(18) & clk_counter(12) & clk_counter(6); ram_cnt_input(71 downto 64) <= tlmu_trg_a_c; ram_cnt_input(79 downto 72) <= tlmu_trg_a_notc; ram_cnt_input(87 downto 80) <= tlmu_trg_nota_c; ram_cnt_input(95 downto 88) <= tlmu_trg_nota_notc; ram_cnt_input(103 downto 96) <= cba_coinc_cnt_en; ram_cnt_input(111 downto 104) <= cbc_coinc_cnt_en; ram_cnt_input(127 downto 112) <= (others => '1'); tlmu_trg_a_c <= pt_trg_ctb_r(9 downto 2) when pt_trg_ctb_r(10) = '1' and pattern_match_cba = '1' and pattern_match_cbc = '1' else x"00"; tlmu_trg_a_notc <= pt_trg_ctb_r(9 downto 2) when pt_trg_ctb_r(10) = '1' and pattern_match_cba = '1' and pattern_match_cbc = '0' else x"00"; tlmu_trg_nota_c <= pt_trg_ctb_r(9 downto 2) when pt_trg_ctb_r(10) = '1' and pattern_match_cba = '0' and pattern_match_cbc = '1' else x"00"; tlmu_trg_nota_notc <= pt_trg_ctb_r(9 downto 2) when pt_trg_ctb_r(10) = '1' and pattern_match_cba = '0' and pattern_match_cbc = '0' else x"00"; -- -- Timing analyzer tim_ana : entity work.timing_analyzer port map ( clk40 => clk40, rst40 => rst40, clk_scsn => clk_scsn, rst_scsn => rst_scsn, signals(0) => l0_ttcrx, signals(1) => l1_ttcrx, signals(2) => l0_to_ctp, signals(3) => tin1_out, signals(4) => l0_ctb, signals(5) => pt_to_sm, signals(6) => l0_to_sm, signals(7) => l1_to_sm, signals(8) => pt_req, signals(9) => pt_trg_ctb_r(10), -- trg_bc, --signals(10) => pt_trg_ctb_r(11), -- rnd_trg, signals(18 downto 11) => pt_trg_ctb_r(9 downto 2), -- tlmu_trg, signals(20 downto 19) => pt_trg_ctb(1 downto 0), -- lut_trg, signals(21) => pt_emu, signals(22) => pt_ctp, signals(23) => l0_emu, signals(24) => l1_emu, --signals(25) => a_channel_out, signals(27 downto 26) => pt_trg_ctb_r(15 downto 14), -- cba_lut_r, signals(29 downto 28) => pt_trg_ctb_r(13 downto 12), -- cbc_lut_r, signals(30) => gtu_busy, -- temporary signals(10) => ac_short(0), signals(25) => tlmu_trg_a_c(0), -- signals(11 downto 0) => scsn_bus_dout(11 downto 0), -- signals(23 downto 12) => scsn_bus_addr(11 downto 0), -- signals(24) => scsn_bus_req, -- signals(25) => scsn_bus_ack, -- signals(26) => scsn_bus_we, -- signals(27) => scsn_bus_we_bctrg, -- signals(30 downto 28) => "000", trg_mask => tana_trg_mask(30 downto 0), arm => tana_arm, post_cnt => tana_postcnt, scsn_addr => scsn_bus_addr_r, scsn_req => scsn_bus_req_ta, scsn_data => scsn_bus_din_ta, scsn_ack => scsn_bus_ack_ta ); -- tlmureceiver cbbr_top_1: entity work.cbbr_top generic map ( clkratio => 10) port map ( clk40 => clk40, reset_n => rst40_n, address => scsn_bus_addr_r(3 downto 0), cbbr_IBO => scsn_bus_dout_r, cbbr_OBI => scsn_bus_din_tlrec, we => scsn_bus_we_tlrec, ack => scsn_bus_ack_tlrec, req => scsn_bus_req_tlrec, din => tlmu_trg_r, do => open, do_strobe => open); -- -- I/O buffers -- -- LEDs ledbuf1 : OBUF port map ( I => led1_i, O => LED1 ); ledbuf2 : OBUF port map ( I => led2_i, O => LED2 ); -- TTCex ttcex_clk_buf : ODDR2 port map ( CE => '1', R => '0', S => '0', C0 => clk40_ps, C1 => clk40_ps_180, D0 => '1', D1 => '0', Q => BC_ECL ); -- ttcex_clk_buf : ODDR2 port map ( CE => '1', R => '0', S => '0', C0 => clk40_90, C1 => not clk40_90, D0 => '1', D1 => '0', Q => BC_ECL ); ttcex_a_buf : OBUF port map ( I => a_channel_out, O => A_ECL ); ttcex_b_buf : OBUF port map ( I => b_channel_out, O => B_ECL ); -- SCSN ibufds_scsn_feb_in : IBUFDS port map ( I => SCSNFEBINp, IB => SCSNFEBINn, O => scsn_feb_in ); ibufds_scsn_in : IBUFDS port map ( I => SCSNINp, IB => SCSNINn, O => scsn_in ); obufds_scsn_feb_out : OBUFDS port map ( I => scsn_feb_out, O => SCSNFEBOUTp, OB => SCSNFEBOUTn ); obufds_scsn_out : OBUFDS port map ( I => scsn_out, O => SCSNOUTp, OB => SCSNOUTn ); -- TTCrx ibufds_a_channel : IBUFDS port map ( I => L1ACCEPTp, IB => L1ACCEPTn, O => ttc_a_channel ); ibuf_b_channel : IBUF port map ( I => B_Channel, O => ttc_b_channel ); -- CB-A/C ibuf_cba : IBUF port map ( I => CB_A, O => cba_in ); ibuf_cbc : IBUF port map ( I => CB_C, O => cbc_in ); -- TLMU obuf_tlmu_clk40 : ODDR2 port map ( CE => '1', R => '0', S => '0', C0 => clk40, C1 => not clk40, D0 => '0', D1 => '1', Q => CLK40T ); obuf_tlmu_rst40 : OBUF port map ( I => rst40_tlmu, O => RESET_TOFFPGA ); -- GTU ddr_gtu_busy : IDDR2 port map ( CE => '1', R => '0', S => '0', C0 => clk40_90, C1 => not clk40_90, D => BUSY, Q0 => gtu_busy_ddr(0), Q1 => gtu_busy_ddr(1) ); -- PIM ddr_pim_0 : ODDR2 port map ( CE => '1', R => '0', S => '0', C0 => clk40, C1 => not clk40, D0 => '1', D1 => '0', Q => PIMLINK(0) ); ddr_pim_1 : ODDR2 port map ( CE => '1', R => '0', S => '0', C0 => clk40_90, C1 => not clk40_90, D0 => not tin1_out, D1 => tin1_out, Q => PIMLINK(1) ); ddr_pim_2 : ODDR2 port map ( CE => '1', R => '0', S => '0', C0 => clk40_90, C1 => not clk40_90, D0 => not tin2_out, D1 => tin2_out, Q => PIMLINK(2) ); end default;