-- VHDL Entity work.top_extphy.symbol
--
-- Created:
--          by - phdgc.users (fortis.phy.bris.ac.uk)
--          at - 16:06:33 01/24/14
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2012.2b (Build 5)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

ENTITY top_extphy IS
   GENERIC( 
      g_NUM_DUTS            : positive := 3;
      g_NUM_TRIG_INPUTS     : positive := 4;
      g_NUM_EXT_SLAVES      : positive := 11;      --! Number of slaves outside IPBus interface
      g_EVENT_DATA_WIDTH    : positive := 64;
      g_IPBUS_WIDTH         : positive := 32;
      g_NUM_EDGE_INPUTS     : positive := 4;
      g_SPILL_COUNTER_WIDTH : positive := 12
   );
   PORT( 
      busy_n_i            : IN     std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);
      busy_p_i            : IN     std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);         --! Busy lines from DUTs ( active high )
      cfd_discr_n_i       : IN     std_logic_vector (g_NUM_TRIG_INPUTS-1 DOWNTO 0);
      cfd_discr_p_i       : IN     std_logic_vector (g_NUM_TRIG_INPUTS-1 DOWNTO 0);
      dip_switch_i        : IN     std_logic_vector (3 DOWNTO 0);
      gmii_rx_clk_i       : IN     std_logic;
      gmii_rx_dv_i        : IN     std_logic;
      gmii_rx_er_i        : IN     std_logic;
      gmii_rxd_i          : IN     std_logic_vector (7 DOWNTO 0);
      sysclk_n_i          : IN     std_logic;                                        --! 200 MHz xtal clock
      sysclk_p_i          : IN     std_logic;
      threshold_discr_n_i : IN     std_logic_vector (g_NUM_TRIG_INPUTS-1 DOWNTO 0);
      threshold_discr_p_i : IN     std_logic_vector (g_NUM_TRIG_INPUTS-1 DOWNTO 0);
		reset_i				  : IN 		std_logic;
      gmii_gtx_clk_o      : OUT    std_logic;
      gmii_tx_en_o        : OUT    std_logic;
      gmii_tx_er_o        : OUT    std_logic;
      gmii_txd_o          : OUT    std_logic_vector (7 DOWNTO 0);
      gpio_hdr            : OUT    std_logic_vector (7 DOWNTO 0);
      leds_o              : OUT    std_logic_vector (3 DOWNTO 0);
      phy_rstb_o          : OUT    std_logic;
		dut_clk_n_o         : INOUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);
      dut_clk_p_o         : INOUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);
      reset_or_clk_n_o    : OUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);
      reset_or_clk_p_o    : OUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);
      triggers_n_o        : OUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);
      triggers_p_o        : OUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);         --! Trigger lines to DUT
      extclk_n_b          : INOUT  std_logic;
      extclk_p_b          : INOUT  std_logic;                                        --! either external clock in, or a clock being driven out
      i2c_scl_b           : INOUT  std_logic;
      i2c_sda_b           : INOUT  std_logic
   );

-- Declarations

END ENTITY top_extphy ;

--=============================================================================
--! @file top_extphy_struct.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL -- VHDL Architecture work.top_extphy.struct
--
--! @brief \n
--! \n
--
--! @author David Cussans , David.Cussans@bristol.ac.uk ( phdgc.users (fortis.phy.bris.ac.uk))
--
--! @date 16:18:26 01/24/14
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by:</b>\n
--! Author: 
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
--
--
-- Generated by Mentor Graphics' HDL Designer(TM) 2012.2b (Build 5)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

LIBRARY work;
USE work.ipbus.all;
USE work.emac_hostbus_decl.all;

USE work.fmcTLU.all;
LIBRARY unisim;
USE unisim.vcomponents.all;


