-------------------------------------------------------------
-- MSS copyright 2010-2014
--	Filename:  GMII_MII_WRAPPER.VHD
-- Author: Alain Zarembowitch / MSS
--	Version: 4
--	Date last modified: 2/1/14
-- Inheritance: 	N/A
--
-- Use Case: this MII/GMII wrapper may need simple adjustments depending on the hardware platform.
-- (a) adjust RX_CLK delay so that the RX_CLK edges are clearly separated from the RXD data bits transitions
-- see RXC_DELAY constant below.
-- (b) Same for GTX_CLK
-- see TXC_DELAY constant below.
-- 
-- 
-- description:  Wrapper between the MAC and the PHY (GMII/MII interface) 
-- 10/100 Mbps: Complies with the MII interface specification in the 802.3 standard clause 22
-- 1000 Mbps:  Complies with the GMII interface specification in the 802.3 standard clause 35
-- Automatic detection of the rx speed.
-- 
-- IMPORTANT Key design assumption: PHY always generates a RX_CLK, even when no cable is connected.
--
-- Rev 2 11/18/11 AZ
-- Corrected bug in speed detection. (previous code assumed that CLK frequency was 125 MHz)
-- Reduced number of clocks from 2 (125 MHz reference clock from PHY, RX clock from PHY)
-- to just one (RX clock from PHY). The main reason is that a 125 MHz from the PHY may not be available or clean enough, 
-- nor is it absolutely necessary. Cleaner code. The fewer clocks the better.
-- Link status is no longer read here. Use generic status status register 1 instead (works for all PHYs)
--
-- Rev 3 8/8/12 AZ
-- Improved SPEED STATUS detection algorithm to cover the case when the PHY does not generate a clock (while in reset for example)
--
-- Rev 4 2/1/14 AZ
-- changed sensitivity lists to avoid warnings
---------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity GMII_MII_WRAPPER is
	generic (
		CLK_FREQUENCY: integer
			-- CLK frequency in MHz. Used as frequency reference for detecting PHY speed.
	);
    Port ( 
		--// CLK, RESET
		SYNC_RESET: in std_logic;
			-- block the GMII/MII output signals to the PHY during the PHY reset.
		CLK: in std_logic;
			-- USER-side GLOBAL CLOCK (used as time-reference only)
			-- Only used as frequency reference for detecting speed.
		
		--// PHY GMII/MII Interface ----------------------------------------------------------------
		-- Connect directly to FPGA pins
		TX_CLK: in std_logic;  
			-- MII tx clock from PHY. Continuous clock. (10/100 Mbps only) 
			-- 25 MHz (100 Mbps), or 2.5 MHz (10 Mbps) depending on speed
			-- accuracy: +/- 100ppm (MII)
			-- duty cycle between 35% and 65% inclusive (MII).
		GTX_CLK: out std_logic;  
			-- GMII tx clock to PHY. Continuous clock. 125MHz (1000 Mbps only)
			-- 2ns delay inside (user adjustable).
		TXD: out std_logic_vector(7 downto 0);  
			-- tx data (when TX_EN = '1' and TX_ER = '0') or special codes otherwise (carrier extend, 
			-- carrier extend error, transmit error propagation). See 802.3 table 35-1 for definitions.
		TX_EN: out std_logic;  
			-- 
		TX_ER: out std_logic;  
			-- to deliberately corrupt the contents of the frame (so as to be detected as such by the receiver)
		
		RX_CLK: in std_logic;  
			-- continuous receive reference clock recovered by the PHY from the received signal
			-- 125/25/2.5 MHz +/- 50 ppm. 
			-- Duty cycle better than 35%/65% (MII)
			-- 125 MHz must be delayed by 1.5 to 2.1 ns to prevent glitches (TBC. true for RGMII, but for GMII TOO???)
			
		RXD: in std_logic_vector(7 downto 0);  
			-- rx data. 8-bit when 1000 Mbps. 4-bit nibble (3:0) when 10/100 Mbps.
		RX_DV: in std_logic;  
		RX_ER: in std_logic;  
		CRS: in std_logic;  
			-- carrier sense
		COL: in std_logic;  
			-- collision detection
		
		--// MAC Interface ----------------------------------------------------------------
		
		-- Rx signals are synchronous with the rising edge of the RXCG_OUT clock 
		-- recovered by the PHY (could be 2.5/25/125 MHz)
		MAC_RXD: out std_logic_vector(7 downto 0);
			-- 8-bits of rx data
			-- read the above MAC_RX? signals at the rising edge of RXCG_OUT when MAC_RX_SAMPLE_CLK = '1'.
		MAC_RX_DV: out std_logic;
		MAC_RX_ER: out std_logic;
		MAC_RX_SAMPLE_CLK: out std_logic;
		RXCG_OUT: out std_logic;
			-- received clock (already a global clock, no need for any additional BUFG)
			-- 125 MHz (1000 Mbps), 25 MHz (100 Mbps) or 2.5 MHz (10 Mbps)
			
		-- Tx signals are synchronous with the rising edge of the TXCG_OUT clock 
		-- from the PHY (could be 2.5/25/125 MHz)
		MAC_TXD: in std_logic_vector(7 downto 0);
			-- 8-bits of tx data
			-- tx data (when MAC_TX_EN = '1' and MAC_TX_ER = '0') or special codes otherwise (carrier extend, 
			-- carrier extend error, transmit error propagation). See 802.3 table 35-1 for definitions.
		MAC_TX_EN: in std_logic;
			-- The MAC is responsible for holding the tx enable low until it has verified that it
			-- operates at the same speed as the PHY (as reported in the SPEED_STATUS)
		MAC_TX_ER: in std_logic;
			-- use (MAC_TX_EN, MAC_TX_ER) as follows:
			-- 0,0  = transmit complete
			-- 0,1 and MAC_TXD = 0x0F = carrier extend
			-- 0,1 and MAC_TXD = 0x1F = carrier extend error
			-- 1,0 = normal transmission
			-- 1,1 = transmit error
		MAC_TX_SAMPLE_CLK: in std_logic;
			-- 1-TXCG_OUT wide pulse. 
			-- read the above MAC_TX? signals at the rising edge of TXCG_OUT when MAC_TX_SAMPLE_CLK = '1'.
			-- Continuous '1' when the transmit speed is set at 1000 Mbps  
			-- 1-TXCG_OUT pulse once every (exactly) 2 TXCG_OUT when the transmit speed is set at 100 Mbps = 12.5 MHz
			-- 1-TXCG_OUT pulse once every (exactly) 2 TXCG_OUT when the transmit speed is set at 10 Mbps = 1.25 MHz
		TXCG_OUT: out std_logic;
			-- tx clock (already a global clock, no need for any additional BUFG)
			-- 125 MHz (1000 Mbps), 25 MHz (100 Mbps) or 2.5 MHz (10 Mbps)
			-- can be same as RXCG (1000 Mbps) or independent (10/100 Mbps)
			
		-- MAC monitoring and control
		MAC_TX_SPEED: in std_logic_vector(1 downto 0);
			-- 00/01/10  for 10/100/1000 Mbps transmit speed (not really a control, but this component
			-- needs to know what speed it should run at).
		MAC_CRS: out std_logic;  
			-- carrier sense. Directly from PHY over MII.
		MAC_COL: out std_logic;  
			-- collision detection. Directly from PHY over MII.
		
		--// PHY status
		SPEED_STATUS: out std_logic_vector(1 downto 0)
			-- Detected RX_CLK clock speed, 00 = 2.5 MHz, 01 = 25 MHz, 10 = 125 MHz, 11 = reserved
		
 );
