------------------------------------------------------- -- Design Name : dtb4_3nn_015 -- File Name : dtb4_3nn_015.vhd -- Function : top level design, fanout combinatorial, 3nn -- external 50 MHz or local 25 MHz clock, by jumper -- Coder : K.-H. Sulanke, DESY, 2019-05-10 ------------------------------------------------------- -- 2017-02-24 like for the L0s, for L1A and 1PPS delay load, even if BUSY, -- the latest delay value will be taken always -- 2017-03-01 extra clock for cl0_pdat added + extra odelay for the FANOUTs to get rid off the 78h inital delay load -- see trig_pulse_shaper_03, oserdes_reset => reset, required (?) to get clean pulse shapes for trig etc. -- function pix_trig_3_of_19_asyn_02, sub_trig(4..6) are not working (?), disabled now -- 2017-03-03 first 3nn design, to be used for the DTB4 -- 2017-03-15 CL0_IDELAY changed from 40h->60h, fanout routing fixed (.ucf), fanout delay tuned -- 2017-03-30 in_del_w_cal_01, iserdes_ph_ctrl_02, sw_led_ctrl_01 introduced -- 2017-04-02 iserdes_ph_ctrl_02 bug fixed, EXTRA_INC_CNT for final adjustment introduced -- 2017-04-24 fanout 1..6 corrected -- 2017-09-18 16bit L1 scaler implemented, updated every second, when overflow it stays at 0xffffh, access via SPI -- to avoid race conditions, the L1_SCALER_L register should be read first -- l0_del_sel_rg renamed to pixel_sel_rg -- 2017-10-17 1PPS check implemented, PLL: CLKOUT5_PHASE => 135.0, see .ucf, gclkb_dld timing constraint commented -- iserdes_ph_ctrl_01 -> .._02 changed, -- 2017-10-25 new iserdes input delay schema implemented, see in_del_cl0_01 / .._05 -- 2017-12-20 new registers: TRIG_MASK_0 .._6, registers TRIG_MASK_C, .._N removed, -- 2018-02-26 new register: L1_SC_WIN, programmable window size for the L1 scaler, 10ms - 2.55s -- 2018-03-05 TRGL1 local clock bug fixed -- 2019-04-24 trying to fix the "first L1A loss bug" by removing the adjustable L1 input delay stage -- 2019-04-26 trying to fix the "first L1A loss bug" by connecting "reset" to TRGL1_oddr2_inst 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.trigger_3nn_pkg.all; entity dtb4_3nn_015 is generic ( FW_REV : std_logic_vector(15 downto 0) := X"000F"; CLKIN_PERIOD : real := 20.0; -- 50 MHz external clock LCLK_CLKIN_PERIOD : real := 40.0; -- 50 MHz onboard clock PLL_MULT : integer := 20; -- to get 1 GHz from 50 MHz , max. possible serdes rate LCLK_PLL_MULT : integer := 16; -- to get 400 MHz from the 25 MHz oscillator LCLK_DIV : integer := 8; -- to get 50 MHz PLL_DIV : integer := 1; -- affects all pll clock outputs S : integer := 8; -- serdes factor DELCLK_DIV : integer := 8; -- to get 125 MHz iodelay2 clock for a delay range of 0 to 8ns EXTCLK_DIV : integer := 20 -- to get 50 Mhz ); port ( LCLK_ENA : out std_logic; -- LVCMOS, oscillator enable LCLK : in std_logic; -- LVCMOS, local clock input by QOSC GCLKB_P : in std_logic; -- dedicated clock pin, signal from J13-1,2 , LVDS, GCLKB_N : in std_logic; -- external clock + pps input, both are also used as 24V power line --GCLKB_IN_P : in std_logic; -- GCLKB_P additionally connected to this standard I/O pin --GCLKB_IN_N : in std_logic; -- GCLKB_N additionally connected to this standard I/O pin J13_BUSY_OUT_P : inout std_logic; -- J13-6,3, DIFF_SSTL2_I, used to transmit the FEB-BUSY signal J13_BUSY_OUT_N : inout std_logic; -- was PPS input before J13_L2_IN_P : inout std_logic; -- J13-4,5, bank2, LVDS, camera trigger input J13_L2_IN_N : inout std_logic; -- from TIB via L2-crate J13_L1_OUT_P : inout std_logic; -- J13-8,7, bank0, LVDS, output, J13_L1_OUT_N : inout std_logic; -- used as pulse shaped L1_out CL0_P : in std_logic_vector (0 to 6); -- bank1, LVDS, from FE-board discriminator CL0_N : in std_logic_vector (0 to 6); -- CL1_P : in std_logic_vector (0 to 4); -- bank3 CL1_N : in std_logic_vector (0 to 4); CL2_P : in std_logic_vector (0 to 4); -- bank3 CL2_N : in std_logic_vector (0 to 4); CL3_P : in std_logic_vector (0 to 4); -- bank3 CL3_N : in std_logic_vector (0 to 4); CL4_P : in std_logic_vector (0 to 4); -- bank1 CL4_N : in std_logic_vector (0 to 4); CL5_P : in std_logic_vector (0 to 4); -- bank1 CL5_N : in std_logic_vector (0 to 4); CL6_P : in std_logic_vector (0 to 4); -- bank1 CL6_N : in std_logic_vector (0 to 4); NBOR_IN : in std_logic_vector (1 to 6); -- low active signals, '0' means neigbor is connected TEST_IO0_P : out std_logic; -- bank0 TEST_IO0_N : in std_logic; -- TEST_IO1_P : in std_logic; -- bank0 TEST_IO1_N : out std_logic; -- TEST_IO2_P : in std_logic; -- bank3 TEST_IO2_N : in std_logic; -- TEST_IO3_P : in std_logic; -- bank3 TEST_IO3_N : in std_logic; -- FANOUT1_P : out std_logic_vector (0 to 4); -- bank0 FANOUT1_N : out std_logic_vector (0 to 4); FANOUT2_P : out std_logic_vector (0 to 4); -- bank2 FANOUT2_N : out std_logic_vector (0 to 4); FANOUT3_P : out std_logic_vector (0 to 4); -- bank2 FANOUT3_N : out std_logic_vector (0 to 4); FANOUT4_P : out std_logic_vector (0 to 4); -- bank2 FANOUT4_N : out std_logic_vector (0 to 4); FANOUT5_P : out std_logic_vector (0 to 4); -- bank0 FANOUT5_N : out std_logic_vector (0 to 4); FANOUT6_P : out std_logic_vector (0 to 4); -- bank0 FANOUT6_N : out std_logic_vector (0 to 4); -- TRIG_IN_P : in std_logic_vector (1 to 6); -- from neighbor clusters -- TRIG_IN_N : in std_logic_vector (1 to 6); -- TRIG_OUT_P : out std_logic_vector (1 to 6); -- to neighbor clusters -- TRIG_OUT_N : out std_logic_vector (1 to 6); BUSY_P : in std_logic; -- LVDS BUSY_N : in std_logic; -- FEB-BUSY EXTCLK_P : out std_logic; -- LVDS, connected to FE-board EXTCLK_N : out std_logic; -- TRGL1_P : out std_logic; -- bank2, LVDS, connected to FE-board TRGL1_N : out std_logic; -- TIMEPPS_P : out std_logic; -- bank ?, LVDS, connected to FE-board TIMEPPS_N : out std_logic; -- FPGA_SLOW_0 : in std_logic ; -- 2.5V CMOS, SPI_CLK, J12-C6 FPGA_SLOW_1 : in std_logic ; -- 2.5V CMOS, SPI_MOSI, J12-D6 FPGA_SLOW_2 : in std_logic ; -- 2.5V CMOS, SPI_CE, J12-A7 FPGA_SLOW_3 : out std_logic ; -- 2.5V CMOS, SPI_MISO, J12-B7 LT3680_SYNC : out std_logic ; -- LVCMOS, 2 Mhz clock (from system clock) -- to synchronize the DC-DC converter IC "LT3680" -- TRGCONF_P : out std_logic ; -- -- TRGCONF_N : out std_logic ; -- -- -- TRGTYPE_P : out std_logic_vector (0 to 2); -- TRGTYPE_N : out std_logic_vector (0 to 2); -- -- SPARES0_P : in std_logic; -- unused FEB signals at J11 -- SPARES0_N : in std_logic; -- SPARES1_P : in std_logic; -- SPARES1_N : in std_logic; -- SPARES2_P : in std_logic; -- SPARES2_N : in std_logic; -- nSW1 : in std_logic; -- on board push button, can be used for calibration -- nSW2 : in std_logic; -- on board push button, pulls signal to GND -- nLED_ENA : out std_logic; -- '1' disables all LEDs (incl. ethernet jack) nLED_GREEN : out std_logic; -- '0' = LED V3-green is on nLED_RED : out std_logic -- '0' = LED V3-red is on -- I2C_CLK : out std_logic; -- to be used for temp. sensor X1 (LM73CIMXKX-) and EEPROM U4 (24AAxx) -- I2C_DAT : out std_logic -- to be used for temp. sensor X1 (LM73CIMXKX-) and EEPROM U4 (24AAxx) ); --attribute maxskew: string; --attribute maxskew of FANOUT0_P : signal is "1.1 ns"; --attribute maxskew of FANOUT0_N : signal is "1.1 ns"; end entity; architecture dtb4_3nn_015_arch of dtb4_3nn_015 is --constant USE_EXT_CLOCK : std_logic := '1'; --constant USE_LOCAL_CLOCK : std_logic := '0'; -- jumper set, TEST_IO0_N on GND constant FW_REVL : std_logic_vector := X"01";--last to be used is X"19"; constant FW_REVH : std_logic_vector := X"00"; constant ONE_SECOND : std_logic_vector := X"64"; -- multiples of 10 ms constant PPS_LENGTH : integer := 3; -- in multiples of 20 ns constant J13_CLK_EXT_IDELAY : integer := 1;--0 / 36; -- here 36 ps per tap constant J13_TRIG_IN_IDELAY : integer := 1;--0 / 36; -- here 36 ps per tap -- constant LOCAL_CLOCK_ENA : std_logic := '1'; -- type out_delay_array is array (0 to 29) of integer; -- constant OUT_DELAY : out_delay_array := -- local clock, 37ps/tap -- ( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- bank_2 -- 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11); -- bank_0 -- constant BANK2_ODELAY : integer := 0;-- 0; -- constant BANK0_ODELAY : integer := 11;--11; constant CL1to6_IDELAY : std_logic_vector := B"0_0000"; -- 0 ... 1ns, in 37ps steps constant CL0_IDELAY : std_logic_vector := B"0_0000"; -- 0 ... 1ns, in 37ps steps --constant TRIG_DEAD_TIME : integer := 12; -- L1 trigger dead time, amount of gclk2 clocks type out_delay_array is array (0 to 4) of integer; -- delays, calculated (EXCEL) from Post Map Static Timing report / -- Data Sheet report, assuming 37ps/tap -- 0 1 2 3 4 constant FANOUT1_DELAY : out_delay_array := ( 17, 13, 0, 6, 5); -- as final step, use "Post-PAR Static Timing" for constant FANOUT2_DELAY : out_delay_array := ( 23, 45, 21, 16, 25); -- delay adjustment !!! constant FANOUT3_DELAY : out_delay_array := ( 71, 48, 45, 31, 13); constant FANOUT4_DELAY : out_delay_array := ( 60, 69, 42, 58, 58); constant FANOUT5_DELAY : out_delay_array := ( 41, 61, 52, 44, 57); constant FANOUT6_DELAY : out_delay_array := ( 35, 32, 42, 19, 9); component spi_slave_8bit_02 port ( clk : in std_logic ; -- high speed system clock spi_reset : in std_logic ; -- synchronous spi_reset spi_txd : in std_logic_vector (7 downto 0); -- data to be sent spi_rxd : out std_logic_vector (7 downto 0); -- data received spi_rxd_val : out std_logic; -- Rx data vaild, single pulse spi_addr : out std_logic_vector ( 6 downto 0); -- register address spi_addr_val : out std_logic; -- Rx data vaild spi_wr_nrd : out std_logic ; -- spi cycle is active spi_sync : in std_logic ; -- backplane bus, low active sync signal spi_sclk : in std_logic ; -- backplane bus, SPI clock spi_mosi : in std_logic ; -- backplane bus, serial SPI tx-data spi_miso : out std_logic -- backplane bus, serial SPI rx-data ); end component spi_slave_8bit_02; constant REG_WIDTH : integer := 8; -- register width constant BLOCK_SIZE : integer := 7; signal spi_addr : std_logic_vector (BLOCK_SIZE-1 downto 0):= (others => '0'); signal spi_rxd_val : std_logic; -- synchronous write enable signal spi_txd : std_logic_vector (REG_WIDTH-1 downto 0); -- signal spi_rxd : std_logic_vector (REG_WIDTH-1 downto 0); -- signal pps_del_load : std_logic := '0'; signal pps_del_busy : std_logic := '0'; signal l1a_del_load : std_logic := '0'; signal l1a_del_busy : std_logic := '0'; component in_del_1x_03 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; -- lvds serial data inputs del_data : in std_logic_vector (7 downto 0); -- delay value del_load : in std_logic; -- to initiate the DELAY cycle, handshake with del_done cal_iodelay_cenLED del_busy : out std_logic; -- delay done, handshake with del_load del_dataout2 : out std_logic -- ); end component in_del_1x_03 ; signal del_ioclk0 : std_logic := '0'; signal del_ioclk1 : std_logic := '0'; signal del_ioclk2 : std_logic := '0'; signal del_ioclk3 : std_logic := '0'; component iserdes_pulse_shaper_03 is port ( clk : in std_logic ; -- pdat clock iserdes_pdat : in std_logic_vector (0 to 7); -- iserdes pdat out pulse_pdat : out std_logic_vector (0 to 7); -- pulse shaped pdat pulse_width : in std_logic_vector (2 downto 0) ); end component iserdes_pulse_shaper_03 ; -- component trig_pulse_shaper_01 is -- port ( -- clk : in std_logic ; -- pdat clock -- serdes_pdat : in std_logic_vector (0 to 7); -- serdes pdat -- pulse_pdat : out std_logic_vector (0 to 7); -- pulse shaped oserdes pdat -- pulse_width : in std_logic_vector (2 downto 0); -- dead_time : in std_logic_vector (7 downto 0) -- trigger inactive, amount of clks -- ); -- end component trig_pulse_shaper_01 ; component trig_pulse_shaper_03 is port ( clk : in std_logic ; -- pdat clock pulse_width : in std_logic_vector (3 downto 0); -- length in clock cycles dead_time : in std_logic_vector (7 downto 0); -- trigger inactive, amount of clks 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 : out std_logic -- serial oserdes output ); end component trig_pulse_shaper_03 ; component in_del_cl0_02 is generic ( S : integer := 8; -- Parameter to set the serdes factor 1..8 INIT_DELAY : std_logic_vector := B"0_0001" ); -- clock period (ns) of input clock on clkin_p port ( reset : in std_logic ; -- reset (active high) clk : in std_logic ; -- global clock input trig_mask : in std_logic ; -- if '0' pdat_out <= X"00" 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; -- delay status sdat_in_p : in std_logic; -- lvds serial data inputs sdat_in_n : in std_logic; -- lvds serial data inputs sdat_out : out std_logic; -- output of LVDS receiver stage iserdes_ioclk : in std_logic ; -- high speed i/o clock iserdes_stb : in std_logic ; -- pdat_out : out std_logic_vector (0 to 7) -- synchronized (clk) iserdes par. data output --sdat_dld : out std_logic -- delayed serial data output, for test purposes ); end component in_del_cl0_02 ; component in_del_cl1to6_02 is generic ( S : integer := 8; -- Parameter to set the serdes factor 1..8 INIT_DELAY : std_logic_vector := B"0_0001" ); -- clock period (ns) of input clock on clkin_p port ( reset : in std_logic ; -- reset (active high) clk : in std_logic ; -- global clock input trig_mask : in std_logic ; -- if '0' pdat_out <= X"00" 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; -- delay status sdat_in_p : in std_logic; -- lvds serial data inputs sdat_in_n : in std_logic; -- lvds serial data inputs iserdes_ioclk : in std_logic ; -- high speed i/o clock iserdes_stb : in std_logic ; -- pdat_out : out std_logic_vector (0 to 7) -- synchronized (clk) iserdes par. data output ); end component in_del_cl1to6_02 ; component center_pixel_delay_cal_01 is generic ( CLUSTER_NR : std_logic_vector (2 downto 0) := B"000" ); port ( --clk : in std_logic ; -- global clock input l0_del_sel_rg : in std_logic_vector (5 downto 0); -- bits 5..3= cluster_#, 2..0= pixel_# cl0_pdat0 : in std_logic_vector (0 to 7); -- cl0_pdat1 : in std_logic_vector (0 to 7); -- cl0_pdat2 : in std_logic_vector (0 to 7); -- cl0_pdat3 : in std_logic_vector (0 to 7); -- is the reference pixel cl0_pdat4 : in std_logic_vector (0 to 7); -- cl0_pdat5 : in std_logic_vector (0 to 7); -- cl0_pdat6 : in std_logic_vector (0 to 7); -- trig_2of37 : out std_logic_vector (0 to 7) -- ); end component center_pixel_delay_cal_01 ; component outer_pixel_delay_cal_01 is generic ( CLUSTER_NR : std_logic_vector (2 downto 0) := B"000" ); port ( --clk : in std_logic ; -- global clock input l0_del_sel_rg : in std_logic_vector (5 downto 0); -- bits 5..3= cluster_#, 2..0= pixel_# cl0_pdat3 : in std_logic_vector (0 to 7); -- cl0_pdat3 is the reference pixel clx_pdat0 : in std_logic_vector (0 to 7); -- all pulse shaped, according to the clx_pdat1 : in std_logic_vector (0 to 7); -- TRIG_WIN register clx_pdat2 : in std_logic_vector (0 to 7); -- clx_pdat3 : in std_logic_vector (0 to 7); -- clx_pdat4 : in std_logic_vector (0 to 7); -- trig_2of37 : out std_logic_vector (0 to 7) -- ); end component outer_pixel_delay_cal_01 ; component sw_led_ctrl_01 is port ( reset : in std_logic ; -- reset (active high) clk : in std_logic ; -- global clock input nSW1 : in std_logic; -- on board push button, can be used for calibration nLED_GREEN : out std_logic; -- '0' = LED V3-green is on nLED_RED : out std_logic; -- '0' = LED V3-red is on cal_start : out std_logic ; -- start calibration cycle, single pulse cal_done : in std_logic; -- calibration status cal_err : in std_logic -- calibration error, gets cleared by next cal_start ); end component sw_led_ctrl_01 ; component iserdes_ph_ctrl_02 is generic ( S : integer := 8; -- to set the serdes factor 1..8 ALIGNMENT_CNT : std_logic_vector := B"0001_1111"; -- required max. successfull phase alignments, before calibration is done EXTRA_INC_CNT : std_logic_vector := B"0000_1000" -- for final adjustment ); -- clock period (ns) of input clock on clkin_p port ( reset : in std_logic ; -- reset (active high) clk : in std_logic ; -- global clock input del_ioclk0 : in std_logic ; -- fast (5 x clk), needed by iodelay instance ref_sdat_in_p : in std_logic; -- lvds serial data inputs, reference signal ref_sdat_in_n : in std_logic; -- cal_sdat_in_p : in std_logic; -- lvds serial data inputs, signal with its delay to be calibrated cal_sdat_in_n : in std_logic; -- iserdes_ioclk : in std_logic ; -- high speed i/o clock iserdes_stb : in std_logic ; -- cal_iodelay_rst : out std_logic; -- iodelay_rst, to control the delay of the signal to be calibrated cal_iodelay_cal : out std_logic; -- iodelay_cal, to control the delay of the signal to be calibrated cal_iodelay_ce : out std_logic; -- iodelay_ce, to control the delay of the signal to be calibrated cal_iodelay_inc : out std_logic; -- iodelay_inc, to control the delay of the signal to be calibrated cal_iodelay_busy : in std_logic; -- iodelay_busy, from the signal to be calibrated cal_start : in std_logic ; -- start calibration cycle, single pulse cal_busy : out std_logic; -- one while calibrating cal_done : out std_logic; -- single pulse cal_err : out std_logic -- calibration error, gets cleared by next cal_start ); end component iserdes_ph_ctrl_02 ; component in_del_w_cal_01 is port ( reset : in std_logic ; -- reset (active high) clk : in std_logic ; -- global clock input iodelay_ioclk0 : in std_logic ; -- high speed i/o delay clock sdat_in_p : in std_logic; -- lvds serial data inputs sdat_in_n : in std_logic; 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; -- delay done, handshake with del_load cal_iodelay_rst : in std_logic; -- iodelay_rst, controlled by phase detecting unit cal_start : in std_logic; -- single pulse to initiate the calibration cycle cal_iodelay_cal : in std_logic; -- iodelay_cal, controlled by phase detecting unit cal_iodelay_ce : in std_logic; -- iodelay_ce, controlled by phase detecting unit cal_iodelay_inc : in std_logic; -- iodelay_inc, controlled by phase detecting unit cal_iodelay_busy : out std_logic; -- iodelay_busy, needed by phase detecting unit cal_data : out std_logic_vector (7 downto 0); -- gained delay value, after calibration cal_err : in std_logic; -- single pulse cal_done : in std_logic; -- --cal_cyc_nd : out std_logic; -- --del_cyc_nd : out std_logic; -- iodelay_dataout2 : out std_logic -- delayed sdat_in signal ); end component in_del_w_cal_01 ; component serdes_lh_edge_01 is port ( clk : in std_logic ; -- pdat clock serdes_pdat : in std_logic_vector (0 to 7); -- serdes pdat lh_edge : out std_logic -- pulse of one clk length ); end component serdes_lh_edge_01 ; component trig_1_of_37_01 is port ( pixel_sel_rg : in std_logic_vector (5 downto 0); -- bits 5..3= cluster_#, 2..0= pixel_# NBOR_IN : in std_logic_vector (1 to 6); -- low active signal with pullup, cl0_pdat0, cl0_pdat1, cl0_pdat2, cl0_pdat3, cl0_pdat4, cl0_pdat5, cl0_pdat6 : in std_logic_vector (0 to 7); cl1_pdat0, cl1_pdat1, cl1_pdat2, cl1_pdat3, cl1_pdat4 : in std_logic_vector (0 to 7); -- all pulse shaped, according to the cl2_pdat0, cl2_pdat1, cl2_pdat2, cl2_pdat3, cl2_pdat4 : in std_logic_vector (0 to 7); cl3_pdat0, cl3_pdat1, cl3_pdat2, cl3_pdat3, cl3_pdat4 : in std_logic_vector (0 to 7); cl4_pdat0, cl4_pdat1, cl4_pdat2, cl4_pdat3, cl4_pdat4 : in std_logic_vector (0 to 7); cl5_pdat0, cl5_pdat1, cl5_pdat2, cl5_pdat3, cl5_pdat4 : in std_logic_vector (0 to 7); cl6_pdat0, cl6_pdat1, cl6_pdat2, cl6_pdat3, cl6_pdat4 : in std_logic_vector (0 to 7); trig_1of37 : out std_logic_vector (0 to 7) -- ); end component trig_1_of_37_01 ; component oserdes_01 is 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 : out std_logic -- serial oserdes output ); end component oserdes_01 ; -- cl0...6 ----------------------------------------------------------------------- signal cl0 : std_logic_vector(0 to 6) := B"000_0000"; signal cl0_dld : std_logic_vector(0 to 6) := B"000_0000"; -- signal cl1 : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl2 : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl3 : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl4 : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl5 : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl6 : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl0_dld : std_logic_vector(0 to 6) := B"000_0000"; -- signal cl1_dld : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl2_dld : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl3_dld : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl4_dld : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl5_dld : std_logic_vector(0 to 4) := B"0_0000"; -- signal cl6_dld : std_logic_vector(0 to 4) := B"0_0000"; signal cl0_del_load : std_logic_vector(0 to 6):= B"000_0000"; signal cl1_del_load : std_logic_vector(0 to 4):= B"0_0000"; signal cl2_del_load : std_logic_vector(0 to 4):= B"0_0000"; signal cl3_del_load : std_logic_vector(0 to 4):= B"0_0000"; signal cl4_del_load : std_logic_vector(0 to 4):= B"0_0000"; signal cl5_del_load : std_logic_vector(0 to 4):= B"0_0000"; signal cl6_del_load : std_logic_vector(0 to 4):= B"0_0000"; signal cl0_del_busy : std_logic_vector(0 to 6):= B"000_0000"; signal cl1_del_busy : std_logic_vector(0 to 4):= B"0_0000"; signal cl2_del_busy : std_logic_vector(0 to 4):= B"0_0000"; signal cl3_del_busy : std_logic_vector(0 to 4):= B"0_0000"; signal cl4_del_busy : std_logic_vector(0 to 4):= B"0_0000"; signal cl5_del_busy : std_logic_vector(0 to 4):= B"0_0000"; signal cl6_del_busy : std_logic_vector(0 to 4):= B"0_0000"; type cl0_iserdes_pdat is array (0 to 6) of std_logic_vector(0 to 7); signal cl0_pdat0, cl0_pdat : cl0_iserdes_pdat; -- cl0_pdat0 is delayed unmodified iserdes output -- cl0_pdat is pulse shaped final pipeline stage, to be used for the trigger type cl_iserdes_pdat is array (0 to 4) of std_logic_vector(0 to 7); signal cl1_pdat0, cl1_pdat : cl_iserdes_pdat; signal cl2_pdat0, cl2_pdat : cl_iserdes_pdat; signal cl3_pdat0, cl3_pdat : cl_iserdes_pdat; signal cl4_pdat0, cl4_pdat : cl_iserdes_pdat; signal cl5_pdat0, cl5_pdat : cl_iserdes_pdat; signal cl6_pdat0, cl6_pdat : cl_iserdes_pdat; -- fanout1...6 ----------------------------------------------------------------------- --attribute maxskew: string; --attribute maxskew of fanout0 : signal is "0.5ns"; signal fanout1_sdat : std_logic_vector(0 to 4); -- direct fanout from cl0 via output delays signal fanout2_sdat : std_logic_vector(0 to 4); signal fanout3_sdat : std_logic_vector(0 to 4); signal fanout4_sdat : std_logic_vector(0 to 4); signal fanout5_sdat : std_logic_vector(0 to 4); signal fanout6_sdat : std_logic_vector(0 to 4); signal fanout1_sdat_dld : std_logic_vector(0 to 4); -- using fixed output delays signal fanout2_sdat_dld : std_logic_vector(0 to 4); signal fanout3_sdat_dld : std_logic_vector(0 to 4); signal fanout4_sdat_dld : std_logic_vector(0 to 4); signal fanout5_sdat_dld : std_logic_vector(0 to 4); signal fanout6_sdat_dld : std_logic_vector(0 to 4); -- trigger signals ----------------------------------------------------------------- type array_7x8 is array (6 downto 0) of std_logic_vector(7 downto 0); type array_5x8 is array (4 downto 0) of std_logic_vector(7 downto 0); signal center : std_logic_vector(0 to S-1); -- 3nn of inner 19 pixel type outer_trig is array (1 to 6) of std_logic_vector(0 to S-1); signal outer : outer_trig; -- 3nn of outer 11 pixel region -- type trig_3nn_pipe is array (0 to 1) of std_logic_vector (0 to S-1); -- signal trig_3nn : trig_3nn_pipe := (others => X"00"); -- 3nn trigger, 8 time slices signal trig_3nn : std_logic_vector(0 to S-1); -- 3NN (3 connected) trigger signal trig_1of7 : std_logic_vector(0 to S-1); -- 1 of 7 central pixels (cl0) signal trig_1of37 : std_logic_vector(0 to S-1); -- the 1 of 37 pixels, selected by pixel_sel_rg, triggers signal trig_2_of_37 : std_logic_vector(0 to S-1); -- 1 of 7 for pixel delay calibration signal trig_2of37 : array_7x8; signal trig : std_logic_vector(0 to S-1); -- selected (by ctrl_rg) trigger signal up_trig : std_logic_vector(0 to S-1); -- up going (to CTDB) trigger pulse signal up_trig_lh_edge : std_logic := '0'; -- max. one edge per gclk2 possible signal l1_scaler : std_logic_vector(15 downto 0); -- updated once per second signal l1_scaler_rg : std_logic_vector(15 downto 0) := X"0000"; -- used for read sync. signal l1_scaler_upd : std_logic; -- used for l1_scaler signal l1_sc_win_rg_wstb : std_logic; -- --signal l1_sc_ms10 : std_logic; -- L1 scaler 10ms pulse signal pps_error : std_logic := '0'; signal pps_error_pipe : std_logic_vector(3 downto 0) := B"0000"; signal trgl1 : std_logic := '0'; -- lvds outbuf input, in IOB (ODDDR) signal trgl1_copy : std_logic := '0'; -- copy to generate the trgl1_clr signal signal trgl1_clr_nd : std_logic := '0'; signal trgl1_clr : std_logic := '0'; signal trgl1_or : std_logic := '0'; -- needed for needed for local clock mode signal trgl1_bufg : std_logic := '0'; -- clock routing + ODDR2 used for improved timing signal not_trgl1_bufg : std_logic := '0'; -- signal trgl1_S : std_logic := '0'; -- asynchronous set, needed for local clock mode -- signal trgl1_R : std_logic := '0'; -- asynchronous reset, needed for local clock mode signal trig1_shiftout1_m : std_logic; -- master-slave cascading signal trig1_shiftout2_m : std_logic; signal trig1_shiftout3_s : std_logic; signal trig1_shiftout4_s : std_logic; -- J13 (RJ45) signals signal gclkb : std_logic; -- J13-1,2, input signal gclkb_dld : std_logic; -- delayed gclkb signal signal j13_63_trig_out : std_logic; -- J13-8,7, output signal j13_63_trig_out_lb : std_logic; -- looped back output signal j13_45_l2_T : std_logic; -- signal j13_63_l2_T : std_logic; -- signal j13_45_l2_in : std_logic; -- signal j13_63_l2_in : std_logic; -- signal j13_45_l2_in_dld : std_logic; -- signal j13_63_l2_in_dld : std_logic; -- signal j13_45_l2_in_del_busy : std_logic; -- signal j13_63_l2_in_del_busy : std_logic; -- -- local clock, plls and clocks signal lclk_pll_rst : std_logic; signal lclk_pll_clkin : std_logic; -- primary clock input signal lclk_pll_clkfbout : std_logic; -- signal lclk_pll_clkout2 : std_logic; -- pll output, par. data clock, as gclk2 main clock signal lclk_pll_locked : std_logic; -- active high pll lock signal -- external clock, plls and clocks signal pll_rst : std_logic; signal pll_clkin : std_logic; -- primary clock input signal pll_clkfbin : std_logic; -- signal pll_clkfbout : std_logic; -- signal pll_clkfbout_bufg : std_logic; -- signal pll_clkout0 : std_logic; -- pll output, fast i/o clock, used for progr. delay lines signal pll_clkout1 : std_logic; -- pll output, fast i/o clock, used for iserdes, oserdes signal pll_clkout2 : std_logic; -- pll output, par. data clock, as gclk2 main clock signal pll_clkout3 : std_logic; -- used for EXTCLK_P/N signal pll_clkout4 : std_logic; -- used for EXTCLK_P/N, 180° phase shifted signal pll_clkout5 : std_logic; -- used for TIMEPPS_P/N recover, 90° phase shifted signal pll_locked : std_logic; -- active high pll lock signal --signal gclk0 : std_logic; -- made from pll_clkout0 --signal gclk1 : std_logic; -- made from pll_clkout0 signal gclk2 : std_logic; -- signal gclk3 : std_logic; -- made from pll_clkout3 signal gclk4 : std_logic; -- made from pll_clkout4 signal gclk5 : std_logic; -- made from pll_clkout5 signal lclk_x2 : std_logic; -- made from lclk_pll_clkout2 signal reset : std_logic := '0'; -- synchronous to gclk2 signal reset_ct : std_logic_vector(3 downto 0) := X"0"; -- synchronous to gclk2 -- bufpll signal oserdes_stb0 : std_logic; -- index according to the bank signal oserdes_stb2 : std_logic; signal iserdes_stb1 : std_logic; signal iserdes_stb3 : std_logic; -- signal iserdes_stb4 : std_logic; signal serdes_ioclk0 : std_logic; -- index according to the bank signal serdes_ioclk1 : std_logic; signal serdes_ioclk2 : std_logic; signal serdes_ioclk3 : std_logic; -- DC-DC syncronization signal lt3680_sync_clk : std_logic := '0'; -- output connections to the FE-board -- signal trgtype : std_logic_vector(0 to 2) := B"000"; -- -- signal trgconf : std_logic := '0'; -- signal timepps : std_logic := '0'; signal pulse_length_ct : integer range 0 to PPS_LENGTH := 0; -- pulse length, multiples of 20 ns signal extclk : std_logic := '0'; signal timepps_q0 : std_logic := '0'; signal timepps_q1 : std_logic := '0'; signal timepps_int : std_logic := '0'; signal ctdb_pps : std_logic := '0'; signal spares3 : std_logic := '0'; signal busy_out_63 : std_logic := '0'; signal busy_out_45 : std_logic := '0'; signal test_io0 : std_logic := '0'; signal test_io0_lb : std_logic := '0'; signal test_io1 : std_logic := '0'; signal l1_leading_edge : std_logic := '0'; type state_type is (TRIG_IDLE, TRIG_RUN2, TRIG_WAIT); signal state : state_type := TRIG_IDLE; -- SPI signals signal spi_sync : std_logic := '0'; signal spi_sclk : std_logic := '0'; signal spi_mosi : std_logic := '0'; signal spi_miso : std_logic := '0'; signal spi_wr_nrd : std_logic := '0'; signal spi_addr_val : std_logic := '0'; -- register definition, control via FE-board SPI bus (FPGA_SLOW__0..3 -- reset / power on values constant TRIGGER_DEAD_TIME_INIT : std_logic_vector := B"0000_1100"; -- 12 constant TRIGGER_PULSE_WIDTH_INIT : std_logic_vector := B"0101"; -- 5, upgoing (to CTDB) pulse constant TRIGGER_WINDOW_INIT : std_logic_vector := B"010"; -- 2 constant CTRL_ADDR : std_logic_vector := B"000_0000"; constant STAT_ADDR : std_logic_vector := B"000_0001"; constant L1_SC_WIN_ADDR : std_logic_vector := B"000_0010"; constant TRIG_PULS_ADDR : std_logic_vector := B"000_0100"; constant TRIG_DTIM_ADDR : std_logic_vector := B"000_0101"; constant TRIG_WIN_ADDR : std_logic_vector := B"000_0110"; constant PPS_DEL_ADDR : std_logic_vector := B"000_0111"; constant L1A_DEL_ADDR : std_logic_vector := B"000_1000"; constant PIXEL_SEL_ADDR : std_logic_vector := B"000_1001"; constant L0_DEL_ADDR : std_logic_vector := B"000_1010"; --constant L0_DEL_OFFS_ADDR : std_logic_vector := B"000_1011"; -- reserved constant L1_SCALER_L_ADDR : std_logic_vector := B"000_1100"; constant L1_SCALER_H_ADDR : std_logic_vector := B"000_1101"; constant PPS_FAILED_ADDR : std_logic_vector := B"000_1110"; constant PPS_CAL_ADDR : std_logic_vector := B"000_1111"; constant TRIG_MASK_0_ADDR : std_logic_vector := B"001_0000"; constant TRIG_MASK_1_ADDR : std_logic_vector := B"001_0001"; constant TRIG_MASK_2_ADDR : std_logic_vector := B"001_0010"; constant TRIG_MASK_3_ADDR : std_logic_vector := B"001_0011"; constant TRIG_MASK_4_ADDR : std_logic_vector := B"001_0100"; constant TRIG_MASK_5_ADDR : std_logic_vector := B"001_0101"; constant TRIG_MASK_6_ADDR : std_logic_vector := B"001_0110"; constant FW_REVL_ADDR : std_logic_vector := B"111_1110"; constant FW_REVH_ADDR : std_logic_vector := B"111_1111"; -- constant L00_DEL_ADDR : array_7x7 := -- 10 .. 16 dec. -- ( B"000_1010",B"000_1011",B"000_1100",B"000_1101",B"000_1110",B"000_1111",B"001_0000"); signal ctrl_rg : std_logic_vector(7 downto 0) := X"00"; -- synchronous to gclk2 signal stat_rg : std_logic_vector(4 downto 0) := B"0_0000"; -- signal trig_puls_rg : std_logic_vector(3 downto 0) := B"0000"; -- signal trig_dtim_rg : std_logic_vector(7 downto 0) := X"00"; -- signal trig_win_rg : std_logic_vector(2 downto 0) := B"000"; -- signal pps_del_rg : std_logic_vector(7 downto 0) := X"00"; -- signal l1a_del_rg : std_logic_vector(7 downto 0) := X"00"; -- signal pixel_sel_rg : std_logic_vector(5 downto 0) := B"00_0000"; -- signal l0_del_wr_rg : std_logic_vector(7 downto 0) := X"00"; -- used for write access signal l0_del_rd_rg : std_logic_vector(7 downto 0) := X"00"; -- used for read access signal l1_sc_win_rg : std_logic_vector(7 downto 0) := X"00"; -- L1 scaler window signal l1_sc_win_rd_rg : std_logic_vector(7 downto 0) := X"00"; -- L1 scaler window read register signal l1_scaler_h_rg : std_logic_vector(7 downto 0) := X"00"; -- signal pps_failed_ct : std_logic_vector(7 downto 0); -- counter for mismatched / missed PPS pulses signal pps_failure : std_logic := '0'; signal trig_mask_0_rg : std_logic_vector(6 downto 0); signal trig_mask_1_rg : std_logic_vector(6 downto 0); signal trig_mask_2_rg : std_logic_vector(6 downto 0); signal trig_mask_3_rg : std_logic_vector(6 downto 0); signal trig_mask_4_rg : std_logic_vector(6 downto 0); signal trig_mask_5_rg : std_logic_vector(6 downto 0); signal trig_mask_6_rg : std_logic_vector(6 downto 0); signal cl0_l0_del_rg : array_7x8; signal cl1_l0_del_rg : array_5x8; signal cl2_l0_del_rg : array_5x8; signal cl3_l0_del_rg : array_5x8; signal cl4_l0_del_rg : array_5x8; signal cl5_l0_del_rg : array_5x8; signal cl6_l0_del_rg : array_5x8; signal l0_del_load : std_logic := '0'; signal l0_del_load0 : std_logic := '0'; -- signal l0_del_load, delayed by one clock signal l0_del_busy : std_logic := '0'; -- calibration related signals signal cal_start : std_logic; -- single pulse to initiate the calibration cycle signal cal_iodelay_rst : std_logic; -- iodelay_rst, controlled by phase detecting unit signal cal_iodelay_cal : std_logic; -- iodelay_cal, controlled by phase detecting unit signal cal_iodelay_ce : std_logic; -- iodelay_ce, controlled by phase detecting unit signal cal_iodelay_inc : std_logic; -- iodelay_inc, controlled by phase detecting unit signal cal_iodelay_busy : std_logic; -- iodelay_busy, needed by phase detecting unit signal cal_data : std_logic_vector (7 downto 0); -- gained delay value, after calibration signal cal_err : std_logic; -- calibration failed, single pulse signal cal_busy : std_logic; -- calibration in progress signal cal_done : std_logic; -- calibration ready, single pulse --signal cal_cyc_nd : std_logic; -- --signal del_cyc_nd : std_logic; -- begin -- I/O port mapping ---------------------------------------------------------------------------------- LT3680_SYNC <= '0'; -- to get a low ripple LCLK_ENA <= '1' when (TEST_IO0_N = '0') else '0'; lclk_pll_clkin_BUFG_inst : BUFG port map ( O => lclk_pll_clkin, -- 1-bit output: Clock buffer output I => LCLK -- 1-bit input: Clock buffer input ); LCLK_PLL_BASE_inst : PLL_BASE generic map ( BANDWIDTH => "OPTIMIZED", -- "HIGH", "LOW" or "OPTIMIZED" !!! "LOW" gives 2x more jitter !!! CLKFBOUT_MULT => LCLK_PLL_MULT, -- 25Mhz->1Ghz (max.), multiplication factor for all output clocks CLK_FEEDBACK => "CLKFBOUT",--"CLKOUT0", -- needed (!) to phase align with the input clock was "CLKFBOUT" before w. no pps CLKFBOUT_PHASE => 0.0, -- Phase shift (degrees) of all output clocks CLKIN_PERIOD => LCLK_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 => LCLK_DIV, -- 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 => LCLK_DIV, -- 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 => LCLK_DIV, -- 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 => LCLK_DIV, -- 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, -- dependant on internal delay ! 120°-170° did work, gclk_dld to gclk5, .ucf constraint not used COMPENSATION => "INTERNAL", -- "SYSTEM_SYNCHRONOUS", -- "SOURCE_SYNCHRONOUS", "INTERNAL", -- "EXTERNAL", "DCM2PLL", "PLL2DCM" DIVCLK_DIVIDE => PLL_DIV,--1,--5,--PLL_DIV, -- Division factor for all clocks (1 to 52) REF_JITTER => 0.1) -- Input reference jitter (0.000 to 0.999 UI%) port map ( CLKFBOUT => lclk_pll_clkfbout, -- General output feedback signal CLKOUT0 => open, -- One of six general clock output signals CLKOUT1 => open, -- One of six general clock output signals CLKOUT2 => lclk_pll_clkout2, -- One of six general clock output signals CLKOUT3 => open, -- One of six general clock output signals CLKOUT4 => open, -- One of six general clock output signals+ CLKOUT5 => open,--pll_clkout5, -- One of six general clock output signals LOCKED => lclk_pll_locked, -- Active high PLL lock output signal CLKFBIN => lclk_pll_clkfbout, -- Clock feedback input CLKIN => lclk_pll_clkin, -- dcm_clkfx,--,Clock input RST => lclk_pll_rst --open -- Asynchronous PLL reset ); LCLK_PLL_RESET_GEN: process(LCLK) -- 25 MHz variable lclk_pll_reset_ct : integer range 0 to 65535 := 0; begin if rising_edge (LCLK) then if (lclk_pll_reset_ct /= 65535) then lclk_pll_reset_ct := lclk_pll_reset_ct + 1; if (lclk_pll_reset_ct = 65500) then lclk_pll_rst <= '1'; else lclk_pll_rst <= '0'; end if; -- (lclk_pll_reset_ct = 65500) end if; --(lclk_pll_reset_ct /= 65535) end if; -- rising_edge (LCLK) end process LCLK_PLL_RESET_GEN; LCLK_GCKL2_inst : BUFG port map ( I => lclk_pll_clkout2, -- 1-bit Clock buffer input O => lclk_x2 -- 1-bit Clock buffer output ); pll_clkin_BUFGMUX_inst : BUFGMUX generic map ( CLK_SEL_TYPE => "ASYNC" -- Glitchles ("SYNC") or fast ("ASYNC") clock switch-over ) port map ( O => pll_clkin, -- 1-bit output: Clock buffer output I0 => lclk_x2, -- 1-bit input: Clock buffer input (S=0) I1 => gclkb_dld, -- 1-bit input: Clock buffer input (S=1) S => TEST_IO0_N -- with pull_up ); sw_led_ctrl_01_port_map: sw_led_ctrl_01 port map ( reset => reset, -- reset (active high) clk => gclk2, -- global clock input nSW1 => nSW1, -- on board push button, can be used for calibration nLED_GREEN => nLED_GREEN, -- '0' = LED V3-green is on nLED_RED => nLED_RED, -- '0' = LED V3-red is on cal_start => cal_start, -- start calibration cycle, single pulse cal_done => cal_done, -- calibration status cal_err => cal_err -- calibration error, gets cleared by next cal_start ); iserdes_ph_ctrl_02_port_map: iserdes_ph_ctrl_02 generic map( S => 8, -- to set the serdes factor 1..8 ALIGNMENT_CNT => B"0001_1111", -- required max. successfull phase alignments, before calibration is done EXTRA_INC_CNT => B"0000_1000" -- for final adjustment ) port map( reset => reset, -- reset (active high) clk => gclk2, -- global clock input del_ioclk0 => del_ioclk3, -- fast (5 x clk), needed by iodelay instance ref_sdat_in_p => TEST_IO2_P, -- bank3, lvds serial data inputs, reference signal ref_sdat_in_n => TEST_IO2_N, -- cal_sdat_in_p => TEST_IO3_P, -- bank3, lvds serial data inputs, signal with its delay to be calibrated cal_sdat_in_n => TEST_IO3_N, -- iserdes_ioclk => serdes_ioclk3, -- high speed i/o clock iserdes_stb => iserdes_stb3, -- cal_iodelay_rst => cal_iodelay_rst, -- iodelay_ce, to control the delay of the signal to be calibrated cal_iodelay_cal => cal_iodelay_cal, -- iodelay_ce, to control the delay of the signal to be calibrated cal_iodelay_ce => cal_iodelay_ce, -- iodelay_ce, to control the delay of the signal to be calibrated cal_iodelay_inc => cal_iodelay_inc, -- iodelay_inc, to control the delay of the signal to be calibrated cal_iodelay_busy => cal_iodelay_busy, -- iodelay_busy, from the signal to be calibrated cal_start => cal_start, -- start calibration cycle, single pulse cal_busy => cal_busy, -- one while calibrating cal_done => cal_done, -- single pulse cal_err => cal_err -- calibration error, gets cleared by next cal_start ); GCLKB_PPS_DELAY_ADJ:in_del_w_cal_01 port map ( reset => reset, clk => gclk2, iodelay_ioclk0 => del_ioclk1, sdat_in_p => GCLKB_P, sdat_in_n => GCLKB_N, del_data => pps_del_rg, -- delay value del_load => pps_del_load, -- to initiate the DELAY cycle del_busy => pps_del_busy, -- delay cycle status cal_start => cal_start, -- single pulse to initiate the calibration cycle cal_iodelay_rst => cal_iodelay_rst, -- iodelay_rst, controlled by phase detecting unit cal_iodelay_cal => cal_iodelay_cal, -- iodelay_cal, controlled by phase detecting unit cal_iodelay_ce => cal_iodelay_ce, -- iodelay_ce, controlled by phase detecting unit cal_iodelay_inc => cal_iodelay_inc, -- iodelay_inc, controlled by phase detecting unit cal_iodelay_busy => cal_iodelay_busy, -- iodelay_busy, needed by phase detecting unit cal_data => cal_data, -- gained delay value, after calibration cal_err => cal_err, -- single pulse cal_done => cal_done, -- single pulse --cal_cyc_nd => open, --cal_cyc_nd, -- --del_cyc_nd => open, --del_cyc_nd, -- iodelay_dataout2 => gclkb_dld -- delayed sdat_in signal ); -- pll_clkin_BUFG_inst : BUFG -- port map ( -- O => pll_clkin, -- 1-bit output: Clock buffer output -- I => gclkb_dld -- 1-bit input: Clock buffer input -- ); CL0_L0_DEL_ISERDES_bank1 : for i in 0 to 6 generate CL0_L0_DEL_ISERDES_inst: in_del_cl0_02 generic map ( S => 8, -- Parameter to set the serdes factor 1..8 INIT_DELAY => CL0_IDELAY -- global cl0 input delay ) port map ( reset => reset, -- reset (active high) clk => gclk2, -- gclk2, global clock input trig_mask => trig_mask_0_rg(i), del_data => l0_del_wr_rg, -- delay value del_load => cl0_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => cl0_del_busy(i), -- delay done, single pulse sdat_in_p => CL0_P(i), -- lvds serial data inputs sdat_in_n => CL0_N(i), -- lvds serial data inputs sdat_out => cl0(i), -- output of LVDS receiver stage iserdes_ioclk => serdes_ioclk1, -- serdes_ioclk1, high speed i/o clock iserdes_stb => iserdes_stb1, -- iserdes_stb1, pdat_out => cl0_pdat0(i) -- synchronized (clk) iserdes par. data output --sdat_dld => cl0_dld(i) -- delayed serial data ); end generate CL0_L0_DEL_ISERDES_bank1 ; CL1_L0_DEL_ISERDES_bank3 : for i in 0 to 4 generate --for i in 0 to 4 generate CL1_L0_DEL_ISERDES_inst: in_del_cl1to6_02 generic map ( S => 8 -- Parameter to set the serdes factor 1..8 --INIT_DELAY => CL1to6_IDELAY -- power on value (after reset) ) port map ( reset => reset, -- reset (active high) clk => gclk2, -- global clock input trig_mask => trig_mask_1_rg(pixel_remap_cl1(i)), del_data => l0_del_wr_rg, -- delay value del_load => cl1_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => cl1_del_busy(i), -- delay done, single pulse sdat_in_p => CL1_P(i), -- lvds serial data inputs sdat_in_n => CL1_N(i), -- lvds serial data inputs iserdes_ioclk => serdes_ioclk3, -- high speed i/o clock iserdes_stb => iserdes_stb3, -- pdat_out => cl1_pdat0(i) -- synchronized (clk) iserdes par. data output ); end generate CL1_L0_DEL_ISERDES_bank3 ; CL2_L0_DEL_ISERDES_bank3 : for i in 0 to 4 generate CL2_L0_DEL_ISERDES_inst: in_del_cl1to6_02 generic map ( S => 8 -- Parameter to set the serdes factor 1..8 --INIT_DELAY => CL1to6_IDELAY -- power on value (after reset) ) port map ( reset => reset, -- reset (active high) clk => gclk2, -- global clock input trig_mask => trig_mask_2_rg(pixel_remap_cl2(i)), del_data => l0_del_wr_rg, -- delay value del_load => cl2_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => cl2_del_busy(i), -- delay done, single pulse sdat_in_p => CL2_P(i), -- lvds serial data inputs sdat_in_n => CL2_N(i), -- lvds serial data inputs iserdes_ioclk => serdes_ioclk3, -- high speed i/o clock iserdes_stb => iserdes_stb3, -- pdat_out => cl2_pdat0(i) -- synchronized (clk) iserdes par. data output ); end generate CL2_L0_DEL_ISERDES_bank3 ; CL3_L0_DEL_ISERDES_bank3 : for i in 0 to 4 generate CL3_L0_DEL_ISERDES_inst: in_del_cl1to6_02 generic map ( S => 8 -- Parameter to set the serdes factor 1..8 --INIT_DELAY => CL1to6_IDELAY -- power on value (after reset) ) -- clock period (ns) of input clock on clkin_p port map ( reset => reset, -- reset (active high) clk => gclk2, -- global clock input trig_mask => trig_mask_3_rg(pixel_remap_cl3(i)), del_data => l0_del_wr_rg, -- delay value del_load => cl3_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => cl3_del_busy(i), -- delay done, single pulse sdat_in_p => CL3_P(i), -- lvds serial data inputs sdat_in_n => CL3_N(i), -- lvds serial data inputs iserdes_ioclk => serdes_ioclk3, -- high speed i/o clock iserdes_stb => iserdes_stb3, -- pdat_out => cl3_pdat0(i) -- synchronized (clk) iserdes par. data output ); end generate CL3_L0_DEL_ISERDES_bank3 ; CL4_L0_DEL_ISERDES_bank1 : for i in 0 to 4 generate CL4_L0_DEL_ISERDES_inst: in_del_cl1to6_02 generic map ( S => 8 -- Parameter to set the serdes factor 1..8 --INIT_DELAY => CL1to6_IDELAY -- power on value (after reset) ) -- clock period (ns) of input clock on clkin_p port map ( reset => reset, -- reset (active high) clk => gclk2, -- global clock input trig_mask => trig_mask_4_rg(pixel_remap_cl4(i)), del_data => l0_del_wr_rg, -- delay value del_load => cl4_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => cl4_del_busy(i), -- delay done, single pulse sdat_in_p => CL4_P(i), -- lvds serial data inputs sdat_in_n => CL4_N(i), -- lvds serial data inputs iserdes_ioclk => serdes_ioclk1, -- high speed i/o clock iserdes_stb => iserdes_stb1, -- pdat_out => cl4_pdat0(i) -- synchronized (clk) iserdes par. data output ); end generate CL4_L0_DEL_ISERDES_bank1 ; CL5_L0_DEL_ISERDES_bank1 : for i in 0 to 4 generate CL5_L0_DEL_ISERDES_inst: in_del_cl1to6_02 generic map ( S => 8 -- Parameter to set the serdes factor 1..8 --INIT_DELAY => CL1to6_IDELAY -- power on value (after reset) ) -- clock period (ns) of input clock on clkin_p port map ( reset => reset, -- reset (active high) clk => gclk2, -- global clock input trig_mask => trig_mask_5_rg(pixel_remap_cl5(i)), del_data => l0_del_wr_rg, -- delay value del_load => cl5_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => cl5_del_busy(i), -- delay done, single pulse sdat_in_p => CL5_P(i), -- lvds serial data inputs sdat_in_n => CL5_N(i), -- lvds serial data inputs iserdes_ioclk => serdes_ioclk1, -- high speed i/o clock iserdes_stb => iserdes_stb1, -- pdat_out => cl5_pdat0(i) -- synchronized (clk) iserdes par. data output ); end generate CL5_L0_DEL_ISERDES_bank1 ; CL6_L0_DEL_ISERDES_bank1 : for i in 0 to 4 generate CL6_L0_DEL_ISERDES_inst: in_del_cl1to6_02 generic map ( S => 8 -- Parameter to set the serdes factor 1..8 --INIT_DELAY => CL1to6_IDELAY -- power on value (after reset) ) -- clock period (ns) of input clock on clkin_p port map ( reset => reset, -- reset (active high) clk => gclk2, -- global clock input trig_mask => trig_mask_6_rg(pixel_remap_cl6(i)), del_data => l0_del_wr_rg, -- delay value del_load => cl6_del_load(i), -- to initiate the DELAY cycle, single pulse del_busy => cl6_del_busy(i), -- delay done, single pulse sdat_in_p => CL6_P(i), -- lvds serial data inputs sdat_in_n => CL6_N(i), -- lvds serial data input iserdes_ioclk => serdes_ioclk1, -- high speed i/o clock iserdes_stb => iserdes_stb1, -- pdat_out => cl6_pdat0(i) -- synchronized (clk) iserdes par. data output ); end generate CL6_L0_DEL_ISERDES_bank1 ; FEB_BUSY_inst : IBUFDS generic map ( CAPACITANCE => "DONT_CARE", -- "LOW", "NORMAL", "DONT_CARE" (Virtex-4 only) DIFF_TERM => TRUE, --FALSE, -- Differential Termination (Virtex-4/5, Spartan-3E/3A) IBUF_DELAY_VALUE => "0", -- Specify the amount of added input delay for buffer, IFD_DELAY_VALUE => "0", -- Specify the amount of added delay for input register, -- "AUTO", "0"-"6" (Spartan-3E) IOSTANDARD => "LVDS_25")--"LVDS33") port map ( O => spares3, -- buffer output I => BUSY_P, -- buffer input (connect directly to top-level port) IB => BUSY_N -- buffer input (connect directly to top-level port) ); --busy_out <= spares3; busy_out_63 <= '1' when ((spares3 = '1') and (TEST_IO0_N = '1')) else '0'; j13_63_l2_T <= '1' when TEST_IO0_N = '0' else '0'; J13_63_L2_IN_ext_clock : IOBUFDS -- FEB test L2 input mode (with local clock enabled) generic map ( IOSTANDARD => "LVDS_25") port map ( O => j13_63_l2_in, -- Buffer output IO => J13_BUSY_OUT_P, -- Diff_p inout (connect directly to top-level port) IOB => J13_BUSY_OUT_N, -- Diff_n inout (connect directly to top-level port) I => busy_out_63, -- Buffer input T => j13_63_l2_T -- 3-state enable input, high=input, low=output ); busy_out_45 <= '1' when ((spares3 = '1') and (TEST_IO0_N = '0')) else '0'; j13_45_l2_T <= '1' when TEST_IO0_N = '1' else '0'; J13_45_L2_inout : IOBUFDS -- standard L2 input mode generic map ( IOSTANDARD => "LVDS_25") port map ( O => j13_45_l2_in, -- Buffer output IO => J13_L2_IN_P, -- Diff_p inout (connect directly to top-level port) IOB => J13_L2_IN_N, -- Diff_n inout (connect directly to top-level port) I => busy_out_45, -- Buffer input T => j13_45_l2_T -- 3-state enable input, high=input, low=output ); -- J13_45_L2_in_inst : IBUFDS -- generic map ( -- CAPACITANCE => "DONT_CARE", -- "LOW", "NORMAL", "DONT_CARE" (Virtex-4 only) -- DIFF_TERM => FALSE, -- Differential Termination (Virtex-4/5, Spartan-3E/3A) -- IBUF_DELAY_VALUE => "0", -- Specify the amount of added input delay for buffer, -- IFD_DELAY_VALUE => "0", -- Specify the amount of added delay for input register, -- -- "AUTO", "0"-"6" (Spartan-3E) -- IOSTANDARD => "LVDS_25")--"LVDS33") -- port map ( -- O => j13_45_l2_in, -- buffer output -- I => J13_L2_IN_P, -- buffer input (connect directly to top-level port) -- IB => J13_L2_IN_N -- buffer input (connect directly to top-level port) -- ); -- 2019-04-24, disabling the TRIG_IN_DELAY_ADJ to fix the first L1A trigger loss bug -- -- J13_45_TRIG_IN_DELAY_ADJ: in_del_1x_03 port map -- TRGL1 (L1A) delay, EXTERNALLY clocked (standard mode) -- ( -- reset => reset, -- reset (active high) -- clk => gclk2, -- global clock input -- io_clk => del_ioclk2, --bufpll_ioclk1,-- high speed i/o clock -- sdat_in => j13_45_l2_in, -- lvds serial data inputs -- del_data => l1a_del_rg, -- delay value -- del_load => l1a_del_load, -- to initiate the DELAY cycle, handshake with del_done -- del_busy => j13_45_l2_in_del_busy, -- delay done -- del_dataout2 => j13_45_l2_in_dld -- -- ); -- -- J13_63_TRIG_IN_DELAY_ADJ: in_del_1x_03 port map -- TRGL1 (L1A) delay,LOCALLY clocked (FEB test) -- ( -- reset => reset, -- reset (active high) -- clk => gclk2, -- global clock input -- io_clk => del_ioclk2, --bufpll_ioclk1,-- high speed i/o clock -- sdat_in => j13_63_l2_in, -- lvds serial data inputs -- del_data => l1a_del_rg, -- delay value -- del_load => l1a_del_load, -- to initiate the DELAY cycle, handshake with del_done -- del_busy => j13_63_l2_in_del_busy, -- delay done -- del_dataout2 => j13_63_l2_in_dld -- -- ); -- -- l1a_del_busy <= '1' when ((j13_45_l2_in_del_busy = '1') and (TEST_IO0_N = '1')) or -- ((j13_63_l2_in_del_busy = '1') and (TEST_IO0_N = '0')) -- else '0'; -- -- -- trgl1_or <= '1' when (((TEST_IO1_P = '1') and (TEST_IO0_N = '0') and (ctrl_rg(7) = '0')) or -- TEST_IO1_P is jumpered to TEST_IO0_P (=up_trig) -- ((j13_63_l2_in_dld = '1') and (TEST_IO0_N = '0') and (ctrl_rg(7) = '1')) or -- ((j13_45_l2_in_dld = '1') and (TEST_IO0_N = '1'))) else '0'; -- l1a_del_busy <= '0'; trgl1_or <= '1' when (((TEST_IO1_P = '1') and (TEST_IO0_N = '0') and (ctrl_rg(7) = '0')) or -- TEST_IO1_P is jumpered to TEST_IO0_P (=up_trig) ((j13_63_l2_in = '1') and (TEST_IO0_N = '0') and (ctrl_rg(7) = '1')) or ((j13_45_l2_in = '1') and (TEST_IO0_N = '1'))) else '0'; --trgl1_or <= j13_45_l2_in; TRGL1_BUFG_inst: BUFG port map ( I => trgl1_or, -- 1-bit Clock buffer input O => trgl1_bufg -- 1-bit Clock buffer output ); not_trgl1_bufg <= not trgl1_bufg; -- TRGL1_GEN: process(reset, trgl1_bufg, not_trgl1_bufg) -- begin -- if(reset = '1') then -- trgl1 <= '0'; -- elsif rising_edge(trgl1_bufg) then -- trgl1 <= '1'; -- elsif rising_edge(not_trgl1_bufg) then -- trgl1 <= '0'; -- end if; -- end process TRGL1_GEN; TRGL1_LH_GEN: process(trgl1_clr, trgl1_bufg) begin if(trgl1_clr = '1') then trgl1 <= '0'; trgl1_copy <= '0'; elsif rising_edge(trgl1_bufg) then trgl1 <= '1'; trgl1_copy <= '1'; end if; end process TRGL1_LH_GEN; TRGL1_HL_GEN: process(reset, trgl1_clr_nd, trgl1_copy, not_trgl1_bufg) begin if trgl1_copy = '1' then if rising_edge(not_trgl1_bufg) then trgl1_clr_nd <= '1'; end if; else trgl1_clr_nd <= '0'; end if; -- trgl1_copy = '1' trgl1_clr <= trgl1_clr_nd or reset; end process TRGL1_HL_GEN; -- -- -- TRGL1_oddr2_inst : ODDR2 -- dummy, to allow time constraints for DCM clk_fx -- generic map( -- DDR_ALIGNMENT => "c1", -- Sets output alignment to "NONE", "C0", "C1" -- INIT => '0', -- Sets initial state of the Q output to '0' or '1' -- SRTYPE => "ASYNC") -- Specifies "SYNC" or "ASYNC" set/reset -- port map ( -- Q => trgl1, -- 1-bit output data -- C1 => trgl1_bufg, -- 1-bit clock input -- C0 => not_trgl1_bufg, -- 1-bit clock input -- CE => '1', -- 1-bit clock enable input -- D0 => '0', -- 1-bit data input (associated with C0) -- D1 => '1', -- 1-bit data input (associated with C1) -- R => reset,--'0', --trgl1_R, -- 1-bit reset input -- S => '0' --trgl1_S -- 1-bit set input -- ); TRGL1_inst : OBUFDS -- propagating received L2 to the FEB generic map (IOSTANDARD => "LVDS_25") port map ( O => TRGL1_P, OB => TRGL1_N, I => trgl1); EXTCLK_inst : OBUFDS generic map (IOSTANDARD => "LVDS_25") port map ( O => EXTCLK_P, OB => EXTCLK_N, I => extclk); spi_slave_8bit_02_port_map: spi_slave_8bit_02 port map ( clk => gclk2, spi_reset => reset, spi_txd => spi_txd, spi_rxd => spi_rxd, spi_rxd_val => spi_rxd_val, spi_addr => spi_addr, spi_addr_val => spi_addr_val, -- single pulse spi_wr_nrd => spi_wr_nrd, spi_sync => spi_sync, spi_sclk => spi_sclk, spi_mosi => spi_mosi, spi_miso => spi_miso ); spi_sync <= FPGA_SLOW_2 ; spi_sclk <= FPGA_SLOW_0 ; spi_mosi <= FPGA_SLOW_1 ; FPGA_SLOW_3 <= spi_miso; -- Equations---------------------------------------------------------------------- REG_WRITE: process(gclk2) -- FEB writes to regs via SPI begin if rising_edge(gclk2) then pps_del_load <= '0'; -- to get a single pulse l1a_del_load <= '0'; l0_del_load <= '0'; l1_sc_win_rg_wstb <= '0'; if(reset = '1') then -- PPS_DEL adjustment causes a reset !!! ctrl_rg <= B"0000_0000"; trig_puls_rg <= TRIGGER_PULSE_WIDTH_INIT; trig_dtim_rg <= TRIGGER_DEAD_TIME_INIT; trig_win_rg <= TRIGGER_WINDOW_INIT; --pps_del_rg <= B"0000_0000"; -- PPS_DEL adjustment causes a reset !!! l1a_del_rg <= B"0000_0000"; l0_del_wr_rg <= B"0000_0000"; trig_mask_0_rg <= B"111_1111"; trig_mask_1_rg <= B"111_1111"; trig_mask_2_rg <= B"111_1111"; trig_mask_3_rg <= B"111_1111"; trig_mask_4_rg <= B"111_1111"; trig_mask_5_rg <= B"111_1111"; trig_mask_6_rg <= B"111_1111"; else if spi_rxd_val='1' and spi_wr_nrd = '1' then case (spi_addr) is when CTRL_ADDR => ctrl_rg <= spi_rxd; when L1_SC_WIN_ADDR => l1_sc_win_rg <= spi_rxd; l1_sc_win_rg_wstb <= '1'; when TRIG_PULS_ADDR => trig_puls_rg <= spi_rxd(3 downto 0); when TRIG_DTIM_ADDR => trig_dtim_rg <= spi_rxd(7 downto 0); when TRIG_WIN_ADDR => trig_win_rg <= spi_rxd(2 downto 0); when PPS_DEL_ADDR => pps_del_rg <= spi_rxd; pps_del_load <= '1'; when L1A_DEL_ADDR => l1a_del_rg <= spi_rxd; l1a_del_load <= '1'; when PIXEL_SEL_ADDR => pixel_sel_rg <= (spi_rxd(6 downto 4) & spi_rxd(2 downto 0)); when L0_DEL_ADDR => l0_del_wr_rg <= spi_rxd; l0_del_load <= '1'; when TRIG_MASK_0_ADDR => trig_mask_0_rg <= spi_rxd(6 downto 0); when TRIG_MASK_1_ADDR => trig_mask_1_rg <= spi_rxd(6 downto 0); when TRIG_MASK_2_ADDR => trig_mask_2_rg <= spi_rxd(6 downto 0); when TRIG_MASK_3_ADDR => trig_mask_3_rg <= spi_rxd(6 downto 0); when TRIG_MASK_4_ADDR => trig_mask_4_rg <= spi_rxd(6 downto 0); when TRIG_MASK_5_ADDR => trig_mask_5_rg <= spi_rxd(6 downto 0); when TRIG_MASK_6_ADDR => trig_mask_6_rg <= spi_rxd(6 downto 0); when others => NULL; end case; end if; -- spi_rxd_val='1' and spi_wr_nrd = '1' end if; --(reset = '1') end if; -- rising_edge(gclk2) end process REG_WRITE; REG_READ: process(reset,gclk2) -- FEB reads regs via SPI begin if rising_edge(gclk2) then if spi_addr_val='1' and spi_wr_nrd = '0' then case (spi_addr) is when CTRL_ADDR => spi_txd <= ctrl_rg; when STAT_ADDR => spi_txd <= (B"000" & stat_rg); when L1_SC_WIN_ADDR => spi_txd <= l1_sc_win_rd_rg; when TRIG_PULS_ADDR => spi_txd <= (B"0000" & trig_puls_rg); when TRIG_DTIM_ADDR => spi_txd <= trig_dtim_rg; when TRIG_WIN_ADDR => spi_txd <= (B"00000" & trig_win_rg); when PPS_DEL_ADDR => spi_txd <= pps_del_rg; when L1A_DEL_ADDR => spi_txd <= l1a_del_rg; when PIXEL_SEL_ADDR => spi_txd <= ('0' & pixel_sel_rg(5 downto 3) & '0' & pixel_sel_rg(2 downto 0)); when L0_DEL_ADDR => spi_txd <= l0_del_rd_rg; when PPS_CAL_ADDR => spi_txd <= cal_data; when L1_SCALER_L_ADDR => spi_txd <= l1_scaler_rg( 7 downto 0); l1_scaler_h_rg <= l1_scaler_rg(15 downto 8); -- fill l/h register at the same time when L1_SCALER_H_ADDR => -- should be read afterwards spi_txd <= l1_scaler_h_rg; when PPS_FAILED_ADDR => spi_txd <= pps_failed_ct; when TRIG_MASK_0_ADDR => spi_txd <= ('0' & trig_mask_0_rg); when TRIG_MASK_1_ADDR => spi_txd <= ('0' & (trig_mask_1_rg and B"0111110")); when TRIG_MASK_2_ADDR => spi_txd <= ('0' & (trig_mask_2_rg and B"1111100")); when TRIG_MASK_3_ADDR => spi_txd <= ('0' & (trig_mask_3_rg and B"1111001")); when TRIG_MASK_4_ADDR => spi_txd <= ('0' & (trig_mask_4_rg and B"1101011")); when TRIG_MASK_5_ADDR => spi_txd <= ('0' & (trig_mask_5_rg and B"1001111")); when TRIG_MASK_6_ADDR => spi_txd <= ('0' & (trig_mask_6_rg and B"0011111")); when FW_REVL_ADDR => spi_txd <= FW_REV(7 downto 0); when FW_REVH_ADDR => spi_txd <= FW_REV(15 downto 8); when others => NULL; --spi_txd <= X"00"; end case; end if; -- spi_addr_val='1' and spi_wr_nrd = '0' end if; -- rising_edge(gclk2) end process REG_READ; STAT_REG: process(gclk2) begin if rising_edge(gclk2) then stat_rg(0) <= pps_del_busy; stat_rg(1) <= l1a_del_busy; stat_rg(2) <= l0_del_busy; stat_rg(3) <= cal_busy; -- PPS delay calibration stat_rg(4) <= pps_failure; -- PPS mismatch or missing end if; end process STAT_REG; L0_DEL_REG_ACCESS: process (reset,gclk2) begin if rising_edge(gclk2) then if reset = '1' then -- cl0_l0_del_rg(0) <= CL0_IDELAY; -- cl0_l0_del_rg(1) <= CL0_IDELAY; -- cl0_l0_del_rg(2) <= CL0_IDELAY; -- cl0_l0_del_rg(3) <= CL0_IDELAY; -- cl0_l0_del_rg(4) <= CL0_IDELAY; -- cl0_l0_del_rg(5) <= CL0_IDELAY; -- cl0_l0_del_rg(6) <= CL0_IDELAY; l0_del_load0 <= '0'; else l0_del_load0 <= l0_del_load; -- single pulse if l0_del_load0 ='1' then case pixel_sel_rg(5 downto 3) is -- l0 register write when B"000" => cl0_l0_del_rg(pixel_remap(B"000" & pixel_sel_rg(2 downto 0))) <= l0_del_wr_rg; cl0_del_load(pixel_remap(B"000" & pixel_sel_rg(2 downto 0))) <= '1'; when B"001" => if NBOR_IN(1)='0' then -- NBOR_IN is low active, clx_del_load() only, when neighbor do exist cl1_l0_del_rg(pixel_remap(B"001" & pixel_sel_rg(2 downto 0))) <= l0_del_wr_rg; cl1_del_load(pixel_remap(B"001" & pixel_sel_rg(2 downto 0))) <= '1'; end if; when B"010" => if NBOR_IN(2)='0' then cl2_l0_del_rg(pixel_remap(B"010" & pixel_sel_rg(2 downto 0))) <= l0_del_wr_rg; cl2_del_load(pixel_remap(B"010" & pixel_sel_rg(2 downto 0))) <= '1'; end if; when B"011" => if NBOR_IN(3)='0' then cl3_l0_del_rg(pixel_remap(B"011" & pixel_sel_rg(2 downto 0))) <= l0_del_wr_rg; cl3_del_load(pixel_remap(B"011" & pixel_sel_rg(2 downto 0))) <= '1'; end if; when B"100" => if NBOR_IN(4)='0' then cl4_l0_del_rg(pixel_remap(B"100" & pixel_sel_rg(2 downto 0))) <= l0_del_wr_rg; cl4_del_load(pixel_remap(B"100" & pixel_sel_rg(2 downto 0))) <= '1'; end if; when B"101" => if NBOR_IN(5)='0' then cl5_l0_del_rg(pixel_remap(B"101" & pixel_sel_rg(2 downto 0))) <= l0_del_wr_rg; cl5_del_load(pixel_remap(B"101" & pixel_sel_rg(2 downto 0))) <= '1'; end if; when B"110" => if NBOR_IN(6)='0' then cl6_l0_del_rg(pixel_remap(B"110" & pixel_sel_rg(2 downto 0))) <= l0_del_wr_rg; cl6_del_load(pixel_remap(B"110" & pixel_sel_rg(2 downto 0))) <= '1'; end if; when others => NULL; end case; else cl0_del_load <= B"000_0000"; -- to generate single clock length pulses cl1_del_load <= B"0_0000"; cl2_del_load <= B"0_0000"; cl3_del_load <= B"0_0000"; cl4_del_load <= B"0_0000"; cl5_del_load <= B"0_0000"; cl6_del_load <= B"0_0000"; end if; --l0_del_load0 ='1' case pixel_sel_rg(5 downto 3) is -- l0 register read back when B"000" => l0_del_rd_rg <= cl0_l0_del_rg(pixel_remap(B"000" & pixel_sel_rg(2 downto 0))); when B"001" => l0_del_rd_rg <= cl1_l0_del_rg(pixel_remap(B"001" & pixel_sel_rg(2 downto 0))); when B"010" => l0_del_rd_rg <= cl2_l0_del_rg(pixel_remap(B"010" & pixel_sel_rg(2 downto 0))); when B"011" => l0_del_rd_rg <= cl3_l0_del_rg(pixel_remap(B"011" & pixel_sel_rg(2 downto 0))); when B"100" => l0_del_rd_rg <= cl4_l0_del_rg(pixel_remap(B"100" & pixel_sel_rg(2 downto 0))); when B"101" => l0_del_rd_rg <= cl5_l0_del_rg(pixel_remap(B"101" & pixel_sel_rg(2 downto 0))); when B"110" => l0_del_rd_rg <= cl6_l0_del_rg(pixel_remap(B"110" & pixel_sel_rg(2 downto 0))); when others => l0_del_rd_rg <= X"00";--NULL; end case; end if; --reset = '1' end if;-- rising_edge(gclk2) end process L0_DEL_REG_ACCESS; L0_DEL_BUSY_GEN: process (reset,gclk2) begin if rising_edge(gclk2) then if reset = '1' then l0_del_busy <= '0'; else case pixel_sel_rg(5 downto 3) is when B"000" => l0_del_busy <= cl0_del_busy(pixel_remap(B"000" & pixel_sel_rg(2 downto 0))); when B"001" => l0_del_busy <= cl1_del_busy(pixel_remap(B"001" & pixel_sel_rg(2 downto 0))); when B"010" => l0_del_busy <= cl2_del_busy(pixel_remap(B"010" & pixel_sel_rg(2 downto 0))); when B"011" => l0_del_busy <= cl3_del_busy(pixel_remap(B"011" & pixel_sel_rg(2 downto 0))); when B"100" => l0_del_busy <= cl4_del_busy(pixel_remap(B"100" & pixel_sel_rg(2 downto 0))); when B"101" => l0_del_busy <= cl5_del_busy(pixel_remap(B"101" & pixel_sel_rg(2 downto 0))); when B"110" => l0_del_busy <= cl6_del_busy(pixel_remap(B"110" & pixel_sel_rg(2 downto 0))); when others => l0_del_busy <= '0'; end case; end if; --reset = '1' end if;-- rising_edge(gclk2) end process L0_DEL_BUSY_GEN; -- time from pll_rst HL to pll_locked LH max. 100 us, async pll_rst > 5ns on !!! -- new, since rev006 PLL_RESET_GEN: process(gclkb_dld) -- 50 MHz variable pll_reset_ct : integer range 0 to 65535 := 0; begin if rising_edge (gclkb_dld) then if (pll_reset_ct /= 65535) then pll_reset_ct := pll_reset_ct + 1; if (pll_reset_ct = 65500) then pll_rst <= '1'; else pll_rst <= '0'; end if; -- (pll_reset_ct = 65500) end if; --(pll_reset_ct /= 65535) end if; -- rising_edge (gclkb_dld) end process PLL_RESET_GEN; -- until rev005 -- PLL_RESET_GEN: process(gclkb_dld) -- 50 MHz -- variable pll_reset_ct : integer range 0 to 65535 := 0; -- begin -- if rising_edge (gclkb_dld) then -- if ((pll_locked = '0') and (pll_reset_ct = 0)) then -- pll_reset_ct := 65535; -- end if; -- if (pll_reset_ct /= 0) then -- pll_reset_ct := pll_reset_ct - 1; -- if (pll_reset_ct = 65500) then -- pll_rst <= '1'; -- else -- pll_rst <= '0'; -- end if; -- (pll_reset_ct = 65500) -- end if; --(pll_reset_ct /= 0) -- end if; -- rising_edge (gclkb_dld) -- end process PLL_RESET_GEN; --pll_rst <='0'; PLL_BASE_inst : PLL_BASE generic map ( BANDWIDTH => "OPTIMIZED", -- "HIGH", "LOW" or "OPTIMIZED" !!! "LOW" gives 2x more jitter !!! CLKFBOUT_MULT => PLL_MULT, -- 50Mhz->1Ghz (max.), multiplication factor for all output clocks CLK_FEEDBACK => "CLKFBOUT",--"CLKOUT0", -- needed (!) to phase align with the input clock was "CLKFBOUT" before w. no pps CLKFBOUT_PHASE => 0.0, -- Phase shift (degrees) of all output clocks CLKIN_PERIOD => CLKIN_PERIOD, -- Clock period (ns) of input clock on CLKIN CLKOUT0_DIVIDE => DELCLK_DIV, -- 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 => S, -- 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 => EXTCLK_DIV, -- 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 => EXTCLK_DIV, -- 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 => EXTCLK_DIV, -- Division factor for CLKOUT5 (1 to 128) CLKOUT5_DUTY_CYCLE => 0.5, -- Duty cycle for CLKOUT5 (0.01 to 0.99) CLKOUT5_PHASE => 130.5,-- 135.0-3.8 = 131.2, -- 3.8 by BUFGMUX, before 120°-170° did work, gclk_dld to gclk5, .ucf constraint not used COMPENSATION => "INTERNAL", -- "SYSTEM_SYNCHRONOUS", -- "SOURCE_SYNCHRONOUS", "INTERNAL", -- "EXTERNAL", "DCM2PLL", "PLL2DCM" DIVCLK_DIVIDE => PLL_DIV,--1,--5,--PLL_DIV, -- Division factor for all clocks (1 to 52) REF_JITTER => 0.1) -- Input reference jitter (0.000 to 0.999 UI%) port map ( CLKFBOUT => pll_clkfbout, -- General output feedback signal CLKOUT0 => pll_clkout0, -- One of six general clock output signals CLKOUT1 => pll_clkout1, -- One of six general clock output signals CLKOUT2 => pll_clkout2, -- One of six general clock output signals CLKOUT3 => pll_clkout3, -- One of six general clock output signals CLKOUT4 => pll_clkout4, -- One of six general clock output signals+ CLKOUT5 => pll_clkout5,--pll_clkout5, -- One of six general clock output signals LOCKED => pll_locked, -- Active high PLL lock output signal CLKFBIN => pll_clkfbout, -- Clock feedback input CLKIN => pll_clkin, -- dcm_clkfx,--,Clock input RST => pll_rst --open -- Asynchronous PLL reset ); SYNC_RESET: process ( pll_locked, gclk2) begin -- do power on reset, just once ! if rising_edge(gclk2) then if (pll_locked ='1') or (lclk_pll_locked ='1')then if reset_ct /= B"1111" then reset_ct <= reset_ct + '1'; end if; if (reset_ct = B"1110") then reset <= '1'; else reset <= '0'; end if; end if; -- (pll_locked ='1') or (lclk_pll_locked ='1') -- else -- reset_ct <= B"0000"; end if; -- rising_edge(gclk2) end process SYNC_RESET; -- SYNC_RESET: process ( pll_locked, gclk2) -- begin -- do power on reset, just once ! -- if (pll_locked ='0') then -- reset_ct <= B"0000"; -- reset <= '0'; -- elsif rising_edge(gclk2) then -- if reset_ct /= B"1111" then -- reset_ct <= reset_ct + '1'; -- end if; -- if (reset_ct = B"1101") or (reset_ct = B"1110") then -- reset <= '1'; -- else -- reset <= '0'; -- end if; --(reset_ct = B"1110") -- end if; -- (pll_locked ='0') -- end process SYNC_RESET; -- GCKL0_inst : BUFG -- port map ( -- I => pll_clkout0, -- 1-bit Clock buffer input -- O => gclk0 -- 1-bit Clock buffer output -- ); BUFPLL_BANK0_DEL_inst : BUFPLL generic map( DIVIDE => S) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => pll_clkout0, -- input, PLL clock by PLL_ADV GCLK => gclk2, -- input, Global Clock input LOCKED => pll_locked, -- input, Clock0 locked input IOCLK => del_ioclk0, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => open) ; -- output, SERDES strobe BUFPLL_BANK1_DEL_inst : BUFPLL generic map( DIVIDE => S) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => pll_clkout0, -- input, PLL clock by PLL_ADV GCLK => gclk2, -- input, Global Clock input LOCKED => pll_locked, -- input, Clock0 locked input IOCLK => del_ioclk1, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => open) ; -- output, SERDES strobe BUFPLL_BANK2_DEL_inst : BUFPLL generic map( DIVIDE => S) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => pll_clkout0, -- input, PLL clock by PLL_ADV GCLK => gclk2, -- input, Global Clock input LOCKED => pll_locked, -- input, Clock0 locked input IOCLK => del_ioclk2, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => open) ; -- output, SERDES strobe BUFPLL_BANK3_DEL_inst : BUFPLL generic map( DIVIDE => S) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => pll_clkout0, -- input, PLL clock by PLL_ADV GCLK => gclk2, -- input, Global Clock input LOCKED => pll_locked, -- input, Clock0 locked input IOCLK => del_ioclk3, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => open) ; -- output, SERDES strobe -- GCKL1_inst : BUFG -- port map ( -- I => pll_clkout1, -- 1-bit Clock buffer input -- O => gclk1 -- 1-bit Clock buffer output -- ); GCKL2_inst : BUFG port map ( I => pll_clkout2, -- 1-bit Clock buffer input O => gclk2 -- 1-bit Clock buffer output ); GCKL3_inst : BUFG port map ( I => pll_clkout3, -- 1-bit Clock buffer input O => gclk3 -- 1-bit Clock buffer output ); GCKL4_inst : BUFG port map ( I => pll_clkout4, -- 1-bit Clock buffer input O => gclk4 -- 1-bit Clock buffer output ); GCKL5_inst : BUFG port map ( I => pll_clkout5, -- 1-bit Clock buffer input O => gclk5 -- 1-bit Clock buffer output ); -- TEST_IO0_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 => test_io0, --extclk, -- 1-bit output data -- C0 => gclk3,--pll_clkout4, -- 1-bit clock input -- C1 => gclk4,--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 -- ); EXTCLK_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 => extclk, -- 1-bit output data C0 => gclk3,--pll_clkout4, -- 1-bit clock input C1 => gclk4,--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 ); -- LCLK_TIMEPPS_gen: process(gclk5) -- variable ct: integer := 0; -- begin -- if rising_edge (gclk5) then -- if (TEST_IO0_N = '0') then --'0' -- if ct /= 49_999_999 then -- ct := ct + 1; -- else -- ct := 0; -- end if; -- if ct=0 or ct=1 or ct=2 then -- lclk_timepps <= '1'; -- else -- lclk_timepps <= '0'; -- end if; -- else -- ct := 0; -- lclk_timepps <= '0'; -- end if; -- (TEST_IO0_N = '0') -- end if; -- rising_edge (gclk3) -- end process LCLK_TIMEPPS_gen; -- recover pps from pps_clk PPS_GEN_RECOVER: process(gclk5) -- xxx° phase shifted to 'pll_clkin' variable ct: integer := 0; --variable pulse_length_ct : integer range 0 to PPS_LENGTH := 0; -- pulse length, multiples of 20 ns begin if rising_edge(gclk5) then if (pll_locked = '0') or (reset = '1') then timepps_int <= '0'; timepps <= '0'; ctdb_pps <= '0'; else ctdb_pps <= '0'; timepps <= timepps_int; -- to get an output registers if TEST_IO0_N = '1' then --clock_sel = USE_EXT_CLOCK ct := 0; if(timepps_int = '0') and (gclkb_dld = '0') then ctdb_pps <= '1'; timepps_int <= '1'; pulse_length_ct <= PPS_LENGTH -1 ; elsif (timepps_int = '1') then if pulse_length_ct /= 0 then pulse_length_ct <= pulse_length_ct - 1; else timepps_int <= '0'; end if; end if; --(timepps_int = '0') and (gclkb_dld = '0') else -- (TEST_IO0_N = '0') timepps_int <= '0'; ctdb_pps <= '0'; if ct /= 49_999_999 then ct := ct + 1; else ct := 0; end if; if ct=0 or ct=1 or ct=2 then timepps_int <= '1'; else timepps_int <= '0'; end if; end if; -- TEST_IO0_N = '1' end if; -- (pll_locked = '0') end if; --rising_edge(gclk5) end process PPS_GEN_RECOVER; TIMEPPS_OUT_inst : OBUFDS -- propagating received pps to the FEB generic map (IOSTANDARD => "LVDS_25") port map ( O => TIMEPPS_P, OB => TIMEPPS_N, I => timepps); PPS_CHECK: process (gclk5, pll_locked) -- gclk5 = 50MHz (20ns) variable pps_ct : integer range 0 to 49_999_999 := 0; variable first_pps : boolean := false; begin if rising_edge (gclk5) then if TEST_IO0_N = '1' then --clock_sel = USE_EXT_CLOCK pps_error <= '0'; if (reset = '1') or (ctrl_rg(5) = '1') or (pll_locked = '0') then pps_ct := 0; first_pps := false; else if first_pps = false then if ctdb_pps = '1' then first_pps := true; end if; else if ((ctdb_pps = '1' and pps_ct /= 49_999_999) or (ctdb_pps = '0' and pps_ct = 49_999_999)) then pps_error <= '1'; -- for synchronization with gclk2 (SPI read) end if; if (ctdb_pps = '1') or (pps_ct = 49_999_999) then pps_ct := 0; else pps_ct := pps_ct + 1; end if; end if; -- first_pps = false end if; -- pll_locked = '0' else pps_ct := 0; first_pps := false; pps_error <= '0'; end if; -- TEST_IO0_N = '1' end if; -- rising_edge (gclk5) end process PPS_CHECK; PPS_FAILED_SYNC: process (gclk2) -- gclk2 = 125MHz (8ns) --variable pps_error_pipe : std_logic_vector(3 downto 0) := B"0000"; begin if rising_edge (gclk2) then if (reset = '1') or (ctrl_rg(5) = '1') or (pll_locked = '0') then pps_failed_ct <= X"00"; pps_failure <= '0'; pps_error_pipe <= B"0000"; else pps_error_pipe(0) <= pps_error; -- 20 ns pulse pps_error_pipe(3 downto 1) <= pps_error_pipe(2 downto 0); if pps_error_pipe(3 downto 2) = B"01" then -- after LH-edge if pps_failed_ct /= X"FF" then pps_failed_ct <= pps_failed_ct + '1'; end if; end if; --pps_error_pipe(3 downto 2) = B"01" if pps_failed_ct /= X"00" then pps_failure <= '1'; end if; end if; -- (reset = '1') or (ctrl_rg(5) = '1') or (pll_locked = '0') end if; -- rising_edge (gclk2) end process PPS_FAILED_SYNC; BUFPLL_bank0_oserdes_inst : BUFPLL generic map( DIVIDE => S) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => pll_clkout1, -- input, PLL clock by PLL_ADV GCLK => gclk2, -- input, Global Clock input LOCKED => pll_locked, -- input, Clock0 locked input IOCLK => serdes_ioclk0, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => oserdes_stb0) ; -- output, SERDES strobe BUFPLL_bank2_oserdes_inst : BUFPLL generic map( DIVIDE => S) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => pll_clkout1, -- input, PLL clock by PLL_ADV GCLK => gclk2, -- input, Global Clock input LOCKED => pll_locked, -- input, Clock0 locked input IOCLK => serdes_ioclk2, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => oserdes_stb2) ; -- output, SERDES strobe BUFPLL_bank1_iserdes_inst : BUFPLL generic map( DIVIDE => S) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => pll_clkout1, -- input, PLL clock by PLL_ADV GCLK => gclk2, -- input, Global Clock input LOCKED => pll_locked, -- input, Clock0 locked input IOCLK => serdes_ioclk1, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => iserdes_stb1) ; -- output, SERDES strobe BUFPLL_bank3_iserdes_inst : BUFPLL generic map( DIVIDE => S) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1 port map ( PLLIN => pll_clkout1, -- input, PLL clock by PLL_ADV GCLK => gclk2, -- input, Global Clock input LOCKED => pll_locked, -- input, Clock0 locked input IOCLK => serdes_ioclk3, -- output, PLL Clock LOCK => open, -- output, BUFPLL Clock and strobe locked serdesstrobe => iserdes_stb3) ; -- output, SERDES strobe --------------------------------------------------------------------------------------------------------------- fanout2_sdat( 0 to 4) <= -- J2 -> J5 ( cl0(6), cl0(0), cl0(1), cl0(3), cl0(2));-- and FANOUT2_gen: for i in 0 to 4 generate -- bank2 begin -- setup a fixed serial data ouput delay FANOUT2_ODELAY_gen: IODELAY2 generic map ( DATA_RATE => "SDR", ODELAY_VALUE => FANOUT2_DELAY(i),--BANK2_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 => fanout2_sdat_dld(i), ODATAIN => fanout2_sdat(i), 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'); FANOUT2_inst : OBUFDS generic map (IOSTANDARD => "LVDS_25") port map ( O => FANOUT2_P(i), OB => FANOUT2_N(i), I => fanout2_sdat_dld(i)); end generate FANOUT2_gen; fanout3_sdat( 0 to 4) <= -- J3 -> J6 ( cl0(0), cl0(1), cl0(2), cl0(3), cl0(4)); FANOUT3_gen: for i in 0 to 4 generate -- bank2 begin -- setup a fixed serial data ouput delay FANOUT3_ODELAY_gen: IODELAY2 generic map ( DATA_RATE => "SDR", ODELAY_VALUE => FANOUT3_DELAY(i),--BANK2_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 => fanout3_sdat_dld(i), ODATAIN => fanout3_sdat(i), 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'); FANOUT3_inst : OBUFDS generic map (IOSTANDARD => "LVDS_25") port map ( O => FANOUT3_P(i), OB => FANOUT3_N(i), I => fanout3_sdat_dld(i)); end generate FANOUT3_gen; fanout4_sdat( 0 to 4) <= -- J4 -> J1 ( cl0(1), cl0(2), cl0(4), cl0(3), cl0(5)) ; FANOUT4_gen: for i in 0 to 4 generate -- bank2 begin -- setup a fixed serial data ouput delay FANOUT4_ODELAY_gen: IODELAY2 generic map ( DATA_RATE => "SDR", ODELAY_VALUE => FANOUT4_DELAY(i),--BANK2_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 => fanout4_sdat_dld(i), ODATAIN => fanout4_sdat(i), 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'); FANOUT4_inst : OBUFDS generic map (IOSTANDARD => "LVDS_25") port map ( O => FANOUT4_P(i), OB => FANOUT4_N(i), I => fanout4_sdat_dld(i)); end generate FANOUT4_gen; fanout5_sdat( 0 to 4) <= -- J5 -> J2 ( cl0(2), cl0(4), cl0(5), cl0(3), cl0(6)) ; FANOUT5_gen: for i in 0 to 4 generate -- bank0 begin -- setup a fixed serial data ouput delay FANOUT5_ODELAY_gen: IODELAY2 generic map ( DATA_RATE => "SDR", ODELAY_VALUE => FANOUT5_DELAY(i),--BANK0_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 => fanout5_sdat_dld(i), ODATAIN => fanout5_sdat(i), 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'); FANOUT5_inst : OBUFDS generic map (IOSTANDARD => "LVDS_25") port map ( O => FANOUT5_P(i), OB => FANOUT5_N(i), I => fanout5_sdat_dld(i)); end generate FANOUT5_gen; fanout6_sdat( 0 to 4) <= -- J6 -> J3 ( cl0(4), cl0(5), cl0(6), cl0(3), cl0(0)); FANOUT6_gen: for i in 0 to 4 generate -- bank0 begin -- setup a fixed serial data ouput delay FANOUT6_ODELAY_gen: IODELAY2 generic map ( DATA_RATE => "SDR", ODELAY_VALUE => FANOUT6_DELAY(i),--BANK0_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 => fanout6_sdat_dld(i), ODATAIN => fanout6_sdat(i), 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'); FANOUT6_inst : OBUFDS generic map (IOSTANDARD => "LVDS_25") port map ( O => FANOUT6_P(i), OB => FANOUT6_N(i), I => fanout6_sdat_dld(i)); end generate FANOUT6_gen; fanout1_sdat( 0 to 4) <= -- J1 -> J4 ( cl0(5), cl0(6), cl0(0), cl0(3), cl0(1)); FANOUT1_gen: for i in 0 to 4 generate -- bank0 begin -- setup a fixed serial data ouput delay FANOUT1_ODELAY_gen: IODELAY2 generic map ( DATA_RATE => "SDR", ODELAY_VALUE => FANOUT1_DELAY(i),--BANK0_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 => fanout1_sdat_dld(i), ODATAIN => fanout1_sdat(i), 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'); FANOUT1_inst : OBUFDS generic map (IOSTANDARD => "LVDS_25") port map ( O => FANOUT1_P(i), OB => FANOUT1_N(i), I => fanout1_sdat_dld(i)); end generate FANOUT1_gen; -- CL0_PDAT_RGS: process(gclk2) -- begin -- add 1 extra clock delay -- if (gclk2'event and gclk2 = '1') then -- cl0_pdat1 <= cl0_pdat0; -- --cl0_pdat2 <= cl0_pdat1; -- end if; -- end process CL0_PDAT_RGS; CL0_LEADING_EDGE_gen: for i in 0 to 6 generate -- begin CL0_LEADING_EDGE: iserdes_pulse_shaper_03 port map ( clk => gclk2, iserdes_pdat => cl0_pdat0(i)(0 to 7), pulse_pdat => cl0_pdat(i)(0 to 7), pulse_width => trig_win_rg ); end generate CL0_LEADING_EDGE_gen; -- -- CL0_PDAT_RGS: process(gclk2) -- begin -- add 1 extra clock delay -- if (gclk2'event and gclk2 = '1') then -- cl0_pdat <= cl0_pdat2; -- end if; -- end process CL0_PDAT_RGS; CL1to6_LEADING_EDGE_gen: for i in 0 to 4 generate -- for i in 0 to 4 generate begin CL1_LEADING_EDGE: iserdes_pulse_shaper_03 port map ( clk => gclk2, iserdes_pdat => cl1_pdat0(i)(0 to 7), pulse_pdat => cl1_pdat(i)(0 to 7), pulse_width => trig_win_rg ); CL2_LEADING_EDGE: iserdes_pulse_shaper_03 port map ( clk => gclk2, iserdes_pdat => cl2_pdat0(i)(0 to 7), pulse_pdat => cl2_pdat(i)(0 to 7), pulse_width => trig_win_rg ); CL3_LEADING_EDGE: iserdes_pulse_shaper_03 port map ( clk => gclk2, iserdes_pdat => cl3_pdat0(i)(0 to 7), pulse_pdat => cl3_pdat(i)(0 to 7), pulse_width => trig_win_rg ); CL4_LEADING_EDGE: iserdes_pulse_shaper_03 port map ( clk => gclk2, iserdes_pdat => cl4_pdat0(i)(0 to 7), pulse_pdat => cl4_pdat(i)(0 to 7), pulse_width => trig_win_rg ); CL5_LEADING_EDGE: iserdes_pulse_shaper_03 port map ( clk => gclk2, iserdes_pdat => cl5_pdat0(i)(0 to 7), pulse_pdat => cl5_pdat(i)(0 to 7), pulse_width => trig_win_rg ); CL6_LEADING_EDGE: iserdes_pulse_shaper_03 port map ( clk => gclk2, iserdes_pdat => cl6_pdat0(i)(0 to 7), pulse_pdat => cl6_pdat(i)(0 to 7), pulse_width => trig_win_rg ); end generate CL1to6_LEADING_EDGE_gen; -- -- -- -- CL1to6_PDAT_RG: process(gclk2) -- begin -- if (gclk2'event and gclk2 = '1') then -- cl1_pdat <= cl1_pdat0; -- cl2_pdat <= cl2_pdat0; -- cl3_pdat <= cl3_pdat0; -- cl4_pdat <= cl4_pdat0; -- cl5_pdat <= cl5_pdat0; -- cl6_pdat <= cl6_pdat0; -- end if; -- end process CL1to6_PDAT_RG; -- connect J4<->J1 and check cl0 delays --function pix_trig_3_of_19_asyn_04 (a,b,c,d,e,f,g,e1,d1,e2,d2,e3,d3,e4,d4,e5,d5,e6,d6 : in std_logic; -- nbor_in : in std_logic_vector(1 to 6)) TRIGG_3NN: for i in 0 to S-1 generate begin center(i) <= pix_trig_3_of_19_asyn_04 ( cl0_pdat(3)(i), -- a cl0_pdat(1)(i), -- b cl0_pdat(0)(i), -- c cl0_pdat(6)(i), -- d cl0_pdat(5)(i), -- e cl0_pdat(4)(i), -- f cl0_pdat(2)(i), -- g cl1_pdat(2)(i), -- e1 cl1_pdat(1)(i), -- d1 cl2_pdat(2)(i), -- e2 cl2_pdat(1)(i), -- d2 cl3_pdat(2)(i), -- e3 cl3_pdat(1)(i), -- d3 cl4_pdat(2)(i), -- e4 cl4_pdat(1)(i), -- d4 cl5_pdat(2)(i), -- e5 cl5_pdat(1)(i), -- d5 cl6_pdat(2)(i), -- e6 cl6_pdat(1)(i), -- d6 NBOR_IN ); --function pix_trig_3_of_11_asyn_01 (a,c,d,e,f,h,i,j,k,l,m : in std_logic) outer(3)(i) <= pix_trig_3_of_11_asyn_01 -- was 1 ( cl3_pdat(3)(i) and not NBOR_IN(3) , -- a cl3_pdat(0)(i) and not NBOR_IN(3) , -- c cl3_pdat(1)(i) and not NBOR_IN(3) , -- d cl3_pdat(2)(i) and not NBOR_IN(3) , -- e cl3_pdat(4)(i) and not NBOR_IN(3) , -- f cl4_pdat(4)(i) and not NBOR_IN(4) , -- h cl4_pdat(2)(i) and not NBOR_IN(4) , -- i cl0_pdat(2)(i) , -- j cl0_pdat(1)(i) , -- k cl2_pdat(1)(i) and not NBOR_IN(2) , -- l cl2_pdat(0)(i) and not NBOR_IN(2) -- m ) ; -- NBOR_INx is low active input with pullup, '1' means no neighbor cluster exist outer(4)(i) <= pix_trig_3_of_11_asyn_01 -- was 2 ( cl4_pdat(3)(i) and not NBOR_IN(4) , -- a cl4_pdat(0)(i) and not NBOR_IN(4) , -- c cl4_pdat(1)(i) and not NBOR_IN(4) , -- d cl4_pdat(2)(i) and not NBOR_IN(4) , -- e cl4_pdat(4)(i) and not NBOR_IN(4) , -- f cl5_pdat(4)(i) and not NBOR_IN(5) , -- h cl5_pdat(2)(i) and not NBOR_IN(5) , -- i cl0_pdat(4)(i) , -- j cl0_pdat(2)(i) , -- k cl3_pdat(1)(i) and not NBOR_IN(3) , -- l cl3_pdat(0)(i) and not NBOR_IN(3) -- m ) ; outer(5)(i) <= pix_trig_3_of_11_asyn_01 -- was 3 ( cl5_pdat(3)(i) and not NBOR_IN(5) , -- a cl5_pdat(0)(i) and not NBOR_IN(5) , -- c cl5_pdat(1)(i) and not NBOR_IN(5) , -- d cl5_pdat(2)(i) and not NBOR_IN(5) , -- e cl5_pdat(4)(i) and not NBOR_IN(5) , -- f cl6_pdat(4)(i) and not NBOR_IN(6) , -- h cl6_pdat(2)(i) and not NBOR_IN(6) , -- i cl0_pdat(5)(i) , -- j cl0_pdat(4)(i) , -- k cl4_pdat(1)(i) and not NBOR_IN(4) , -- l cl4_pdat(0)(i) and not NBOR_IN(4) -- m ); outer(6)(i) <= pix_trig_3_of_11_asyn_01 -- was 4 ( cl6_pdat(3)(i) and not NBOR_IN(6) , -- a cl6_pdat(0)(i) and not NBOR_IN(6) , -- c cl6_pdat(1)(i) and not NBOR_IN(6) , -- d cl6_pdat(2)(i) and not NBOR_IN(6) , -- e cl6_pdat(4)(i) and not NBOR_IN(6) , -- f cl1_pdat(4)(i) and not NBOR_IN(1) , -- h cl1_pdat(2)(i) and not NBOR_IN(1) , -- i cl0_pdat(6)(i) , -- j cl0_pdat(5)(i) , -- k cl5_pdat(1)(i) and not NBOR_IN(5) , -- l cl5_pdat(0)(i) and not NBOR_IN(5) -- m ) ; outer(1)(i) <= pix_trig_3_of_11_asyn_01 -- was 5 ( cl1_pdat(3)(i)and not NBOR_IN(1) , -- a cl1_pdat(0)(i)and not NBOR_IN(1) , -- c cl1_pdat(1)(i)and not NBOR_IN(1) , -- d cl1_pdat(2)(i)and not NBOR_IN(1) , -- e cl1_pdat(4)(i)and not NBOR_IN(1) , -- f cl2_pdat(4)(i)and not NBOR_IN(2) , -- h cl2_pdat(2)(i)and not NBOR_IN(2) , -- i cl0_pdat(0)(i) , -- j cl0_pdat(6)(i) , -- k cl6_pdat(1)(i)and not NBOR_IN(6) , -- l cl6_pdat(0)(i)and not NBOR_IN(6) -- m ); outer(2)(i) <= pix_trig_3_of_11_asyn_01 -- was 6 ( cl2_pdat(3)(i) and not NBOR_IN(2) , -- a cl2_pdat(0)(i) and not NBOR_IN(2) , -- c cl2_pdat(1)(i) and not NBOR_IN(2) , -- d cl2_pdat(2)(i) and not NBOR_IN(2) , -- e cl2_pdat(4)(i) and not NBOR_IN(2) , -- f cl3_pdat(4)(i) and not NBOR_IN(3) , -- h cl3_pdat(2)(i) and not NBOR_IN(3) , -- i cl0_pdat(1)(i) , -- j cl0_pdat(0)(i) , -- k cl1_pdat(1)(i) and not NBOR_IN(1) , -- l cl1_pdat(0)(i) and not NBOR_IN(1) -- m ); trig_3nn(i) <= outer(1)(i) or outer(2)(i) or outer(3)(i) or outer(4)(i) or outer(5)(i) or outer(6)(i) or center(i); --trig_3nn(i) <= center(i); end generate TRIGG_3NN; -- TRIG_3NN_SYNC: process (gclk2) -- begin -- if rising_edge(gclk2) then -- trig_3nn <= outer(1) or outer(2) or outer(3) or outer(4) or outer(5) or outer(6) or center; -- else -- trig_3nn <= X"00"; -- end if; -- end process TRIG_3NN_SYNC; -- function pix_trig_1_of_7_asyn_02 (pix_0_to_6 : in std_logic_vector(0 to 6)) -- return std_logic is --type cl0_iserdes_pdat is array (0 to 6) of std_logic_vector(0 to 7); TRIG_CL0_1_of_7: for i in 0 to S-1 generate begin trig_1of7(i) <= pix_trig_1_of_7_asyn_02((cl0_pdat(0)(i), cl0_pdat(1)(i), cl0_pdat(2)(i), cl0_pdat(3)(i), cl0_pdat(4)(i), cl0_pdat(5)(i), cl0_pdat(6)(i)), trig_mask_0_rg); end generate TRIG_CL0_1_of_7; cl0_pixel_delay_cal_01_port_map: center_pixel_delay_cal_01 generic map (CLUSTER_NR => B"000") port map ( --clk => gclk2, -- global clock input l0_del_sel_rg => pixel_sel_rg, -- bits 5..3= cluster_#, 2..0= pixel_# cl0_pdat0 => cl0_pdat(0), -- cl0_pdat1 => cl0_pdat(1), -- cl0_pdat2 => cl0_pdat(2), -- cl0_pdat3 => cl0_pdat(3), -- is the reference pixel cl0_pdat4 => cl0_pdat(4), -- cl0_pdat5 => cl0_pdat(5), -- cl0_pdat6 => cl0_pdat(6), -- trig_2of37 => trig_2of37(0) -- ); cl1_pixel_delay_cal_01_port_map: outer_pixel_delay_cal_01 generic map (CLUSTER_NR => B"001") port map( --clk => gclk2, -- global clock input l0_del_sel_rg => pixel_sel_rg, -- bits 5..3= cluster_#, 2..0= pixel_# cl0_pdat3 => cl0_pdat(3), -- cl0_pdat3 is the reference pixel clx_pdat0 => cl1_pdat(0), -- all pulse shaped, according to the clx_pdat1 => cl1_pdat(1), -- TRIG_WIN register clx_pdat2 => cl1_pdat(2), -- clx_pdat3 => cl1_pdat(3), -- clx_pdat4 => cl1_pdat(4), -- trig_2of37 => trig_2of37(1) -- ); cl2_pixel_delay_cal_01_port_map: outer_pixel_delay_cal_01 generic map (CLUSTER_NR => B"010") port map( --clk => gclk2, -- global clock input l0_del_sel_rg => pixel_sel_rg, -- bits 5..3= cluster_#, 2..0= pixel_# cl0_pdat3 => cl0_pdat(3), -- cl0_pdat3 is the reference pixel clx_pdat0 => cl2_pdat(0), -- all pulse shaped, according to the clx_pdat1 => cl2_pdat(1), -- TRIG_WIN register clx_pdat2 => cl2_pdat(2), -- clx_pdat3 => cl2_pdat(3), -- clx_pdat4 => cl2_pdat(4), -- trig_2of37 => trig_2of37(2) -- ); cl3_pixel_delay_cal_01_port_map: outer_pixel_delay_cal_01 generic map (CLUSTER_NR => B"011") port map( --clk => gclk2, -- global clock input l0_del_sel_rg => pixel_sel_rg, -- bits 5..3= cluster_#, 2..0= pixel_# cl0_pdat3 => cl0_pdat(3), -- cl0_pdat3 is the reference pixel clx_pdat0 => cl3_pdat(0), -- all pulse shaped, according to the clx_pdat1 => cl3_pdat(1), -- TRIG_WIN register clx_pdat2 => cl3_pdat(2), -- clx_pdat3 => cl3_pdat(3), -- clx_pdat4 => cl3_pdat(4), -- trig_2of37 => trig_2of37(3) -- ); cl4_pixel_delay_cal_01_port_map: outer_pixel_delay_cal_01 generic map (CLUSTER_NR => B"100") port map( --clk => gclk2, -- global clock input l0_del_sel_rg => pixel_sel_rg, -- bits 5..3= cluster_#, 2..0= pixel_# cl0_pdat3 => cl0_pdat(3), -- cl0_pdat3 is the reference pixel clx_pdat0 => cl4_pdat(0), -- all pulse shaped, according to the clx_pdat1 => cl4_pdat(1), -- TRIG_WIN register clx_pdat2 => cl4_pdat(2), -- clx_pdat3 => cl4_pdat(3), -- clx_pdat4 => cl4_pdat(4), -- trig_2of37 => trig_2of37(4) -- ); cl5_pixel_delay_cal_01_port_map: outer_pixel_delay_cal_01 generic map (CLUSTER_NR => B"101") port map( --clk => gclk2, -- global clock input l0_del_sel_rg => pixel_sel_rg, -- bits 5..3= cluster_#, 2..0= pixel_# cl0_pdat3 => cl0_pdat(3), -- cl0_pdat3 is the reference pixel clx_pdat0 => cl5_pdat(0), -- all pulse shaped, according to the clx_pdat1 => cl5_pdat(1), -- TRIG_WIN register clx_pdat2 => cl5_pdat(2), -- clx_pdat3 => cl5_pdat(3), -- clx_pdat4 => cl5_pdat(4), -- trig_2of37 => trig_2of37(5) -- ); cl6_pixel_delay_cal_01_port_map: outer_pixel_delay_cal_01 generic map (CLUSTER_NR => B"110") port map( --clk => gclk2, -- global clock input l0_del_sel_rg => pixel_sel_rg, -- bits 5..3= cluster_#, 2..0= pixel_# cl0_pdat3 => cl0_pdat(3), -- cl0_pdat3 is the reference pixel clx_pdat0 => cl6_pdat(0), -- all pulse shaped, according to the clx_pdat1 => cl6_pdat(1), -- TRIG_WIN register clx_pdat2 => cl6_pdat(2), -- clx_pdat3 => cl6_pdat(3), -- clx_pdat4 => cl6_pdat(4), -- trig_2of37 => trig_2of37(6) -- ); trig_2_of_37 <= trig_2of37(0) or trig_2of37(1) or trig_2of37(2) or trig_2of37(3) or trig_2of37(4) or trig_2of37(5) or trig_2of37(6); trig_1_of_37_01_port_map: trig_1_of_37_01 port map( pixel_sel_rg => pixel_sel_rg, -- bits 5..3= cluster_#, 2..0= pixel_# NBOR_IN => NBOR_IN, -- low active signal with pullup cl0_pdat0 => cl0_pdat(0), cl0_pdat1 => cl0_pdat(1), cl0_pdat2 => cl0_pdat(2), cl0_pdat3 => cl0_pdat(3), cl0_pdat4 => cl0_pdat(4), cl0_pdat5 => cl0_pdat(5), cl0_pdat6 => cl0_pdat(6), cl1_pdat0 => cl1_pdat(0), cl1_pdat1 => cl1_pdat(1), cl1_pdat2 => cl1_pdat(2), cl1_pdat3 => cl1_pdat(3), cl1_pdat4 => cl1_pdat(4), cl2_pdat0 => cl2_pdat(0), cl2_pdat1 => cl2_pdat(1), cl2_pdat2 => cl2_pdat(2), cl2_pdat3 => cl2_pdat(3), cl2_pdat4 => cl2_pdat(4), cl3_pdat0 => cl3_pdat(0), cl3_pdat1 => cl3_pdat(1), cl3_pdat2 => cl3_pdat(2), cl3_pdat3 => cl3_pdat(3), cl3_pdat4 => cl3_pdat(4), cl4_pdat0 => cl4_pdat(0), cl4_pdat1 => cl4_pdat(1), cl4_pdat2 => cl4_pdat(2), cl4_pdat3 => cl4_pdat(3), cl4_pdat4 => cl4_pdat(4), cl5_pdat0 => cl5_pdat(0), cl5_pdat1 => cl5_pdat(1), cl5_pdat2 => cl5_pdat(2), cl5_pdat3 => cl5_pdat(3), cl5_pdat4 => cl5_pdat(4), cl6_pdat0 => cl6_pdat(0), cl6_pdat1 => cl6_pdat(1), cl6_pdat2 => cl6_pdat(2), cl6_pdat3 => cl6_pdat(3), cl6_pdat4 => cl6_pdat(4), trig_1of37 => trig_1of37 -- ); UP_TRIGGER_SELECT: process (gclk2) begin if rising_edge (gclk2) then case ctrl_rg(2 downto 0) is when B"000" => trig <= trig_3nn; when B"001" => trig <= trig_1of7; when B"010" => trig <= trig_2_of_37; -- for delay calibration when B"100" => trig <= trig_1of37; -- for L0 verification (cable test, etc.) when others => trig <= X"00"; end case; end if; end process UP_TRIGGER_SELECT; UP_TRIG_PULSE_GEN_port_map: trig_pulse_shaper_03 port map ( clk => gclk2, -- pdat clock pulse_width => trig_puls_rg, -- length in clock cycles dead_time => trig_dtim_rg, -- trigger dead time, amount of clks reset => reset, oserdes_pdat => trig, -- serdes pdat oserdes_ioclk => serdes_ioclk0, oserdes_stb => oserdes_stb0, oserdes_out => j13_63_trig_out -- serial oserdes output ); J13_63_TRIG1_OUT_inst : OBUFDS -- up going trigger generic map (IOSTANDARD => "LVDS_25") port map ( O => J13_L1_OUT_P, OB => J13_L1_OUT_N, I => j13_63_trig_out); UP_TRIG_PULSE_GEN_LB_port_map: trig_pulse_shaper_03 port map -- loop back for locally clocked usage ( clk => gclk2, -- pdat clock pulse_width => trig_puls_rg, -- length in clock cycles dead_time => trig_dtim_rg, -- trigger dead time, amount of clks reset => reset, oserdes_pdat => trig, -- serdes pdat oserdes_ioclk => serdes_ioclk0, oserdes_stb => oserdes_stb0, oserdes_out => TEST_IO0_P -- serial oserdes output ); -- test_io0_inst : IOBUF -- generic map ( DRIVE => 12, IOSTANDARD => "LVCMOS25", SLEW => "FAST") -- port map -- ( -- O => test_io0_lb, -- Buffer output -- IO => TEST_IO0_P, -- Buffer inout port (connect directly to top-level port) -- I => test_io0, -- Buffer input -- T => '0' -- 3-state enable input, high=input, low=output -- ); SCALER_WINDOW_GEN: process (gclk2, reset) variable ct : integer range 0 to 1_249_999 := 0; variable nx10ms_ct : std_logic_vector(7 downto 0); begin if rising_edge (gclk2) then if (reset = '1') then ct := 0; l1_sc_win_rd_rg <= ONE_SECOND; nx10ms_ct := ONE_SECOND - '1'; elsif l1_sc_win_rg_wstb = '1' then ct := 0; if l1_sc_win_rg = X"00" then nx10ms_ct := X"01"; -- minmum window size is 10 ms l1_sc_win_rd_rg <= X"01"; -- read register reflecting actual value else nx10ms_ct := l1_sc_win_rg - '1'; l1_sc_win_rd_rg <= l1_sc_win_rg; end if; --l1_sc_win_rg = X"00" else if ct = 1_249_999 then ct := 0; --l1_sc_ms10 <= '1'; -- for test purposes if nx10ms_ct = X"00" then l1_scaler_upd <= '1'; nx10ms_ct := l1_sc_win_rd_rg - '1'; else l1_scaler_upd <= '0'; nx10ms_ct := nx10ms_ct - '1'; end if; --nx10ms_ct = (others=>'0) else ct := ct + 1; --l1_sc_ms10 <= '0'; l1_scaler_upd <= '0'; end if; -- ct = 1_249_999 end if; -- reset = '1' end if; -- rising_edge (gclk2) end process SCALER_WINDOW_GEN; UP_TRIG_LH_EDGE_port_map: serdes_lh_edge_01 port map ( clk => gclk2, -- pdat clock serdes_pdat => trig, -- serdes pdat lh_edge => up_trig_lh_edge -- pulse of one clk length ); L1_SCALER_GEN: process (gclk2, reset) begin if rising_edge (gclk2) then if (reset = '1') or (l1_sc_win_rg_wstb = '1') then l1_scaler_rg <= X"0000"; elsif l1_scaler_upd = '1' then l1_scaler_rg <= l1_scaler; -- latch for read sync. if up_trig_lh_edge = '1' then l1_scaler <= X"0001"; else l1_scaler <= X"0000"; end if; elsif up_trig_lh_edge = '1' and l1_scaler /= X"ffff" then l1_scaler <= l1_scaler + '1'; end if; -- reset = '1' end if; -- rising_edge (gclk2) end process L1_SCALER_GEN; nLED_ENA <= '0' when ctrl_rg(4)='1' else 'Z'; -- nLED_GREEN <= '1'; -- '0' = LED V3-green is on -- nLED_RED <= '1'; -- '0' = LED V3-red is on -- test_io0 <= ctdb_pps; --timepps_int;--up_trig_lh_edge; -- test_io0 <= cl0(0); -- TEST_IO0_port_map : oserdes_01 port map -- using pixel_0 of cl0 -- ( -- clk => gclk2 , -- pdat clock -- reset => reset, -- oserdes_pdat => cl0_pdat0(0), -- serdes pdat -- oserdes_ioclk => serdes_ioclk0, -- oserdes_stb => oserdes_stb0, -- oserdes_out => test_io0 -- serial oserdes output -- ); -- -- TEST_IO0_inst : OBUFDS -- generic map (IOSTANDARD => "LVDS_25") -- port map ( O => TEST_IO0_P, OB => TEST_IO0_N, I => test_io0); -- -- -- -- TEST_IO1_port_map : oserdes_01 port map -- using pixel_1 of cl1 -- ( -- clk => gclk2 , -- pdat clock -- reset => reset, -- oserdes_pdat => cl1_pdat0(0), -- serdes pdat -- oserdes_ioclk => serdes_ioclk0, -- oserdes_stb => oserdes_stb0, -- oserdes_out => test_io1 -- serial oserdes output -- ); -- -- TEST_IO1_inst : OBUFDS -- generic map (IOSTANDARD => "LVDS_25") -- port map ( O => TEST_IO1_P, OB => TEST_IO1_N, I => test_io1); -- --TEST_IO0_P <= cl0(0);--pll_locked; -- --TEST_IO1_P <= cl0(0); --pps_error; --l1_scaler_upd;--cal_start; -- TEST_IO1_N <= l1_scaler_upd; --pps_ct_max; --cal_done; -- end architecture dtb4_3nn_015_arch;