----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    17:03:27 03/16/2011 
-- Design Name: 
-- Module Name:    macb_top - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
-- NOTE all in/out notations are relative to this unit
entity macb_apr20 is
    Port ( 
			  port1_sp : inout  STD_LOGIC_VECTOR (3 downto 0);
			  port2_sp : inout  STD_LOGIC_VECTOR (3 downto 0);
			  port3_sp : inout  STD_LOGIC_VECTOR (3 downto 0);
			  port4_sp : inout  STD_LOGIC_VECTOR (3 downto 0);
			  layer_sp : inout  STD_LOGIC_VECTOR (3 downto 0);
			  layer_trigger : out std_logic ;
           sync_return : in  STD_LOGIC_VECTOR (3 downto 1);
           selector : in  STD_LOGIC_VECTOR (3 downto 0);
           sync_select : out  STD_LOGIC_vector(1 downto 0 );
           clock200_select : out  STD_LOGIC_vector( 1 downto 0 ) ;
			  butis_divide_reset : out std_logic ;
			  butis_divide_s : out std_logic_vector( 2 downto 0 ) ;
			  clock_5 : in std_logic ;
			  sync_5 : in std_logic ;
			  trigger : in std_logic_vector( 3 downto 0 ) ;
           MBS_in : in  STD_LOGIC_VECTOR (3 downto 0);
           MBS_out : out  STD_LOGIC_VECTOR (3 downto 0));
end macb_apr20;

architecture Behavioral of macb_apr20 is
signal port1_spi :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal port1_spo :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal port1_t :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '1' );
signal port2_spi :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal port2_spo :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal port2_t :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '1' );
signal port3_spi :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal port3_spo :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal port3_t :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '1' );
signal port4_spi :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal port4_spo :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal port4_t :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '1' );
signal layer_spi :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal layer_spo :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '0' );
signal layer_t :  STD_LOGIC_VECTOR (3 downto 0) := ( others => '1' );
signal seli : integer range 0 to 15 := 0  ;
-- well really
signal MBS_in_n : std_logic_vector( 3 downto 0 ) := "0000" ;
begin
MBS_in_n <= ( not MBS_in);
seli <= conv_integer(not selector) ;
-- MBS signal allocations to sp lines and HDMI pin. This maps to NIM connections
-- 0 :	MBS_clock10 	SP0	13
-- 1 :	MBS_reset		SP1	14
-- 2 :	MBS_reset_rq	SP2	15
-- 3 :	MBS_Trigger		SP3	16
layer_trigger <= trigger(0) or trigger(1) or trigger(2) or trigger(3) ;

-- divider controls set for pass-through
butis_divide_reset <= '1' ; -- for now don't reset ;