end entity;

architecture Behavioral of GMII_MII_WRAPPER is
--------------------------------------------------------
--      COMPONENTS
--------------------------------------------------------
--------------------------------------------------------
--     SIGNALS
--------------------------------------------------------
constant RXC_DELAY: integer range 0 to 255 := 32;  -- adjust as needed. Here: 2ns
constant TXC_DELAY: integer range 0 to 255 := 32;  -- adjust as needed. Here: 2ns
--
signal RX_CLKB: std_logic;
signal RX_CLK_DELAYED: std_logic := '0';
signal RX_CLK2: std_logic;
signal RX_CLKG: std_logic := '0';	-- global clock, delayed 2ns w.r.t. received RXC.
signal RX_DV_D: std_logic;
signal RX_DV_D2: std_logic;
signal RX_ER_D: std_logic;
signal RXD_NIBBLE_TOGGLE: std_logic := '0';
signal RXD_D: std_logic_vector(7 downto 0) := (others => '0');

--// RXC clock frequency detection
signal RX_COUNTER1: std_logic_vector(7 downto 0) := (others => '0');
signal RX_COUNTER: std_logic_vector(8 downto 0) := (others => '0');
signal RX_COUNTER_FINAL: std_logic_vector(8 downto 0) := (others => '0');
signal RX_COUNTER_FINAL_D: std_logic_vector(8 downto 0) := (others => '0');
signal C1MSB: std_logic := '0';
signal C1MSB_D: std_logic := '0';
signal CMSB: std_logic := '0';
signal CMSB_D: std_logic := '0';
signal SPEED_STATUS_local: std_logic_vector(1 downto 0) := "00";

