------------------------------------------------------- -- Design Name : L2CB_015_top -- File Name : L2CB_015_top.vhd -- Device : Spartan 6, XC6SLX100FGG-L1FGG676I -- Migration Device : Spartan 6, XC6SLX100FGG-L1FGG676I -- Function : digital trigger L2 controller board, top level design -- Coder(s) : K.-H. Sulanke, DESY, 2024-09-11 ------------------------------------------------------- -- 2016-01-19, for test purposes, TIB_CLK /_PPS signal generation added -- 2016-01-22, L1 inputs with iodelay only, L2 outputs with iodelay only -- 2016-02-10, CTDB_CLKx_P/N is 50 MHz now, with PPS modulated -- 2016-02-16, CTDB_CLKx_P/N is 50 MHz, not with PPS modulated anymore -- 2016-03-18, artificial L2 trigger signal added for test purposes (pull LVDS_IO_P_7 on GND) -- 2016-03-31, artificial L2 trigger removed, trying to implement L2_TRIG() as ODDR2 -- 2016-04-01, constant CTDB_L2_TRIGGER_DELAY optimized for the use of CTDB1 #1..3 in -- slots 1..3 -- artificial TIB, loop back connection: grey cable=>J15, blue cable=>J14 -- test pins: J7-5=black, J7-6=green, J7-7=orange, J7-8=red -- 2016-10-18, QOSC1_OUT used for local (SPI, Stamp,..) control, spi_master_16bit_01 introduced -- 2017-02-21, recompiled, check the CTDB_PPS distribution ! with left side (slots 1..9) triggered -- at right side slots (13..21) missed pps observed -- 2017-03-21 missing termination for tib_clck and tib_pps added, CTDB_PPS2_ODELAY changed from 0 to 48 -- further recommended improvement: smapling the tib_pps using iserdes -- 2017-05-09 rev. 004, spi_master_16bit_02.vhd with corrected SPI bus busy handling now -- 2017-05-22 rev. 005, l1-trigger masking included, -- IOSTANDARD changed to PCI33_3 for high level > = 0.6V (50% of VCCO) see ... -- NET "L1_BUSY<>" IOBDELAY = IBUF | IOSTANDARD = PCI33_3; # will be again LVCMOS12 with CTDB2; -- NET "L1_TRIG<>" IOBDELAY = NONE | IOSTANDARD = PCI33_3; # LVCMOS12; -- PCI33_3 => VIHmin=0.6V, VILmax=0.48V; LVCMOS12 => VIHmin=0.8V, VILmax=0.38V; -- 2018-03-22 trying to recover already running rev. 004 -- 2023-10-18 trying to implement the Muon trigger, using jumper-connected -- LVDS_IO6->LVDS_IO7 as external trigger edge delay -- 2024-02-28 for test purposes removed the L2_TRIG() output delay, to understand the missing last trigger; -- changed the way the tib_mcf_trig is being generated -- 2024-03-01 reinstalled the L2_TRIG() output delay, added the register MUDEL -- 2024-09-11 added programmable gating of tib_event when FEB-BUSY is on, using CTRL-bit14 (default is '1') library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all ; use IEEE.numeric_std.all ; library unisim ; use unisim.vcomponents.all ; use work.L2CB_pkg.all; entity L2CB_015_top is generic ( FW_REVISION : std_logic_vector(15 downto 0) := X"000f"; BASE_ADDR : std_logic_vector(20 downto 8) := '0' & X"000"; CLKIN_PERIOD_Q3 : real := 100.0 -- onboard QOSC Q3 ); port( PON_RESETn : in std_logic ; -- 2.5V CMOS with pullup, reset (active low, by power monitor LTC2903-A1) -- 200 ms after all power lines are settled, might be useless due to race condition -- with FPGA configuration time DCDC_SYNC : out std_logic ; -- 3.3V CMOS, QOSC1_OUT : in std_logic ; -- 3.3V CMOS, GCLK18, 25 MHz QOSC1_DAC_SYNCn : out std_logic ; -- 3.3V CMOS, QOSC1_DAC_SCKL : out std_logic ; -- 3.3V CMOS, QOSC1_DAC_SDIN : out std_logic ; -- 3.3V CMOS, QOSC2_OUT : in std_logic ; -- 3.3V CMOS, GCLK13, 10 MHz QOSC2_DAC_SYNCn : out std_logic ; -- 3.3V CMOS, QOSC2_ENA : out std_logic ; -- 3.3V CMOS, L1_TRIG : in std_logic_vector(1 to 270); L1_BUSY : in std_logic_vector( 1 to 18); -- ORed clusters BUSY L2_TRIG_P : out std_logic_vector( 1 to 18); -- LVDS, gets fanout to all CTDBs L2_TRIG_N : out std_logic_vector( 1 to 18); -- LVDS CTDB_CLK1_P : out std_logic; -- LVDS, xored EXT_CLK + EXT_PPS CTDB_CLK1_N : out std_logic; -- LVDS CTDB_CLK2_P : out std_logic; -- LVDS, xored EXT_CLK + EXT_PPS CTDB_CLK2_N : out std_logic; -- LVDS CTDB_PPS1_P : out std_logic; -- LVDS, xored EXT_CLK + EXT_PPS CTDB_PPS1_N : out std_logic; -- LVDS CTDB_PPS2_P : out std_logic; -- LVDS, xored EXT_CLK + EXT_PPS CTDB_PPS2_N : out std_logic; -- LVDS CTDB_CLK_SEL : out std_logic; -- connected to IN_SEL of the clock fanout / driver ADCLK854 CTDB_PPS_SEL : out std_logic; -- connected to IN_SEL of the PPS fanout / driver ADCLK854 -- TIB related signals TIB_CLK_P : in std_logic; -- GCLK17, TIB, cable 1, all LVDS TIB_CLK_N : in std_logic; -- GCLK16, TIB_PPS_P : in std_logic; -- GCLK15, TIB_PPS_N : in std_logic; -- GCLK14, TIB_CAMERA_T0_P : out std_logic; -- TIB_CAMERA_T0_N : out std_logic; -- TIB_SPARE0_P : out std_logic; -- LVDS I/Otib_pps TIB_SPARE0_N : out std_logic; -- TIB_CAMERA_T1_P : out std_logic; -- TIB, cable 2, all LVDS TIB_CAMERA_T1_N : out std_logic; -- TIB_BUSY_P : out std_logic; -- LVDS TIB_BUSY_N : out std_logic; -- LVDS TIB_EVENT_T_P : in std_logic; -- TIB_EVENT_T_N : in std_logic; -- TIB_SPARE1_P : out std_logic; -- used as MCF_P (Muon Candidate Flag) TIB_SPARE1_N : out std_logic; -- used as MCF_N (Muon Candidate Flag) -- Stamp9G45 1.8V signals EBI1_ADDR : in std_logic_vector(20 downto 0); -- up to 21 memory bus address signals EBI1_D : inout std_logic_vector(15 downto 0); -- memory bus data signals EBI1_NWE : in std_logic; --EBI1_NWE/NWR0/CFWE, low active write strobe EBI1_NCS2 : in std_logic; --PC13/NCS2, address (hex) 3000 0000, low active Chip Select 2 EBI1_NRD : in std_logic; --EBI1_NRD/CFOE, low active read strobe EBI1_NWAIT : out std_logic; --PC15/NWAIT, low active -- Stamp9G45 3.3V signals PC1_ARM_IRQ0 : out std_logic; -- PIO port PC1, used as edge (both) triggered interrupt signal -- single wire 64 bit EEPROM ADDR_64BIT : inout std_logic; -- 3.3V CMOS, one wire serial EEPROM DS2431P+ -- slow control SPI Bus, as BUS LVDS on the backplane SPI_MISO_P : in std_logic; -- 3.3V CMOS, diff. LVDS receiver FIN1101 SPI_MISO_N : in std_logic; -- 3.3V CMOS, diff. LVDS receiver FIN1101 SPI_SCLK : out std_logic; -- 3.3V CMOS, multipoint LVDS driver SN65MLVD047A SPI_SYNCn : out std_logic; -- 3.3V CMOS, multipoint LVDS driver SN65MLVD047A SPI_MOSI : out std_logic; -- 3.3V CMOS, multipoint LVDS driver SN65MLVD047A, L2CB view -- GPS module LEA-6T GPS_RESET_N : out std_logic; -- 3.3V CMOS, GPS-module reset GPS_EXTINT0 : out std_logic; -- 3.3V CMOS, interrupt signal for time stamping an event GPS_TIMEPULSE1 : in std_logic; -- 3.3V CMOS, GCLK12, typical used as PPS pulse GPS_TIMEPULSE2 : in std_logic; -- 3.3V CMOS, GCLK19, configurable, clock from 0.25 Hz to 10 MHz GPS_RXD1 : out std_logic; -- 3.3V CMOS, GPS_TXD1 : in std_logic; -- 3.3V CMOS, -- RS232 port RS232_TXD : out std_logic; -- 3.3V CMOS, RS232_RXD : in std_logic; -- 3.3V CMOS, -- USB to RS232 port USB_RS_TXD : out std_logic; -- 3.3V CMOS, USB_RS_RXD : in std_logic; -- 3.3V CMOS, -- Temperature TEMPERATURE : inout std_logic; -- 3.3V CMOS, inout , one wire temp. sensor TMP05BRTZ -- test signals -- LVDS_IO_P : out std_logic_vector(7 downto 0); -- LVDS bidir. test port -- LVDS_IO_N : out std_logic_vector(7 downto 0) -- LVDS bidir. test port LVDS_IO_P0 : out std_logic; --in TIB_CLK_P , faked TIB signals, connected to RJ45 J15 LVDS_IO_N0 : out std_logic; --in TIB_CLK_N LVDS_IO_P1 : out std_logic; --in TIB_PPS_P LVDS_IO_N1 : out std_logic; --in TIB_PPS_N LVDS_IO_P2 : out std_logic; -- LVDS_IO_N2 : out std_logic; -- LVDS_IO_P3 : out std_logic; -- trigger clock output LVDS_IO_N3 : out std_logic; -- trigger clock output LVDS_IO_P4 : out std_logic; -- trigger clock input LVDS_IO_N4 : out std_logic; -- trigger clock input LVDS_IO_P5 : out std_logic; -- LVDS_IO_N5 : out std_logic; -- LVDS_IO_P6 : out std_logic; -- LVDS_IO_N6 : out std_logic; -- LVDS_IO_P7 : out std_logic; -- LVDS_IO_N7 : out std_logic -- ); end L2CB_015_top; architecture arch_L2CB_015_top of L2CB_015_top is type out_delay_array is array (1 to 18) of integer; -- delays, calculated (EXCEL) from Post Map Static Timing report / -- Data Sheet report, assuming 37ps/tap constant CTDB_L2_TRIGGER_DELAY : out_delay_array := --( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 ); ( 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); constant CTDB_CLK1_ODELAY : integer:= 3; constant CTDB_CLK2_ODELAY : integer:= 0; constant CTDB_PPS1_ODELAY : integer:= 0; constant CTDB_PPS2_ODELAY : integer:= 66; constant TIB_TRIG_ODELAY : integer:= 255; -- 9.4ns ? 37ps * 255? constant MUON_THR_INIT : std_logic_vector (8 downto 0) := B"0_0001_0100"; constant MUON_DEL_INIT : std_logic_vector (3 downto 0) := B"1010"; constant CTRL_RG_INIT : std_logic_vector (15 downto 0) := X"4000"; constant UP_TRIG_PULSE_LENGTH : integer:= 25; -- trigger pulse to TIB in multiples of 4ns constant MCF_DELAY : integer:= 10; -- delay after the up-trigger-LH edge before checking -- for the MCF trigger, in multiples of 4ns component spi_master_16bit_02 is generic (CLOCK_DIVIDER : integer := 2); --was 2, SPI_CLK = SYS_CLK / (CLOCK_DIVIDER * 4) port ( reset : in std_logic ; -- synchronous reset clk : in std_logic ; -- 50 MHz clock tx_addr : in std_logic_vector (14 downto 0); -- header, destination address tx_data : in std_logic_vector (15 downto 0); -- data to be sent rx_data : out std_logic_vector (15 downto 0); -- data received spi_run : in std_logic ; -- initiate spi cycle spi_wr : in std_logic ; -- '0' if read cycle, header bit 31 spi_busy : out std_logic ; -- spi cycle pending spi_sync : out std_logic ; -- backplane bus, low active sync signal spi_sclk : out std_logic ; -- backplane bus, SPI clock spi_mosi : out std_logic ; -- backplane bus, serial SPI tx-data spi_miso : in std_logic -- backplane bus, serial SPI rx-data ); end component spi_master_16bit_02; component in_single_ended_del_01 is port ( reset : in std_logic ; -- reset (active high) clk : in std_logic ; -- global clock input io_clk : in std_logic ; -- high speed i/o clock sdat_in : in std_logic; -- single ended serial data input del_data : in std_logic_vector (7 downto 0); -- delay value del_load : in std_logic; -- to initiate the DELAY cycle, single pulse del_busy : out std_logic; -- '1' until delay set procedure finished del_dataout2 : out std_logic -- ); end component in_single_ended_del_01 ; component oserdes_odelay_01 is generic (odelay : integer range 0 to 255 := 0); port ( clk : in std_logic ; -- pdat clock reset : in std_logic; oserdes_pdat : in std_logic_vector (0 to 7); -- serdes pdat oserdes_ioclk : in std_logic; oserdes_stb : in std_logic; oserdes_out_dld : out std_logic -- delayed oserdes output ); end component oserdes_odelay_01 ; constant GPS_FREQUENCY : std_logic_vector(24 downto 0) := B"1011011100011011000000000"; -- 24000000, (24 MHz) constant ZERO_64 : std_logic_vector(0 to 63) := X"0000000000000000"; signal qosc1_reset : std_logic := '0'; -- driven by pll_locked signal qosc1_clk : std_logic; -- local 25 MHz, base for SPI and Stamp9G45 memory interface, also used for Stamp9G45 ethernet -- pll, driven by QOSC1 clock signal qosc1_pll_reset : std_logic := '0'; signal qosc1_pll_clkin : std_logic; -- primary clock input signal qosc1_pll_clkfbin : std_logic; -- signal qosc1_pll_clkout2 : std_logic; -- pll output, par. data clock signal qosc1_pll_clkout3 : std_logic; -- pll output, par. data clock signal qosc1_pll_locked : std_logic; -- active high pll lock signal signal qosc1_gclk2 : std_logic; -- system clock for SPI etc. signal qosc1_gclk3 : std_logic; -- hign speed synchronizer clock -- QOSC2_OUT, used for test purposes (e.g. TIB_CLK / _PPS generation) signal qosc2_clk : std_logic; signal qosc2_divclk : std_logic; -- for test purposes signal qosc2_dcm_clkin : std_logic; signal qosc2_dcm_clk0 : std_logic; signal qosc2_dcm_clkfb : std_logic; signal qosc2_dcm_clkfx : std_logic; signal qosc2_dcm_clkfx180 : std_logic; signal qosc2_dcm_locked : std_logic; signal qosc2_dcm_rst : std_logic; signal qosc2_dcm_status : std_logic_vector(7 downto 0); signal qosc2_bufg_clkfx : std_logic; signal qosc2_bufg_clkfx180 : std_logic; -- TIB_CLK, DCM_SP signals signal tib_dcm_clkin : std_logic; signal tib_dcm_clk0 : std_logic; signal tib_dcm_clkfb : std_logic; signal tib_dcm_locked : std_logic; signal tib_dcm_rst : std_logic; signal tib_dcm_status : std_logic_vector(7 downto 0); -- pll, driven by TIB clock signal tib_pll_reset : std_logic; signal tib_pll_clkin : std_logic; -- primary clock input signal tib_pll_clkfbout : std_logic; -- signal tib_pll_clkout0 : std_logic; -- pll output, fast i/o clock signal tib_pll_clkout1 : std_logic; -- pll output, fast i/o clock signal tib_pll_clkout2 : std_logic; -- pll output, par. data clock signal tib_pll_clkout3 : std_logic; -- pll output, par. data clock signal tib_pll_clkout4 : std_logic; -- pll output, par. data clock signal tib_pll_clkout5 : std_logic; -- pll output, par. data clock signal tib_pll_locked : std_logic; -- active high pll lock signal -- global clocks, made from TIB-10MHz signal tib_gclk2 : std_logic; -- made from pll_clkout2 signal tib_gclk3 : std_logic; -- made from pll_clkout3 signal tib_gclk4 : std_logic; -- made from pll_clkout4 signal tib_gclk2x2 : std_logic; -- made from pll_clkout5 signal tib_reset : std_logic := '0'; -- made from tib_pll_locked -- bufpll signal tib_oserdes_stb0 : std_logic; -- bank_0 signal tib_oserdes_stb2 : std_logic; -- bank_2 signal tib_oserdes_clk0 : std_logic; signal tib_iserdes_clk1 : std_logic; signal tib_oserdes_clk2 : std_logic; signal tib_iserdes_clk3 : std_logic; signal tib_iserdes_clk4 : std_logic; signal tib_iserdes_clk5 : std_logic; -- SPI bus (backplane) control signal spi_run : std_logic := '0'; signal spi_busy : std_logic := '0'; --signal spi_done : std_logic := '0'; signal spi_miso : std_logic := '0'; -- time stamping signal time_stamp_ct : std_logic_vector(47 downto 0); -- driven by tib_gclk2, e.g. 950 / 8 MHz signal tstmp_lat : std_logic := '0'; -- -- CTDB signals signal l2_trig_out : std_logic; signal l2_trig_out_n : std_logic; attribute clock_signal : string; attribute clock_signal of l2_trig_out : signal is "yes"; attribute clock_signal of l2_trig_out_n : signal is "yes"; signal l2_trig_bufg : std_logic; signal l2_trig_bufg_n : std_logic; signal l2_trig : std_logic_vector(1 to 18); signal l2_trig_dld : std_logic_vector(1 to 18); signal ctdb_clk1 : std_logic := '0'; signal ctdb_clk_oserdes_pdat : std_logic_vector(7 downto 0); signal ctdb_clk1_dld : std_logic := '0'; signal ctdb_clk2 : std_logic := '0'; signal ctdb_clk2_dld : std_logic := '0'; signal ctdb_pps1 : std_logic := '0'; signal ctdb_pps1_dld : std_logic := '0'; signal ctdb_pps2 : std_logic := '0'; signal ctdb_pps2_dld : std_logic := '0'; -- TIB signals signal tib_clk : std_logic := '0'; signal tib_pps : std_logic := '0'; signal tib_pps_pipe : std_logic := '0'; --signal tib_single_pps : std_logic := '1'; signal tib_camera_t0 : std_logic := '0'; signal tib_camera_t1 : std_logic := '0'; signal tib_event_t : std_logic := '0'; signal tib_busy : std_logic := '0'; signal tib_spare0 : std_logic := '0'; signal tib_mcf : std_logic := '0'; -- Muon Candidate Flag now signal tib_clk_out : std_logic := '0'; -- for test purposes, connected to LVDS_IO_P/N(0) signal tib_pps_out : std_logic := '0'; -- for test purposes, connected to LVDS_IO_P/N(1) -- GPS signals signal gps_clk : std_logic; -- made from GPS_TIMEPULSE2 signal gps_reset : std_logic := '0'; -- made from qosc1_reset signal gps_pps : std_logic; -- made from GPS_TIMEPULSE1 signal pps : std_logic_vector(1 downto 0) := B"00"; signal pps_lh_edge : std_logic := '0'; -- signal gps_ct_mismatch : std_logic := '0'; -- amount of clock cycles between pps pulse not like expected signal gps_ct : std_logic_vector(GPS_FREQUENCY'length downto 0) := (others =>'0'); -- -- cluster trigger iserdes, signal delay and parallel outputs signal l1_trig_rm : std_logic_vector(269 downto 0) := (others =>'0'); -- remapped L1_TRIG() signals signal l1_trig_dld : std_logic_vector(269 downto 0) := (others =>'0'); signal l1_trig_msk : std_logic_vector(269 downto 0) := (others =>'0'); -- trigger mask programmed signal l1_trig_msk_rm : std_logic_vector(269 downto 0) := (others =>'0'); -- remapped trigger mask signal l1_trig_dld_msk_rm : std_logic_vector(269 downto 0) := (others =>'0'); -- delayed, masked and remapped l1 trigger signal l1_del_load : std_logic_vector(269 downto 0) := (others =>'0'); -- single pulse signal l1_del_busy : std_logic_vector(269 downto 0) := (others =>'0'); -- '1' while delay is being adjusted signal l1_delay_busy : std_logic := '0'; type array_270x8 is array (269 downto 0) of std_logic_vector(7 downto 0); signal l1_del_rg : array_270x8; -- to keep all delay values for read back signal camera_trig_intermediate : std_logic_vector(269 downto 0); signal camera_trig : std_logic; signal camera_trig_dld : std_logic; signal l1_trig_sum : natural range 0 to 266; signal muon_detected : std_logic; -- trigger pulse generation signal trig_pipe : std_logic_vector(2 downto 0) := B"000"; signal camera_trig_bufg : std_logic := '0'; signal camera_trig_clr : std_logic := '0'; signal camera_trig_en : std_logic := '0'; signal camera_trig_t0 : std_logic := '0'; signal mcf_pipe : std_logic_vector(2 downto 0) := B"000"; signal tib_mcf_trig : std_logic := '0'; -- local Stamp9G45 - bus signal ebi1_d_in : std_logic_vector(15 downto 0); -- IO_BUF_O, data from memory signal ebi1_d_out : std_logic_vector(15 downto 0); -- IO_BUF_I, data to memory signal ebi1_d_trst : std_logic; -- IO_BUF_T, io buffer tristate signal ebi1_d_rg : std_logic_vector(15 downto 0); -- register to latch data from Stamp9G45 signal ebi1_ncs2_pipe : std_logic_vector(2 downto 0) := B"000"; signal ebi1_ncs2_hl : std_logic := '0'; signal ebi1_ncs2_hl_clr : std_logic := '0'; signal ebi1_nwe_pipe : std_logic_vector(2 downto 0) := B"000"; signal ebi1_nwe_lh : std_logic := '0'; signal ebi1_nwe_lh_clr : std_logic := '0'; signal reg_sel : std_logic := '0'; signal rg_wstb : std_logic := '0'; -- register to latch the EBI1_NWE signal rg_wstb_clr : std_logic := '0'; -- asynchronous clear -- 64 bit unique (1-wire) ID chip, signal addr_64bit_in : std_logic; -- IO_BUF_O, data receiveduj signal addr_64bit_out : std_logic; -- IO_BUF_I, data to be sent signal addr_64bit_trst : std_logic; -- IO_BUF_T, io buffer tristate -- TEMPERATURE sensor signal temperature_in : std_logic; -- IO_BUF_O, data receiveduj signal temperature_out : std_logic; -- IO_BUF_I, data to be sent signal temperature_trst : std_logic; -- IO_BUF_T, io buffer tristate -- status and control registers signal ctrl_rg : std_logic_vector(15 downto 0) := (others => '0'); -- global control register signal spad_rg : std_logic_vector(15 downto 0) := (others => '0'); -- SPI Address & WRnRD register signal sptx_rg : std_logic_vector(15 downto 0) := (others => '0'); -- SPI tx data register signal sprx_rg : std_logic_vector(15 downto 0) := (others => '0'); -- SPI rx data register signal l1sel_rg : std_logic_vector( 8 downto 0) := (others => '0'); -- trigger mask slot nr. signal l1msk_rg : std_logic_vector(15 downto 1) := (others => '0'); -- trigger channel mask signal l1msk_rd_rg : std_logic_vector(15 downto 1) := (others => '0'); -- trigger channel mask read back reg. signal muon_thr_rg : std_logic_vector( 8 downto 0) := (others => '0'); -- min. amount of L1 to cause a muon trigger signal muon_del_rg : std_logic_vector( 3 downto 0) := (others => '0'); -- muon trigger detect window required -- by the 265bit adder, multiples of 4ns signal l1msk_rg_wstb : std_logic := '0' ; -- synchronous to qosc1_gclk2 signal l1_del_rg_wstb : std_logic := '0' ; signal l1_del_rg_wstb_clr : std_logic := '0' ; signal l1_del_rg_wstb_clr_pipe : std_logic_vector(3 downto 0) := B"0000" ; signal l1_del_rg_wstb_syncd : std_logic := '0' ; -- synchronous to tib_gclk2 signal l1_del_rg_wstb_pipe : std_logic_vector(3 downto 0) := B"0000" ; signal test_rg : std_logic_vector(15 downto 0) := (others => '0'); -- test register signal stat_rg : std_logic_vector(15 downto 0) := (others => '0'); -- global status register signal tstmp0_rg : std_logic_vector(15 downto 0) := (others => '0'); -- time stamp #0 reg. signal tstmp1_rg : std_logic_vector(15 downto 0) := (others => '0'); -- time stamp #1 reg. signal tstmp2_rg : std_logic_vector(15 downto 0) := (others => '0'); -- time stamp #2 reg. signal fwrev_rg : std_logic_vector(15 downto 0) := (others => '0'); -- fimware revision signal ctrl_addr : std_logic := '0' ; -- needed for write access only signal spad_addr : std_logic := '0' ; signal sptx_addr : std_logic := '0' ; signal l1sel_addr : std_logic := '0' ; signal l1msk_addr : std_logic := '0' ; signal l1del_addr : std_logic := '0' ; signal test_addr : std_logic := '0' ; signal muthr_addr : std_logic := '0' ; signal mudel_addr : std_logic := '0' ; signal lvds_io_0 : std_logic; signal lvds_io_1 : std_logic; signal lvds_io_2 : std_logic; signal lvds_io_3 : std_logic; signal lvds_io_4 : std_logic; -- used as ... signal lvds_io_5 : std_logic; signal lvds_io_6 : std_logic; signal lvds_io_7 : std_logic; begin -- of arch_L2CB_015_top -- L1 trigger input remapping required for easier iserdes setup -- L1_TRIG() bank_5 mapping ------------------------- l1_trig_rm(0) <= L1_TRIG(1); l1_trig_rm(1) <= L1_TRIG(2); l1_trig_rm(2) <= L1_TRIG(3); l1_trig_rm(3) <= L1_TRIG(4); l1_trig_rm(4) <= L1_TRIG(5); l1_trig_rm(5) <= L1_TRIG(6); l1_trig_rm(6) <= L1_TRIG(7); l1_trig_rm(7) <= L1_TRIG(8); l1_trig_rm(8) <= L1_TRIG(9); l1_trig_rm(9) <= L1_TRIG(10); l1_trig_rm(10) <= L1_TRIG(11); l1_trig_rm(11) <= L1_TRIG(12); l1_trig_rm(12) <= L1_TRIG(13); l1_trig_rm(13) <= L1_TRIG(14); l1_trig_rm(14) <= L1_TRIG(15); l1_trig_rm(15) <= L1_TRIG(31); l1_trig_rm(16) <= L1_TRIG(34); l1_trig_rm(17) <= L1_TRIG(126); l1_trig_rm(18) <= L1_TRIG(128); l1_trig_rm(19) <= L1_TRIG(129); l1_trig_rm(20) <= L1_TRIG(130); l1_trig_rm(21) <= L1_TRIG(141); l1_trig_rm(22) <= L1_TRIG(226); l1_trig_rm(23) <= L1_TRIG(227); l1_trig_rm(24) <= L1_TRIG(228); l1_trig_rm(25) <= L1_TRIG(229); l1_trig_rm(26) <= L1_TRIG(230); l1_trig_rm(27) <= L1_TRIG(231); l1_trig_rm(28) <= L1_TRIG(233); l1_trig_rm(29) <= L1_TRIG(235); l1_trig_rm(30) <= L1_TRIG(236); l1_trig_rm(31) <= L1_TRIG(239); l1_trig_rm(32) <= L1_TRIG(240); l1_trig_rm(33) <= L1_TRIG(256); l1_trig_rm(34) <= L1_TRIG(257); l1_trig_rm(35) <= L1_TRIG(258); l1_trig_rm(36) <= L1_TRIG(259); l1_trig_rm(37) <= L1_TRIG(260); l1_trig_rm(38) <= L1_TRIG(261); l1_trig_rm(39) <= L1_TRIG(262); l1_trig_rm(40) <= L1_TRIG(263); l1_trig_rm(41) <= L1_TRIG(264); l1_trig_rm(42) <= L1_TRIG(265); l1_trig_rm(43) <= L1_TRIG(266); l1_trig_rm(44) <= L1_TRIG(267); l1_trig_rm(45) <= L1_TRIG(268); l1_trig_rm(46) <= L1_TRIG(269); -- L1_TRIG() bank_1 mapping ------------------------- l1_trig_rm(47+0) <= L1_TRIG(32); l1_trig_rm(47+1) <= L1_TRIG(33); l1_trig_rm(47+2) <= L1_TRIG(35); l1_trig_rm(47+3) <= L1_TRIG(36); l1_trig_rm(47+4) <= L1_TRIG(37); l1_trig_rm(47+5) <= L1_TRIG(38); l1_trig_rm(47+6) <= L1_TRIG(39); l1_trig_rm(47+7) <= L1_TRIG(40); l1_trig_rm(47+8) <= L1_TRIG(41); l1_trig_rm(47+9) <= L1_TRIG(42); l1_trig_rm(47+10) <= L1_TRIG(43); l1_trig_rm(47+11) <= L1_TRIG(44); l1_trig_rm(47+12) <= L1_TRIG(45); l1_trig_rm(47+13) <= L1_TRIG(61); l1_trig_rm(47+14) <= L1_TRIG(62); l1_trig_rm(47+15) <= L1_TRIG(63); l1_trig_rm(47+16) <= L1_TRIG(64); l1_trig_rm(47+17) <= L1_TRIG(65); l1_trig_rm(47+18) <= L1_TRIG(66); l1_trig_rm(47+19) <= L1_TRIG(67); l1_trig_rm(47+20) <= L1_TRIG(68); l1_trig_rm(47+21) <= L1_TRIG(69); l1_trig_rm(47+22) <= L1_TRIG(70); l1_trig_rm(47+23) <= L1_TRIG(71); l1_trig_rm(47+24) <= L1_TRIG(72); l1_trig_rm(47+25) <= L1_TRIG(73); l1_trig_rm(47+26) <= L1_TRIG(74); l1_trig_rm(47+27) <= L1_TRIG(75); l1_trig_rm(47+28) <= L1_TRIG(91); l1_trig_rm(47+29) <= L1_TRIG(92); l1_trig_rm(47+30) <= L1_TRIG(93); l1_trig_rm(47+31) <= L1_TRIG(94); l1_trig_rm(47+32) <= L1_TRIG(95); l1_trig_rm(47+33) <= L1_TRIG(96); l1_trig_rm(47+34) <= L1_TRIG(97); l1_trig_rm(47+35) <= L1_TRIG(98); l1_trig_rm(47+36) <= L1_TRIG(99); l1_trig_rm(47+37) <= L1_TRIG(100); l1_trig_rm(47+38) <= L1_TRIG(101); l1_trig_rm(47+39) <= L1_TRIG(102); l1_trig_rm(47+40) <= L1_TRIG(103); l1_trig_rm(47+41) <= L1_TRIG(104); l1_trig_rm(47+42) <= L1_TRIG(105); l1_trig_rm(47+43) <= L1_TRIG(121); l1_trig_rm(47+44) <= L1_TRIG(122); l1_trig_rm(47+45) <= L1_TRIG(123); l1_trig_rm(47+46) <= L1_TRIG(124); l1_trig_rm(47+47) <= L1_TRIG(125); l1_trig_rm(47+48) <= L1_TRIG(127); l1_trig_rm(47+49) <= L1_TRIG(136); l1_trig_rm(47+50) <= L1_TRIG(137); l1_trig_rm(47+51) <= L1_TRIG(138); l1_trig_rm(47+52) <= L1_TRIG(139); l1_trig_rm(47+53) <= L1_TRIG(140); l1_trig_rm(47+54) <= L1_TRIG(166); l1_trig_rm(47+55) <= L1_TRIG(167); l1_trig_rm(47+56) <= L1_TRIG(168); l1_trig_rm(47+57) <= L1_TRIG(169); l1_trig_rm(47+58) <= L1_TRIG(170); l1_trig_rm(47+59) <= L1_TRIG(171); l1_trig_rm(47+60) <= L1_TRIG(172); l1_trig_rm(47+61) <= L1_TRIG(173); l1_trig_rm(47+62) <= L1_TRIG(174); l1_trig_rm(47+63) <= L1_TRIG(175); l1_trig_rm(47+64) <= L1_TRIG(176); l1_trig_rm(47+65) <= L1_TRIG(177); l1_trig_rm(47+66) <= L1_TRIG(178); l1_trig_rm(47+67) <= L1_TRIG(179); l1_trig_rm(47+68) <= L1_TRIG(180); l1_trig_rm(47+69) <= L1_TRIG(196); l1_trig_rm(47+70) <= L1_TRIG(197); l1_trig_rm(47+71) <= L1_TRIG(198); l1_trig_rm(47+72) <= L1_TRIG(199); l1_trig_rm(47+73) <= L1_TRIG(200); l1_trig_rm(47+74) <= L1_TRIG(201); l1_trig_rm(47+75) <= L1_TRIG(202); l1_trig_rm(47+76) <= L1_TRIG(203); l1_trig_rm(47+77) <= L1_TRIG(204); l1_trig_rm(47+78) <= L1_TRIG(205); l1_trig_rm(47+79) <= L1_TRIG(206); l1_trig_rm(47+80) <= L1_TRIG(207); l1_trig_rm(47+81) <= L1_TRIG(208); l1_trig_rm(47+82) <= L1_TRIG(209); l1_trig_rm(47+83) <= L1_TRIG(210); l1_trig_rm(47+84) <= L1_TRIG(232); l1_trig_rm(47+85) <= L1_TRIG(234); l1_trig_rm(47+86) <= L1_TRIG(237); l1_trig_rm(47+87) <= L1_TRIG(238); l1_trig_rm(47+88) <= L1_TRIG(270); -- L1_TRIG() bank_3 mapping ------------------------- l1_trig_rm(47+89+0) <= L1_TRIG(46) ; l1_trig_rm(47+89+1) <= L1_TRIG(47) ; l1_trig_rm(47+89+2) <= L1_TRIG(48) ; l1_trig_rm(47+89+3) <= L1_TRIG(49) ; l1_trig_rm(47+89+4) <= L1_TRIG(50) ; l1_trig_rm(47+89+5) <= L1_TRIG(51) ; l1_trig_rm(47+89+6) <= L1_TRIG(53) ; l1_trig_rm(47+89+7) <= L1_TRIG(54) ; l1_trig_rm(47+89+8) <= L1_TRIG(55) ; l1_trig_rm(47+89+9) <= L1_TRIG(58) ; l1_trig_rm(47+89+10) <= L1_TRIG(60) ; l1_trig_rm(47+89+11) <= L1_TRIG(76) ; l1_trig_rm(47+89+12) <= L1_TRIG(77) ; l1_trig_rm(47+89+13) <= L1_TRIG(78) ; l1_trig_rm(47+89+14) <= L1_TRIG(79) ; l1_trig_rm(47+89+15) <= L1_TRIG(80) ; l1_trig_rm(47+89+16) <= L1_TRIG(81) ; l1_trig_rm(47+89+17) <= L1_TRIG(82) ; l1_trig_rm(47+89+18) <= L1_TRIG(83) ; l1_trig_rm(47+89+19) <= L1_TRIG(84) ; l1_trig_rm(47+89+20) <= L1_TRIG(85) ; l1_trig_rm(47+89+21) <= L1_TRIG(86) ; l1_trig_rm(47+89+22) <= L1_TRIG(87) ; l1_trig_rm(47+89+23) <= L1_TRIG(88) ; l1_trig_rm(47+89+24) <= L1_TRIG(89) ; l1_trig_rm(47+89+25) <= L1_TRIG(90) ; l1_trig_rm(47+89+26) <= L1_TRIG(106) ; l1_trig_rm(47+89+27) <= L1_TRIG(107) ; l1_trig_rm(47+89+28) <= L1_TRIG(108) ; l1_trig_rm(47+89+29) <= L1_TRIG(109) ; l1_trig_rm(47+89+30) <= L1_TRIG(110) ; l1_trig_rm(47+89+31) <= L1_TRIG(111) ; l1_trig_rm(47+89+32) <= L1_TRIG(112) ; l1_trig_rm(47+89+33) <= L1_TRIG(113) ; l1_trig_rm(47+89+34) <= L1_TRIG(114) ; l1_trig_rm(47+89+35) <= L1_TRIG(115) ; l1_trig_rm(47+89+36) <= L1_TRIG(116) ; l1_trig_rm(47+89+37) <= L1_TRIG(117) ; l1_trig_rm(47+89+38) <= L1_TRIG(118) ; l1_trig_rm(47+89+39) <= L1_TRIG(119) ; l1_trig_rm(47+89+40) <= L1_TRIG(120) ; l1_trig_rm(47+89+41) <= L1_TRIG(131) ; l1_trig_rm(47+89+42) <= L1_TRIG(132) ; l1_trig_rm(47+89+43) <= L1_TRIG(133) ; l1_trig_rm(47+89+44) <= L1_TRIG(134) ; l1_trig_rm(47+89+45) <= L1_TRIG(135) ; l1_trig_rm(47+89+46) <= L1_TRIG(142) ; l1_trig_rm(47+89+47) <= L1_TRIG(143) ; l1_trig_rm(47+89+48) <= L1_TRIG(144) ; l1_trig_rm(47+89+49) <= L1_TRIG(145) ; l1_trig_rm(47+89+50) <= L1_TRIG(146) ; l1_trig_rm(47+89+51) <= L1_TRIG(147) ; l1_trig_rm(47+89+52) <= L1_TRIG(148) ; l1_trig_rm(47+89+53) <= L1_TRIG(149) ; l1_trig_rm(47+89+54) <= L1_TRIG(150) ; l1_trig_rm(47+89+55) <= L1_TRIG(151) ; l1_trig_rm(47+89+56) <= L1_TRIG(152) ; l1_trig_rm(47+89+57) <= L1_TRIG(153) ; l1_trig_rm(47+89+58) <= L1_TRIG(154) ; l1_trig_rm(47+89+59) <= L1_TRIG(155) ; l1_trig_rm(47+89+60) <= L1_TRIG(156) ; l1_trig_rm(47+89+61) <= L1_TRIG(157) ; l1_trig_rm(47+89+62) <= L1_TRIG(158) ; l1_trig_rm(47+89+63) <= L1_TRIG(159) ; l1_trig_rm(47+89+64) <= L1_TRIG(160) ; l1_trig_rm(47+89+65) <= L1_TRIG(161) ; l1_trig_rm(47+89+66) <= L1_TRIG(162) ; l1_trig_rm(47+89+67) <= L1_TRIG(163) ; l1_trig_rm(47+89+68) <= L1_TRIG(164) ; l1_trig_rm(47+89+69) <= L1_TRIG(165) ; l1_trig_rm(47+89+70) <= L1_TRIG(181) ; l1_trig_rm(47+89+71) <= L1_TRIG(182) ; l1_trig_rm(47+89+72) <= L1_TRIG(183) ; l1_trig_rm(47+89+73) <= L1_TRIG(184) ; l1_trig_rm(47+89+74) <= L1_TRIG(185) ; l1_trig_rm(47+89+75) <= L1_TRIG(186) ; l1_trig_rm(47+89+76) <= L1_TRIG(187) ; l1_trig_rm(47+89+77) <= L1_TRIG(188) ; l1_trig_rm(47+89+78) <= L1_TRIG(189) ; l1_trig_rm(47+89+79) <= L1_TRIG(191) ; l1_trig_rm(47+89+80) <= L1_TRIG(192) ; l1_trig_rm(47+89+81) <= L1_TRIG(195) ; l1_trig_rm(47+89+82) <= L1_TRIG(212) ; l1_trig_rm(47+89+83) <= L1_TRIG(213) ; l1_trig_rm(47+89+84) <= L1_TRIG(214) ; l1_trig_rm(47+89+85) <= L1_TRIG(215) ; l1_trig_rm(47+89+86) <= L1_TRIG(217) ; -- L1_TRIG() bank_4 mapping ------------------------- l1_trig_rm(47+89+87+0) <= L1_TRIG(16); l1_trig_rm(47+89+87+1) <= L1_TRIG(17); l1_trig_rm(47+89+87+2) <= L1_TRIG(18); l1_trig_rm(47+89+87+3) <= L1_TRIG(19); l1_trig_rm(47+89+87+4) <= L1_TRIG(20); l1_trig_rm(47+89+87+5) <= L1_TRIG(21); l1_trig_rm(47+89+87+6) <= L1_TRIG(22); l1_trig_rm(47+89+87+7) <= L1_TRIG(23); l1_trig_rm(47+89+87+8) <= L1_TRIG(24); l1_trig_rm(47+89+87+9) <= L1_TRIG(25); l1_trig_rm(47+89+87+10) <= L1_TRIG(26); l1_trig_rm(47+89+87+11) <= L1_TRIG(27); l1_trig_rm(47+89+87+12) <= L1_TRIG(28); l1_trig_rm(47+89+87+13) <= L1_TRIG(29); l1_trig_rm(47+89+87+14) <= L1_TRIG(30); l1_trig_rm(47+89+87+15) <= L1_TRIG(52); l1_trig_rm(47+89+87+16) <= L1_TRIG(56); l1_trig_rm(47+89+87+17) <= L1_TRIG(57); l1_trig_rm(47+89+87+18) <= L1_TRIG(59); l1_trig_rm(47+89+87+19) <= L1_TRIG(190); l1_trig_rm(47+89+87+20) <= L1_TRIG(193); l1_trig_rm(47+89+87+21) <= L1_TRIG(194); l1_trig_rm(47+89+87+22) <= L1_TRIG(211); l1_trig_rm(47+89+87+23) <= L1_TRIG(216); l1_trig_rm(47+89+87+24) <= L1_TRIG(218); l1_trig_rm(47+89+87+25) <= L1_TRIG(219); l1_trig_rm(47+89+87+26) <= L1_TRIG(220); l1_trig_rm(47+89+87+27) <= L1_TRIG(221); l1_trig_rm(47+89+87+28) <= L1_TRIG(222); l1_trig_rm(47+89+87+29) <= L1_TRIG(223); l1_trig_rm(47+89+87+30) <= L1_TRIG(224); l1_trig_rm(47+89+87+31) <= L1_TRIG(225); l1_trig_rm(47+89+87+32) <= L1_TRIG(241); l1_trig_rm(47+89+87+33) <= L1_TRIG(242); l1_trig_rm(47+89+87+34) <= L1_TRIG(243); l1_trig_rm(47+89+87+35) <= L1_TRIG(244); l1_trig_rm(47+89+87+36) <= L1_TRIG(245); l1_trig_rm(47+89+87+37) <= L1_TRIG(246); l1_trig_rm(47+89+87+38) <= L1_TRIG(247); l1_trig_rm(47+89+87+39) <= L1_TRIG(248); l1_trig_rm(47+89+87+40) <= L1_TRIG(249); l1_trig_rm(47+89+87+41) <= L1_TRIG(250); l1_trig_rm(47+89+87+42) <= L1_TRIG(251); l1_trig_rm(47+89+87+43) <= L1_TRIG(252); l1_trig_rm(47+89+87+44) <= L1_TRIG(253); l1_trig_rm(47+89+87+45) <= L1_TRIG(254); l1_trig_rm(47+89+87+46) <= L1_TRIG(255); -- local clock QOSC1_OUT used for register access by stamp9G45 and SPI backplane bus LOCAL_CLK1_inst: IBUFG --generic map (IOSTANDARD => "DEFAULT") port map (I => QOSC1_OUT, O => qosc1_clk); -- 25 MHz local clock QOSC1_BUFIO2_inst : BUFIO2 generic map ( DIVIDE => 1, -- DIVCLK divider (1,3-8) DIVIDE_BYPASS => TRUE, -- Bypass the divider circuitry (TRUE/FALSE) I_INVERT => FALSE, -- Invert clock (TRUE/FALSE) USE_DOUBLER => FALSE -- Use doubler circuitry (TRUE/FALSE) ) port map ( DIVCLK => qosc1_pll_clkin, -- 1-bit output: Divided clock output IOCLK => open, -- 1-bit output: I/O output clock SERDESSTROBE => open, -- 1-bit output: Output SERDES strobe (connect to ISERDES2/OSERDES2) I => qosc1_clk -- 1-bit input: Clock input (connect to IBUFG) ); qosc1_pll_reset <='0'; PLL_BASE_inst : PLL_BASE generic map ( BANDWIDTH => "LOW", -- "HIGH", "LOW" or "OPTIMIZED" CLKFBOUT_MULT => 16, -- 25Mhz -> 400Mhz, Multiplication factor for all output clocks CLKFBOUT_PHASE => 0.0, -- Phase shift (degrees) of all output clocks CLKIN_PERIOD => 40.0, --CLKIN_PERIOD, -- Clock period (ns) of input clock on CLKIN CLKOUT0_DIVIDE => 1, -- Division factor for CLKOUT0 (1 to 128), used as fast I/O clock CLKOUT0_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT0 (0.01 to 0.99) CLKOUT0_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT0 (0.0 to 360.0) CLKOUT1_DIVIDE => 1, -- Division factor for CLKOUT1 (1 to 128), used as fast I/O clock CLKOUT1_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT1 (0.01 to 0.99) CLKOUT1_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT1 (0.0 to 360.0) CLKOUT2_DIVIDE => 8, -- Division factor for CLKOUT2 (1 to 128) CLKOUT2_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT2 (0.01 to 0.99) CLKOUT2_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT2 (0.0 to 360.0) CLKOUT3_DIVIDE => 2, -- Division factor for CLKOUT3 (1 to 128) CLKOUT3_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT3 (0.01 to 0.99) CLKOUT3_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT3 (0.0 to 360.0) CLKOUT4_DIVIDE => 8, -- Division factor for CLKOUT4 (1 to 128) CLKOUT4_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT4 (0.01 to 0.99) CLKOUT4_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT4 (0.0 to 360.0) CLKOUT5_DIVIDE => 8, -- Division factor for CLKOUT5 (1 to 128) CLKOUT5_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT5 (0.01 to 0.99) CLKOUT5_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT5 (0.0 to 360.0) COMPENSATION => "INTERNAL", -- "SOURCE_SYNCHRONOUS", "INTERNAL", -- "EXTERNAL", "DCM2PLL", "PLL2DCM" DIVCLK_DIVIDE => 1,--1,--5,--PLL_DIV, -- Division factor for all clocks (1 to 52) REF_JITTER => 0.100) -- Input reference jitter (0.000 to 0.999 UI%) port map ( CLKFBOUT => qosc1_pll_clkfbin, -- General output feedback signal CLKOUT0 => open, -- One of six general clock output signals CLKOUT1 => open, -- One of six general clock output signals CLKOUT2 => qosc1_pll_clkout2, -- 50MHz, system clock CLKOUT3 => qosc1_pll_clkout3, -- 200MHz, used to synchronize Stamp9G45 strobe signals CLKOUT4 => open, -- One of six general clock output signals+ CLKOUT5 => open, -- One of six general clock output signals LOCKED => qosc1_pll_locked, -- Active high PLL lock signal CLKFBIN => qosc1_pll_clkfbin, -- Clock feedback input CLKIN => qosc1_pll_clkin, -- Clock input RST => qosc1_pll_reset --open -- Asynchronous PLL reset ); QOSC1_GCKL2_inst : BUFG port map ( O => qosc1_gclk2, -- 50 MHz I => qosc1_pll_clkout2 -- 1-bit Clock buffer input ); QOSC1_GCKL3_inst : BUFG port map ( O => qosc1_gclk3, -- 1-bit Clock buffer output I => qosc1_pll_clkout3 -- 1-bit Clock buffer input ); QOSC1_RESET_GEN: process(qosc1_pll_locked, qosc1_gclk2) variable reset_ct : std_logic_vector(2 downto 0) := B"000"; begin if qosc1_pll_locked='0' then reset_ct := B"000"; qosc1_reset <='0'; else if rising_edge(qosc1_gclk2) then if reset_ct /= B"111" then reset_ct := reset_ct + '1'; end if; if reset_ct = B"110" then qosc1_reset <='1'; else qosc1_reset <='0'; end if; end if; -- rising_edge(qosc1_gclk2) end if; -- qosc1_pll_locked='0' end process QOSC1_RESET_GEN; GPS_CLK_inst: IBUFG generic map (IOSTANDARD => "DEFAULT") port map (I => GPS_TIMEPULSE2, O => gps_clk); -- gps_clk <= GPS_TIMEPULSE2; GPS_PPS_inst: IBUFG generic map (IOSTANDARD => "DEFAULT") port map (I => GPS_TIMEPULSE1, O => gps_pps); -- gps_pps <= GPS_TIMEPULSE1; -- EBI1_NCS2_inst: IBUFG generic map ( IOSTANDARD => "DEFAULT") -- port map (I => EBI1_NCS2, O => ebi1_ncs2_stb); -- -- EBI1_NWE_inst: IBUFG generic map ( IOSTANDARD => "DEFAULT") -- port map (I => EBI1_NWE, O => ebi1_nwe_stb); -- -- EBI1_NRD_inst: IBUFG generic map ( IOSTANDARD => "DEFAULT") -- port map (I => EBI1_NRD, O => ebi1_nrd_stb); -- test pins -- LVDS_O_bufs : for i in 0 to 7 generate -- LVDS_O_inst : OBUFDS -- generic map (IOSTANDARD => "LVDS_33") -- port map ( O => LVDS_IO_P(i), OB =>LVDS_IO_N(i), I => lvds_io(i)); -- end generate LVDS_O_bufs; -- TIB, in out buffers, start ------------------------------------------------------------------------------ TIB_CLK_IBUFGDS_inst : IBUFGDS generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards IOSTANDARD => "LVDS_33") port map ( O => tib_clk, -- Clock buffer output I => TIB_CLK_P, -- Diff_p clock buffer input (connect directly to top-level port) IB => TIB_CLK_N -- Diff_n clock buffer input (connect directly to top-level port) ); TIB_PPS_IBUFGDS_inst : IBUFGDS generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards IOSTANDARD => "LVDS_33") port map ( O => tib_pps, -- Clock buffer output I => TIB_PPS_P, -- Diff_p clock buffer input (connect directly to top-level port) IB => TIB_PPS_N -- Diff_n clock buffer input (connect directly to top-level port) ); TIB_EVENT_T_inst : IBUFDS generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards IOSTANDARD => "LVDS_33") port map ( O => tib_event_t, -- camera trigger I => TIB_EVENT_T_P, IB => TIB_EVENT_T_N ); TIB_CAMERA_T0_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => TIB_CAMERA_T0_P, OB => TIB_CAMERA_T0_N, I => tib_camera_t0); TIB_CAMERA_T1_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => TIB_CAMERA_T1_P, OB => TIB_CAMERA_T1_N, I => tib_camera_t1); TIB_SPARE0_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => TIB_SPARE0_P, OB => TIB_SPARE0_N, I => tib_spare0); -- TIB_SPARE1_inst : OBUFDS -- generic map (IOSTANDARD => "LVDS_33") -- port map ( O => TIB_SPARE1_P, OB => TIB_SPARE1_N, I => tib_spare1); TIB_BUSY_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => TIB_BUSY_P, OB => TIB_BUSY_N, I => tib_busy); -- TIB_CLK / _PPS generation, for test purposes only --------------------------------------- -- use local clock QOSC2_OUT to generate the 10Mhz and 1PPS as faked TIB signals QOSC2_CLK_inst: IBUFG --generic map (IOSTANDARD => "DEFAULT") port map (I => QOSC2_OUT, O => qosc2_clk); QOSC2_DCM_SP_inst : DCM_SP -- generating 10 MHz from 10 MHz (Q3), to be used as faked TIB_CLK_P/N generic map ( CLKDV_DIVIDE => 2.0, -- CLKDV divide value -- (1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,9,10,11,12,13,14,15,16). CLKFX_DIVIDE => 2, -- Divide value on CLKFX outputs - D - (1-32) CLKFX_MULTIPLY => 2, -- Multiply value on CLKFX outputs - M - (2-32) CLKIN_DIVIDE_BY_2 => FALSE, -- CLKIN divide by two (TRUE/FALSE) CLKIN_PERIOD => 100.0, -- Input clock period specified in nS, CLKIN_PERIOD_Q3 CLKOUT_PHASE_SHIFT => "NONE", -- Output phase shift (NONE, FIXED, VARIABLE) CLK_FEEDBACK => "1X", -- Feedback source (NONE, 1X, 2X) DESKEW_ADJUST => "SOURCE_SYNCHRONOUS", -- SYSTEM_SYNCHRONOUS or SOURCE_SYNCHRONOUS DFS_FREQUENCY_MODE => "LOW", -- Unsupported - Do not change value DLL_FREQUENCY_MODE => "LOW", -- Unsupported - Do not change value DSS_MODE => "NONE", -- Unsupported - Do not change value DUTY_CYCLE_CORRECTION => TRUE, -- Unsupported - Do not change value FACTORY_JF => X"c080", -- Unsupported - Do not change value PHASE_SHIFT => 0, -- Amount of fixed phase shift (-255 to 255) STARTUP_WAIT => FALSE -- Delay config DONE until DCM_SP LOCKED (TRUE/FALSE) ) port map ( CLK0 => qosc2_dcm_clk0, -- 1-bit output: 0 degree clock output CLK180 => open, -- 1-bit output: 180 degree clock output CLK270 => open, -- 1-bit output: 270 degree clock output CLK2X => open, -- 1-bit output: 2X clock frequency clock output CLK2X180 => open, -- 1-bit output: 2X clock frequency, 180 degree clock output CLK90 => open, -- 1-bit output: 90 degree clock output CLKDV => open, -- 1-bit output: Divided clock output CLKFX => qosc2_dcm_clkfx, -- 1-bit output: Digital Frequency Synthesizer output (DFS) CLKFX180 => qosc2_dcm_clkfx180, -- 1-bit output: 180 degree CLKFX output LOCKED => qosc2_dcm_locked, -- 1-bit output: DCM_SP Lock Output PSDONE => open, -- 1-bit output: Phase shift done output STATUS => qosc2_dcm_status, -- 8-bit output: DCM_SP status output CLKFB => qosc2_dcm_clkfb, -- 1-bit input: Clock feedback input CLKIN => qosc2_clk,--qosc2_dcm_clkin, -- 1-bit input: Clock input DSSEN => '0', -- 1-bit input: Unsupported, specify to GND. PSCLK => '0', -- 1-bit input: Phase shift clock input PSEN => '0', -- 1-bit input: Phase shift enable PSINCDEC => '0', -- 1-bit input: Phase shift increment/decrement input RST => qosc2_dcm_rst -- 1-bit input: Active high reset input ); QOSC2_BUFIO2FB_inst : BUFIO2FB generic map (DIVIDE_BYPASS => TRUE ) port map (I => qosc2_dcm_clk0, -- 1-bit input: Feedback clock input (connect to input port) O => qosc2_dcm_clkfb); -- 1-bit output: Output feedback clock (connect to feedback input of DCM/PLL) QOSC2_DCM_SP_RESET: process (qosc2_clk) -- 10 MHz variable cyc_ct : integer range 0 to 65535 := 0; -- time to lock is 5 ms max. !!! begin if rising_edge (qosc2_clk) then if ((qosc2_dcm_status(2 downto 0) /= B"000") or (qosc2_dcm_locked = '0')) and (cyc_ct = 0) then cyc_ct := 65535; qosc2_dcm_rst <= '1'; -- active for 3 clock cycles min. elsif cyc_ct /= 0 then cyc_ct := cyc_ct - 1; if cyc_ct = 65525 then qosc2_dcm_rst <= '0'; end if; end if; --(qosc2_dcm_status(2) = '1') and .. end if; -- rising_edge (qosc2_clk) end process QOSC2_DCM_SP_RESET; QOSC2_FX_inst: BUFG --generic map (IOSTANDARD => "DEFAULT") port map (I => qosc2_dcm_clkfx, O => qosc2_bufg_clkfx); QOSC2_FX180_inst: BUFG --generic map (IOSTANDARD => "DEFAULT") port map (I => qosc2_dcm_clkfx180, O => qosc2_bufg_clkfx180); TIB_CLK_OUT_ODDR2_inst : ODDR2 -- 10 MHz clock output generic map( DDR_ALIGNMENT => "NONE", -- Sets output alignment to "NONE", "C0", "C1" INIT => '0', -- Sets initial state of the Q output to '0' or '1' SRTYPE => "SYNC") -- Specifies "SYNC" or "ASYNC" set/reset port map ( Q => tib_clk_out, -- 1-bit output data C0 => qosc2_bufg_clkfx,--pll_clkout4, -- 1-bit clock input C1 => qosc2_bufg_clkfx180,--pll_clkout5, -- 1-bit clock input CE => '1', -- 1-bit clock enable input D0 => '1', -- 1-bit data input (associated with C0) D1 => '0', -- 1-bit data input (associated with C1) R => '0', -- 1-bit reset input S => '0' -- 1-bit set input ); TIB_PPS_gen: process (qosc2_clk) -- generating a 100ns timepps-pulse variable pps_ct : integer range 0 to 9999999 := 0; begin if rising_edge(qosc2_clk) then -- 10 MHz clock if pps_ct = 9999999 then pps_ct := 0; tib_pps_out <= '1'; else pps_ct := pps_ct + 1; tib_pps_out <= '0'; end if; end if; end process TIB_PPS_gen; -- CTDB_CLK / _PPS outputs ----------------------------------------- CTDB_CLK_GEN: process(tib_gclk2) -- generate a 50MHz clock by oserdes variable ct: integer range 0 to 4 := 0; begin if rising_edge(tib_gclk2) then -- 125MHz if tib_reset = '1' then ct := 0; else if ct = 4 then ct := 0; else ct := ct + 1; end if; case ct is when 0 => ctdb_clk_oserdes_pdat <= X"FF"; when 1 => ctdb_clk_oserdes_pdat <= X"C0"; when 2 => ctdb_clk_oserdes_pdat <= X"0F"; when 3 => ctdb_clk_oserdes_pdat <= X"FC"; when 4 => ctdb_clk_oserdes_pdat <= X"00"; end case; end if; -- tib_reset = 1 end if; -- rising_edge(tib_gclk2) end process CTDB_CLK_GEN; CTDB_CLK1_oserdes_odelay_port_map : oserdes_odelay_01 generic map (odelay => CTDB_CLK1_ODELAY) port map ( clk => tib_gclk2 , -- pdat clock reset => tib_reset, oserdes_pdat => ctdb_clk_oserdes_pdat, -- serdes pdat oserdes_ioclk => tib_oserdes_clk0, oserdes_stb => tib_oserdes_stb0, oserdes_out_dld => ctdb_clk1_dld -- serial oserdes output ); CTDB_CLK1_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") -- IOSTANDARD => "LVDS_25" port map ( O => CTDB_CLK1_P, OB => CTDB_CLK1_N, I => ctdb_clk1_dld); CTDB_CLK2_oserdes_odelay_port_map : oserdes_odelay_01 generic map (odelay => CTDB_CLK2_ODELAY) port map ( clk => tib_gclk2 , -- pdat clock reset => tib_reset, oserdes_pdat => ctdb_clk_oserdes_pdat, -- serdes pdat oserdes_ioclk => tib_oserdes_clk0, oserdes_stb => tib_oserdes_stb0, oserdes_out_dld => ctdb_clk2_dld -- serial oserdes output ); CTDB_CLK2_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") -- IOSTANDARD => "LVDS_25" port map ( O => CTDB_CLK2_P, OB => CTDB_CLK2_N, I => ctdb_clk2_dld); ctdb_pps1 <= tib_pps; CTDB_PPS1_IODELAY2_bank_2 : IODELAY2 generic map ( DATA_RATE => "SDR", ODELAY_VALUE => CTDB_PPS1_ODELAY, --37ps/tap COUNTER_WRAPAROUND => "STAY_AT_LIMIT", DELAY_SRC => "ODATAIN", SERDES_MODE => "NONE", SIM_TAPDELAY_VALUE => 75) port map ( -- required datapath T => '0', DOUT => ctdb_pps1_dld, ODATAIN => ctdb_pps1, IDATAIN => '0', TOUT => open, DATAOUT => open, DATAOUT2 => open, IOCLK0 => '0', -- No calibration needed IOCLK1 => '0', -- No calibration needed CLK => '0', CAL => '0', INC => '0', CE => '0', BUSY => open, RST => '0'); CTDB_PPS1_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") -- IOSTANDARD => "LVDS_25" port map ( O => CTDB_PPS1_P, OB => CTDB_PPS1_N, I => ctdb_pps1_dld); ctdb_pps2 <= tib_pps; CTDB_PPS2_IODELAY2_bank_2 : IODELAY2 generic map ( DATA_RATE => "SDR", ODELAY_VALUE => CTDB_PPS2_ODELAY, --37ps/tap COUNTER_WRAPAROUND => "STAY_AT_LIMIT", DELAY_SRC => "ODATAIN", SERDES_MODE => "NONE", SIM_TAPDELAY_VALUE => 75) port map ( -- required datapath T => '0', DOUT => ctdb_pps2_dld, ODATAIN => ctdb_pps2, IDATAIN => '0', TOUT => open, DATAOUT => open, DATAOUT2 => open, IOCLK0 => '0', -- No calibration needed IOCLK1 => '0', -- No calibration needed CLK => '0', CAL => '0', INC => '0', CE => '0', BUSY => open, RST => '0'); CTDB_PPS2_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") -- IOSTANDARD => "LVDS_25" port map ( O => CTDB_PPS2_P, OB => CTDB_PPS2_N, I => ctdb_pps2_dld); SPI_MISO_IBUFDS_inst : IBUFDS generic map ( DIFF_TERM => TRUE, -- Differential Termination IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards IOSTANDARD => "LVDS_33") port map ( O => spi_miso, -- SPI read back data I => SPI_MISO_P, IB => SPI_MISO_N ); ADDR_64BIT_IOBUF_inst : IOBUF generic map ( DRIVE => 12, IBUF_DELAY_VALUE => "0", -- 0..12 ? amount of added input delay for buffer IFD_DELAY_VALUE => "AUTO", -- 0..6 ? amount of added delay for input register, IOSTANDARD => "DEFAULT", SLEW => "SLOW") port map ( O => addr_64bit_in, -- Buffer output IO => ADDR_64BIT, -- Buffer inout port (connect directly to top-level port) I => addr_64bit_out, -- Buffer input T => addr_64bit_trst -- 3-state enable input, high=input, low=output ); TEMPERATURE_IOBUF_inst : IOBUF generic map ( DRIVE => 12, IBUF_DELAY_VALUE => "0", -- 0..12 ? amount of added input delay for buffer IFD_DELAY_VALUE => "AUTO", -- 0..6 ? amount of added delay for input register, IOSTANDARD => "DEFAULT", SLEW => "SLOW") port map ( O => temperature_in, -- Buffer output IO => TEMPERATURE, -- Buffer inout port (connect directly to top-level port) I => temperature_out, -- Buffer input T => temperature_trst -- 3-state enable input, high=input, low=output ); -- PLLs ------------------------------------------------------------------------- DCDC_SYNC <= '0'; -- will be ? mhz by pll output later -- *************** external clock source ***************** ------------------------- BUFIO2_CLK_IN_inst : BUFIO2 generic map( DIVIDE => 1, -- The DIVCLK divider divide-by value; default 1 DIVIDE_BYPASS => TRUE) -- DIVCLK output sourced from Divider (FALSE) or from I input, by-passing Divider (TRUE); default TRUE port map ( I => tib_clk, -- from FPGA clock input IOCLK => open, -- Output Clock DIVCLK => tib_dcm_clkin, -- Output Divided Clock SERDESSTROBE => open) ; -- Output SERDES strobe (Clock Enable) -- DCM_SP: Digital Clock Manager -- Spartan-6 -- Xilinx HDL Language Template, version 13.4 DCM_SP_inst : DCM_SP -- generating 50 MHz from 10 MHz (Q3) generic map ( CLKDV_DIVIDE => 2.0, -- CLKDV divide value -- (1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,9,10,11,12,13,14,15,16). CLKFX_DIVIDE => 2, -- Divide value on CLKFX outputs - D - (1-32) CLKFX_MULTIPLY => 10, -- Multiply value on CLKFX outputs - M - (2-32) CLKIN_DIVIDE_BY_2 => FALSE, -- CLKIN divide by two (TRUE/FALSE) CLKIN_PERIOD => 100.0, -- Input clock period specified in nS, CLKIN_PERIOD_Q3 CLKOUT_PHASE_SHIFT => "NONE", -- Output phase shift (NONE, FIXED, VARIABLE) CLK_FEEDBACK => "1X", -- Feedback source (NONE, 1X, 2X) DESKEW_ADJUST => "SOURCE_SYNCHRONOUS", -- SYSTEM_SYNCHRONOUS or SOURCE_SYNCHRONOUS DFS_FREQUENCY_MODE => "LOW", -- Unsupported - Do not change value DLL_FREQUENCY_MODE => "LOW", -- Unsupported - Do not change value DSS_MODE => "NONE", -- Unsupported - Do not change value DUTY_CYCLE_CORRECTION => TRUE, -- Unsupported - Do not change value FACTORY_JF => X"c080", -- Unsupported - Do not change value PHASE_SHIFT => 0, -- Amount of fixed phase shift (-255 to 255) STARTUP_WAIT => FALSE -- Delay config DONE until DCM_SP LOCKED (TRUE/FALSE) ) port map ( CLK0 => tib_dcm_clk0, -- 1-bit output: 0 degree clock output CLK180 => open, -- 1-bit output: 180 degree clock output CLK270 => open, -- 1-bit output: 270 degree clock output CLK2X => open, -- 1-bit output: 2X clock frequency clock output CLK2X180 => open, -- 1-bit output: 2X clock frequency, 180 degree clock output CLK90 => open, -- 1-bit output: 90 degree clock output CLKDV => open, -- 1-bit output: Divided clock output CLKFX => tib_pll_clkin, -- 1-bit output: Digital Frequency Synthesizer output (DFS) CLKFX180 => open, -- 1-bit output: 180 degree CLKFX output LOCKED => tib_dcm_locked, -- 1-bit output: DCM_SP Lock Output PSDONE => open, -- 1-bit output: Phase shift done output STATUS => tib_dcm_status, -- 8-bit output: DCM_SP status output CLKFB => tib_dcm_clkfb, -- 1-bit input: Clock feedback input CLKIN => tib_dcm_clkin, -- 1-bit input: Clock input DSSEN => '0', -- 1-bit input: Unsupported, specify to GND. PSCLK => '0', -- 1-bit input: Phase shift clock input PSEN => '0', -- 1-bit input: Phase shift enable PSINCDEC => '0', -- 1-bit input: Phase shift increment/decrement input RST => tib_dcm_rst -- 1-bit input: Active high reset input ); -- End of DCM_SP_inst instantiation DCM_BUFIO2FB_inst : BUFIO2FB generic map (DIVIDE_BYPASS => TRUE ) port map (I => tib_dcm_clk0, -- 1-bit input: Feedback clock input (connect to input port) O => tib_dcm_clkfb); -- 1-bit output: Output feedback clock (connect to feedback input of DCM/PLL) DCM_SP_RESET: process (tib_clk) -- 10 MHz variable cyc_ct : integer range 0 to 65535 := 0; -- time to lock is 5 ms max. !!! begin if rising_edge (tib_clk) then -- if (tib_dcm_status(2) = '1') and (tib_dcm_locked = '0') and (cyc_ct = 0) then if ((tib_dcm_status(2 downto 0) /= B"000") or (tib_dcm_locked = '0')) and (cyc_ct = 0) then cyc_ct := 65535; tib_dcm_rst <= '1'; -- active for 3 clock cycles min. elsif cyc_ct /= 0 then cyc_ct := cyc_ct - 1; if cyc_ct = 65525 then tib_dcm_rst <= '0'; end if; end if; --(tib_dcm_status(2) = '1') and .. end if; -- rising_edge (tib_clk) end process DCM_SP_RESET; tib_pll_reset <='0'; TIB_PLL_BASE_inst : PLL_BASE generic map ( BANDWIDTH => "OPTIMIZED", -- "HIGH", "LOW" or "OPTIMIZED" CLKFBOUT_MULT => 20, -- 50Mhz -> 1000 Mhz, Multiplication factor for all output clocks CLKFBOUT_PHASE => 0.0, -- Phase shift (degrees) of all output clocks CLKIN_PERIOD => 20.0, --CLKIN_PERIOD, -- Clock period (ns) of input clock on CLKIN CLKOUT0_DIVIDE => 1, -- 1000 MHz, Division factor for CLKOUT0 (1 to 128), used as iodel_clk0 CLKOUT0_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT0 (0.01 to 0.99) CLKOUT0_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT0 (0.0 to 360.0) CLKOUT1_DIVIDE => 5, -- 1000 MHz, Division factor for CLKOUT1 (1 to 128), used as iodel_clk1 CLKOUT1_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT1 (0.01 to 0.99) CLKOUT1_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT1 (0.0 to 360.0) CLKOUT2_DIVIDE => 8, -- 50 MHz, Division factor for CLKOUT2 (1 to 128) CLKOUT2_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT2 (0.01 to 0.99) CLKOUT2_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT2 (0.0 to 360.0) CLKOUT3_DIVIDE => 20, -- 50 MHz, Division factor for CLKOUT3 (1 to 128) CLKOUT3_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT3 (0.01 to 0.99) CLKOUT3_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT3 (0.0 to 360.0) CLKOUT4_DIVIDE => 20, -- 50 MHz, Division factor for CLKOUT4 (1 to 128) CLKOUT4_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT4 (0.01 to 0.99) CLKOUT4_PHASE => 180.0, -- Phase shift (degrees) for CLKOUT4 (0.0 to 360.0) CLKOUT5_DIVIDE => 4, -- 250 MHz, Division factor for CLKOUT5 (1 to 128) CLKOUT5_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT5 (0.01 to 0.99) CLKOUT5_PHASE => 0.0, -- Phase shift (degrees) for CLKOUT5 (0.0 to 360.0) COMPENSATION => "DCM2PLL", -- "SYSTEM_SYNCHRONOUS", -- "SOURCE_SYNCHRNOUS", "INTERNAL", -- "EXTERNAL", "DCM2PLL", "PLL2DCM" DIVCLK_DIVIDE => 1,--1,--5,--PLL_DIV, -- Division factor for all clocks (1 to 52) REF_JITTER => 0.100) -- Input reference jitter (0.000 to 0.999 UI%) port map ( CLKFBOUT => tib_pll_clkfbout, -- General output feedback signal CLKOUT0 => tib_pll_clkout0, -- One of six general clock output signals CLKOUT1 => tib_pll_clkout1, -- One of six general clock output signals CLKOUT2 => tib_pll_clkout2, -- One of six general clock output signals CLKOUT3 => tib_pll_clkout3, -- One of six general clock output signals CLKOUT4 => tib_pll_clkout4, -- One of six general clock output signals+ CLKOUT5 => tib_pll_clkout5, -- One of six general clock output signals LOCKED => tib_pll_locked, -- Active high PLL lock signal CLKFBIN => tib_pll_clkfbout, -- Clock feedback input CLKIN => tib_pll_clkin, -- Clock input, 50MHz RST => tib_pll_reset --open -- Asynchronous PLL reset ); TIB_GCKL2_inst : BUFG port map ( I => tib_pll_clkout2, -- 1-bit Clock buffer input O => tib_gclk2 -- 125 MHz main clock ); TIB_GCKL3_inst : BUFG port map ( I => tib_pll_clkout3, -- 1-bit Clock buffer input O => tib_gclk3 -- 50 MHz, used for CTDB clock generation ); TIB_GCKL4_inst : BUFG port map ( I => tib_pll_clkout4, -- 1-bit Clock buffer input O => tib_gclk4 -- 50 MHz, 180° phase shift, used for CTDB clock generation ); TIB_GCKL5_inst : BUFG port map ( I => tib_pll_clkout5, -- 1-bit Clock buffer input O => tib_gclk2x2 -- 250 MHz, no phase shift ); TIB_BUFPLL_bank0_oserdes_inst : BUFPLL generic map( DIVIDE => 8) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => tib_pll_clkout0, -- input, PLL clock by PLL_ADV GCLK => tib_gclk2, -- input, Global Clock input LOCKED => tib_pll_locked, -- input, Clock0 locked input IOCLK => tib_oserdes_clk0, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => tib_oserdes_stb0) ; -- output, SERDES strobe TIB_BUFPLL_bank2_oserdes_inst : BUFPLL generic map( DIVIDE => 8) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => tib_pll_clkout0, -- input, PLL clock by PLL_ADV GCLK => tib_gclk2, -- input, Global Clock input LOCKED => tib_pll_locked, -- input, Clock0 locked input IOCLK => tib_oserdes_clk2, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => tib_oserdes_stb2) ; -- output, SERDES strobe TIB_BUFPLL_bank1_iserdes_inst : BUFPLL generic map( DIVIDE => 4) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => tib_pll_clkout1, -- input, PLL clock by PLL_ADV GCLK => tib_gclk2, -- input, Global Clock input LOCKED => tib_pll_locked, -- input, Clock0 locked input IOCLK => tib_iserdes_clk1, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => open ); --tib_iserdes_stb1) ; -- output, SERDES strobe TIB_BUFPLL_bank3_iserdes_inst : BUFPLL generic map( DIVIDE => 4) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => tib_pll_clkout1, -- input, PLL clock by PLL_ADV GCLK => tib_gclk2, -- input, Global Clock input LOCKED => tib_pll_locked, -- input, Clock0 locked input IOCLK => tib_iserdes_clk3, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => open ); --tib_iserdes_stb3) ; -- output, SERDES strobe TIB_BUFPLL_bank4_iserdes_inst : BUFPLL generic map( DIVIDE => 4) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => tib_pll_clkout1, -- input, PLL clock by PLL_ADV GCLK => tib_gclk2, -- input, Global Clock input LOCKED => tib_pll_locked, -- input, Clock0 locked input IOCLK => tib_iserdes_clk4, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => open ); --tib_iserdes_stb4) ; -- output, SERDES strobe TIB_BUFPLL_bank5_iserdes_inst : BUFPLL generic map( DIVIDE => 4) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => tib_pll_clkout1, -- input, PLL clock by PLL_ADV GCLK => tib_gclk2, -- input, Global Clock input LOCKED => tib_pll_locked, -- input, Clock0 locked input IOCLK => tib_iserdes_clk5, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => open ); --tib_iserdes_stb5) ; -- output, SERDES strobe TIB_RESET_GEN: process(tib_gclk2, tib_pll_locked) variable reset_ct : std_logic_vector (2 downto 0) := B"000"; begin if tib_pll_locked ='0' then reset_ct := B"000"; tib_reset <= '0'; else if rising_edge (tib_gclk2) then if (reset_ct /= B"111") then reset_ct := reset_ct + '1'; end if; if reset_ct = B"110" then tib_reset <= '1'; else tib_reset <= '0'; end if; end if; -- rising_edge (tib_gclk2) end if; -- tib_pll_locked ='0' end process TIB_RESET_GEN; -- l1_del_load() and l1_delay_busy generation ---------------------------------------------------- L1_DELAY_CTRL: process (tib_gclk2, tib_reset) begin if rising_edge(tib_gclk2) then if tib_reset = '1' then l1_del_load <= (others => '0'); l1_delay_busy <= '0'; else if l1_del_rg_wstb_syncd = '1' then -- single pulse after l1_del_rg write operation l1_del_load(l1_trig_chan_remapped(l1sel_rg)) <= '1'; else l1_del_load <= (others => '0'); end if; l1_delay_busy <= l1_del_busy(l1_trig_chan_remapped(l1sel_rg)); end if; -- tib_reset = '1' end if; -- rising_edge(tib_gclk2) end process L1_DELAY_CTRL; ----- L1 trigger IODELAY2 Implementation ------------------------------------------------------------- L1_TRIG_IODELAY2_BANK_5: for i in 0 to 46 generate begin L1_in_del_bank_5_inst: in_single_ended_del_01 port map ( reset => tib_reset, -- reset (active high) clk => tib_gclk2, -- global clock input io_clk => tib_iserdes_clk5, -- high speed i/o clock sdat_in => l1_trig_rm(i), -- single ended serial data input del_data => l1_del_rg(i), -- delay value del_load => l1_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => l1_del_busy(i), -- '1' until delay set procedure finished del_dataout2 => l1_trig_dld(i) -- ); end generate L1_TRIG_IODELAY2_BANK_5; --l1_trig_rm(47+89+87+46) L1_TRIG_IODELAY2_BANK_1: for i in 47 to 135 generate begin L1_in_del_bank_1_inst: in_single_ended_del_01 port map ( reset => tib_reset, -- reset (active high) clk => tib_gclk2, -- global clock input io_clk => tib_iserdes_clk1, -- high speed i/o clock sdat_in => l1_trig_rm(i), -- single ended serial data input del_data => l1_del_rg(i), -- delay value del_load => l1_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => l1_del_busy(i), -- '1' until delay set procedure finished del_dataout2 => l1_trig_dld(i) -- ); end generate L1_TRIG_IODELAY2_BANK_1; L1_TRIG_IODELAY2_BANK_3: for i in 136 to 222 generate begin L1_in_del_bank_3_inst: in_single_ended_del_01 port map ( reset => tib_reset, -- reset (active high) clk => tib_gclk2, -- global clock input io_clk => tib_iserdes_clk3, -- high speed i/o clock sdat_in => l1_trig_rm(i), -- single ended serial data input del_data => l1_del_rg(i), -- delay value del_load => l1_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => l1_del_busy(i), -- '1' until delay set procedure finished del_dataout2 => l1_trig_dld(i) -- ); end generate L1_TRIG_IODELAY2_BANK_3; L1_TRIG_IODELAY2_BANK_4: for i in 223 to 269 generate begin L1_in_del_bank_4_inst: in_single_ended_del_01 port map ( reset => tib_reset, -- reset (active high) clk => tib_gclk2, -- global clock input io_clk => tib_iserdes_clk4, -- high speed i/o clock sdat_in => l1_trig_rm(i), -- single ended serial data input del_data => l1_del_rg(i), -- delay value del_load => l1_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => l1_del_busy(i), -- '1' until delay set procedure finished del_dataout2 => l1_trig_dld(i) -- ); end generate L1_TRIG_IODELAY2_BANK_4; ------------------------ begin of generating the L1 trigger -------------------------------------------------------- TIB_TRIG_ODELAY_inst: IODELAY2 generic map ( DATA_RATE => "SDR", ODELAY_VALUE => TIB_TRIG_ODELAY, --37ps/tap COUNTER_WRAPAROUND => "STAY_AT_LIMIT", DELAY_SRC => "ODATAIN", SERDES_MODE => "NONE", SIM_TAPDELAY_VALUE => 75) port map ( -- required datapath T => '0', DOUT => camera_trig_dld, ODATAIN => camera_trig, IDATAIN => '0', TOUT => open, DATAOUT => open, DATAOUT2 => open, IOCLK0 => '0', -- No calibration needed IOCLK1 => '0', -- No calibration needed CLK => '0', CAL => '0', INC => '0', CE => '0', BUSY => open, RST => '0'); -- TRIG_OUT_EDGE_inst : OBUFDS -- generic map (IOSTANDARD => "LVDS_33") -- port map ( O => LVDS_IO_P5, OB => LVDS_IO_N5, I => camera_trig_dld); -- TRIG_IN_EDGE_inst : IBUFDS -- generic map ( -- DIFF_TERM => TRUE, -- Differential Termination -- IBUF_LOW_PWR => FALSE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards -- IOSTANDARD => "LVDS_33") -- port map ( -- O => camera_trig_bufg, -- camera trigger -- I => LVDS_IO_P4, -- IB => LVDS_IO_N4 -- ); l1_trig_msk_rm <= l1_trig_mask_remapped(l1_trig_msk); -- see L2CB_pkg.vhd camera_trig_intermediate(0) <= (l1_trig_dld(0) and l1_trig_msk_rm(0)) OR (l1_trig_dld(1) and l1_trig_msk_rm(1)); CAMERA_TRIG_OR: for i in 2 to 269 generate begin camera_trig_intermediate(i-1) <= camera_trig_intermediate(i-2) OR (l1_trig_dld(i) and l1_trig_msk_rm(i)); end generate CAMERA_TRIG_OR; camera_trig <= camera_trig_intermediate(268); -- !!! i-1 (last) is 268 NOT 269 !!! camera_trig_BUFG_inst: BUFG port map (I => camera_trig, O => camera_trig_bufg); -- CAMERA_TRIG_PULSE: process (tib_gclk2x2) -- 250 MHz (4 ns), generate a 52 ns pulse with sync-reset -- variable ct : integer range 0 to 15 := 0; -- --variable trig_pipe : std_logic_vector(2 downto 0) := B"000"; -- begin -- if rising_edge (tib_gclk2x2) then -- camera_trig_clr <= '0'; -- for a single clock length pulse -- trig_pipe(0) <= camera_trig_t0; -- trig_pipe(1) <= trig_pipe(0); -- trig_pipe(2) <= trig_pipe(1); -- if (trig_pipe = B"011") and (ct = 0) then -- ct := 12; -- camera_trig_en <= '0'; -- end if; -- if ct /= 0 then -- ct := ct - 1; -- if ct = 2 then camera_trig_clr <= '1'; end if; -- else -- camera_trig_en <= '1'; -- end if; -- ct /= 0 -- end if; -- rising_edge (tib_gclk2x2) -- end process CAMERA_TRIG_PULSE; CAMERA_TRIG_PULSE_INCL_MCF: process (tib_gclk2x2) -- 250 MHz (4 ns), generate a 100 ns pulse with sync-reset variable ct : integer range 0 to 31 := 0; begin if rising_edge (tib_gclk2x2) then camera_trig_clr <= '0'; -- for a single clock length pulse trig_pipe(0) <= tib_camera_t0; trig_pipe(1) <= trig_pipe(0); trig_pipe(2) <= trig_pipe(1); mcf_pipe(0) <= muon_detected; mcf_pipe(1) <= mcf_pipe(0); mcf_pipe(2) <= mcf_pipe(1); if (trig_pipe = B"011") and (ct = 0) then ct := UP_TRIG_PULSE_LENGTH; camera_trig_en <= '0'; end if; if ct /= 0 then ct := ct - 1; if (mcf_pipe = B"011") and (ct > (UP_TRIG_PULSE_LENGTH-to_integer(unsigned(muon_del_rg)))) then tib_mcf_trig <= '1'; end if; if ct = 2 then camera_trig_clr <= '1'; tib_mcf_trig <= '0'; end if; else camera_trig_en <= '1'; end if; -- ct /= 0 end if; -- rising_edge (tib_gclk2x2) end process CAMERA_TRIG_PULSE_INCL_MCF; tib_camera_t0_FDCE_inst : FDCE generic map (INIT => '0') -- Initial value of register ('0' or '1') port map ( Q => tib_camera_t0, -- Data output C => camera_trig_bufg, -- Clock input CE => camera_trig_en, -- Clock enable input CLR => camera_trig_clr, -- Asynchronous clear input D => '1' -- Data input ); tib_camera_t1_FDCE_inst : FDCE generic map (INIT => '0') -- Initial value of register ('0' or '1') port map ( Q => tib_camera_t1, -- Data output C => camera_trig_bufg, -- Clock input CE => camera_trig_en, -- Clock enable input CLR => camera_trig_clr, -- Asynchronous clear input D => '1' -- Data input ); --------------------- end of generating the L1 trigger ----------------------------------- -------------- begin of generating the MCF trigger --------------------------------------- l1_trig_dld_msk_rm <= l1_trig_dld and l1_trig_msk_rm; -- l1_trig_sum <= sum_of_vectorbits(l1_trig_dld_msk_rm); l1_trig_sum <= sum_of_up_going_trig(l1_trig_dld_msk_rm); -- l1_trig_sum <= hw_tree(l1_trig_dld_msk_rm); -- is zero always??? muon_detected <= '1' when l1_trig_sum > to_integer(unsigned(muon_thr_rg)) else '0'; -- mcf_trig_FDCE_inst : FDCE -- generic map (INIT => '0') -- Initial value of register ('0' or '1') -- port map ( -- Q => tib_mcf_trig, -- Data output -- C => camera_trig_bufg, -- Clock input -- CE => camera_trig_en, -- Clock enable input -- CLR => camera_trig_clr, -- Asynchronous clear input -- D => muon_detected -- Data input -- ); -- mcf_trig_FDCE_inst : FDCE -- generic map (INIT => '0') -- Initial value of register ('0' or '1') -- port map ( -- Q => tib_mcf_trig, -- Data output -- C => camera_trig_bufg, -- Clock input -- CE => camera_trig_en, -- Clock enable input -- CLR => camera_trig_clr, -- Asynchronous clear input -- D => muon_detected -- Data input -- ); TIB_MCF_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => TIB_SPARE1_P, OB => TIB_SPARE1_N, I => tib_mcf_trig); ------------------- end of generating the MCF trigger --------------------------------------- --l2_trig_out <= tib_event_t; -- changed for rev. 015 -- l2_trig_out <= tib_event_t and -- ((ctrl_rg(14)='0') or ((ctrl_rg(14)='1') and (tib_busy='0'))); l2_trig_out <= '1' when ((tib_event_t='1') and (ctrl_rg(14)='0')) or ((tib_event_t='1') and (ctrl_rg(14)='1') and (tib_busy='0')) else '0'; l2_trig_out_n <= not l2_trig_out; L2_TRIG_BUFG_inst : BUFG port map ( O => l2_trig_bufg, I => l2_trig_out); L2_TRIG_N_BUFG_inst : BUFG port map ( O => l2_trig_bufg_n, I => l2_trig_out_n); CTDB_L2_TRIGGER: for i in 1 to 18 generate begin ODDR2_inst : ODDR2 generic map( DDR_ALIGNMENT => "NONE", -- Sets output alignment to "NONE", "C0", "C1" INIT => '0', -- Sets initial state of the Q output to '0' or '1' SRTYPE => "SYNC") -- Specifies "SYNC" or "ASYNC" set/reset port map ( Q => l2_trig(i), -- 1-bit output data C0 => l2_trig_bufg, -- 1-bit clock input C1 => l2_trig_bufg_n, -- 1-bit clock input CE => '1', -- 1-bit clock enable input D0 => '1', -- 1-bit data input (associated with C0) D1 => '0', -- 1-bit data input (associated with C1) R => '0', -- 1-bit reset input S => '0' -- 1-bit set input ); -- output delay CTDB_L2_TRIGGER_odelay_inst : IODELAY2 generic map ( COUNTER_WRAPAROUND => "STAY_AT_LIMIT", -- "STAY_AT_LIMIT" or "WRAPAROUND" DATA_RATE => "SDR", -- "SDR" or "DDR" DELAY_SRC => "ODATAIN", -- "IO", "ODATAIN" or "IDATAIN" IDELAY2_VALUE => 0, -- Delay value when IDELAY_MODE="PCI" (0-255) IDELAY_MODE => "NORMAL", -- "NORMAL" or "PCI" IDELAY_TYPE => "FIXED", -- "FIXED", "DEFAULT", "VARIABLE_FROM_ZERO", "VARIABLE_FROM_HALF_MAX" -- or "DIFF_PHASE_DETECTOR" IDELAY_VALUE => 0, -- Amount of taps for fixed input delay (0-255) ODELAY_VALUE => CTDB_L2_TRIGGER_DELAY(i), -- Amount of taps fixed output delay (0-255) SERDES_MODE => "NONE", -- "NONE", "MASTER" or "SLAVE" SIM_TAPDELAY_VALUE => 75 -- Per tap delay used for simulation in ps ) port map ( BUSY => open, -- 1-bit output: Busy output after CAL DATAOUT => open, -- 1-bit output: Delayed data output to ISERDES/input register DATAOUT2 => open, -- 1-bit output: Delayed data output to general FPGA fabric DOUT => l2_trig_dld(i), -- 1-bit output: Delayed data output TOUT => open, -- 1-bit output: Delayed 3-state output CAL => '0', -- 1-bit input: Initiate calibration input CE => '0', -- 1-bit input: Enable INC input CLK => '0', -- 1-bit input: Clock input IDATAIN => '0', -- 1-bit input: Data input (connect to top-level port or I/O buffer) INC => '0', -- 1-bit input: Increment / decrement input IOCLK0 => '0', -- 1-bit input: Input from the I/O clock network IOCLK1 => '0', -- 1-bit input: Input from the I/O clock network ODATAIN => l2_trig(i), -- 1-bit input: Output data input from output register or OSERDES2. RST => '0', -- 1-bit input: Reset to zero or 1/2 of total delay period T => '1' -- 1-bit input: 3-state input signal ); L2_TRIG_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => L2_TRIG_P(i), OB => L2_TRIG_N(i), I => l2_trig_dld(i)); -- L2_TRIG_inst : OBUFDS -- generic map (IOSTANDARD => "LVDS_33") -- port map ( O => L2_TRIG_P(i), OB => L2_TRIG_N(i), I => l2_trig(i)); end generate CTDB_L2_TRIGGER; ----- start of REGISTER DESCRIPTION ------------------------------------------------------ TIME_STAMP_COUNTER: process (tib_reset, tib_gclk2) begin if rising_edge (tib_gclk2) then if (tib_reset = '1') or time_stamp_ct = X"ffffffffffff" then time_stamp_ct <= (others => '0'); else time_stamp_ct <= time_stamp_ct + '1'; end if; -- (tib_reset = '1') or .. end if; -- rising_edge (tib_gclk2) end process TIME_STAMP_COUNTER; TIME_STAMP_LATCH: process (tib_gclk2) variable ctrl15_pipe : std_logic_vector(2 downto 0) := B"000"; variable ctrl15_lh : std_logic := '0'; begin if rising_edge (tib_gclk2) then ctrl15_pipe(0) := ctrl_rg(15); ctrl15_pipe(2 downto 1) := ctrl15_pipe(1 downto 0); if ctrl15_pipe = B"011" then ctrl15_lh := '1'; else ctrl15_lh := '0'; end if; if ctrl15_lh = '1' then tstmp0_rg <= time_stamp_ct(15 downto 0); tstmp1_rg <= time_stamp_ct(31 downto 16); tstmp2_rg <= time_stamp_ct(47 downto 32); end if; -- ctrl15_lh = '1' end if; -- rising_edge (tib_gclk2) end process TIME_STAMP_LATCH; GPS_RESET_gen: process(gps_clk, qosc1_reset) variable reset_ct : std_logic_vector(2 downto 0) := B"000"; begin if qosc1_reset='1' then reset_ct := B"000"; gps_reset <= '0'; else if rising_edge (gps_clk) then if reset_ct /= B"111" then reset_ct := reset_ct + '1'; end if; if reset_ct = B"110" then gps_reset <= '1'; else gps_reset <= '0'; end if; end if; -- rising_edge (gps_gclk) end if; -- qosc1_reset='1' end process GPS_RESET_gen; GPS_PPS_CHECK: process (gps_clk, gps_reset) variable first_pps : boolean := true; --variable pps : std_logic_vector(1 downto 0) := B"00"; begin if rising_edge(gps_clk) then -- 24 MHz if(gps_reset = '1') then pps <= B"00"; first_pps := true; gps_ct_mismatch <= '0'; gps_ct <= (others => '0'); pps_lh_edge <= '0'; else pps(0) <= gps_pps; pps(1) <= pps(0); if pps = B"01" then pps_lh_edge <= '1'; else pps_lh_edge <= '0'; end if;-- pps = B"01" if pps_lh_edge = '1' then if first_pps = true then first_pps := false; else GPS_EXTINT0 <= '1'; if gps_ct /= (GPS_FREQUENCY - '1') then gps_ct_mismatch <= '1'; else gps_ct_mismatch <= '0'; end if; -- gps_ct /= (GPS_FREQUENCY -1) end if; --first_pps = true gps_ct <= (others => '0'); else GPS_EXTINT0 <= '0'; gps_ct <= gps_ct + '1'; end if; --pps_lh_edge = '1' end if; -- reset = '1' end if; --rising_edge(gps_clk) end process GPS_PPS_CHECK; EBI1_STROBES_SYNC: process(qosc1_reset, qosc1_gclk3) -- high speed synchronizer begin if rising_edge(qosc1_gclk3) then if qosc1_reset ='1' then ebi1_ncs2_pipe <= B"000"; ebi1_ncs2_hl <= '0'; ebi1_nwe_pipe <= B"000"; ebi1_nwe_lh <= '0'; else ebi1_ncs2_pipe(0) <= EBI1_NCS2; ebi1_ncs2_pipe(1) <= ebi1_ncs2_pipe(0); ebi1_ncs2_pipe(2) <= ebi1_ncs2_pipe(1); if ebi1_ncs2_pipe(1)='0' and ebi1_ncs2_pipe(2)='1' then ebi1_ncs2_hl <= '1'; elsif ebi1_ncs2_hl_clr='1' then ebi1_ncs2_hl <= '0'; end if; ebi1_nwe_pipe(0) <= EBI1_NWE; ebi1_nwe_pipe(1) <= ebi1_nwe_pipe(0); ebi1_nwe_pipe(2) <= ebi1_nwe_pipe(1); if ebi1_nwe_pipe(1)='1' and ebi1_nwe_pipe(2)='0' then ebi1_nwe_lh <= '1'; elsif ebi1_nwe_lh_clr='1' then ebi1_nwe_lh <= '0'; end if; end if; --qosc1_reset ='1' end if; -- rising_edge(qosc1_gclk3) end process EBI1_STROBES_SYNC; EBI1_D_bufs : for i in 0 to 15 generate EBI1_D_iobuf_inst : IOBUF generic map ( DRIVE => 2,--12, IBUF_DELAY_VALUE => "0", -- 0..12 ? amount of added input delay for buffer IFD_DELAY_VALUE => "AUTO", -- 0..6 ? amount of added delay for input register, IOSTANDARD => "DEFAULT",--"LVCMOS18", SLEW => "SLOW") port map ( O => ebi1_d_in(i), -- Buffer output, memory -> FPGA IO => EBI1_D(i), -- memory data bus I => ebi1_d_out(i), -- Buffer input, FPGA -> memory T => EBI1_NRD -- disable FPGA -> memory ); end generate EBI1_D_bufs; REGISTER_ADDRESS: process (qosc1_gclk2) -- needed for write access begin if rising_edge(qosc1_gclk2) then ebi1_ncs2_hl_clr <= '0'; -- for single pulse if EBI1_ADDR(20 downto 8)= BASE_ADDR then reg_sel <='1'; else reg_sel <= '0'; end if; if reg_sel='1' and ebi1_ncs2_hl='1' then ebi1_ncs2_hl_clr <= '1'; if (EBI1_ADDR(7 downto 0) = X"00") then ctrl_addr <= '1'; else ctrl_addr <='0'; end if; if (EBI1_ADDR(7 downto 0) = X"04") then spad_addr <= '1'; else spad_addr <='0'; end if; if (EBI1_ADDR(7 downto 0) = X"06") then sptx_addr <= '1'; else sptx_addr <='0'; end if; -- if (EBI1_ADDR(7 downto 0) = X"0a") then tstmp0_addr <= '1'; else tstmp0_addr <='0'; end if; -- if (EBI1_ADDR(7 downto 0) = X"0c") then tstmp1_addr <= '1'; else tstmp1_addr <='0'; end if; -- if (EBI1_ADDR(7 downto 0) = X"0e") then tstmp2_addr <= '1'; else tstmp2_addr <='0'; end if; if (EBI1_ADDR(7 downto 0) = X"10") then test_addr <= '1'; else test_addr <='0'; end if; if (EBI1_ADDR(7 downto 0) = X"12") then l1sel_addr <= '1'; else l1sel_addr <='0'; end if; if (EBI1_ADDR(7 downto 0) = X"14") then l1msk_addr <= '1'; else l1msk_addr <='0'; end if; if (EBI1_ADDR(7 downto 0) = X"16") then l1del_addr <= '1'; else l1del_addr <='0'; end if; if (EBI1_ADDR(7 downto 0) = X"18") then muthr_addr <= '1'; else muthr_addr <='0'; end if; if (EBI1_ADDR(7 downto 0) = X"20") then mudel_addr <= '1'; else mudel_addr <='0'; end if; -- if (EBI1_ADDR(7 downto 0) = X"fe") then fwrev_addr <= '1'; else fwrev_addr <='0'; end if; end if; -- reg_sel='1' and ebi1_ncs2_hl='1' end if;-- rising_edge(qosc1_gclk2) end process REGISTER_ADDRESS; REGISTER_WRITE: process (qosc1_gclk2) begin if rising_edge(qosc1_gclk2) then if qosc1_reset = '1' then muon_thr_rg <= MUON_THR_INIT; -- initial muon trigger threshold, use 8 to 20 decimal as initial value muon_del_rg <= MUON_DEL_INIT; -- initial value in multiples of 4ns ctrl_rg <= CTRL_RG_INIT; else ebi1_nwe_lh_clr <= '0'; -- for single pulse l1msk_rg_wstb <= '0'; -- for single pulse if l1_del_rg_wstb_clr = '1' then l1_del_rg_wstb <= '0'; end if; if ebi1_nwe_lh='1' then ebi1_nwe_lh_clr <= '1'; if ctrl_addr = '1' then ctrl_rg <= ebi1_d_in; end if; if spad_addr = '1' then spad_rg <= ebi1_d_in; end if; if sptx_addr = '1' then sptx_rg <= ebi1_d_in; end if; if test_addr = '1' then test_rg <= ebi1_d_in; end if; if l1sel_addr = '1' then l1sel_rg <= ebi1_d_in(8 downto 0); end if; -- L2BP, slots 1..9, 13..21 if l1msk_addr = '1' then l1msk_rg <= ebi1_d_in(15 downto 1); l1msk_rg_wstb <= '1'; end if; -- CTDB, RJ45 1..15 if l1del_addr = '1' then l1_del_rg(l1_trig_chan_remapped(l1sel_rg)) <= ebi1_d_in(7 downto 0); l1_del_rg_wstb <= '1'; end if; if muthr_addr = '1' then muon_thr_rg <= ebi1_d_in(8 downto 0); end if; if mudel_addr = '1' then muon_del_rg <= ebi1_d_in(3 downto 0); end if; end if; -- ebi1_nwe_lh='1' end if; -- if qosc1_reset = '1' end if; -- rising_edge(qosc1_gclk2) end process REGISTER_WRITE; DEL_RG_WSTB_SYNC: process(qosc1_gclk2, tib_gclk2) begin if rising_edge(qosc1_gclk2) then l1_del_rg_wstb_clr_pipe(0) <= l1_del_rg_wstb_pipe(3); l1_del_rg_wstb_clr_pipe(3 downto 1) <= l1_del_rg_wstb_clr_pipe(2 downto 0); if l1_del_rg_wstb_clr_pipe(3 downto 2) = B"01" then l1_del_rg_wstb_clr <= '1'; else l1_del_rg_wstb_clr <= '0'; end if; -- l1_del_rg_wstb_clr_pipe(3 downto 2) = B"01" end if; -- rising_edge(qosc1_gclk2) if rising_edge(tib_gclk2) then l1_del_rg_wstb_pipe(0) <= l1_del_rg_wstb; l1_del_rg_wstb_pipe(3 downto 1) <= l1_del_rg_wstb_pipe(2 downto 0); if l1_del_rg_wstb_pipe(3 downto 2) = B"01" then l1_del_rg_wstb_syncd <= '1'; else l1_del_rg_wstb_syncd <= '0'; end if; -- l1_del_load_pipe(3 downto 2) = B"01" end if; -- rising_edge(tib_gclk2) end process DEL_RG_WSTB_SYNC; REGISTER_READ: process (EBI1_ADDR(7 downto 0), ctrl_rg,stat_rg,spad_rg,sptx_rg,sprx_rg,tstmp0_rg,tstmp1_rg,tstmp2_rg, test_rg, l1sel_rg, l1msk_rd_rg, l1_del_rg, muon_thr_rg, muon_del_rg) begin case EBI1_ADDR(7 downto 0) is when X"00" => ebi1_d_out <= ctrl_rg; when X"02" => ebi1_d_out <= stat_rg; when X"04" => ebi1_d_out <= spad_rg; when X"06" => ebi1_d_out <= sptx_rg; when X"08" => ebi1_d_out <= sprx_rg; when X"0a" => ebi1_d_out <= tstmp0_rg; when X"0c" => ebi1_d_out <= tstmp1_rg; when X"0e" => ebi1_d_out <= tstmp2_rg; when X"10" => ebi1_d_out <= test_rg; when X"12" => ebi1_d_out <= B"0000000" & l1sel_rg; when X"14" => ebi1_d_out <= l1msk_rd_rg & '0'; when X"16" => ebi1_d_out <= X"00" & l1_del_rg(l1_trig_chan_remapped(l1sel_rg)); when X"18" => ebi1_d_out <= B"0000000" & muon_thr_rg; when X"20" => ebi1_d_out <= X"000" & muon_del_rg; when X"fe" => ebi1_d_out <= FW_REVISION; when others => ebi1_d_out <= X"0000"; end case; end process REGISTER_READ; STAT_REG: process (qosc1_gclk2) begin if rising_edge(qosc1_gclk2) then stat_rg(0) <= spi_busy; stat_rg(1) <= l1_delay_busy; stat_rg(14 downto 2) <= B"0" & X"000"; stat_rg(15) <= gps_ct_mismatch; end if; -- rising_edge(qosc1_gclk2) end process STAT_REG; TRIG_MASK: process(qosc1_gclk2) begin if rising_edge(qosc1_gclk2) then if l1msk_rg_wstb = '1' then -- single pulse, after l1msk_rg write operation case l1sel_rg(8 downto 4) is when "00001" => l1_trig_msk( 14 downto 0) <= l1msk_rg; -- slot 1 when "00010" => l1_trig_msk( 29 downto 15) <= l1msk_rg; when "00011" => l1_trig_msk( 44 downto 30) <= l1msk_rg; when "00100" => l1_trig_msk( 59 downto 45) <= l1msk_rg; when "00101" => l1_trig_msk( 74 downto 60) <= l1msk_rg; when "00110" => l1_trig_msk( 89 downto 75) <= l1msk_rg; when "00111" => l1_trig_msk(104 downto 90) <= l1msk_rg; when "01000" => l1_trig_msk(119 downto 105) <= l1msk_rg; when "01001" => l1_trig_msk(134 downto 120) <= l1msk_rg; -- slot 9 when "01101" => l1_trig_msk(149 downto 135) <= l1msk_rg; -- slot 13 when "01110" => l1_trig_msk(164 downto 150) <= l1msk_rg; when "01111" => l1_trig_msk(179 downto 165) <= l1msk_rg; when "10000" => l1_trig_msk(194 downto 180) <= l1msk_rg; when "10001" => l1_trig_msk(209 downto 195) <= l1msk_rg; when "10010" => l1_trig_msk(224 downto 210) <= l1msk_rg; when "10011" => l1_trig_msk(239 downto 225) <= l1msk_rg; when "10100" => l1_trig_msk(254 downto 240) <= l1msk_rg; when "10101" => l1_trig_msk(269 downto 255) <= l1msk_rg; -- slot 21 when others => NULL; end case; end if; -- l1msk_rg_wstb = '1' case l1sel_rg(8 downto 4) is when "00001" => l1msk_rd_rg <= l1_trig_msk( 14 downto 0); -- slot 1 when "00010" => l1msk_rd_rg <= l1_trig_msk( 29 downto 15); when "00011" => l1msk_rd_rg <= l1_trig_msk( 44 downto 30); when "00100" => l1msk_rd_rg <= l1_trig_msk( 59 downto 45); when "00101" => l1msk_rd_rg <= l1_trig_msk( 74 downto 60); when "00110" => l1msk_rd_rg <= l1_trig_msk( 89 downto 75); when "00111" => l1msk_rd_rg <= l1_trig_msk(104 downto 90); when "01000" => l1msk_rd_rg <= l1_trig_msk(119 downto 105); when "01001" => l1msk_rd_rg <= l1_trig_msk(134 downto 120); -- slot 9 when "01101" => l1msk_rd_rg <= l1_trig_msk(149 downto 135); -- slot 13 when "01110" => l1msk_rd_rg <= l1_trig_msk(164 downto 150); when "01111" => l1msk_rd_rg <= l1_trig_msk(179 downto 165); when "10000" => l1msk_rd_rg <= l1_trig_msk(194 downto 180); when "10001" => l1msk_rd_rg <= l1_trig_msk(209 downto 195); when "10010" => l1msk_rd_rg <= l1_trig_msk(224 downto 210); when "10011" => l1msk_rd_rg <= l1_trig_msk(239 downto 225); when "10100" => l1msk_rd_rg <= l1_trig_msk(254 downto 240); when "10101" => l1msk_rd_rg <= l1_trig_msk(269 downto 255); -- slot 21 when others => NULL; end case; end if; --if rising_edge(qosc1_gclk2) end process TRIG_MASK; ----- end of REGISTER DESCRIPTION ------------------------------------------------------ -- configuring the GPS on power on -- gps_confg_en <= not(gps_confg_done); -- -- GPS_ublox_Lea6T_confg_port_map: GPS_ublox_Lea6T_confg -- generic map -- ( -- divisor => 325 -- ) -- port map -- ( -- clk => tib_gclk2, -- reset => treset, -- test_clk => uart_clk, -- tx_enable=> gps_confg_en, -- tx => test_tx, -- tx_done => gps_confg_done -- ); -- generating a SPI start pulse SPI_RUN_gen: process (qosc1_gclk2) begin if rising_edge(qosc1_gclk2) then spi_run <= '0'; -- to get a single pulse if ebi1_nwe_lh='1' then if spad_addr = '1' then spi_run <= '1'; end if; end if; -- ebi1_nwe_lh='1' end if; -- rising_edge(qosc1_gclk2) end process SPI_RUN_gen; spi_master_16bit_02_port_map: spi_master_16bit_02 generic map (CLOCK_DIVIDER => 2) -- SPI_CLK = SYS_CLK / (CLOCK_DIVIDER * 4) port map ( reset => qosc1_reset, clk => qosc1_gclk2, -- 50 MHz tx_addr => spad_rg(14 downto 0), tx_data => sptx_rg, rx_data => sprx_rg, spi_run => spi_run, spi_wr => spad_rg(15), spi_busy => spi_busy, spi_sync => SPI_SYNCn, spi_sclk => SPI_SCLK, spi_mosi => SPI_MOSI, spi_miso => spi_miso ); TIB_BUSY_gen: process (L1_BUSY) begin if L1_BUSY /= X"0000" & B"00" then tib_busy <= '1'; else tib_busy <= '0'; end if; end process TIB_BUSY_gen; -- ******************** unused inputs / outputs dummy usage ********************************* DUMMY_1: process (tib_gclk2) begin if rising_edge(tib_gclk2) then QOSC1_DAC_SYNCn <= '1'; QOSC1_DAC_SCKL <= '0'; QOSC1_DAC_SDIN <= '0'; EBI1_NWAIT <= '1'; PC1_ARM_IRQ0 <= '0'; CTDB_CLK_SEL <= '0'; CTDB_PPS_SEL <= '0'; tib_spare0 <= '0'; --tib_spare1 <= '0'; QOSC2_DAC_SYNCn <= '1'; QOSC2_ENA <= '1'; addr_64bit_out <= '0'; addr_64bit_trst <= '1'; temperature_out <= '0'; temperature_trst <= '1'; end if; -- rising_edge(tib_gclk2) end process DUMMY_1; -- RS232 / RS485 ports DUMMY_2: process (qosc1_clk) begin if rising_edge(qosc1_clk) then GPS_RXD1 <= RS232_RXD; -- 3.3V CMOS, USB_RS_TXD <= USB_RS_RXD; RS232_TXD <= GPS_TXD1; -- 3.3V CMOS, -- GPS module LEA-6T GPS_RESET_N <= PON_RESETn; -- 3.3V CMOS, GPS-module reset --GPS_EXTINT0 <= '0'; -- 3.3V CMOS, interrupt signal for time stamping an event end if; -- rising_edge(qosc1_clk) end process DUMMY_2; lvds_io_0 <= tib_clk_out; lvds_io_1 <= tib_pps_out; lvds_io_2 <= '0'; -- lvds_io_3 <= '0'; lvds_io_4 <= camera_trig; -- is also differential clock input, pin AE13, AF13 lvds_io_5 <= camera_trig_dld; -- used as back looped trigger signal, jumpered to lvds_io(4) lvds_io_6 <= addr_64bit_in; --dummy lvds_io_7 <= temperature_in; --dummy LVDS_IO0_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => LVDS_IO_P0, OB =>LVDS_IO_N0, I => lvds_io_0); LVDS_IO1_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => LVDS_IO_P1, OB =>LVDS_IO_N1, I => lvds_io_1); LVDS_IO2_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => LVDS_IO_P2, OB =>LVDS_IO_N2, I => lvds_io_2); LVDS_IO3_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => LVDS_IO_P3, OB =>LVDS_IO_N3, I => lvds_io_3); LVDS_IO4_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => LVDS_IO_P4, OB =>LVDS_IO_N4, I => lvds_io_4); LVDS_IO5_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => LVDS_IO_P5, OB =>LVDS_IO_N5, I => lvds_io_5); LVDS_IO6_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => LVDS_IO_P6, OB =>LVDS_IO_N6, I => lvds_io_6); LVDS_IO7_inst : OBUFDS generic map (IOSTANDARD => "LVDS_33") port map ( O => LVDS_IO_P7, OB =>LVDS_IO_N7, I => lvds_io_7); end architecture arch_L2CB_015_top;