ARCHITECTURE struct OF top_extphy IS

   -- Architecture declarations

   -- Internal signal declarations
   SIGNAL buffer_full_o      : std_logic;                                             --! Goes high when event buffer almost full
   SIGNAL clk_16x_logic      : std_logic;                                             -- 640MHz clock
   SIGNAL clk_4x_logic       : std_logic;                                             --! normally 160MHz
   SIGNAL clk_logic_xtal     : std_logic;                                             -- ! 40MHz clock from onboard xtal
	SIGNAL s_DUT_clk			  : std_logic;															-- ! Clock to DUT
   SIGNAL data_strobe        : std_logic;                                             -- goes high when data ready to load into event buffer
   SIGNAL edge_fall_i        : std_logic_vector(g_NUM_EDGE_INPUTS-1 DOWNTO 0);        -- ! High when falling edge
   SIGNAL edge_fall_time_i   : t_triggerTimeArray(g_NUM_EDGE_INPUTS-1 DOWNTO 0);      -- Array of edge times ( w.r.t. logic_strobe)
   SIGNAL edge_rise_i        : std_logic_vector(g_NUM_EDGE_INPUTS-1 DOWNTO 0);        -- ! High when rising edge
   SIGNAL edge_rise_time_i   : t_triggerTimeArray(g_NUM_EDGE_INPUTS-1 DOWNTO 0);      -- Array of edge times ( w.r.t. logic_strobe)
   SIGNAL event_data         : std_logic_vector(g_EVENT_DATA_WIDTH-1 DOWNTO 0);
   SIGNAL event_number_o     : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0);            -- starts at one. Increments for each post_veto_trigger
   SIGNAL ipbr               : ipb_rbus_array(g_NUM_EXT_SLAVES-1 DOWNTO 0);           --! IPBus read signals
   SIGNAL ipbus_clk          : std_logic;
   SIGNAL ipbus_reset        : std_logic;
   SIGNAL ipbus_rst          : std_logic;                                             -- ! IPBus reset to slaves
   SIGNAL ipbw               : ipb_wbus_array(g_NUM_EXT_SLAVES-1 DOWNTO 0);           --! IBus write signals
   SIGNAL logic_clocks_reset : std_logic;                                             -- Goes high to reset counters etc. Sync with clk_4x_logic
   SIGNAL logic_reset        : std_logic;                                             -- Goes high to reset counters etc. Sync with clk_4x_logic
   SIGNAL overall_trigger    : std_logic;                                             --! goes high to load trigger data
   SIGNAL overall_veto       : std_logic;                                             --! Halts triggers when high
	SIGNAL postVeto_trigger_times      : t_triggerTimeArray(g_NUM_TRIG_INPUTS-1 DOWNTO 0);      -- ! trigger arrival time ( w.r.t. logic_strobe)
   SIGNAL s_rst_buffer			: std_logic;
	SIGNAL s_AIDAhandshake		: std_logic;
	SIGNAL s_i2c_scl_enb      : std_logic;
   SIGNAL s_i2c_sda_enb      : std_logic;
   SIGNAL shutter_cnt_i      : std_logic_vector(g_SPILL_COUNTER_WIDTH-1 DOWNTO 0);
   SIGNAL shutter_i          : std_logic;
   SIGNAL spill_cnt_i        : std_logic_vector(g_SPILL_COUNTER_WIDTH-1 DOWNTO 0);
   SIGNAL spill_i            : std_logic;
   SIGNAL strobe_16x_logic   : std_logic;                                             --! Pulses one cycle every 4 of 16x clock.
   SIGNAL strobe_4x_logic    : std_logic;                                             -- one pulse every 4 cycles of clk_4x
   SIGNAL trigger_cnt_i      : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0);
   SIGNAL trigger_count      : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0);
   SIGNAL trigger_times      : t_triggerTimeArray(g_NUM_TRIG_INPUTS-1 DOWNTO 0);      -- ! trigger arrival time ( w.r.t. logic_strobe)
   SIGNAL triggers           : std_logic_vector(g_NUM_TRIG_INPUTS-1 DOWNTO 0);
	SIGNAL postVeto_triggers  : std_logic_vector(g_NUM_TRIG_INPUTS-1 DOWNTO 0);
   SIGNAL veto_o             : std_logic;                                             --! goes high when one or more DUT are busy
	SIGNAL s_Trig_TO_DUT			: std_logic;
	SIGNAL s_rst_or_clk_to_dut: std_logic;

   -- Component Declarations
   COMPONENT DUTInterfaces
   GENERIC (
      g_NUM_DUTS    : positive := 3;
      g_IPBUS_WIDTH : positive := 32
   );
   PORT (
      busy_from_dut_n_i       : IN     std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);  -- BUSY input from DUTs
      busy_from_dut_p_i       : IN     std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);  -- BUSY input from DUTs
      clk_4x_logic_i          : IN     std_logic ;
      ipbus_clk_i             : IN     std_logic ;
      ipbus_i                 : IN     ipb_wbus ;                                 -- Signals from IPBus core TO slave
      ipbus_reset_i           : IN     std_logic ;
      strobe_4x_logic_i       : IN     std_logic ;                                -- ! goes high every 4th clock cycle
      --trigger_counter_i       : IN     std_logic_vector (g_IPBUS_WIDTH-1 DOWNTO 0);
      trigger_i               : IN     std_logic ;                                -- goes high when trigger logic issues a trigger
		clk_to_dut_i				: IN     std_logic ;											-- ! clock to DUT
		reset_or_clk_to_dut_i	: IN 		std_logic ;											-- ! Either reset line or trigger
		AIDAhandshake_i			: IN 		std_logic ;											-- AIDA/EUDET 
      ipbus_o                 : OUT    ipb_rbus ;                                 -- signals from slave TO IPBus core
      clk_to_dut_n_o        	: INOUT     std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);  -- clocks trigger data when in EUDET mode
      clk_to_dut_p_o       	: INOUT     std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);  -- clocks trigger data when in EUDET mode
		reset_or_clk_to_dut_n_o : OUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);  -- ! Either reset line or trigger
      reset_or_clk_to_dut_p_o : OUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);  -- ! Either reset line or trigger
      trigger_to_dut_n_o      : OUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);  -- ! Trigger output
      trigger_to_dut_p_o      : OUT    std_logic_vector (g_NUM_DUTS-1 DOWNTO 0);  -- ! Trigger output
      veto_o                  : OUT    std_logic                                  -- goes high when one or more DUT are busy
   );
   END COMPONENT DUTInterfaces;
   COMPONENT IPBusInterface
   GENERIC (
      NUM_EXT_SLAVES : positive := 5
   );
   PORT (
      gmii_rx_clk_i    : IN     std_logic ;
      gmii_rx_dv_i     : IN     std_logic ;
      gmii_rx_er_i     : IN     std_logic ;
      gmii_rxd_i       : IN     std_logic_vector (7 DOWNTO 0);
      ipbr_i           : IN     ipb_rbus_array (NUM_EXT_SLAVES-1 DOWNTO 0); -- ! IPBus read signals
      sysclk_n_i       : IN     std_logic ;
      sysclk_p_i       : IN     std_logic ;                                 -- ! 200 MHz xtal clock
      clocks_locked_o  : OUT    std_logic ;
      gmii_gtx_clk_o   : OUT    std_logic ;
      gmii_tx_en_o     : OUT    std_logic ;
      gmii_tx_er_o     : OUT    std_logic ;
      gmii_txd_o       : OUT    std_logic_vector (7 DOWNTO 0);
      ipb_clk_o        : OUT    std_logic ;                                 -- ! IPBus clock TO slaves
      ipb_rst_o        : OUT    std_logic ;                                 -- ! IPBus reset TO slaves
      ipbw_o           : OUT    ipb_wbus_array (NUM_EXT_SLAVES-1 DOWNTO 0); -- ! IBus write signals
      onehz_o          : OUT    std_logic ;
      phy_rstb_o       : OUT    std_logic ;
      dip_switch_i     : IN     std_logic_vector (3 DOWNTO 0);
      clk_logic_xtal_o : OUT    std_logic 
   );
   END COMPONENT IPBusInterface;
   COMPONENT eventBuffer
   GENERIC (
      g_EVENT_DATA_WIDTH    : positive := 64;
      g_IPBUS_WIDTH         : positive := 32;
      g_WRITE_COUNTER_WIDTH : positive := 15;
      g_READ_COUNTER_WIDTH  : positive := 16
   );
   PORT (
      clk_4x_logic_i    : IN     std_logic ;
      data_strobe_i     : IN     std_logic ;                                     -- Indicates data TO transfer
      event_data_i      : IN     std_logic_vector (g_EVENT_DATA_WIDTH-1 DOWNTO 0);
      ipbus_clk_i       : IN     std_logic ;
      ipbus_i           : IN     ipb_wbus ;
      ipbus_reset_i     : IN     std_logic ;
      strobe_4x_logic_i : IN     std_logic ;
      --trigger_count_i   : IN     std_logic_vector (g_IPBUS_WIDTH-1 DOWNTO 0);    --! Not used yet.
      rst_fifo_o			: OUT 	std_logic;														--! rst signal to first level fifos
		buffer_full_o     : OUT    std_logic ;                                     --! Goes high when event buffer almost full
      ipbus_o           : OUT    ipb_rbus ;
      logic_reset_i     : IN     std_logic                                       -- reset buffers when high. Synch withclk_4x_logic
   );
   END COMPONENT eventBuffer;
   COMPONENT eventFormatter
   GENERIC (
      g_EVENT_DATA_WIDTH   : positive := 64;
      g_IPBUS_WIDTH        : positive := 32;
      g_COUNTER_TRIG_WIDTH : positive := 32;
      g_COUNTER_WIDTH      : positive := 12;
      g_EVTTYPE_WIDTH      : positive := 4;      -- Width of the event type word
      --g_NUM_INPUT_TYPES     : positive := 4;               -- Number of different input types (trigger, shutter, edge...)
      g_NUM_EDGE_INPUTS    : positive := 4;      -- Number of edge inputs
      g_NUM_TRIG_INPUTS    : positive := 5       -- Number of trigger inputs
   );
   PORT (
      clk_4x_logic_i         : IN     std_logic ;                                        -- ! Rising edge active
      ipbus_clk_i            : IN     std_logic ;
      logic_strobe_i         : IN     std_logic ;                                        -- ! Pulses high once every 4 cycles of clk_4x_logic
      logic_reset_i          : IN     std_logic ;                                        -- goes high TO reset counters. Synchronous with clk_4x_logic
      rst_fifo_i					: IN 		std_logic;														--! Reset fifos
		buffer_full_i			  : IN 	  std_logic; 														-- Buffer full signal from main buffer
		trigger_i              : IN     std_logic ;                                        --! goes high TO load trigger data. One cycle of clk_4x_logic
      trigger_times_i        : IN     t_triggerTimeArray (g_NUM_TRIG_INPUTS-1 DOWNTO 0); -- Array of trigger times ( w.r.t. logic_strobe)
      trigger_inputs_fired_i : IN     std_logic_vector (g_NUM_TRIG_INPUTS-1 DOWNTO 0);   -- high for each input that "fired"
      trigger_cnt_i          : IN     std_logic_vector (g_COUNTER_TRIG_WIDTH-1 DOWNTO 0);
      shutter_i              : IN     std_logic ;
      shutter_cnt_i          : IN     std_logic_vector (g_COUNTER_WIDTH-1 DOWNTO 0);
      spill_i                : IN     std_logic ;
      spill_cnt_i            : IN     std_logic_vector (g_COUNTER_WIDTH-1 DOWNTO 0);
      edge_rise_i            : IN     std_logic_vector (g_NUM_EDGE_INPUTS-1 DOWNTO 0);   -- ! High when rising edge
      edge_fall_i            : IN     std_logic_vector (g_NUM_EDGE_INPUTS-1 DOWNTO 0);   -- ! High when falling edge
      edge_rise_time_i       : IN     t_triggerTimeArray (g_NUM_EDGE_INPUTS-1 DOWNTO 0); -- Array of edge times ( w.r.t. logic_strobe)
      edge_fall_time_i       : IN     t_triggerTimeArray (g_NUM_EDGE_INPUTS-1 DOWNTO 0); -- Array of edge times ( w.r.t. logic_strobe)
		ipbus_i                : IN     ipb_wbus ;
      ipbus_o                : OUT    ipb_rbus ;
      data_strobe_o          : OUT    std_logic ;                                        -- goes high when data ready TO load into event buffer
      event_data_o           : OUT    std_logic_vector (g_EVENT_DATA_WIDTH-1 DOWNTO 0);
      event_number_i         : IN     std_logic_vector (g_IPBUS_WIDTH-1 DOWNTO 0);
      trigger_count_o        : OUT    std_logic_vector (g_IPBUS_WIDTH-1 DOWNTO 0)
   );
   END COMPONENT eventFormatter;
   COMPONENT i2c_master
   PORT (
      i2c_scl_i     : IN     std_logic ;
      i2c_sda_i     : IN     std_logic ;
      ipbus_clk_i   : IN     std_logic ;
      ipbus_i       : IN     ipb_wbus ; -- Signals from IPBus core TO slave
      ipbus_reset_i : IN     std_logic ;
      i2c_scl_enb_o : OUT    std_logic ;
      i2c_sda_enb_o : OUT    std_logic ;
      ipbus_o       : OUT    ipb_rbus   -- signals from slave TO IPBus core
   );
   END COMPONENT i2c_master;
   COMPONENT logic_clocks
   PORT (
      ipbus_clk_i           : IN     std_logic ;
      ipbus_i               : IN     ipb_wbus ;
      ipbus_reset_i         : IN     std_logic ;
      Reset_i               : IN     std_logic ;
      clk_logic_xtal_i      : IN     std_logic ; -- ! 40MHz clock from onboard xtal
      clk_16x_logic_o       : OUT    std_logic ; -- 640MHz clock
      clk_4x_logic_o        : OUT    std_logic ; -- 160MHz clock
      ipbus_o               : OUT    ipb_rbus ;
      strobe_16x_logic_o    : OUT    std_logic ; -- strobes once every 4 cycles of clk_16x
      strobe_4x_logic_o     : OUT    std_logic ; -- one pulse every 4 cycles of clk_4x
      extclk_p_b            : INOUT  std_logic ; -- either external clock in, or a clock being driven out
      extclk_n_b            : INOUT  std_logic ;
      DUT_clk_o     	       : OUT    std_logic ;
      logic_clocks_locked_o : OUT    std_logic ;
      logic_reset_o         : OUT    std_logic   -- Goes high TO reset counters etc. Sync with clk_4x_logic
   );
   END COMPONENT logic_clocks;
   COMPONENT triggerInputs
   GENERIC (
      g_NUM_INPUTS : natural := 1
   );
   PORT (
      cfd_discr_p_i        : IN     std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
      cfd_discr_n_i        : IN     std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);
      clk_4x_logic         : IN     std_logic ;                                        -- ! Rising edge active
      strobe_4x_logic_i    : IN     std_logic ;                                        -- ! Pulses high once every 4 cycles of clk_4x_logic
      threshold_discr_p_i  : IN     std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);        -- ! inputs from threshold comparators
      threshold_discr_n_i  : IN     std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);        -- ! inputs from threshold comparators
		reset_i					: IN 		std_logic;
      trigger_times_o      : OUT    t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);      -- ! trigger arrival time ( w.r.t. logic_strobe)
      trigger_o            : OUT    std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);        -- ! High when trigger active
      trigger_debug_o      : OUT    std_logic_vector ( ((2*g_NUM_INPUTS)-1) DOWNTO 0); -- ! Copy of input trigger level. High bits CFD, Low threshold
      edge_rising_times_o  : OUT    t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);      -- ! edge arrival time ( w.r.t. logic_strobe)
      edge_falling_times_o : OUT    t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);      -- ! edge arrival time ( w.r.t. logic_strobe)
      edge_rising_o        : OUT    std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);        -- ! High when rising edge
      edge_falling_o       : OUT    std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);        -- ! High when falling edge
      ipbus_clk_i          : IN     std_logic ;
      ipbus_reset_i        : IN     std_logic ;
      ipbus_i              : IN     ipb_wbus ;                                         -- Signals from IPBus core TO slave
      ipbus_o              : OUT    ipb_rbus ;                                         -- signals from slave TO IPBus core
      clk_16x_logic_i      : IN     std_logic ;                                        --! 640MHz clock ( 16x 40MHz )
      strobe_16x_logic_i   : IN     std_logic                                          --! Pulses one cycle every 4 of 16x clock.
   );
   END COMPONENT triggerInputs;
   COMPONENT triggerLogic
   GENERIC (
      g_NUM_INPUTS  : positive := 4;
      g_IPBUS_WIDTH : positive := 32
   );
   PORT (
      clk_4x_logic_i      : IN     std_logic ;                                  -- ! Rising edge active
      ipbus_clk_i         : IN     std_logic ;
      ipbus_i             : IN     ipb_wbus ;                                   -- Signals from IPBus core TO slave
      ipbus_reset_i       : IN     std_logic ;
      logic_reset_i       : IN     std_logic ;                                  -- active high. Synchronous with clk_4x_logic
      logic_strobe_i      : IN     std_logic ;                                  -- ! Pulses high once every 4 cycles of clk_4x_logic
      trigger_i           : IN     std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);  -- ! High when trigger from input connector active
		trigger_times_i     : IN    t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);  --! trigger arrival time 
      veto_i              : IN     std_logic ;                                  -- ! Halts triggers when high
		trigger_o           : OUT     std_logic_vector (g_NUM_INPUTS-1 DOWNTO 0);  -- ! High when trigger from input connector active and input enabled
		trigger_times_o     : OUT    t_triggerTimeArray (g_NUM_INPUTS-1 DOWNTO 0);  --! trigger arrival time 
      event_number_o      : OUT    std_logic_vector (g_IPBUS_WIDTH-1 DOWNTO 0); -- starts at one. Increments for each post_veto_trigger
      ipbus_o             : OUT    ipb_rbus ;                                   -- signals from slave TO IPBus core
      post_veto_trigger_o : OUT    std_logic ;                                  -- ! goes high when trigger passes
      pre_veto_trigger_o  : OUT    std_logic ;
      trigger_active_o    : OUT    std_logic                                    --! Goes high when triggers are active ( ie. not veoted)
   );
   END COMPONENT triggerLogic;
	COMPONENT handshakes
   GENERIC( 
      g_IPBUS_WIDTH         : positive := 32
   );
   PORT( 
      clk_i    			: IN     std_logic;
		Trigger_i			: IN 		std_logic;
      ipbus_clk_i       : IN     std_logic;
      ipbus_i           : IN     ipb_wbus;
      ipbus_reset_i     : IN     std_logic;
      ipbus_o           : OUT    ipb_rbus;
      logic_reset_i     : IN     std_logic;    -- reset buffers when high. Synch withclk_4x_logic
		Busy_i				: IN		std_logic;
		AIDAhandshake_o	: OUT		std_logic;		-- running an AIDA handshake or the old EUDET handshake
		Trigger_o			: OUT 	std_logic;
		rst_or_clk_o		: OUT 	std_logic
   );
	END COMPONENT handshakes;

   -- Optional embedded configurations
   -- pragma synthesis_off
   FOR ALL : DUTInterfaces USE ENTITY work.DUTInterfaces;
   FOR ALL : IPBusInterface USE ENTITY work.IPBusInterface;
   FOR ALL : eventBuffer USE ENTITY work.eventBuffer;
   FOR ALL : eventFormatter USE ENTITY work.eventFormatter;
   FOR ALL : i2c_master USE ENTITY work.i2c_master;
   FOR ALL : logic_clocks USE ENTITY work.logic_clocks;
   FOR ALL : triggerInputs USE ENTITY work.triggerInputs;
   FOR ALL : triggerLogic USE ENTITY work.triggerLogic;
	FOR ALL : handshakes USE ENTITY work.handshakes;
   -- pragma synthesis_on