signal GMII_FLAG: std_logic := '0';
signal MAC_RX_ER_LOCAL: std_logic := '0';

signal TX_CLKG: std_logic := '0';	
signal MAC_TX_SAMPLE_CLK_D: std_logic := '0';	
signal MAC_TXD_D: std_logic_vector(7 downto 0);
signal MAC_TX_EN_D: std_logic;
signal MAC_TX_ER_D: std_logic;
signal TXD_NIBBLE_TOGGLE: std_logic;


--------------------------------------------------------
--      IMPLEMENTATION
--------------------------------------------------------
begin

--RGMII_EN <= not SYNC_RESET;
--  -- disable the RGMII outputs while the PHY is being reset.
--
---------------------------------------------
-- RECEIVE SECTION
---------------------------------------------

-- force IBUF or IBUFG selection (otherwise tools may select the wrong primitive)
-- Use IBUF if the signal is connected to a regular I/O pin.
-- Use IBUFG if the signal is connected to a global clock pin.
IBUF_001: IBUF port map( I => RX_CLK, O => RX_CLKB);

-- delay the RX clock by 2ns so that the clock is always slightly AFTER the signal transition.
   IODELAY2_001 : IODELAY2
   generic map (
      COUNTER_WRAPAROUND => "STAY_AT_LIMIT", -- STAY_AT_LIMIT or WRAPAROUND
      DATA_RATE => "SDR",                 -- SDR or DDR (???NOT SURE apply equal delay to the rising edge/falling edge)
 		DELAY_SRC => "IDATAIN",             -- IO, ODATAIN or IDATAIN (output is not delayed)
      IDELAY2_VALUE => 0,                 -- Amount of Input Delay (0-255) 
      IDELAY_MODE => "NORMAL",            -- Unsupported
      IDELAY_TYPE => "FIXED",             -- FIXED, DEFAULT, VARIABLE_FROM_ZERO, VARIABLE_FROM_HALF_MAX or
                                          -- DIFF_PHASE_DETECTOR
      IDELAY_VALUE => RXC_DELAY,          -- Amount of input delay (0-255) 
      ODELAY_VALUE => 0,                  -- Amount of output delay (0-255)
      SERDES_MODE => "NONE",              -- NONE, MASTER or SLAVE
      SIM_TAPDELAY_VALUE => 62            -- Amount of delay used for simulation in pS
   )
   port map (
		-- IOB interface
      IDATAIN => RX_CLKB,  	 		-- 1-bit Data Signal from IOB
		DOUT => open,  				-- Delayed signal to IOB
		TOUT => open,  	 			-- Delayed Tristate signal to IOB
		-- logic interface
		ODATAIN => '0', 				-- Data from OLOGIC or OSERDES.
		DATAOUT => RX_CLK_DELAYED,		-- Delayed data to D pin of ILOGIC2 or ISERDES2
		T => '0',              		-- Tristate control signal (input/output flow selection)
		DATAOUT2 => open, 	 		-- Secondary delayed data output. Unused.
		-- m&c
		CAL => '0',						-- Initiate calibration command
		BUSY => open,         		-- Busy after CAL. Unused.  Just for test purposes.
      CE => '0',            		-- 1-bit Enable increment/decrement
      CLK => '0',           		-- 1-bit Clock input. FIXED delay mode. no clock needed.
      INC => '0',           		-- 1-bit Increment / Decrement input
      IOCLK0 => '0',			 		-- 
		IOCLK1 => '0',	 				-- secondary clock input/frequency doubler.
		RST => '0'     				-- Reset to zero or 1/2 of total period
 );