process ( seli , MBS_in_n, port1_spi, port2_spi, port3_spi, port4_spi, layer_spi, sync_return ,sync_5  )
-- note : & => concatenate
begin
	case seli is 
	when 0 => --- Master/ Root / MBS / Internal clock
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "00" ; -- select sync from port 1 
		clock200_select <= "00" ; -- select internal 200 MHz oscillator
		MBS_out <=  MBS_in_n(3) & MBS_in_n(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "000" ; -- s2 is 0 for pass,
		
	when 1 => --- Master/ Root / MBS / BuTiS clock and SYNC
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "01" ; -- select sync from external using SMA input 
		clock200_select <= "01" ; -- select external 200 MHz oscillator using SMA input
		MBS_out <=  MBS_in_n(3) & MBS_in_n(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "000" ; -- s2 is 0 for pass,

	when 2 => --- Master/ Branch / MBS / Next layer clock next layer SYNC
		port1_spo <= layer_spi(3) & layer_spi(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= layer_spi(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= layer_spi(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= layer_spi(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <=  '0' & '0' & port1_spi(1) & port1_spi(0) ; -- drive the clock and reset down a layer
		layer_t <= "1100" ; -- just drive the bottom two bits to the "next" port
		sync_select <= "10" ; -- select sync from next_layer 
		clock200_select <= "10" ; -- select clock from next layer
		MBS_out <=  layer_spi(3) & layer_spi(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "000" ; -- s2 is 0 for pass,

	when 3 => --- Slave / Branch / MBS / Next layer clock and sync
		port1_spo <= layer_spi(3) & '0'  & layer_spi(1) & layer_spi(0);
		port1_t <= "0100" ; -- drive clock, reset, trigger only 
		port2_spo <= layer_spi(3) & '0' & layer_spi(1) & layer_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= layer_spi(3) & '0' & layer_spi(1) & layer_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= layer_spi(3) & '0' & layer_spi(1) & layer_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <=  '0' & '0' & '0' & '0' ; -- drive nothing
		layer_t <= "1111" ; -- just drive nothing down
		sync_select <= "10" ; -- select sync from next layer 
		clock200_select <= "10" ; -- select clock from next layer
		MBS_out <=  layer_spi ; -- map all the signals for monitoring ?
		butis_divide_s <= "000" ; -- s2 is 0 for pass,
		
	when 4 => --- Master/ Root / MBS / BuTiS clock / Internal SYNC / External timestamp reset
		port1_spo <= MBS_in_n(3) & '0' & MBS_in_n(1)  & '0' ;
		port1_t <= "0100" ; -- drive clock, reset, trigger only
		port2_spo <= MBS_in_n(3) & '0' & MBS_in_n(1)  & '0' ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & MBS_in_n(1)  & '0' ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & MBS_in_n(1)  & '0' ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "00" ; -- select sync from port 1 
		clock200_select <= "01" ; -- select external 50 MHz oscillator using SMA input
		MBS_out <=  MBS_in_n(3) & MBS_in_n(2) & MBS_in_n(1) & sync_5 ;
		butis_divide_s <= "000" ; -- s2 is 0 for pass,

	when 5 => --- Master/ Root / MBS / External 50Mhz clock / Internal Sync
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "00" ; -- select sync from port 1 
		clock200_select <= "01" ; -- select external SMA input 
		MBS_out <=  MBS_in_n(3) & MBS_in_n(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "000" ; -- s2 is 0 for pass through.
			
	when 6 => --- Master/ Root / MBS / External 100Mhz clock / Internal Sync
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "00" ; -- select sync from port 1 
		clock200_select <= "01" ; -- select external SMA input 
		MBS_out <=  MBS_in_n(3) & MBS_in_n(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "100" ; -- s2 is 1 for external, 00 for /2.
		
	when 7 => --- Fast NIM input for each FEE / Next layer clock next layer SYNC
		port1_spo <= MBS_in_n(0) & layer_spi(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(1) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(2) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <=  '0' & '0' & port1_spi(1) & port1_spi(0) ; -- drive the clock and reset down a layer
		layer_t <= "1100" ; -- just drive the bottom two bits to the "next" port
		sync_select <= "10" ; -- select sync from next_layer 
		clock200_select <= "10" ; -- select clock from next layer
		MBS_out <=  layer_spi(3) & layer_spi(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "000" ; -- s2 is 0 for pass,

	when 8 => --- Fast NIM input from Input 3 for each FEE / Next layer clock next layer SYNC
		port1_spo <= MBS_in_n(3) & layer_spi(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <=  '0' & '0' & port1_spi(1) & port1_spi(0) ; -- drive the clock and reset down a layer
		layer_t <= "1100" ; -- just drive the bottom two bits to the "next" port
		sync_select <= "10" ; -- select sync from next_layer 
		clock200_select <= "10" ; -- select clock from next layer
		MBS_out <=  layer_spi(3) & layer_spi(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "000" ; -- s2 is 0 for pass,
	
	when 9 => --- Master/ Root / Internal clock / sync_returns to NIM
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "00" ; -- select sync from port 1 
		clock200_select <= "00" ; -- select internal 200 MHz oscillator
		MBS_out <=  sync_return(3) & sync_return(2) & sync_return(1) & '0' ;
		butis_divide_s <= "000" ; -- s2 is 0 for pass,

	when 10 => --- Master/ Root / MBS / BuTiS clock /2 and SYNC
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= "0000" ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "01" ; -- select sync from external using SMA input 
		clock200_select <= "01" ; -- select external 200 MHz oscillator using SMA input
		MBS_out <=  MBS_in_n ; -- for testing NIM I/O
		butis_divide_s <= "100" ; --  s2 = 1 and s1,s0 decode to 00=>/2 , 01=>/4, /8 , /16

	when 12 => --- Master/ Root / MBS / BuTiS clock /2 and SYNC
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "01" ; -- select sync from external using SMA input 
		clock200_select <= "01" ; -- select external 200 MHz oscillator using SMA input
		MBS_out <=  MBS_in_n(3) & MBS_in_n(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "100" ; --  s2 = 1 and s1,s0 decode to 00=>/2 , 01=>/4, /8 , /16

	when 13 => --- Master/ Root / MBS / BuTiS clock /4 and SYNC
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "01" ; -- select sync from external using SMA input 
		clock200_select <= "01" ; -- select external 200 MHz oscillator using SMA input
		MBS_out <=  MBS_in_n(3) & MBS_in_n(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "101" ; --  s2 = 1 and s1,s0 decode to  01=>/4
		
	when 14 => --- Master/ Root / MBS / BuTiS clock /8 and SYNC
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "01" ; -- select sync from external using SMA input 
		clock200_select <= "01" ; -- select external 200 MHz oscillator using SMA input
		MBS_out <=  MBS_in_n(3) & MBS_in_n(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "110" ; --  s2 = 1 and s1,s0 decode to 10=>/8
		
	when 15 => --- Master/ Root / MBS / BuTiS clock and SYNC
		port1_spo <= MBS_in_n(3) & MBS_in_n(2) & '0' & '0' ;
		port1_t <= "0011" ; -- drive trigger and reset request only
		port2_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port2_t <= "0100" ; -- drive clock, reset, trigger only 
		port3_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port3_t <= "0100" ; -- drive clock, reset, trigger only
		port4_spo <= MBS_in_n(3) & '0' & port1_spi(1) & port1_spi(0) ;
		port4_t <= "0100" ; -- drive clock, reset, trigger only
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ; -- disable the drive to the "next" port
		sync_select <= "01" ; -- select sync from external using SMA input 
		clock200_select <= "01" ; -- select external 200 MHz oscillator using SMA input
		MBS_out <=  MBS_in_n(3) & MBS_in_n(2) & port1_spi(1) & port1_spi(0) ;
		butis_divide_s <= "111" ; --  s2 = 1 and s1,s0 decode to 11=>/16
		
	when others =>
		port1_spo <= ( others => '0' ) ;-- default is disabled with all pulled to logic '0' 
		port1_t <= ( others => '1' ) ;
		port2_spo <= ( others => '0' ) ;
		port2_t <= ( others => '1' ) ;
		port3_spo <= ( others => '0' ) ;
		port3_t <= ( others => '1' ) ;
		port4_spo <= ( others => '0' ) ;
		port4_t <= ( others => '1' ) ;
		layer_spo <= ( others => '0' ) ;
		layer_t <= ( others => '1' ) ;
		sync_select <= "00" ;
		clock200_select <= "11" ; -- selects next layer so should be dead if only macb
		MBS_out <= ( others => '0' ) ;
		butis_divide_s <= "000" ; -- s2 is 0 for pass,

	end case ;
end process ;

port1_buff:
   for spnum in 0 to 3 generate
      begin
   ibuf1_sp : IBUF
   generic map (
      IOSTANDARD => "LVCMOS33")
   port map (
      O => port1_spi(spnum),     -- Buffer output
      I => port1_sp(spnum)      -- Buffer input (connect directly to top-level port)
   );
	
  obuf1_sp : OBUFT
   generic map (
      DRIVE => 12,
      IOSTANDARD => "LVCMOS33",
      SLEW => "FAST")
   port map (
      O => port1_sp(spnum),     -- Buffer output (connect directly to top-level port)
      I => port1_spo(spnum),     -- Buffer input
      T => port1_t(spnum)     -- 3-state enable input 
   );
   end generate;
port2_buff:
   for spnum in 0 to 3 generate
      begin
   ibuf2_sp : IBUF
   generic map (
      IOSTANDARD => "LVCMOS33")
   port map (
      O => port2_spi(spnum),     -- Buffer output
      I => port2_sp(spnum)      -- Buffer input (connect directly to top-level port)
   );
	
  obuf2_sp : OBUFT
   generic map (
      DRIVE => 12,
      IOSTANDARD => "LVCMOS33",
      SLEW => "FAST")
   port map (
      O => port2_sp(spnum),     -- Buffer output (connect directly to top-level port)
      I => port2_spo(spnum),     -- Buffer input
      T => port2_t(spnum)     -- 3-state enable input 
   );
   end generate;
	
port3_buff:
   for spnum in 0 to 3 generate
      begin
   ibuf3_sp : IBUF
   generic map (
      IOSTANDARD => "LVCMOS33")
   port map (
      O => port3_spi(spnum),     -- Buffer output
      I => port3_sp(spnum)      -- Buffer input (connect directly to top-level port)
   );
	
  obuf3_sp : OBUFT
   generic map (
      DRIVE => 12,
      IOSTANDARD => "LVCMOS33",
      SLEW => "FAST")
   port map (
      O => port3_sp(spnum),     -- Buffer output (connect directly to top-level port)
      I => port3_spo(spnum),     -- Buffer input
      T => port3_t(spnum)     -- 3-state enable input 
   );
   end generate;
	
port4_buff:
   for spnum in 0 to 3 generate
      begin
   ibuf4_sp : IBUF
   generic map (
      IOSTANDARD => "LVCMOS33")
   port map (
      O => port4_spi(spnum),     -- Buffer output
      I => port4_sp(spnum)      -- Buffer input (connect directly to top-level port)
   );
	
  obuf4_sp : OBUFT
   generic map (
      DRIVE => 12,
      IOSTANDARD => "LVCMOS33",
      SLEW => "FAST")
   port map (
      O => port4_sp(spnum),     -- Buffer output (connect directly to top-level port)
      I => port4_spo(spnum),     -- Buffer input
      T => port4_t(spnum)     -- 3-state enable input 
   );
   end generate;
layer_buff:
   for spnum in 0 to 3 generate
      begin
   layer_sp : IBUF
   generic map (
      IOSTANDARD => "LVCMOS33")
   port map (
      O => layer_spi(spnum),     -- Buffer output
      I => layer_sp(spnum)      -- Buffer input (connect directly to top-level port)
   );
	
  olayer_sp : OBUFT
   generic map (
      DRIVE => 12,
      IOSTANDARD => "LVCMOS33",
      SLEW => "FAST")
   port map (
      O => layer_sp(spnum),     -- Buffer output (connect directly to top-level port)
      I => layer_spo(spnum),     -- Buffer input
      T => layer_t(spnum)     -- 3-state enable input 
   );
   end generate;
		
end Behavioral;