BEGIN
   -- Architecture concurrent statements
   -- HDL Embedded Text Block 1 i2c_tristate
   -- eb1 1
   i2c_scl_b <= '0' when (s_i2c_scl_enb = '0') else 'Z';
   i2c_sda_b <= '0' when (s_i2c_sda_enb = '0') else 'Z';
   
                               


   -- ModuleWare code(v1.12) for instance 'I9' of 'gnd'
   logic_clocks_reset <= '0';

   -- ModuleWare code(v1.12) for instance 'I10' of 'gnd'
   --trigger_cnt_i <= (OTHERS => '0');
	trigger_cnt_i <= event_number_o;

   -- ModuleWare code(v1.12) for instance 'I11' of 'gnd'
   spill_i <= '0';

   -- ModuleWare code(v1.12) for instance 'I12' of 'gnd'
   spill_cnt_i <= (OTHERS => '0');

   -- ModuleWare code(v1.12) for instance 'I13' of 'gnd'
   shutter_i <= '0';

   -- ModuleWare code(v1.12) for instance 'I14' of 'gnd'
   shutter_cnt_i <= (OTHERS => '0');

   -- ModuleWare code(v1.12) for instance 'I8' of 'sor'
   overall_veto <= buffer_full_o; -- OR veto_o;

   -- Instance port mappings.
   I0 : DUTInterfaces
      GENERIC MAP (
         g_NUM_DUTS    => g_NUM_DUTS,
         g_IPBUS_WIDTH => g_IPBUS_WIDTH
      )
      PORT MAP (
         busy_from_dut_n_i       => busy_n_i,
         busy_from_dut_p_i       => busy_p_i,
         clk_4x_logic_i          => clk_4x_logic,
         ipbus_clk_i             => ipbus_clk,
         ipbus_i                 => ipbw(0),
         ipbus_reset_i           => ipbus_reset,
         strobe_4x_logic_i       => strobe_4x_logic,
         --trigger_counter_i       => trigger_count,
         clk_to_dut_i				=> s_DUT_clk,
			trigger_i               => s_Trig_TO_DUT, --overall_trigger,
			reset_or_clk_to_dut_i	=> s_rst_or_clk_to_dut,
			AIDAhandshake_i			=> s_AIDAhandshake, -- RJ45 DUT clock as output/input (1/0)
         ipbus_o                 => ipbr(0),
			clk_to_dut_n_o        	=> dut_clk_n_o,
         clk_to_dut_p_o        	=> dut_clk_p_o,
         reset_or_clk_to_dut_n_o => reset_or_clk_n_o,
         reset_or_clk_to_dut_p_o => reset_or_clk_p_o,
         trigger_to_dut_n_o      => triggers_n_o,
         trigger_to_dut_p_o      => triggers_p_o,
         veto_o                  => veto_o
      );
   I4 : IPBusInterface
      GENERIC MAP (
         NUM_EXT_SLAVES => g_NUM_EXT_SLAVES
      )
      PORT MAP (
         gmii_rx_clk_i    => gmii_rx_clk_i,
         gmii_rx_dv_i     => gmii_rx_dv_i,
         gmii_rx_er_i     => gmii_rx_er_i,
         gmii_rxd_i       => gmii_rxd_i,
         ipbr_i           => ipbr,
         sysclk_n_i       => sysclk_n_i,
         sysclk_p_i       => sysclk_p_i,
         clocks_locked_o  => leds_o(2),
         gmii_gtx_clk_o   => gmii_gtx_clk_o,
         gmii_tx_en_o     => gmii_tx_en_o,
         gmii_tx_er_o     => gmii_tx_er_o,
         gmii_txd_o       => gmii_txd_o,
         ipb_clk_o        => ipbus_clk,
         ipb_rst_o        => ipbus_rst,
         ipbw_o           => ipbw,
         onehz_o          => leds_o(3),
         phy_rstb_o       => phy_rstb_o,
         dip_switch_i     => dip_switch_i,
         clk_logic_xtal_o => clk_logic_xtal
      );
   I5 : eventBuffer
      GENERIC MAP (
         g_EVENT_DATA_WIDTH    => g_EVENT_DATA_WIDTH,
         g_IPBUS_WIDTH         => g_IPBUS_WIDTH,
         g_WRITE_COUNTER_WIDTH => 15,
         g_READ_COUNTER_WIDTH  => 16
      )
      PORT MAP (
         clk_4x_logic_i    => clk_4x_logic,
         data_strobe_i     => data_strobe,
         event_data_i      => event_data,
         ipbus_clk_i       => ipbus_clk,
         ipbus_i           => ipbw(3),
         ipbus_reset_i     => ipbus_reset,
         strobe_4x_logic_i => strobe_4x_logic,
         --trigger_count_i   => trigger_count,
			rst_fifo_o			=> s_rst_buffer,
         buffer_full_o     => buffer_full_o,
         ipbus_o           => ipbr(3),
         logic_reset_i     => logic_reset or reset_i
      );
   I2 : eventFormatter
      GENERIC MAP (
         g_EVENT_DATA_WIDTH   => g_EVENT_DATA_WIDTH,
         g_IPBUS_WIDTH        => g_IPBUS_WIDTH,
         g_COUNTER_TRIG_WIDTH => g_IPBUS_WIDTH,
         g_COUNTER_WIDTH      => 12,
         g_EVTTYPE_WIDTH      => 4,                         -- Width of the event type word
         --g_NUM_INPUT_TYPES     : positive := 4;               -- Number of different input types (trigger, shutter, edge...)
         g_NUM_EDGE_INPUTS    => g_NUM_EDGE_INPUTS,         -- Number of edge inputs
         g_NUM_TRIG_INPUTS    => g_NUM_TRIG_INPUTS          -- Number of trigger inputs
      )
      PORT MAP (
         clk_4x_logic_i         => clk_4x_logic,
         ipbus_clk_i            => ipbus_clk,
         logic_strobe_i         => strobe_4x_logic,
         logic_reset_i          => logic_reset or reset_i,
			rst_fifo_i					=> s_rst_buffer,
			buffer_full_i				=> buffer_full_o,
         trigger_i              => overall_trigger,
         trigger_times_i        => postVeto_trigger_times,
         trigger_inputs_fired_i => postVeto_triggers, 
         -- trigger_cnt_i          => trigger_cnt_i,
         trigger_cnt_i          => event_number_o,
         shutter_i              => shutter_i,
         shutter_cnt_i          => shutter_cnt_i,
         spill_i                => spill_i,
         spill_cnt_i            => spill_cnt_i,
         edge_rise_i            => edge_rise_i,
         edge_fall_i            => edge_fall_i,
         edge_rise_time_i       => edge_rise_time_i,
         edge_fall_time_i       => edge_fall_time_i,
         ipbus_i                => ipbw(9),
         ipbus_o                => ipbr(9),
         data_strobe_o          => data_strobe,
         event_data_o           => event_data,
         event_number_i         => event_number_o,
         trigger_count_o        => trigger_count
      );
   I7 : i2c_master
      PORT MAP (
         i2c_scl_i     => i2c_scl_b,
         i2c_sda_i     => i2c_sda_b,
         ipbus_clk_i   => ipbus_clk,
         ipbus_i       => ipbw(5),
         ipbus_reset_i => ipbus_reset,
         i2c_scl_enb_o => s_i2c_scl_enb,
         i2c_sda_enb_o => s_i2c_sda_enb,
         ipbus_o       => ipbr(5)
      );
   I6 : logic_clocks
      PORT MAP (
         ipbus_clk_i           => ipbus_clk,
         ipbus_i               => ipbw(4),
         ipbus_reset_i         => ipbus_reset,
         Reset_i               => logic_clocks_reset,
         clk_logic_xtal_i      => clk_logic_xtal,
         clk_16x_logic_o       => clk_16x_logic,
         clk_4x_logic_o        => clk_4x_logic,
         ipbus_o               => ipbr(4),
         strobe_16x_logic_o    => strobe_16x_logic,
         strobe_4x_logic_o     => strobe_4x_logic,
         extclk_p_b            => extclk_p_b,
         extclk_n_b            => extclk_n_b,
         DUT_clk_o           	 => s_DUT_clk,
         logic_clocks_locked_o => leds_o(1),
         logic_reset_o         => logic_reset
      );
   I1 : triggerInputs
      GENERIC MAP (
         g_NUM_INPUTS => g_NUM_TRIG_INPUTS
      )
      PORT MAP (
         cfd_discr_p_i        => cfd_discr_p_i,
         cfd_discr_n_i        => cfd_discr_n_i,
         clk_4x_logic         => clk_4x_logic,
         strobe_4x_logic_i    => strobe_4x_logic,
         threshold_discr_p_i  => threshold_discr_p_i,
         threshold_discr_n_i  => threshold_discr_n_i,
			reset_i					=> reset_i,
         trigger_times_o      => trigger_times,
         trigger_o            => triggers,
			trigger_debug_o		=> gpio_hdr,
         edge_rising_times_o  => OPEN,
         edge_falling_times_o => OPEN,
         edge_rising_o        => OPEN,
         edge_falling_o       => OPEN,
         ipbus_clk_i          => ipbus_clk,
         ipbus_reset_i        => ipbus_reset,
         ipbus_i              => ipbw(1),
         ipbus_o              => ipbr(1),
         clk_16x_logic_i      => clk_16x_logic,
         strobe_16x_logic_i   => strobe_16x_logic
      );
   I3 : triggerLogic
      GENERIC MAP (
         g_NUM_INPUTS  => g_NUM_TRIG_INPUTS,
         g_IPBUS_WIDTH => g_IPBUS_WIDTH
      )
      PORT MAP (
         clk_4x_logic_i      => clk_4x_logic,
         ipbus_clk_i         => ipbus_clk,
         ipbus_i             => ipbw(2),
         ipbus_reset_i       => ipbus_reset,
         logic_reset_i       => logic_reset or reset_i,
         logic_strobe_i      => strobe_4x_logic,
         trigger_i           => triggers,
			trigger_times_i     => trigger_times,
         veto_i              => overall_veto,
			trigger_o           => postVeto_triggers,
			trigger_times_o     => postVeto_trigger_times,
         event_number_o      => event_number_o,
         ipbus_o             => ipbr(2),
         post_veto_trigger_o => overall_trigger,
         pre_veto_trigger_o  => OPEN,
         trigger_active_o    => leds_o(0)
      );
		
	I8 : handshakes
   GENERIC MAP( 
      g_IPBUS_WIDTH => g_IPBUS_WIDTH
   )
   PORT MAP( 
      clk_i    			=> s_DUT_clk,
		Trigger_i			=> overall_trigger,
      ipbus_clk_i       => ipbus_clk,
      ipbus_i           => ipbw(10),
      ipbus_reset_i     => ipbus_reset,
      ipbus_o           => ipbr(10),
      logic_reset_i     => logic_reset or reset_i,
		Busy_i				=> veto_o,
		AIDAhandshake_o	=> s_AIDAhandshake,
		Trigger_o			=> s_Trig_TO_DUT,
		rst_or_clk_o		=> s_rst_or_clk_to_dut
   );

END ARCHITECTURE struct;