BUFIO2_inst : BUFIO2
generic map (
	DIVIDE => 1,           -- DIVCLK divider (1-8)
	DIVIDE_BYPASS => TRUE, -- Bypass the divider circuitry (TRUE/FALSE)
	I_INVERT => FALSE,     -- Invert clock (TRUE/FALSE)
	USE_DOUBLER => FALSE   -- Use doubler circuitry (TRUE/FALSE)
)
port map (
	DIVCLK => RX_CLK2,             -- 1-bit output Divided clock output
	IOCLK => open,               -- 1-bit output I/O output clock
	SERDESSTROBE => open, -- 1-bit output Output SERDES strobe (connect to ISERDES2/OSERDES2)
	I => RX_CLK_DELAYED                        -- 1-bit input Clock input (connect to IBUFG)
);


-- declare the RX clock as a global clock
BUFG_001 : BUFG port map (
	O => RX_CLKG,     -- Clock buffer output
	I => RX_CLK2      -- Clock buffer input
);


-- immediately reclock rx input signals 
RECLOCK_RX_001: process(RX_CLKG)
begin
	if rising_edge(RX_CLKG) then
		RXD_D <= RXD;
		RX_DV_D <= RX_DV;
		RX_ER_D <= RX_ER;
	end if;
end process;

-- re-assemble 8-bit rx data (from 4-bit nibbles at 10/100 Mbps)
RX8B_001: process(RX_CLKG)
begin
	if rising_edge(RX_CLKG) then
		RX_DV_D2 <= RX_DV_D;
		
		if(SPEED_STATUS_local(1) = '0') and (RX_DV_D = '1') and (RX_DV_D2 = '0') then
			-- 10/100 Mbps. Start of new packet. Reset toggle
			RXD_NIBBLE_TOGGLE <= '1';
		else
			RXD_NIBBLE_TOGGLE <= not RXD_NIBBLE_TOGGLE;
		end if;
	end if;
end process;

MAX_RX_OUT_001: process(RX_CLKG)
begin
	if rising_edge(RX_CLKG) then
		MAC_CRS <= CRS;
		MAC_COL <= COL;
		
		if(SPEED_STATUS_local = "10") then
			-- 1000 Mbps
			MAC_RXD <= RXD_D;
			MAC_RX_DV <= RX_DV_D; 
			MAC_RX_ER_LOCAL <= RX_ER_D; 
			MAC_RX_SAMPLE_CLK <= '1';
		elsif(SPEED_STATUS_local(1) = '0') and (RX_DV_D = '1') and (RX_DV_D2 = '0') then
			-- start of new packet. Reset toggle
			MAC_RXD(3 downto 0) <= RXD_D(3 downto 0);
			MAC_RX_DV <= RX_DV_D; 
			MAC_RX_ER_LOCAL <= RX_ER_D; 
			MAC_RX_SAMPLE_CLK <= '0';  -- waiting for the other half
		elsif(SPEED_STATUS_local(1) = '0') and (RXD_NIBBLE_TOGGLE = '0') then
			-- 1st nibble (1/2)
			MAC_RXD(3 downto 0) <= RXD_D(3 downto 0);
			MAC_RX_DV <= RX_DV_D; 
			MAC_RX_ER_LOCAL <= RX_ER_D; 
			MAC_RX_SAMPLE_CLK <= '0';  -- waiting for the other half
		elsif(SPEED_STATUS_local(1) = '0') and (RXD_NIBBLE_TOGGLE = '1') then
			-- 2nd nibble (2/2)
			MAC_RXD(7 downto 4) <= RXD_D(3 downto 0);
			MAC_RX_SAMPLE_CLK <= '1';  -- got a complete byte
			MAC_RX_ER_LOCAL <= MAC_RX_ER_LOCAL or RX_ER_D;  -- RX_ER can be as short as one RX_CLKG.
		else
			MAC_RX_SAMPLE_CLK <= '0';  
		end if;
	end if;
end process;

-- outputs to MAC
RXCG_OUT <= RX_CLKG;
MAC_RX_ER <= MAC_RX_ER_LOCAL;

--// RX_SPEED AUTODETECT ------------------------------------------
-- Automatically detect rx speed based on the RX_CLK.
-- Algorithm: two counters, one based the variable frequency clock (RX_CLKG), the other
-- based on the CLK user-supplied clock.

