-- TTCrx interface module -- TTCrx register file occupies 128 bytes of memory space -- to simplify the design, all accesses are 32 bit wide, -- although only the LSB byte carries data. -- according to TTCrx manual, its SCL line is input only. -- So no arbitration and no wait holding are assumed in this design. -- TTC Hamming encoding (short) -- hmg[0] = d[0]^d[1]^d[2]^d[3]; -- hmg[1] = d[0]^d[4]^d[5]^d[6]; -- hmg[2] = d[1]^d[2]^d[4]^d[5]^d[7]; -- hmg[3] = d[1]^d[3]^d[4]^d[6]^d[7]; -- hmg[4] = d[0]^d[2]^d[3]^d[5]^d[6]^d[7]; -- TTC Hamming encoding (long) -- hmg(0) <= xor_reduce(d(5 downto 0)); -- hmg(1) <= xor_reduce(d(20 downto 6)); -- hmg(2) <= xor_reduce(d(27 downto 21)) xor xor_reduce(d(13 downto 6)); -- hmg(3) <= xor_reduce(d(30 downto 28)) xor xor_reduce(d(24 downto 21)) xor xor_reduce(d(17 downto 14)) xor xor_reduce(d(9 downto 6)) xor xor_reduce(d(2 downto 0)); -- hmg(4) <= d(31) xor d(29) xor d(28) xor d(26) xor d(25) xor d(22) xor d(21) xor d(19) xor d(18) xor d(15) xor d(14) xor d(11) xor d(10) xor d(7) xor d(6) xor d(4) xor d(3) xor d(0); -- hmg(5) <= d(31) xor d(30) xor d(28) xor d(27) xor d(25) xor d(23) xor d(21) xor d(20) xor d(18) xor d(16) xor d(14) xor d(12) xor d(10) xor d(8) xor d(6) xor d(5) xor d(3) xor d(1); -- hmg(6) <= d(31) xor d(30) xor d(29) xor d(27) xor d(26) xor d(24) xor d(21) xor d(20) xor d(19) xor d(17) xor d(14) xor d(13) xor d(10) xor d(8) xor d(7) xor d(5) xor d(4) xor d(2); -- hmg(6) <= xor_reduce(d) xor xor_reduce(hmg(5 downto 0)); -- reset orbit counter command 001x1xxx library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.std_logic_misc.all; use work.amc13_pack.all; library UNISIM; use UNISIM.VComponents.all; Library UNIMACRO; use UNIMACRO.vcomponents.all; entity ttc_if is Port ( clk : in std_logic; refclk : in std_logic; reset : in std_logic; rst_PLL : in std_logic; run : in std_logic; DB_cmd_in : in std_logic; DB_cmd_out : out std_logic; -- IsG2 : in std_logic; BC0 : out std_logic; TTC_strobe : out std_logic; sys_lock : in std_logic; local_TTC : in STD_LOGIC; --! Controls TTS output (for fake TTC output) local_TTCcmd : in STD_LOGIC; single_TTCcmd : in STD_LOGIC; TTS_clk : out std_logic; --! TTS clock (200/160)Mhz for (TTS DDR/fake TTC) -- CDR signals DIV4 : out STD_LOGIC; DIV_nRST : out STD_LOGIC; CDRclk_p : in STD_LOGIC; CDRclk_n : in STD_LOGIC; CDRclk_out : out STD_LOGIC; CDRdata_p : in STD_LOGIC; CDRdata_n : in STD_LOGIC; TTCdata_p : out STD_LOGIC; TTCdata_n : out STD_LOGIC; TTC_LOS : in STD_LOGIC; TTC_LOL : in STD_LOGIC; -- bcn offset BCN_off : in std_logic_vector(12 downto 0); OC_off : in std_logic_vector(3 downto 0); en_cal_win : in std_logic; cal_win_high : in std_logic_vector(11 downto 0); -- five MSB is constant = "110110" cal_win_low : in std_logic_vector(11 downto 0); -- five MSB is constant = "110110" CalType : out std_logic_vector(3 downto 0); TTC_Brcst : out std_logic_vector(3 downto 0); -- Local L1A control en_localL1A : in std_logic; LocalL1A_cfg : in std_logic_vector(31 downto 0); trig_BX : in std_logic_vector(12 downto 0); localL1A_s : in std_logic; localL1A_r : in std_logic; HCAL_trigger : in std_logic; T3_trigger : in std_logic; EvnRSt_l : in std_logic; OcnRSt_l : in std_logic; localL1A_periodic : out std_logic; ovfl_warning : in std_logic; -- ipbus signals ipb_clk : in STD_LOGIC; ipb_write : in STD_LOGIC; ipb_strobe : in STD_LOGIC; ipb_addr : in STD_LOGIC_VECTOR(31 downto 0); ipb_wdata : in STD_LOGIC_VECTOR(31 downto 0); ipb_rdata : out STD_LOGIC_VECTOR(31 downto 0); -- TTCrx status : ready, single error and double error en_brcst : in std_logic; ttc_start : out std_logic; ttc_stop : out std_logic; ttc_soft_reset : out std_logic; -- TTC ReSync ttc_ready : out std_logic; ttc_serr : out std_logic; ttc_derr : out std_logic; ttc_bcnt_err : out std_logic; rate_OFW : out std_logic; sync_lost : out std_logic; inc_oc : out std_logic; inc_l1ac : out std_logic; inc_bcnterr : out std_logic; inc_serr : out std_logic; inc_derr : out std_logic; state : in std_logic_vector(3 downto 0); evn_fifo_full : in std_logic; IgnoreDAQ : in std_logic; ttc_evcnt_reset : out std_logic; event_number_avl : out std_logic; event_number : out std_logic_vector(59 downto 0) ); end ttc_if; architecture ttc_arch of ttc_if is COMPONENT SCRAMBLER generic ( TX_DATA_WIDTH : integer := 32 ); PORT( UNSCRAMBLED_DATA_IN : IN std_logic_vector((TX_DATA_WIDTH-1) downto 0); DATA_VALID_IN : IN std_logic; USER_CLK : IN std_logic; SYSTEM_RESET : IN std_logic; SCRAMBLED_DATA_OUT : OUT std_logic_vector((TX_DATA_WIDTH-1) downto 0) ); END COMPONENT; COMPONENT Threshold PORT( clk : IN std_logic; din : IN std_logic_vector(15 downto 0); nongap_size : IN std_logic_vector(11 downto 0); dout : OUT std_logic_vector(31 downto 0) ); END COMPONENT; function hemming_s(d : std_logic_vector(7 downto 0)) return std_logic_vector is variable hmg : std_logic_vector(4 downto 0); begin hmg(0) := d(0) xor d(1) xor d(2) xor d(3); hmg(1) := d(0) xor d(4) xor d(5) xor d(6); hmg(2) := d(1) xor d(2) xor d(4) xor d(5) xor d(7); hmg(3) := d(1) xor d(3) xor d(4) xor d(6) xor d(7); hmg(4) := d(0) xor d(2) xor d(3) xor d(5) xor d(6) xor d(7); return hmg; end hemming_s; function hemming_l(d : std_logic_vector(31 downto 0)) return std_logic_vector is variable hmg : std_logic_vector(6 downto 0); begin hmg(0) := d(5) xor d(4) xor d(3) xor d(2) xor d(1) xor d(0); hmg(1) := d(20) xor d(19) xor d(18) xor d(17) xor d(16) xor d(15) xor d(14) xor d(13) xor d(12) xor d(11) xor d(10) xor d(9) xor d(8) xor d(7) xor d(6); hmg(2) := d(27) xor d(26) xor d(25) xor d(24) xor d(23) xor d(22) xor d(21) xor d(13) xor d(12) xor d(11) xor d(10) xor d(9) xor d(8) xor d(7) xor d(6); hmg(3) := d(30) xor d(29) xor d(28) xor d(24) xor d(23) xor d(22) xor d(21) xor d(17) xor d(16) xor d(15) xor d(14) xor d(9) xor d(8) xor d(7) xor d(6) xor d(2) xor d(1) xor d(0); hmg(4) := d(31) xor d(29) xor d(28) xor d(26) xor d(25) xor d(22) xor d(21) xor d(19) xor d(18) xor d(15) xor d(14) xor d(11) xor d(10) xor d(7) xor d(6) xor d(4) xor d(3) xor d(0); hmg(5) := d(31) xor d(30) xor d(28) xor d(27) xor d(25) xor d(23) xor d(21) xor d(20) xor d(18) xor d(16) xor d(14) xor d(12) xor d(10) xor d(8) xor d(6) xor d(5) xor d(3) xor d(1); hmg(6) := d(31) xor d(30) xor d(29) xor d(27) xor d(26) xor d(24) xor d(21) xor d(20) xor d(19) xor d(17) xor d(14) xor d(13) xor d(10) xor d(8) xor d(7) xor d(5) xor d(4) xor d(2); return hmg; end hemming_l; function CDRclk_period (A : string) return real is begin if(A = "G2")then return 6.25; else return 6.237; end if; end CDRclk_period; constant TTCclk_pol : std_logic := '1'; constant TTCdata_pol : std_logic := '1'; constant Coarse_Delay: std_logic_vector(3 downto 0) := x"0"; -- constant BX500: std_logic_vector(11 downto 0) := x"1f1"; signal BX500: std_logic_vector(12 downto 0); signal ovfl_warning_SyncRegs : std_logic_vector(3 downto 0) := (others =>'0'); signal en_periodic : std_logic := '0'; signal en_burst : std_logic := '0'; -- signal every_orbit : std_logic := '0'; signal NextL1A : std_logic := '0'; signal periodicL1A_a : std_logic := '0'; signal periodicL1A_b : std_logic := '0'; signal periodicL1A_bp : std_logic := '0'; signal periodicL1A : std_logic := '0'; signal Burst_cntr : std_logic_vector(11 downto 0) := (others =>'0'); signal L1A_dl : std_logic := '0'; signal L1A_dl24 : std_logic_vector(21 downto 0) := (others =>'0'); signal L1A_dl99 : std_logic_vector(74 downto 0) := (others =>'0'); signal L1A_dl239 : std_logic_vector(139 downto 0) := (others =>'0'); signal random_th : std_logic_vector(32 downto 0) := (others =>'0'); signal lfsr : std_logic_vector(31 downto 0) := (others =>'0'); signal lfsr_s : std_logic_vector(32 downto 0) := (others =>'0'); signal rules : std_logic_vector(4 downto 0) := (others =>'0'); signal rule1_cntr : std_logic := '0'; signal rule2_cntr : std_logic_vector(1 downto 0) := (others =>'0'); signal rule3_cntr : std_logic_vector(1 downto 0) := (others =>'0'); signal OrbitCntr : std_logic_vector(15 downto 0) := (others =>'0'); signal BXCntr : std_logic_vector(11 downto 0) := (others =>'0'); signal BXCntr_b : std_logic_vector(15 downto 0) := (others =>'0'); signal localL1A_s_SyncRegs : std_logic_vector(3 downto 0) := (others =>'0'); signal localL1A_r_SyncRegs : std_logic_vector(3 downto 0) := (others =>'0'); signal T3_triggerSyncRegs : std_logic_vector(3 downto 0) := (others =>'0'); signal EvnRst_SyncRegs : std_logic_vector(3 downto 0) := (others =>'0'); signal OcnRst_SyncRegs : std_logic_vector(3 downto 0) := (others =>'0'); signal reset_SyncRegs : std_logic_vector(3 downto 0) := (others =>'0'); signal SendEvnRst : std_logic := '0'; signal SendOcnRst : std_logic := '0'; signal SendBC0 : std_logic := '0'; signal en_SendBC0 : std_logic := '0'; signal TTC_cmd_avl : std_logic := '0'; signal busy_l : std_logic := '0'; signal start_l : std_logic := '0'; signal stop_l : std_logic := '0'; signal Bcnt_l : std_logic_vector(11 downto 0) := (others => '0'); signal sr_l : std_logic_vector(40 downto 0) := (others => '0'); --signal TTC_cmd : std_logic_vector(3 downto 0) := (others => '0'); signal TTC_clkfb : std_logic := '0'; signal TTC_clk_dcm : std_logic := '0'; signal TTC_clk_lock : std_logic := '0'; signal TTC_clk_lock_n : std_logic := '0'; signal clkfb : std_logic := '0'; signal clk160_dcm : std_logic := '0'; signal clk200_dcm : std_logic := '0'; signal sys_lock_n : std_logic := '0'; signal local_TTC_n : std_logic := '0'; signal rst_CDR : std_logic := '0'; signal CDRclk_in : std_logic := '0'; signal PllCDRclk_in : std_logic := '0'; signal CDRclk_dcm : std_logic := '0'; signal CDRclkFB_dcm : std_logic := '0'; signal CDRclkFB : std_logic := '0'; signal CDRclk : std_logic := '0'; signal CDR_lock : std_logic := '0'; signal TTCdata : std_logic := '0'; signal CDRdata_in : std_logic := '0'; signal TTCclk_q : std_logic_vector(1 downto 0) := (others =>'0'); signal CDRdata : std_logic := '0'; signal CDRdata_q : std_logic_vector(2 downto 0) := (others =>'0'); signal div8 : std_logic_vector(2 downto 0) := (others =>'0'); signal toggle_cnt : std_logic_vector(1 downto 0) := (others =>'0'); signal toggle_channel : std_logic := '1'; signal a_channel : std_logic := '1'; signal L1A : std_logic := '0'; signal strng_length : std_logic_vector(3 downto 0) := (others =>'0'); signal div_rst_cnt : std_logic_vector(4 downto 0) := (others =>'0'); signal TTC_str : std_logic := '0'; signal L1Accept : std_logic := '0'; signal sr : std_logic_vector(12 downto 0) := (others => '0'); signal rec_cntr : std_logic_vector(5 downto 0) := (others => '0'); signal rec_cmd : std_logic := '0'; signal FMT : std_logic := '0'; signal TTC_data : std_logic_vector(2 downto 0) := (others => '0'); signal brcst_str : std_logic_vector(3 downto 0) := (others => '0'); signal brcst_data : std_logic_vector(7 downto 0) := (others => '0'); signal brcst_syn : std_logic_vector(4 downto 0) := (others => '0'); signal frame_err : std_logic := '0'; signal single_err : std_logic := '0'; signal double_err : std_logic := '0'; signal EvCntReset : std_logic := '0'; signal BCntReset : std_logic := '0'; signal SinErrStr : std_logic := '0'; signal DbErrStr : std_logic := '0'; signal BrcstStr : std_logic := '0'; signal EvCntRes : std_logic := '0'; signal BCntRes : std_logic := '0'; signal OcRes : std_logic := '0'; signal ReSync : std_logic := '0'; signal BrcstCmd : std_logic_vector(3 downto 0) := (others => '0'); signal Brcst : std_logic_vector(7 downto 0) := (others => '0'); signal TTC_tune_cnt : std_logic_vector(7 downto 0) := (others =>'0'); signal ttc_brcst_i : std_logic_vector(3 downto 0) := (others => '0'); signal ttc_sinerrstr : std_logic := '0'; signal ttc_dberrstr : std_logic := '0'; signal ttc_l1accept : std_logic := '0'; signal ttc_evcntres : std_logic := '0'; signal ttc_l1accept_dl : std_logic := '0'; signal ttc_bcntres_dl : std_logic := '0'; signal ttc_OCres_dl : std_logic := '0'; signal ttc_soft_reset_i : std_logic := '0'; signal dl_a : std_logic_vector(3 downto 0) := (others => '0'); signal dl_b : std_logic_vector(3 downto 0) := (others => '0'); signal bcnt : std_logic_vector(11 downto 0) := (others => '0'); signal LastBcnt : std_logic_vector(11 downto 0) := (others => '0'); signal oc : std_logic_vector(31 downto 0) := (others => '0'); signal en_bcnt_res : std_logic := '0'; signal en_bcnt_err : std_logic_vector(1 downto 0) := (others => '0'); signal brcst_GapTrig : std_logic := '0'; signal brcst_GapPed : std_logic := '0'; signal brcst_GapLaser : std_logic := '0'; signal rst_bcnt : std_logic := '0'; signal cal_win : std_logic := '0'; signal Laser_TO : std_logic_vector(13 downto 0) := (others => '0'); signal bcn_offs1 : std_logic_vector(11 downto 0) := (others => '0'); signal cal_type : std_logic_vector(3 downto 0) := (others => '0'); signal rst_cnt : std_logic_vector(1 downto 0) := (others => '0'); signal event_number_avl_i : std_logic := '0'; signal dec_rate_cntr : std_logic := '0'; signal rate_div : std_logic_vector(7 downto 0) := (others => '0'); signal rate_cntr : std_logic_vector(5 downto 0) := (others => '0'); signal ttc_sync_wa : std_logic_vector(1 downto 0) := (others => '0'); signal ttc_sync_ra : std_logic_vector(1 downto 0) := (others => '0'); signal ttc_sync_din : std_logic_vector(11 downto 0) := (others => '0'); signal ttc_sync_dout : std_logic_vector(11 downto 0) := (others => '0'); signal ttc_sync_wa1_SyncRegs : std_logic_vector(1 downto 0) := (others => '0'); signal ttc_sync_wa0_SyncRegs : std_logic_vector(1 downto 0) := (others => '0'); signal ttc_sync_do : std_logic_vector(11 downto 0) := (others => '0'); signal ttc_sync_do_val : std_logic := '0'; type array4X16 is array(0 to 3) of std_logic_vector(15 downto 0); type array4X32 is array(0 to 3) of std_logic_vector(31 downto 0); signal ttc_cmd : array4x32 := (others => (others => '0')); signal ttc_cmd_cfg : array4x32 := (others => (others => '0')); signal single_TTCcmd_SyncRegs : std_logic_vector(3 downto 0) := (others =>'0'); signal OcPrescal : array4x16 := (others => x"ffff"); signal NoPrescale : std_logic_vector(3 downto 0) := (others => '0'); signal L1A_delay : std_logic_vector(11 downto 0) := (others => '0'); signal SendTTC_cmd : std_logic_vector(3 downto 0) := (others => '0'); signal TTC_cmd_done : std_logic_vector(3 downto 0) := (others => '0'); signal TTC_L1A_Do : std_logic_vector(3 downto 0) := (others => '0'); signal TTC_L1A_Di : std_logic_vector(3 downto 0) := (others => '0'); signal TTC_L1A_wa : std_logic_vector(11 downto 0) := (others => '0'); signal TTC_L1A_ra : std_logic_vector(11 downto 0) := (others => '0'); signal en_TTC_L1A : std_logic := '0'; signal ld_sr_l : std_logic := '0'; signal SendFMT : std_logic := '0'; signal SendCmdData : std_logic_vector(31 downto 0) := (others => '0'); signal hmg_s : std_logic_vector(4 downto 0) := (others => '0'); signal hmg_l : std_logic_vector(6 downto 0) := (others => '0'); signal cmd_cntr : std_logic_vector(5 downto 0) := (others => '0'); signal bcnt_cmd : std_logic_vector(11 downto 0) := x"000"; signal gap_begin : std_logic_vector(11 downto 0) := x"000"; signal gap_end : std_logic_vector(11 downto 0) := x"000"; signal gap_beginp : std_logic_vector(11 downto 0) := x"000"; signal gap_endp : std_logic_vector(11 downto 0) := x"000"; signal nongap_size : std_logic_vector(11 downto 0) := x"000"; signal in_gap : std_logic := '0'; signal random_cnt : std_logic_vector(5 downto 0) := (others => '0'); signal OcNresetCmd : std_logic_vector(15 downto 0) := x"1728"; signal ReSyncCmd : std_logic_vector(15 downto 0) := x"1748"; signal DBCmd : std_logic_vector(15 downto 0) := x"1768"; signal second : std_logic_vector(25 downto 0) := (others => '0'); signal L1A_rate : std_logic_vector(24 downto 0) := (others => '0'); signal L1A_rate_q : std_logic_vector(24 downto 0) := (others => '0'); signal L1A_cntr : std_logic_vector(24 downto 0) := (others => '0'); signal L1AToggle : std_logic := '0'; signal L1AToggleSync : std_logic_vector(3 downto 0) := (others => '0'); signal DB : std_logic := '0'; signal DB_cmd_i : std_logic := '0'; signal DBSync : std_logic_vector(3 downto 0) := (others => '0'); component icon1 PORT ( CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); end component; component ila36x1024 PORT ( CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); CLK : IN STD_LOGIC; DATA : IN STD_LOGIC_VECTOR(35 DOWNTO 0); TRIG0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)); end component; signal CONTROL0 : std_logic_vector(35 downto 0) := (others => '0'); signal cs_data : std_logic_vector(35 downto 0) := (others => '0'); signal cs_trig : std_logic_vector(7 downto 0) := (others => '0'); begin --i_icon1 : icon1 -- port map ( -- CONTROL0 => CONTROL0); --i_ila36x1024 : ila36x1024 -- port map ( -- CONTROL => CONTROL0, -- CLK => CDRclk, -- DATA => cs_data, -- TRIG0 => cs_trig); --cs_trig(7 downto 5) <= sr(2 downto 0); --cs_trig(4) <= BCntRes; --cs_trig(3) <= a_channel; --cs_trig(2 downto 0) <= TTC_data; --cs_data(26 downto 14) <= sr; --cs_data(13) <= double_err; --cs_data(12) <= single_err; --cs_data(11) <= brcst_str(1); --cs_data(10) <= BCntRes; --cs_data(9) <= local_TTCcmd; --cs_data(8) <= en_localL1A; --cs_data(7) <= a_channel; --cs_data(6) <= toggle_channel; --cs_data(5) <= TTC_str; --cs_data(4 downto 2) <= TTC_data; --cs_data(1 downto 0) <= CDRdata_q(2 downto 1); --cs_trig(7 downto 1) <= bcnt(11 downto 5); ----cs_trig(0) <= inc_bcnterr; --cs_data(33) <= local_TTC; --cs_data(32 downto 30) <= ttc_sync_do(10 downto 8); --cs_data(29) <= ttc_sync_do(6); --cs_data(28) <= cs_trig(0); --cs_data(27) <= ttc_sync_do_val; --cs_data(26) <= ttc_bcntres_dl; --cs_data(25 downto 24) <= en_bcnt_err; --cs_data(23 downto 12) <= bcn_offs1; --cs_data(11 downto 0) <= bcnt; ------------------------------------------ LastBcnt <= x"fff" when flavor = "G2" else x"deb"; -- new code starts here ttc_soft_reset <= ttc_soft_reset_i; localL1A_periodic <= en_periodic; CDRclk_out <= CDRclk; TTC_strobe <= TTC_str; rst_CDR <= TTC_LOL or TTC_LOS or rst_PLL; DB_cmd_out <= DB_cmd_i; i_CDRclk_in: ibufgds generic map(DIFF_TERM => TRUE,IOSTANDARD => "LVDS_25") port map(i => CDRclk_p, ib => CDRclk_n, o => CDRclk_in); i_MMCM_CDRclk : PLLE2_BASE -- generic map(CLKFBOUT_MULT => 10,CLKOUT0_DIVIDE => 8,CLKIN1_PERIOD => 6.237) generic map(CLKFBOUT_MULT => 10,CLKOUT0_DIVIDE => 8,CLKIN1_PERIOD => CDRclk_period(flavor)) port map ( CLKOUT0 => clk200_dcm, -- CLKOUT1 => CDRclk_dcm, -- Feedback Clocks: 1-bit (each) Clock feedback ports -- CLKFBOUT => CDRclkFB_dcm, -- 1-bit Feedback clock output CLKFBOUT => CDRclk_dcm, -- 1-bit Feedback clock output -- Clock Inputs: 1-bit (each) Clock inputs CLKIN1 => CDRclk_in, -- 1-bit Clock input -- Control Ports: 1-bit (each) MMCM control ports PWRDWN => '0', -- 1-bit Power-down input RST => rst_CDR, -- 1-bit Reset input LOCKED => CDR_lock, -- 1-bit LOCK output -- Feedback Clocks: 1-bit (each) Clock feedback ports CLKFBIN => CDRclk -- 1-bit Feedback clock input ); i_CDRclk_buf: bufg port map(i => CDRclk_dcm, o => CDRclk); --i_CDRclkFB_buf: bufg port map(i => CDRclkFB_dcm, o => CDRclkFB); g_TTCCLK: if (flavor /= "G2") generate i_MMCM_TTC_clk : MMCME2_BASE generic map(DIVCLK_DIVIDE => 10, CLKFBOUT_MULT_F => 64.0,CLKOUT0_DIVIDE_F => 63.875,CLKIN1_PERIOD => 5.0) port map ( -- Feedback Clocks: 1-bit (each) Clock feedback ports CLKFBOUT => TTC_clkfb, -- 1-bit Feedback clock output CLKOUT0 => TTC_clk_dcm, -- 1-bit CLKOUT0 output 400MHz -- Clock Inputs: 1-bit (each) Clock inputs CLKIN1 => refclk, -- 1-bit Clock input -- Control Ports: 1-bit (each) MMCM control ports PWRDWN => '0', -- 1-bit Power-down input RST => sys_lock_n, -- 1-bit Reset input LOCKED => TTC_clk_lock, -- 1-bit LOCK output -- Feedback Clocks: 1-bit (each) Clock feedback ports CLKFBIN => TTC_clkfb -- 1-bit Feedback clock input ); sys_lock_n <= not sys_lock; i_PLL_TTC_clk : PLLE2_BASE generic map(CLKFBOUT_MULT => 64,CLKOUT0_DIVIDE => 8,CLKIN1_PERIOD => 49.902) port map ( CLKOUT0 => clk160_dcm, CLKFBOUT => clkfb, -- 1-bit Feedback clock output -- Clock Inputs: 1-bit (each) Clock inputs CLKIN1 => TTC_clk_dcm, -- 1-bit Clock input -- Control Ports: 1-bit (each) MMCM control ports PWRDWN => '0', -- 1-bit Power-down input RST => TTC_clk_lock_n, -- 1-bit Reset input LOCKED => open, -- 1-bit LOCK output -- Feedback Clocks: 1-bit (each) Clock feedback ports CLKFBIN => clkfb -- 1-bit Feedback clock input ); TTC_clk_lock_n <= not TTC_clk_lock; end generate g_TTCCLK; g_TTCCLK160: if (flavor = "G2") generate i_TTCclk160 : PLLE2_BASE generic map(CLKFBOUT_MULT => 8,CLKOUT0_DIVIDE => 10,CLKIN1_PERIOD => 5.0) port map ( CLKOUT0 => clk160_dcm, CLKFBOUT => clkfb, -- 1-bit Feedback clock output -- Clock Inputs: 1-bit (each) Clock inputs CLKIN1 => refclk, -- 1-bit Clock input -- Control Ports: 1-bit (each) MMCM control ports PWRDWN => '0', -- 1-bit Power-down input RST => sys_lock_n, -- 1-bit Reset input LOCKED => open, -- 1-bit LOCK output -- Feedback Clocks: 1-bit (each) Clock feedback ports CLKFBIN => clkfb -- 1-bit Feedback clock input ); end generate g_TTCCLK160; i_TTS_clk_buf : BUFGCTRL generic map ( INIT_OUT => 0, -- Initial value of BUFGCTRL output (0/1) PRESELECT_I0 => FALSE, -- BUFGCTRL output uses I0 input (TRUE/FALSE) PRESELECT_I1 => FALSE -- BUFGCTRL output uses I1 input (TRUE/FALSE) ) port map ( O => TTS_clk, -- 1-bit output: Clock Output pin CE0 => '1', -- 1-bit input: Clock enable input for I0 input CE1 => '1', -- 1-bit input: Clock enable input for I1 input I0 => clk200_dcm, -- 1-bit input: Primary clock input I1 => clk160_dcm, -- 1-bit input: Secondary clock input IGNORE0 => '1', -- 1-bit input: Clock ignore input for I0 IGNORE1 => '1', -- 1-bit input: Clock ignore input for I1 S0 => local_TTC_n, -- 1-bit input: Clock select input for I0 S1 => local_TTC -- 1-bit input: Clock select input for I1 ); local_TTC_n <= not local_TTC; i_CDRdata: ibufds generic map(DIFF_TERM => TRUE,IOSTANDARD => "LVDS_25") port map(i => CDRdata_p, ib => CDRdata_n, o => CDRdata); i_TTCdata: obufds generic map(IOSTANDARD => "LVDS_25") port map(o => TTCdata_p, ob => TTCdata_n, i => TTCdata); DIV4 <= '1'; process(CDRclk) begin if(CDRclk'event and CDRclk = '0')then CDRdata_q(0) <= CDRdata; end if; end process; process(CDRclk) begin if(CDRclk'event and CDRclk = '1')then ovfl_warning_SyncRegs <= ovfl_warning_SyncRegs(2 downto 0) & ovfl_warning; -- CDRdata_q <= CDRdata_q(0) & CDRdata; CDRdata_q(2 downto 1) <= CDRdata_q(1 downto 0); if(toggle_channel = '1')then if(a_channel = '1' and en_localL1A = '1')then TTCdata <= TTCdata_pol xor (not ovfl_warning_SyncRegs(3) and periodicL1A); elsif(a_channel = '0' and local_TTCcmd = '1')then TTCdata <= TTCdata_pol xor sr_l(40); else TTCdata <= TTCdata_pol xor (CDRdata_q(1) xor CDRdata_q(2)); end if; end if; if(toggle_channel = '0')then div8 <= div8 + 1; end if; if(div8 = "111" or toggle_cnt = "11")then toggle_cnt <= (others => '0'); -- TTC signal should always toggle at a/b channel crossing, otherwise toggle_channel is at wrong position elsif(CDRdata_q(1) = CDRdata_q(2) and toggle_channel = '0')then toggle_cnt <= toggle_cnt + 1; end if; if(toggle_cnt /= "11")then toggle_channel <= not toggle_channel; end if; -- if illegal L1A='1'/data = '0' sequence reaches 11, resync the phase if(toggle_channel = '1' and (a_channel = '1' or strng_length /= x"b"))then a_channel <= not a_channel; end if; if(a_channel = '1' and toggle_channel = '1')then if(CDRdata_q(1) /= CDRdata_q(2))then L1A <= '1'; else L1A <= '0'; end if; end if; if(a_channel = '0' and toggle_channel = '1')then -- L1A = '1' and b_channel data = '0' can not repeat 11 times if(L1A = '0' or CDRdata_q(1) /= CDRdata_q(2) or strng_length = x"b")then strng_length <= (others => '0'); else strng_length <= strng_length + 1; end if; end if; end if; end process; -- To get the right phase of TTC clock, we do not directly look at the divided clock signal. -- Instead, phase of the divided TTC clock is determined by the time of release of the signal div_nrst process(CDRclk,CDR_lock) begin if(CDR_lock = '0')then div_nrst <= '0'; div_rst_cnt <= (others => '0'); elsif(CDRclk'event and CDRclk = '1')then if(TTC_str = '1')then div_nrst <= div_rst_cnt(4); end if; if(toggle_cnt = "11" or strng_length = x"b")then div_rst_cnt <= (others => '0'); elsif(TTC_str = '1' and div_rst_cnt(4) = '0')then div_rst_cnt <= div_rst_cnt + 1; end if; end if; end process; process(CDRclk) begin if(CDRclk'event and CDRclk = '0')then for i in 0 to 3 loop NoPrescale(i) <= not or_reduce(TTC_cmd_cfg(i)(15 downto 0)); end loop; end if; end process; process(CDRclk,reset) begin if(reset = '1')then TTC_tune_cnt <= (others => '0'); OcPrescal <= (others => x"ffff"); SendTTC_cmd <= x"0"; elsif(CDRclk'event and CDRclk = '1')then if(toggle_cnt = "11" or strng_length = x"b")then TTC_tune_cnt <= TTC_tune_cnt + 1; end if; if(TTC_str = '1')then for i in 0 to 3 loop if(TTC_cmd_done(i) = '1')then SendTTC_cmd(i) <= '0'; elsif(single_TTCcmd_SyncRegs(3 downto 2) = "01" and TTC_cmd_cfg(i)(30) = '1')then SendTTC_cmd(i) <= '1'; elsif(Bcnt_l = x"002" and TTC_cmd_cfg(i)(29) = '1')then if(OcPrescal(i) = x"ffff" or NoPrescale(i) = '1')then OcPrescal(i) <= not TTC_cmd_cfg(i)(15 downto 0); SendTTC_cmd(i) <= TTC_cmd_cfg(i)(29); else OcPrescal(i) <= OcPrescal(i) + 1; end if; end if; end loop; end if; end if; end process; i_SCRAMBLER: SCRAMBLER PORT MAP( UNSCRAMBLED_DATA_IN => lfsr, SCRAMBLED_DATA_OUT => lfsr_s(31 downto 0), DATA_VALID_IN => TTC_str, USER_CLK => CDRclk, SYSTEM_RESET => reset_SyncRegs(3) ); process(CDRclk) begin if(CDRclk'event and CDRclk = '1')then -- 2 1 3 2 1 4 1 3 6 1 1 13 8 5 1 1 1 --TTC_debug <= "000000000" & CDRdata_q & toggle_channel & div8 & toggle_cnt & a_channel & strng_length & TTC_str & TTC_data & rec_cntr & rec_cmd & FMT & sr & brcst_data & brcst_syn & frame_err & single_err & double_err; if(toggle_channel = '1' and a_channel = '0')then TTC_data(2) <= CDRdata_q(1) xor CDRdata_q(2); end if; TTC_str <= not toggle_channel and a_channel; if(TTC_str = '1')then -- locally generated TTC commands reset_SyncRegs <= reset_SyncRegs(2 downto 0) & reset; EvnRst_SyncRegs <= EvnRst_SyncRegs(2 downto 0) & EvnRst_l; OcnRst_SyncRegs <= OcnRst_SyncRegs(2 downto 0) & OcnRst_l; -- if(Bcnt_l = x"deb")then if(Bcnt_l = LastBcnt)then Bcnt_l <= (others => '0'); else Bcnt_l <= Bcnt_l + 1; end if; -- if(Bcnt_l = x"de8")then if(Bcnt_l = (LastBcnt - x"003"))then Bcnt_cmd <= (others => '0'); else Bcnt_cmd <= Bcnt_cmd + 1; end if; if(busy_l = '0' and SendBC0 = '1')then busy_l <= '1'; ld_sr_l <= '1'; SendFMT <= '0'; cmd_cntr <= "110010"; SendCmdData(7 downto 0) <= "000000" & SendEvnRst & SendBC0; elsif(busy_l = '0' and SendOcnRst = '1' and Bcnt_l(9) = '1')then -- this keeps OcNreset away from BC0 busy_l <= '1'; ld_sr_l <= '1'; SendFMT <= '0'; cmd_cntr <= "110010"; -- SendCmdData <= x"000000" & OcNresetCmd(7 downto 2) & '0' & SendBC0; SendCmdData(7 downto 0) <= OcNresetCmd(7 downto 2) & "00"; elsif(busy_l = '0')then for i in 0 to 3 loop if(SendTTC_cmd(i) = '1' and Bcnt_cmd = TTC_cmd_cfg(i)(27 downto 16))then busy_l <= '1'; ld_sr_l <= '1'; SendFMT <= TTC_cmd_cfg(i)(28); if(TTC_cmd_cfg(i)(28) = '0')then cmd_cntr <= "110010"; else cmd_cntr <= "011000"; end if; SendCmdData <= TTC_cmd(i); TTC_cmd_done(i) <= '1'; end if; end loop; else if(stop_l = '1')then busy_l <= '0'; end if; ld_sr_l <= '0'; TTC_cmd_done <= (others => '0'); cmd_cntr <= cmd_cntr + 1; end if; -- if(busy_l = '0')then -- if(SendFMT = '0')then -- cmd_cntr <= "110010"; -- else -- cmd_cntr <= "011000"; -- end if; -- else -- cmd_cntr <= cmd_cntr + 1; -- end if; if(cmd_cntr = "111111")then stop_l <= '1'; else stop_l <= '0'; end if; if(flavor /= "G2" or reset_SyncRegs(3) = '1')then en_SendBc0 <= '1'; elsif(stop_l = '1' and SendFMT = '0' and SendCmdData(0) = '1')then en_SendBc0 <= '0'; end if; -- if(Bcnt_l = x"dd2")then -- if(Bcnt_l = (LastBcnt - x"019") and flavor /= "G2")then if(Bcnt_l = (LastBcnt - x"019") and en_SendBC0 = '1')then SendBC0 <= '1'; else SendBC0 <= '0'; end if; if(reset_SyncRegs(3 downto 2) = "10" or EvnRst_SyncRegs(3 downto 2) = "01")then SendEvnRst <= '1'; elsif(busy_l = '0' and SendBC0 = '1')then SendEvnRst <= '0'; end if; -- if(reset_SyncRegs(3 downto 2) = "10" or OcnRst_SyncRegs(3 downto 2) = "01")then if(OcnRst_SyncRegs(3 downto 2) = "01")then SendOcnRst <= '1'; -- elsif(busy_l = '0' and SendBC0 = '1')then elsif(busy_l = '0' and Bcnt_l(9) = '1')then -- this keeps OcNreset away from BC0 SendOcnRst <= '0'; end if; if(ld_sr_l = '1')then start_l <= '1'; if(SendFMT = '0')then sr_l(40 downto 26) <= "00" & SendCmdData(7 downto 0) & hemming_s(SendCmdData(7 downto 0)); sr_l(25 downto 0) <= (others => '1'); else sr_l <= "01" & SendCmdData & hemming_l(SendCmdData); end if; else start_l <= '0'; sr_l <= sr_l(39 downto 0) & '1'; end if; -- locally generated TTC commands localL1A_s_SyncRegs <= localL1A_s_SyncRegs(2 downto 0) & localL1A_s; localL1A_r_SyncRegs <= localL1A_r_SyncRegs(2 downto 0) & localL1A_r; T3_triggerSyncRegs <= T3_triggerSyncRegs(2 downto 0) & T3_trigger; single_TTCcmd_SyncRegs <= single_TTCcmd_SyncRegs(2 downto 0) & single_TTCcmd; -- if(local_TTC = '0')then -- BC0 <= BCntRes; -- elsif(Bcnt_l = x"deb")then -- BC0 <= '1'; -- else -- BC0 <= '0'; -- end if; -- TTC_data(1) <= TTC_data(2) or not div_rst_cnt(4); BC0 <= BCntRes; if(div_rst_cnt(4) = '0')then TTC_data(0) <= '0'; elsif(en_localL1A = '0')then TTC_data(0) <= CDRdata_q(1) xor CDRdata_q(2); else TTC_data(0) <= not ovfl_warning_SyncRegs(3) and periodicL1A; end if; if(div_rst_cnt(4) = '0')then TTC_data(1) <= '1'; elsif(local_TTCcmd = '0')then TTC_data(1) <= TTC_data(2); else TTC_data(1) <= sr_l(40); end if; if(rec_cmd = '0')then rec_cntr <= (others => '0'); else rec_cntr <= rec_cntr + 1; end if; if(div_rst_cnt(4) = '0' or rec_cntr(5 downto 3) = "101" or (FMT = '0' and rec_cntr(3 downto 0) = x"d"))then rec_cmd <= '0'; elsif(TTC_data(1) = '0')then rec_cmd <= '1'; end if; if(or_reduce(rec_cntr) = '0')then FMT <= TTC_data(1); end if; sr <= sr(11 downto 0) & TTC_data(1); if(FMT = '0' and rec_cntr(3 downto 0) = x"e")then brcst_data <= sr(12 downto 5); brcst_syn(0) <= sr(0) xor sr(5) xor sr(6) xor sr(7) xor sr(8); brcst_syn(1) <= sr(1) xor sr(5) xor sr(9) xor sr(10) xor sr(11); brcst_syn(2) <= sr(2) xor sr(6) xor sr(7) xor sr(9) xor sr(10) xor sr(12); brcst_syn(3) <= sr(3) xor sr(6) xor sr(8) xor sr(9) xor sr(11) xor sr(12); brcst_syn(4) <= xor_reduce(sr); frame_err <= not TTC_data(1); brcst_str(0) <= '1'; else brcst_str(0) <= '0'; end if; single_err <= xor_reduce(brcst_syn) and not frame_err; if((or_reduce(brcst_syn) = '1' and xor_reduce(brcst_syn) = '0') or frame_err = '1')then double_err <= '1'; else double_err <= '0'; end if; SinErrStr <= single_err and brcst_str(1); DbErrStr <= double_err and brcst_str(1); brcst_str(2) <= brcst_str(1) and not double_err; if(brcst_syn(3 downto 0) = x"c")then Brcst(7) <= not brcst_data(7); else Brcst(7) <= brcst_data(7); end if; if(brcst_syn(3 downto 0) = x"a")then Brcst(6) <= not brcst_data(6); else Brcst(6) <= brcst_data(6); end if; if(brcst_syn(3 downto 0) = x"6")then Brcst(5) <= not brcst_data(5); else Brcst(5) <= brcst_data(5); end if; if(brcst_syn(3 downto 0) = x"e")then Brcst(4) <= not brcst_data(4); else Brcst(4) <= brcst_data(4); end if; if(brcst_syn(3 downto 0) = x"9")then Brcst(3) <= not brcst_data(3); else Brcst(3) <= brcst_data(3); end if; if(brcst_syn(3 downto 0) = x"5")then Brcst(2) <= not brcst_data(2); else Brcst(2) <= brcst_data(2); end if; if(brcst_syn(3 downto 0) = x"d")then Brcst(1) <= not brcst_data(1); else Brcst(1) <= brcst_data(1); end if; if(brcst_syn(3 downto 0) = x"3")then Brcst(0) <= not brcst_data(0); else Brcst(0) <= brcst_data(0); end if; if(en_burst = '0' or reset = '1')then Burst_cntr <= LocalL1A_cfg(27 downto 16); elsif(periodicL1A = '1')then Burst_cntr <= Burst_cntr - 1; end if; if(en_localL1A = '0' or reset = '1')then en_periodic <= '0'; elsif(localL1A_s_SyncRegs(3 downto 2) = "01")then en_periodic <= '1'; elsif(localL1A_r_SyncRegs(3 downto 2) = "01")then en_periodic <= '0'; end if; if(en_localL1A = '0' or en_periodic = '1')then en_burst <= '0'; elsif(localL1A_r_SyncRegs(3 downto 2) = "01")then en_burst <= '1'; elsif(periodicL1A = '1' and or_reduce(Burst_cntr) = '0')then en_burst <= '0'; end if; if(BCntRes = '1')then BXCntr <= (others => '0'); else BXCntr <= BXCntr + 1; end if; if(en_periodic = '0' and en_burst = '0')then BXCntr_b <= LocalL1A_cfg(15 downto 0); elsif(BXCntr_b = LocalL1A_cfg(15 downto 0) or LocalL1A_cfg(31 downto 30) /= "10")then BXCntr_b <= (others => '0'); else BXCntr_b <= BXCntr_b + 1; end if; if(BXCntr_b = LocalL1A_cfg(15 downto 0) and LocalL1A_cfg(31 downto 30) = "10" and (en_periodic = '1' or en_burst = '1'))then periodicL1A_a <= '1'; else periodicL1A_a <= '0'; end if; if(random_th > lfsr_s and LocalL1A_cfg(31 downto 30) = "11" and (en_periodic = '1' or en_burst = '1'))then periodicL1A_b <= '1'; else periodicL1A_b <= '0'; end if; if(reset_SyncRegs(3) = '1' or in_gap = '1')then random_cnt <= (others => '0'); elsif(and_reduce(random_cnt) = '0' and periodicL1A_b = '1' and (and_reduce(rules) = '0' or or_reduce(random_cnt) = '0'))then random_cnt <= random_cnt + 1; elsif(or_reduce(random_cnt) = '1' and periodicL1A_b = '0' and and_reduce(rules) = '1')then random_cnt <= random_cnt - 1; end if; -- every_orbit <= not or_reduce(LocalL1A_cfg(15 downto 0)); -- if(BCntRes = '1')then -- if(NextL1A = '1' or every_orbit = '1' or (en_periodic = '0' and en_burst = '0'))then -- orbitCntr <= LocalL1A_cfg(15 downto 0); -- else -- orbitCntr <= orbitCntr - 1; -- end if; -- end if; if(en_periodic = '0' and en_burst = '0')then orbitCntr <= (others => '0'); elsif(BXCntr = BX500(11 downto 0))then if(NextL1A = '1')then orbitCntr <= LocalL1A_cfg(15 downto 0); else orbitCntr <= orbitCntr - 1; end if; end if; -- if(orbitCntr = LocalL1A_cfg(15 downto 0) and LocalL1A_cfg(31) = '0' and (en_periodic = '1' or en_burst = '1'))then if(or_reduce(orbitCntr) = '0' and LocalL1A_cfg(31) = '0' and (en_periodic = '1' or en_burst = '1'))then NextL1A <= '1'; else NextL1A <= '0'; end if; if(gap_beginp = gap_endp or BXCntr = gap_endp)then in_gap <= '0'; elsif(BXCntr = gap_beginp)then in_gap <= '1'; end if; -- if(T3_triggerSyncRegs(3 downto 2) = "01" or (HCAL_trigger = '1' and en_localL1A = '1'))then if(T3_triggerSyncRegs(3 downto 2) = "01")then periodicL1A <= '1'; -- elsif(en_periodic = '0' and en_burst = '0')then -- periodicL1A <= '0'; -- elsif(((BXCntr = BX500 and NextL1A = '1') or periodicL1A_a = '1' or periodicL1A_bp = '1') and and_reduce(rules) = '1')then elsif(((BXCntr = BX500(11 downto 0) and NextL1A = '1') or periodicL1A_a = '1' or periodicL1A_bp = '1' or ((HCAL_trigger = '1' or TTC_L1A_Do(0) = '1') and en_localL1A = '1')) and and_reduce(rules) = '1')then periodicL1A <= '1'; else periodicL1A <= '0'; end if; L1A_dl <= periodicL1A; if(L1A_dl = '1' or (en_periodic = '0' and en_burst = '0'))then rules(0) <= '1'; -- elsif((periodicL1A_a = '1' or periodicL1A_bp = '1') and and_reduce(rules) = '1')then elsif((periodicL1A_a = '1' or periodicL1A_bp = '1' or (HCAL_trigger = '1' and en_localL1A = '1')) and and_reduce(rules) = '1')then rules(0) <= '0'; end if; rule1_cntr <= rule1_cntr xor periodicL1A xor L1A_dl24(21); if(L1A_dl24(21) = '1' or (en_periodic = '0' and en_burst = '0') or LocalL1A_cfg(29 downto 28) = "11")then rules(1) <= '1'; -- elsif(((periodicL1A_a = '1' or periodicL1A_bp = '1') and and_reduce(rules) = '1') and rule1_cntr = '1')then elsif(((periodicL1A_a = '1' or periodicL1A_bp = '1' or (HCAL_trigger = '1' and en_localL1A = '1')) and and_reduce(rules) = '1') and rule1_cntr = '1')then rules(1) <= '0'; end if; if(periodicL1A = '1' and L1A_dl99(74) = '0')then rule2_cntr(1) <= rule2_cntr(1) xor rule2_cntr(0); rule2_cntr(0) <= not rule2_cntr(0); elsif(periodicL1A = '0' and L1A_dl99(74) = '1')then rule2_cntr(1) <= rule2_cntr(1) xnor rule2_cntr(0); rule2_cntr(0) <= not rule2_cntr(0); end if; if(L1A_dl99(74) = '1' or (en_periodic = '0' and en_burst = '0') or LocalL1A_cfg(28) = '1')then rules(2) <= '1'; -- elsif(((periodicL1A_a = '1' or periodicL1A_bp = '1') and and_reduce(rules) = '1') and rule2_cntr(1) = '1')then elsif(((periodicL1A_a = '1' or periodicL1A_bp = '1' or (HCAL_trigger = '1' and en_localL1A = '1')) and and_reduce(rules) = '1') and rule2_cntr(1) = '1')then rules(2) <= '0'; end if; if(periodicL1A = '1' and L1A_dl239(139) = '0')then rule3_cntr(1) <= rule3_cntr(1) xor rule3_cntr(0); rule3_cntr(0) <= not rule3_cntr(0); elsif(periodicL1A = '0' and L1A_dl239(139) = '1')then rule3_cntr(1) <= rule3_cntr(1) xnor rule3_cntr(0); rule3_cntr(0) <= not rule3_cntr(0); end if; if(L1A_dl239(139) = '1' or (en_periodic = '0' and en_burst = '0') or LocalL1A_cfg(29 downto 28) /= "00")then rules(3) <= '1'; -- elsif(((periodicL1A_a = '1' or periodicL1A_bp = '1') and and_reduce(rules) = '1') and rule3_cntr = "11")then elsif(((periodicL1A_a = '1' or periodicL1A_bp = '1' or (HCAL_trigger = '1' and en_localL1A = '1')) and and_reduce(rules) = '1') and rule3_cntr = "11")then rules(3) <= '0'; end if; rules(4) <= not in_gap; L1A_dl24 <= L1A_dl24(20 downto 0) & L1A_dl; L1A_dl99 <= L1A_dl99(73 downto 0) & L1A_dl24(21); L1A_dl239 <= L1A_dl239(138 downto 0) & L1A_dl99(74); BCntRes <= brcst_str(3) and Brcst(0); EvCntRes <= brcst_str(3) and Brcst(1); BrcstStr <= brcst_str(3) and or_reduce(Brcst); OcRes <= brcst_str(3) and and_reduce((Brcst xnor OcNresetCmd(7 downto 0)) or OcNresetCmd(15 downto 8)); ReSync <= brcst_str(3) and and_reduce((Brcst xnor ReSyncCmd(7 downto 0)) or ReSyncCmd(15 downto 8)); DB <= DB xor (brcst_str(3) and and_reduce((Brcst xnor DBCmd(7 downto 0)) or DBCmd(15 downto 8))); if(brcst_str(3) = '1')then BrcstCmd <= Brcst(7 downto 5) & Brcst(3); end if; if(LocalL1A_cfg(31 downto 30) /= "11")then lfsr <= (others => '0'); else lfsr <= lfsr(30 downto 0) & not(lfsr(31) xor lfsr(21) xor lfsr(1) xor lfsr(0)); end if; if(L1Accept = '1')then L1AToggle <= not L1AToggle; end if; end if; end if; end process; periodicL1A_bp <= or_reduce(random_cnt); --rules(4) <= not in_gap; i_Threshold: Threshold PORT MAP( clk => ipb_clk, din => LocalL1A_cfg(15 downto 0), nongap_size => nongap_size, dout => random_th(31 downto 0) ); nongap_size <= gap_begin - gap_end when gap_end < gap_begin else gap_begin - gap_end + x"dec"; i_L1Accept : SRL16E port map ( Q => L1Accept, -- SRL data output A0 => Coarse_Delay(0), -- Select[0] input A1 => Coarse_Delay(1), -- Select[1] input A2 => Coarse_Delay(2), -- Select[2] input A3 => Coarse_Delay(3), -- Select[3] input CE => TTC_str, -- Clock enable input CLK => CDRclk, -- Clock input D => TTC_data(0) -- SRL data input ); i_brcst_str1 : SRL16E port map ( Q => brcst_str(1), -- SRL data output A0 => '1', -- Select[0] input A1 => '0', -- Select[1] input A2 => '0', -- Select[2] input A3 => '0', -- Select[3] input CE => TTC_str, -- Clock enable input CLK => CDRclk, -- Clock input D => brcst_str(0) -- SRL data input ); i_brcst_str3 : SRL16E port map ( Q => brcst_str(3), -- SRL data output A0 => Coarse_Delay(0), -- Select[0] input A1 => Coarse_Delay(1), -- Select[1] input A2 => Coarse_Delay(2), -- Select[2] input A3 => Coarse_Delay(3), -- Select[3] input CE => TTC_str, -- Clock enable input CLK => CDRclk, -- Clock input D => brcst_str(2) -- SRL data input ); -- old ttc_if code event_number_avl <= event_number_avl_i; inc_l1ac <= ttc_l1accept_dl; inc_serr <= ttc_sinerrstr; inc_derr <= ttc_dberrstr; ttc_ready <= CDR_lock; TTC_brcst <= ttc_brcst_i; CalType <= cal_type; process(CDRclk) begin if(CDRclk'event and CDRclk = '1')then -- ttc_sync_din(10) <= BrcstStr and not Brcst(7) and not Brcst(6) and Brcst(5) and Brcst(3); if(TTC_str = '1')then -- if(and_reduce((Brcst xnor OcNresetCmd(7 downto 0)) or OcNresetCmd(15 downto 8)) = '1' and BrcstStr = '1')then -- ttc_sync_din(10) <= '1'; -- else -- ttc_sync_din(10) <= '0'; -- end if; ttc_sync_din(11) <= ReSync; ttc_sync_din(10) <= OcRes; ttc_sync_din(9) <= SinErrStr; ttc_sync_din(8) <= DbErrStr; ttc_sync_din(7) <= L1Accept; ttc_sync_din(6) <= BCntRes; ttc_sync_din(5) <= EvCntRes; ttc_sync_din(4) <= BrcstStr; ttc_sync_din(3 downto 0) <= BrcstCmd; ttc_sync_wa(1 downto 0) <= ttc_sync_wa(0) & not ttc_sync_wa(1); end if; end if; end process; g_ttc_sync : for i in 0 to 11 generate i_ttc_sync : RAM32X1D port map ( DPO => ttc_sync_dout(i), -- Read-only 1-bit data output A0 => ttc_sync_wa(0), -- R/W address[0] input bit A1 => ttc_sync_wa(1), -- R/W address[1] input bit A2 => '0', -- R/W address[2] input bit A3 => '0', -- R/W address[3] input bit A4 => '0', -- R/W address[4] input bit D => ttc_sync_din(i), -- Write 1-bit data input DPRA0 => ttc_sync_ra(0), -- Read-only address[0] input bit DPRA1 => ttc_sync_ra(1), -- Read-only address[1] input bit DPRA2 => '0', -- Read-only address[2] input bit DPRA3 => '0', -- Read-only address[3] input bit DPRA4 => '0', -- Read-only address[4] input bit WCLK => CDRclk, -- Write clock input WE => TTC_str -- Write enable input ); end generate; process(clk) begin if(clk'event and clk = '1')then ttc_sync_wa1_SyncRegs <= ttc_sync_wa1_SyncRegs(0) & ttc_sync_wa(1); ttc_sync_wa0_SyncRegs <= ttc_sync_wa0_SyncRegs(0) & ttc_sync_wa(0); if(ttc_sync_wa1_SyncRegs(1) /= ttc_sync_ra(1) or ttc_sync_wa0_SyncRegs(1) /= ttc_sync_ra(0))then ttc_sync_ra(1 downto 0) <= ttc_sync_ra(0) & not ttc_sync_ra(1); ttc_sync_do_val <= '1'; else ttc_sync_do_val <= '0'; end if; ttc_sync_do <= ttc_sync_dout; end if; end process; process(clk) begin if(clk'event and clk = '1')then if(ttc_sync_do_val = '0')then ttc_soft_reset_i <= '0'; ttc_OCres_dl <= '0'; ttc_sinerrstr <= '0'; ttc_dberrstr <= '0'; ttc_l1accept_dl <= '0'; ttc_evcnt_reset <= '0'; ttc_brcst_i <= x"0"; else ttc_soft_reset_i <= ttc_sync_do(11); ttc_OCres_dl <= ttc_sync_do(10); ttc_sinerrstr <= ttc_sync_do(9); ttc_dberrstr <= ttc_sync_do(8); ttc_l1accept_dl <= ttc_sync_do(7); ttc_evcnt_reset <= ttc_sync_do(5); if(ttc_sync_do(4) = '1')then ttc_brcst_i <= ttc_sync_do(3 downto 0); else ttc_brcst_i <= x"0"; end if; end if; if(ttc_sync_do_val = '1')then if(flavor /= "G2" or local_TTC = '1')then ttc_bcntres_dl <= ttc_sync_do(6); else ttc_bcntres_dl <= ttc_sync_do(10); end if; if(bcnt = (LastBcnt - 1))then rst_bcnt <= '1'; -- elsif(flavor = "G2" and bcnt = x"ffe")then -- rst_bcnt <= '1'; else rst_bcnt <= '0'; end if; end if; if(ttc_sync_do_val = '1')then if(ttc_bcntres_dl = '1' and en_bcnt_res = '1')then if(flavor = "G2")then bcnt <= x"000"; else bcnt <= bcn_off(11 downto 0); end if; -- elsif(rst_bcnt = '1')then elsif(bcnt = LastBcnt)then bcnt <= x"000"; else bcnt <= bcnt + 1; end if; end if; if(ttc_OCres_dl = '1')then oc <= x"0000000" & OC_off; elsif(rst_bcnt = '1' and ttc_sync_do_val = '1')then oc <= oc + 1; end if; inc_oc <= ttc_bcntres_dl and ttc_sync_do_val; if(bcnt = cal_win_low and en_cal_win = '1')then cal_win <= '1'; elsif(bcnt(5 downto 0) = cal_win_high(5 downto 0))then cal_win <= '0'; end if; if(bcn_off(11 downto 0) = x"000" or flavor = "G2")then bcn_offs1 <= LastBcnt; else bcn_offs1 <= bcn_off(11 downto 0) - 1; end if; if(reset = '1' or CDR_lock = '0')then -- modified for dsp_chip301f en_bcnt_err <= "00"; elsif(rst_bcnt = '1' and ttc_sync_do_val = '1')then en_bcnt_err <= en_bcnt_err(0) & '1'; end if; if(reset = '1')then inc_bcnterr <= '0'; ttc_bcnt_err <= '0'; -- cs_trig(0) <= '0'; elsif(((ttc_bcntres_dl = '1' and bcnt /= bcn_offs1) or (ttc_bcntres_dl = '0' and bcnt = bcn_offs1 and flavor /= "G2")) and en_bcnt_err(1) = '1' and ttc_sync_do_val = '1')then inc_bcnterr <= '1'; ttc_bcnt_err <= '1'; -- cs_trig(0) <= '1'; else inc_bcnterr <= '0'; -- cs_trig(0) <= '0'; end if; -- if(ttc_brcst_i = x"7" or ttc_brcst_i = x"5")then -- ttc_soft_reset <= en_brcst; -- else -- ttc_soft_reset <= '0'; -- end if; if(ttc_brcst_i = x"9")then ttc_start <= en_brcst; else ttc_start <= '0'; end if; if(ttc_brcst_i = x"b")then ttc_stop <= en_brcst; else ttc_stop <= '0'; end if; if(ttc_brcst_i = x"4")then brcst_GapTrig <= '1'; elsif(rst_bcnt = '1')then brcst_GapTrig <= '0'; end if; if(ttc_brcst_i = x"6")then brcst_GapPed <= '1'; elsif(rst_bcnt = '1')then brcst_GapPed <= '0'; end if; if(ttc_brcst_i = x"8")then brcst_GapLaser <= '1'; else brcst_GapLaser <= '0'; end if; if(ttc_OCres_dl = '1')then cal_type <= x"0"; elsif(brcst_GapLaser = '1')then if(Laser_TO(13) = '1')then cal_type <= x"1"; elsif(cal_type /= x"f")then cal_type <= cal_type + 1; end if; end if; if(brcst_GapLaser = '1')then Laser_To <= (others => '0'); elsif(Laser_TO(13) = '0' and ttc_bcntres_dl = '1' and ttc_sync_do_val = '1')then Laser_To <= Laser_To + 1; end if; end if; end process; process(clk) begin if(clk'event and clk = '1')then if(reset = '1')then en_bcnt_res <= '1'; elsif(ttc_bcntres_dl = '1' and bcn_off(12) = '1' and ttc_sync_do_val = '1')then en_bcnt_res <= '0'; end if; end if; end process; process(clk) begin if(clk'event and clk = '1')then if(reset = '1')then ttc_serr <= '0'; ttc_derr <= '0'; rate_div <= (others => '0'); rate_cntr <= "000010"; rate_OFW <= '0'; else if(ttc_sinerrstr = '1')then ttc_serr <= '1'; end if; if(ttc_dberrstr = '1')then ttc_derr <= '1'; end if; if(ttc_sync_do_val = '1')then if(rate_div(7 downto 6) = "11" and rate_div(3) = '1')then dec_rate_cntr <= '1'; rate_div <= (others => '0'); else dec_rate_cntr <= '0'; rate_div <= rate_div + 1; end if; if(dec_rate_cntr /= ttc_sync_do(7))then if(ttc_sync_do(7) = '1')then rate_cntr <= rate_cntr + 1; elsif(rate_cntr /= "000010")then rate_cntr <= rate_cntr - 1; end if; end if; end if; if(rate_cntr(5) = '1')then rate_OFW <= '1'; elsif(rate_cntr(4) = '0')then rate_OFW <= '0'; end if; end if; end if; end process; process(clk) begin if(clk'event and clk = '1')then if(reset = '1')then event_number_avl_i <= '0'; else event_number_avl_i <= ttc_l1accept_dl and run and not IgnoreDAQ; end if; -- if(en_cal_win = '0')then -- event_number(51 downto 48) <= x"0"; -- event_number(44) <= '0'; -- else event_number(51) <= cal_win and brcst_GapTrig and cal_type(3) and not brcst_GapPed; event_number(50) <= cal_win and brcst_GapTrig and cal_type(2) and not brcst_GapPed; event_number(49) <= cal_win and brcst_GapTrig and cal_type(1) and not brcst_GapPed; event_number(48) <= cal_win and ((brcst_GapTrig and cal_type(0)) or brcst_GapPed); event_number(44) <= cal_win and (brcst_GapTrig or brcst_GapPed); -- end if; event_number(59 downto 56) <= cal_type; event_number(55 downto 52) <= state; event_number(47) <= brcst_GapTrig; event_number(46) <= brcst_GapPed; event_number(45) <= cal_win; event_number(43 downto 0) <= oc & bcnt; end if; end process; process(clk) begin if(clk'event and clk = '1')then -- if(reset = '1' or ttc_soft_reset_i = '1')then if(reset = '1')then sync_lost <= '0'; elsif(evn_fifo_full = '1' and event_number_avl_i = '1')then sync_lost <= '1'; end if; end if; end process; process(ipb_clk) begin if(ipb_clk'event and ipb_clk = '1')then DBSync <= DBSync(2 downto 0) & DB; if(flavor = "G2")then DB_cmd_i <= '0'; elsif(DBSync(3) /= DBSync(2) or DB_cmd_in = '1')then DB_cmd_i <= '1'; else DB_cmd_i <= '0'; end if; if(DB_cmd_i = '1')then L1A_rate_q <= L1A_rate; end if; if(ipb_strobe = '1' and ipb_write = '1' and ipb_addr(15 downto 4) = x"002" and ipb_addr(27) = '0')then case ipb_addr(3 downto 0) is when x"0" => ttc_cmd(0) <= ipb_wdata(31 downto 0); when x"1" => ttc_cmd(1) <= ipb_wdata(31 downto 0); when x"2" => ttc_cmd(2) <= ipb_wdata(31 downto 0); when x"3" => ttc_cmd(3) <= ipb_wdata(31 downto 0); when x"4" => ttc_cmd_cfg(0) <= ipb_wdata(31 downto 0); when x"5" => ttc_cmd_cfg(1) <= ipb_wdata(31 downto 0); when x"6" => ttc_cmd_cfg(2) <= ipb_wdata(31 downto 0); when x"7" => ttc_cmd_cfg(3) <= ipb_wdata(31 downto 0); when x"8" => gap_begin <= ipb_wdata(11 downto 0); when x"9" => gap_end <= ipb_wdata(11 downto 0); when x"a" => OcNresetCmd <= ipb_wdata(15 downto 0); when x"b" => ReSyncCmd <= ipb_wdata(15 downto 0); when x"d" => DBCmd <= ipb_wdata(15 downto 0); when x"e" => L1A_delay <= ipb_wdata(11 downto 0); when others => NULL; end case; end if; L1AToggleSync <= L1AToggleSync(2 downto 0) & L1AToggle; if(second(25) = '1')then L1A_cntr <= (others => '0'); second <= "00001000110010100110101111"; L1A_rate <= L1A_cntr; else if(L1AToggleSync(3) /= L1AToggleSync(2))then L1A_cntr <= L1A_cntr + 1; end if; second <= second + 1; end if; BX500 <= trig_BX - 3; if(BX500(12) = '1')then BX500 <= BX500 + x"dec"; end if; end if; end process; --ipb_ack <= '0' when ipb_addr(27) = '1' or ipb_addr(15 downto 4) /= x"002" or ipb_write = '1' else ipb_strobe; process(ipb_addr) begin if(ipb_addr(14 downto 4) /= "00000000010")then ipb_rdata <= (others => '0'); else case ipb_addr(3 downto 0) is when x"0" => ipb_rdata <= ttc_cmd(0); when x"1" => ipb_rdata <= ttc_cmd(1); when x"2" => ipb_rdata <= ttc_cmd(2); when x"3" => ipb_rdata <= ttc_cmd(3); when x"4" => ipb_rdata <= ttc_cmd_cfg(0); when x"5" => ipb_rdata <= ttc_cmd_cfg(1); when x"6" => ipb_rdata <= ttc_cmd_cfg(2); when x"7" => ipb_rdata <= ttc_cmd_cfg(3); when x"8" => ipb_rdata <= x"00000" & gap_begin; when x"9" => ipb_rdata <= x"00000" & gap_end; when x"a" => ipb_rdata <= x"0000" & OcNresetCmd; when x"b" => ipb_rdata <= x"0000" & ReSyncCmd; when x"c" => if(ipb_addr(15) = '0')then ipb_rdata <= "0000000" & L1A_rate; else ipb_rdata <= "0000000" & L1A_rate_q; end if; when x"d" => ipb_rdata <= x"0000" & DBCmd; when x"e" => ipb_rdata <= x"00000" & L1A_delay; when others => ipb_rdata <= (others => '0'); end case; end if; end process; gap_beginp <= gap_begin - 5 when gap_begin > 4 else gap_begin + x"de7"; gap_endp <= gap_end - 5 when gap_end > 4 else gap_end + x"de7"; process(CDRclk) begin if(CDRclk'event and CDRclk = '1')then if(TTC_str = '1')then TTC_L1A_wa <= TTC_L1A_wa + 1; if(TTC_L1A_wa = L1A_delay)then TTC_L1A_ra <= (others => '0'); else TTC_L1A_ra <= TTC_L1A_ra + 1; end if; if(cmd_cntr = "111100")then en_TTC_L1A <= '0'; TTC_L1A_Di(0) <= en_TTC_L1A; else for i in 0 to 3 loop if(TTC_cmd_cfg(i)(31) = '1' and TTC_cmd_done(i) = '1')then en_TTC_L1A <= '1'; end if; end loop; TTC_L1A_Di(0) <= '0'; end if; end if; end if; end process; i_TTC_L1A : BRAM_SDP_MACRO generic map ( BRAM_SIZE => "18Kb", -- Target BRAM, "18Kb" or "36Kb" DEVICE => "7SERIES", -- Target device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6" WRITE_WIDTH => 4, -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb") READ_WIDTH => 4) -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb") port map ( DO => TTC_L1A_Do, -- Output read data port, width defined by READ_WIDTH parameter DI => TTC_L1A_Di, -- Input write data port, width defined by WRITE_WIDTH parameter RDADDR => TTC_L1A_ra, -- Input read address, width defined by read port depth RDCLK => CDRclk, -- 1-bit input read clock RDEN => TTC_str, -- 1-bit input read port enable REGCE => '1', -- 1-bit input read output register enable RST => '0', -- 1-bit input reset WE => "1", -- Input write enable, width defined by write port depth WRADDR => TTC_L1A_wa, -- Input write address, width defined by write port depth WRCLK => CDRclk, -- 1-bit input write clock WREN => TTC_str -- 1-bit input write port enable ); end ttc_arch;