DETECT_RX_SPEED_001: process(CLK)
begin
	if rising_edge(CLK) then
		if(SYNC_RESET = '1') then
			RX_COUNTER1 <= (others => '0');
		else
			-- modulo 256 counter
			RX_COUNTER1 <= RX_COUNTER1 + 1;
			C1MSB_D <= C1MSB;
			if(C1MSB_D = '0') and (C1MSB = '1') then
				-- middle of the counter period. resample RX_COUNTER_FINAL when stable.
				RX_COUNTER_FINAL_D <= RX_COUNTER_FINAL;
			end if;

			-- 256*125/CLK_FREQUENCY when 1000Mbps rx mode (RXCG is 125 MHz)
			-- 256*25/CLK_FREQUENCY when 100Mbps rx mode (RXCG is 25 MHz)
			-- 256*2.5/CLK_FREQUENCY when 10Mbps rx mode (RXCG is 2.5 MHz)
			if(RX_COUNTER_FINAL_D > (256*125/(2*CLK_FREQUENCY))) then
				-- 1000Mbps rx mode (125 MHz detected)
				SPEED_STATUS_LOCAL <= "10";
			elsif(RX_COUNTER_FINAL_D > (256*25/(2*CLK_FREQUENCY))) then 
				-- 100Mbps rx mode (25 MHz detected)
				SPEED_STATUS_LOCAL <= "01";
			elsif(RX_COUNTER_FINAL_D > 2) then 
				-- 10Mbps rx mode (2.5 MHz detected)
				SPEED_STATUS_LOCAL <= "00";
			else
				SPEED_STATUS_LOCAL <= "11";	-- undefined (includes the case with no PHY clock RXCG)
			end if;

		end if;
	end if;
end process;
C1MSB <= RX_COUNTER1(7);

DETECT_RX_SPEED_002: process(RX_CLKG)
begin
	if rising_edge(RX_CLKG) then		
		CMSB <= RX_COUNTER1(7);
		CMSB_D <= CMSB;
		if(SYNC_RESET = '1') then
			RX_COUNTER <= (others => '0');
		elsif(CMSB_D = '1') and (CMSB = '0') then
			-- end of counting period. 
			RX_COUNTER_FINAL <= RX_COUNTER;	-- freeze final count
			RX_COUNTER <= (others => '0');	-- start new count
		else
			RX_COUNTER <= RX_COUNTER + 1;
		end if;
	end if;
end process;

GMII_FLAG <= '1' when SPEED_STATUS_local = "10" else '0';

-- report rx speed to MAC
SPEED_STATUS <= SPEED_STATUS_local;

---------------------------------------------
-- TRANSMIT SECTION
---------------------------------------------
-- two cases: @1000 Mbps (GMII), the GTX_CLK is an output . At 10/100Mbps (MII), the TX_CLK in an input.

-- In the 1000Mbps mode, we must provide a 125 MHz GTX_CLK to the PHY. Make tx clock <= rx clock frequency. 
-- In the 10/100 Mbps mode, the TX_CLKG clock is generated by the PHY (may drift w.r.t rx clock frequency)
-- IMPORTANT Key design assumption: PHY always generates a RX_CLK, even when no cable is connected.


BUFGMUX_inst : BUFGMUX
generic map (
	CLK_SEL_TYPE => "SYNC"  -- Glitchless ("SYNC") or fast ("ASYNC") clock switch-over
)
port map (
	O => TX_CLKG,   -- 1-bit output: Clock buffer output
	I0 => TX_CLK, -- 1-bit input: Clock buffer input (S=0)
	I1 => RX_CLKG, -- 1-bit input: Clock buffer input (S=1)
	S => GMII_FLAG    -- 1-bit input: Clock buffer select
);

-- outputs to MAC
TXCG_OUT <= TX_CLKG;

-- Reclock TX signals so that they are stable during the entire period 
RECLOCK_005: process(TX_CLKG)
begin
	if rising_edge(TX_CLKG) then
		MAC_TX_SAMPLE_CLK_D <= MAC_TX_SAMPLE_CLK;
		
		if(SYNC_RESET = '1') then
			MAC_TXD_D <= (others => '0');
			MAC_TX_EN_D <= '0';
			MAC_TX_ER_D <= '0';
			TXD_NIBBLE_TOGGLE <= '0';
		elsif (MAC_TX_SAMPLE_CLK = '1') then
			MAC_TXD_D <= MAC_TXD;
			MAC_TX_EN_D <= MAC_TX_EN;
			MAC_TX_ER_D <= MAC_TX_ER;
			TXD_NIBBLE_TOGGLE <= '0';  -- point to lower nibble (3:0) first
		elsif(MAC_TX_SPEED(1) = '0') and (MAC_TX_SAMPLE_CLK_D = '1') then  -- 10/100 Mbps
			-- read another nibble. toggle upper/lower nibble pointer
			TXD_NIBBLE_TOGGLE <= not TXD_NIBBLE_TOGGLE;
		end if;
	end if;
end process;

TXD_OUTPUT_001: process(TX_CLKG)
begin
	if rising_edge(TX_CLKG) then
		if(SYNC_RESET = '1') then
			-- disable all outputs while the component is being reset.
			TXD <= (others => '0');
			TX_EN <= '0';
			TX_ER <= '0';
		elsif(MAC_TX_SPEED(1) = '0') then  -- 10/100 Mbps
			if(TXD_NIBBLE_TOGGLE = '0') then
				-- lower nibble (3:0)
				TXD <= MAC_TXD_D(3 downto 0) & MAC_TXD_D(3 downto 0);  -- data
			else
				TXD <= MAC_TXD_D(7 downto 4) & MAC_TXD_D(7 downto 4);  -- data
			end if;
			TX_EN <= MAC_TX_EN_D;
			TX_ER <= MAC_TX_ER_D;
		elsif(MAC_TX_SPEED = "10") then  -- 1000 Mbps
			TXD <= MAC_TXD_D;  -- data
			TX_EN <= MAC_TX_EN_D;
			TX_ER <= MAC_TX_ER_D;
		end if;
	end if;
end process;


-- delay the GTX_CLK clock by 2ns so that the clock is always slightly AFTER the signal transition.
   -- IODELAY2: Input and Output Fixed or Variable Delay Element
   --           Spartan-6
   -- Xilinx HDL Language Template, version 11.4

   IODELAY2_002 : IODELAY2
   generic map (
      COUNTER_WRAPAROUND => "STAY_AT_LIMIT", -- STAY_AT_LIMIT or WRAPAROUND
      DATA_RATE => "SDR",                 -- SDR or DDR (???NOT SURE. apply equal delay to the rising edge/falling edge)
      DELAY_SRC => "ODATAIN",             -- IO, ODATAIN or IDATAIN
      IDELAY2_VALUE => 0,                 -- Amount of Input Delay (0-255) 
      IDELAY_MODE => "NORMAL",            -- Unsupported
      IDELAY_TYPE => "FIXED",             -- FIXED, DEFAULT, VARIABLE_FROM_ZERO, VARIABLE_FROM_HALF_MAX or
                                          -- DIFF_PHASE_DETECTOR
      IDELAY_VALUE => 0,          			-- Amount of input delay (0-255) 
      ODELAY_VALUE => TXC_DELAY,          -- Amount of output delay (0-255)
      SERDES_MODE => "NONE",              -- NONE, MASTER or SLAVE
      SIM_TAPDELAY_VALUE => 62            -- Amount of delay used for simulation in pS
   )
   port map (
      BUSY => open,         -- 1-bit Busy after CAL
      DATAOUT => open,   	 -- 1-bit Delayed data output
      DATAOUT2 => open, 	 -- 1-bit Delayed data output
      DOUT => GTX_CLK,      -- 1-bit Delayed Data Output to IOB
      TOUT => open,         -- 1-bit Delayed Tristate Output
      CAL => '0',           -- 1-bit Initiate calibration input
      CE => '0',            -- 1-bit Enable increment/decrement
      CLK => '0',           -- 1-bit Clock input. FIXED delay mode. no clock needed.
      IDATAIN => '0',  	 	 -- 1-bit Data Signal from IOB
      INC => '0',           -- 1-bit Increment / Decrement input
      -- IOCLK0 - IOCLK1: 1-bit (each) I/O Clock inputs
      IOCLK0 => '0',			 -- 
      IOCLK1 => '0',
      ODATAIN => TX_CLKG,   	 -- 1-bit Output data input from OLOGIC or OSERDES.
      RST => '0',    -- 1-bit Reset to zero or 1/2 of total period
      T => '0'              -- 1-bit Tristate input signal
   );


end Behavioral;

