-------------------------------------------------------------
-- MSS copyright 2016-2019
-- Filename:  COM1827_TOP.VHD
-- Authors: 
--		Alain Zarembowitch / MSS
-- Version: Rev 001n
-- Last modified: 4/17/19
-- Inheritance: 	com-1527 FSK modem 001k , COM-5401, COM-5402
--
-- description:  Top level for COM-1827 CPM modem
-- Two FEC schemes are supported: external turbo-code codec or internal convolutional FEC.
-- (See TC_CONVN_CODEC parameter).
--
-- Xilinx Vivado Synthesis settings: "keep equivalent registers" + "resource sharing off"
---------------------------------------------------------------
-- TEST TEST TEST FOR 4004 ON LEFT CONNECTOR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-- DISCARD AFTER TEST
---------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.com5402pkg.all;	-- defines global types, number of TCP streams, etc
Library UNISIM;
use UNISIM.vcomponents.all;

entity COM1827_TOP is
	generic (
--       OPTION: std_logic_vector(7 downto 0) := x"41";    -- 'A' right connector: to 2*12bit DAC, COM-2001 compatible, left connector 2*12-bit input, COM-30XX compatible
--       OPTION: std_logic_vector(7 downto 0) := x"42";    -- 'B' right connector: 2*12-bit input, COM-30XX compatible, left connector serial demod output bit streams
--       OPTION: std_logic_vector(7 downto 0) := x"43";    -- 'C' right connector: dual DAC/ADCs, COM-3504 compatible, left connector synchronous serial modem input and output bit streams
--       OPTION: std_logic_vector(7 downto 0) := x"44";    -- 'D' right connector: 2*16-bit output samples. COM-4009 compatible, left connector 2*12-bit input, COM-30XX compatible
       OPTION: std_logic_vector(7 downto 0) := x"45";    -- 'E' right connector: 2*14-bit output samples. COM-4004 compatible, left connector 2*12-bit input, COM-30XX compatible
--       OPTION: std_logic_vector(7 downto 0) := x"46";    -- 'F' right connector: 2*16-bit output samples. COM-4009 compatible, left connector synchronous serial modem input
		REVISION: std_logic_vector(7 downto 0) := x"31";    -- '0'
			--// FPGA option and revision (ASCII format '0' = x30, 'A' = x41)
			-- These two ASCII characters appear in the Comblock Control Center.
			-- Helpful in identifying which firmware version is currently running in the FPGA. 
			-- Select internal vs external frequency reference option. 
			-- REMINDER: do change the .xdc file according to the option selection -A through -F
		MODULATOR_EN: std_logic := '1';
			-- instantiate (1)/do not instantiate (0) a built-in modulator
		DEMODULATOR_EN: std_logic := '0';
			-- instantiate (1)/do not instantiate (0) a built-in demodulator
		AWGN_EN: std_logic := '1';
			-- additive white Gaussian noise. Usually disabled to save space in FPGA
		TC_CONVN_CODEC: std_logic := '0';   
			-- '1' for Turbo code codec, '0' for convolutional codec
		SIMULATION: std_logic := '0'
		-- 1 during simulation, 0 for release	
	);
    Port ( 
		--GLOBAL CLOCKS
	   CLKREF_TCXO : in std_logic;	
			-- 19.2MHz reference clock. Generated by the VCTCXO on this board.
		CLKREF_EXT: in std_logic;
			-- external (higher-stability) frequency reference via J9 SMA connector ("EXT REF")

		--// GbE LAN. 
		-- connects to RGMII PHY (Micrel KSZ9031)
		LAN_TXC: out std_logic;  -- tx clock
		LAN_TXD: out std_logic_vector(3 downto 0);  -- tx data
		LAN_TX_CTL: out std_logic;  -- tx control: combines TX_EN and TX_ER
			-- valid at the falling clock edge
		LAN_RXC: in std_logic;  -- receive clock
			-- must be delayed by 1.5 to 2.1 ns to prevent glitches
			-- Set the strapping options in the .xdc constraint file.
		LAN_RXD: in std_logic_vector(3 downto 0);  
			-- receive data
			-- Set the strapping options in the .xdc constraint file.
		LAN_RX_CTL: in std_logic;  -- receive control. combines RX_DV and RX_ER
			-- valid at the falling clock edge
			-- Note: Micrel KSZ9021RN PHY defines these as dual-function signals.
			-- Set the strapping options in the .xdc constraint file.
		LAN_RESET_N: out std_logic;
			-- PHY reset
		LAN_MCLK: out std_logic;
		LAN_MDIO: inout std_logic;  -- (tri-state)
		LAN_CLK125: in std_logic;   -- optional 125 MHz from PHY
		LAN_INT_N: in std_logic;    -- unused interrupt
        
		--// Left connector, 98 pin PCIe female connector. 
		-- Pins B5,B20,B31,B42 reserved for Ground
		-- Pins A49/B49 reserved for ComBlock Monitoring and Control.
		-- Place B13 in high-impedance when using the 12-bit DAC or vice versa.
		LCA1: in std_logic;
		LCB1: in std_logic;
		LEFT_CONNECTOR_A: inout std_logic_vector(26 downto 2);
		LEFT_CONNECTOR_B1: inout std_logic_vector(4 downto 2);
		LEFT_CONNECTOR_B2: inout std_logic_vector(16 downto 6);

		--// Right connector: 98 pin PCIe female connector.   
		-- Pins B5,B20,B31,B42 reserved for Ground
		-- Pins A49/B49 reserved for ComBlock Monitoring and Control.
		-- Connector pins A39 - A48, B40,B41,B43-B48 can be used by 
		-- re-routing LEFT_CONNECTOR signals using a resistor array (requires soldering)
		-- See schematics for details.
		RIGHT_CONNECTOR_A: inout std_logic_vector(38 downto 1);
		RIGHT_CONNECTOR_B1: inout std_logic_vector(4 downto 1);
		RIGHT_CONNECTOR_B2: inout std_logic_vector(19 downto 6);
		RIGHT_CONNECTOR_B3: inout std_logic_vector(30 downto 21);
		RIGHT_CONNECTOR_B4: inout std_logic_vector(39 downto 32);

		--// DAC AD5621 IC interface (receiver AGC, drives LEFT_CONNECTOR_B2(13) unless in high impedance)
		DAC_SYNC_B: out std_logic;
		DAC_SCLK: out std_logic;
		DAC_SDIN: out std_logic;

		--// Monitoring & Control: ARM Cortex M3 microcontroller interface
		-- asynchronous bus (shared with NAND flash)
		-- set address at the rising edge of UC_WEB_IN when UC_CSIB_IN = '0' and UC_ALE_IN = '1'
		-- write data the rising edge of UC_WEB_IN when UC_CSIB_IN = '0'
		-- read data when  UC_CSIB_IN = '0' and UC_REB_IN = '0'
		UC_CSIB_IN: in std_logic;  -- chip select. active low.
		UC_ALE_IN: in std_logic;  -- address latch enable. active high.
		UC_REB_IN: in std_logic;  -- read enable #
		UC_WEB_IN: in std_logic;	-- write enable #
		UC_AD: inout std_logic_vector(7 downto 0)  -- shared address/data bus

		  
			  );
end entity;

architecture Behavioral of COM1827_TOP is
--------------------------------------------------------
--      COMPONENTS
--------------------------------------------------------
-- Comment in/out components/drivers as needed
	COMPONENT CLKGEN7_MMCM_ADJ
	GENERIC (
		CLKFBOUT_MULT_F: real;
		CLKOUT0_DIVIDE_F: real;
		CLKIN1_PERIOD: real
    );    
    PORT(
		CLK_IN1 : IN std_logic;
		CLK_OUT1 : OUT std_logic;
		PHASE_SHIFT_VAL: in std_logic_vector(7 downto 0);
		PHASE_SHIFT_TRIGGER_TOGGLE: in std_logic;
		INPUT_CLK_STOPPED : OUT std_logic;
		LOCKED : OUT std_logic;
		TP: OUT std_logic_vector(10 downto 1)
        );
    END COMPONENT;

	COMPONENT CLKGEN7_MMCM_DYNAMIC is
	GENERIC (
      CLKIN1_PERIOD: real;
		CLK_OUT2_PHASE: real
    );    
	PORT(
      CLK_IN1           : in     std_logic;
      SYNC_RESET           : in     std_logic;
      M: in std_logic_vector(9 downto 0);   
      D: in std_logic_vector(6 downto 0);
      O: in std_logic_vector(10 downto 0);
      PROGRAM: in std_logic;
      CLK_OUT1          : out    std_logic;
      CLK_OUT2          : out    std_logic;
      INPUT_CLK_STOPPED : out    std_logic;
      LOCKED            : out    std_logic
     );
	END COMPONENT;

	COMPONENT BRAM_DP2
	GENERIC(
		DATA_WIDTHA: integer;
		ADDR_WIDTHA: integer;
		DATA_WIDTHB: integer;
		ADDR_WIDTHB: integer
	);
	PORT(
		CLKA   : in  std_logic;
		CSA: in std_logic;	
		WEA    : in  std_logic;	
		OEA : in std_logic;	
		ADDRA  : in  std_logic_vector(ADDR_WIDTHA-1 downto 0);
		DIA   : in  std_logic_vector(DATA_WIDTHA-1 downto 0);
		DOA  : out std_logic_vector(DATA_WIDTHA-1 downto 0);
		CLKB   : in  std_logic;
		CSB: in std_logic;	-- chip select, active high
		WEB    : in  std_logic;	-- write enable, active high
		OEB : in std_logic;	-- output enable, active high
		ADDRB  : in  std_logic_vector(ADDR_WIDTHB-1 downto 0);
		DIB   : in  std_logic_vector(DATA_WIDTHB-1 downto 0);
		DOB  : out std_logic_vector(DATA_WIDTHB-1 downto 0)
		);
	END COMPONENT;

	COMPONENT TIMER_4US
	GENERIC (
		CLK_FREQUENCY: integer 
	);
	PORT(
		CLK : IN std_logic;          
		SYNC_RESET : IN std_logic;
		TICK_4US : OUT std_logic;
		TICK_100MS: out std_logic
		);
	END COMPONENT;

	COMPONENT CROSS_CLK_DOMAINS_NODATALOSS
	Generic (
		DATA_WIDTH: integer;
		ADDR_WIDTH: integer;
		LOW_LATENCY: std_logic	
	);
	PORT(
		CLK_A : IN std_logic;
		CLK_B : IN std_logic;
		ASYNC_RESET : IN std_logic;
		DATA_IN : IN std_logic_vector(DATA_WIDTH-1 downto 0);
		SAMPLE_CLK_IN : IN std_logic;
		SOF_IN : IN std_logic;
		EOF_IN : IN std_logic;
		SAMPLE_CLK_OUT_REQ : IN std_logic;          
		SAMPLE_CLK_IN_REQ : OUT std_logic;
		DATA_OUT : OUT std_logic_vector(DATA_WIDTH-1 downto 0);
		SAMPLE_CLK_OUT : OUT std_logic;
		SOF_OUT : OUT std_logic;
		EOF_OUT : OUT std_logic
		);
	END COMPONENT;

	COMPONENT DAC_AD5621
	generic (
		CLK_FREQUENCY: integer 
	);
	PORT(
		CLK : IN std_logic;
		DATA_IN : IN std_logic_vector(11 downto 0);
		DATA_IN_CLK : IN std_logic;
		OP_MODE : IN std_logic_vector(1 downto 0);          
		DONE : OUT std_logic;
		SYNC_B : OUT std_logic;
		SCLK : OUT std_logic;
		SDIN : OUT std_logic
		);
	END COMPONENT;

	COMPONENT PWM2
	generic (
		NBITS: integer 
	);
	PORT(
		CLK : IN std_logic;
		INPUT : IN std_logic_vector(NBITS-1 downto 0);
		INPUT_SAMPLE_CLK : IN std_logic;          
		OUTPUT : OUT std_logic
		);
	END COMPONENT;

	COMPONENT COM1827_RX
	GENERIC (
		BER_EN: std_logic;
		SIMULATION: std_logic
	);
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		ADC_DATA_I_IN : IN std_logic_vector(15 downto 0);
		ADC_DATA_Q_IN : IN std_logic_vector(15 downto 0);
		ADC_SAMPLE_CLK_IN : IN std_logic;
		AGC_RESPONSE : IN std_logic_vector(4 downto 0);
		RECEIVER_CENTER_FREQ : IN std_logic_vector(31 downto 0);
	   CIC_R: in std_logic_vector(15 downto 0);    
		NOMINAL_SYMBOL_RATE: in std_logic_vector(31 downto 0);
		M_SEL: in std_logic_vector(2 downto 0);
		FILT_SEL: in std_logic_vector(3 downto 0);
		MODULATION_INDEX: in std_logic_vector(15 downto 0);
		FRAME_LENGTH: in std_logic_vector(12 downto 0);
		DEMOD_CONTROL : IN std_logic_vector(15 downto 0);
		AGC_DAC : OUT std_logic_vector(11 downto 0);
		AGC_DAC_SAMPLE_CLK : OUT std_logic;
		DATA_OUT: out std_logic_vector(3 downto 0);
		SAMPLE_CLK_OUT: out std_logic;
		AFC_LOCK_OUT: out std_logic;
		CARRIER_LOCK_OUT : OUT std_logic;
		SIGNAL_PRESENT_OUT: OUT std_logic;
		CARRIER_FREQUENCY_ERROR : OUT std_logic_vector(31 downto 0);
		POWER_S_AVERAGE_OUT : OUT std_logic_vector(17 downto 0);
		POWER_N_AVERAGE_OUT : OUT std_logic_vector(17 downto 0);
		SNR_LOCKED_OUT : OUT std_logic_vector(17 downto 0);
		BER_SYNC : OUT std_logic;
		BER_ERROR_COUNT : OUT std_logic_vector(31 downto 0);
		BYTE_ERROR : OUT std_logic;
		CS0 : OUT std_logic_vector(7 downto 0);
		CS0_CLK : OUT std_logic;
		CS1 : OUT std_logic_vector(7 downto 0);
		CS1_CLK : OUT std_logic;
		CS2 : OUT std_logic_vector(7 downto 0);
		CS2_CLK : OUT std_logic;
		CS3 : OUT std_logic_vector(7 downto 0);
		CS3_CLK : OUT std_logic;
		CS4 : OUT std_logic_vector(7 downto 0);
		CS4_CLK : OUT std_logic;
		CS5 : OUT std_logic_vector(7 downto 0);
		CS5_CLK : OUT std_logic;
		CS6 : OUT std_logic_vector(7 downto 0);
		CS6_CLK : OUT std_logic;
		CS7 : OUT std_logic_vector(7 downto 0);
		CS7_CLK : OUT std_logic;
		CS8 : OUT std_logic_vector(7 downto 0);
		CS8_CLK : OUT std_logic;
		CS9 : OUT std_logic_vector(7 downto 0);
		CS9_CLK : OUT std_logic;
		CS10 : OUT std_logic_vector(7 downto 0);
		CS10_CLK : OUT std_logic;
		CS11 : OUT std_logic_vector(7 downto 0);
		CS11_CLK : OUT std_logic;
		T1 : OUT std_logic;
		T1_CLK : OUT std_logic;
		T2 : OUT std_logic;
		T2_CLK : OUT std_logic;
		TP : OUT std_logic_vector(20 downto 1)
		);
	END COMPONENT;

   COMPONENT VITERBI_DECODER
	GENERIC(
		K_MAX: integer;	
		N_PARITY_BITS_MAX: integer;
		NDEC: integer;  
		HARD_SOFTN_DECISION: std_logic;
		TB_DEPTH: integer;	
		SIMULATION: std_logic
	);
   PORT(
		CLK : IN  std_logic;
		SYNC_RESET : IN  std_logic;
		DATAIN: in std_logic_vector(31 downto 0);
		DATAIN_VALID : IN  std_logic;
		DATAIN_READY : OUT  std_logic;
		SKIP1BIT_PULSE: in std_logic;
		G: in std_logic_vector(62 downto 0);  
		N_PARITY_BITS: in integer range 2 to 7;
		K: in integer range 3 to 9;
		R1: in integer range 1 to 7;
		R2: in integer range 2 to 8;
		STANDARD: in integer range 0 to 2;
		DIFF_ENC_ON: in std_logic;
		HIGH_SNR: in std_logic;
        FEC_G1_INVERSION: in std_logic;
		DATAOUT1b: out std_logic;
		DATAOUT1b_VALID: out std_logic;
		DATAOUT8b: out std_logic_vector(7 downto 0);
		DATAOUT8b_VALID: out std_logic;
		BER: out std_logic_vector(23 downto 0);
		BER_VALID : OUT  std_logic;
		BIT_ERROR: out std_logic;
		IN_SYNC: out std_logic;
		OUT_OF_SYNC : OUT  std_logic;
		LOCK_STATUS: out std_logic
        );
    END COMPONENT;

    component SOF_SYNC is
    port (
        CLK: in std_logic;	
        ASYNC_RESET: in  std_logic;
        DATA_IN: in std_logic_vector(3 downto 0);     
        BIT_CLK_IN: in std_logic;
        FRAME_LENGTH: in std_logic_vector(12 downto 0);
        BIT_CLK_OUT: out std_logic;
        SOF: out std_logic;
        SOF_LOCK_DETECT: out std_logic;
        PHASE: out std_logic_vector(1 downto 0);
        DATA_ENABLE: out std_logic;
        DATA_OUT: out std_logic_vector(3 downto 0);
        BER: out std_logic_vector(16 downto 0);
        TP_MRC_SOF: out std_logic_vector(3 downto 0)
        );
 end component;

	COMPONENT TC_DECODER_DVB_RCS2
	generic (
		NQBITS: integer range 3 to 8;
		NADDRBITS: integer range 5 to 10;
		SIMULATION: std_logic
	);
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		DATA_A_IN: in std_logic_vector((NQBITS-1) downto 0);
		DATA_B_IN: in std_logic_vector((NQBITS-1) downto 0);
		DATA_IN_VALID : IN std_logic;
		SOF_IN : IN std_logic;
		EOF_IN: in std_logic;
		BURST_PAYLOAD_SIZE: in std_logic_vector((NADDRBITS-1) downto 0);
		P : IN std_logic_vector(6 downto 0);
		Q0 : IN std_logic_vector(3 downto 0);
		Q1 : IN std_logic_vector(3 downto 0);
		Q2 : IN std_logic_vector(3 downto 0);
		Q3 : IN std_logic_vector(2 downto 0);
		Y_PUNCTURING_PERIOD : IN std_logic_vector(4 downto 0);
		Y_PUNCTURING_PATTERN : IN std_logic_vector(27 downto 0);
		W_PUNCTURING_PATTERN : IN std_logic;
		N_ITER: in std_logic_vector(3 downto 0);
		CRC16_EN: in std_logic;
		CTS_IN : IN std_logic;          
		CTS_OUT : OUT std_logic;
		DATA_OUT : OUT std_logic_vector(1 downto 0);
		DATA_OUT_VALID : OUT std_logic;
		SOF_OUT : OUT std_logic;
		CRC_VALID: out std_logic;
		BAD_CRC: out std_logic;
		FRAME_CNTR: out std_logic_vector(31 downto 0);
		FRAME_ERROR_CNTR: out std_logic_vector(31 downto 0)
		);
	END COMPONENT;

	COMPONENT BER2
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		DATA_IN : IN std_logic_vector(7 downto 0);
		SAMPLE_CLK_IN : IN std_logic;
		CONTROL : IN std_logic_vector(7 downto 0);          
		MF_DETECT : OUT std_logic;
		MF_DETECT_CONFIRMED : OUT std_logic;
		SYNC_LOCK : OUT std_logic;
		BYTE_ERROR : OUT std_logic;
		DATA_REPLICA : OUT std_logic_vector(7 downto 0);
		SAMPLE_CLK_OUT : OUT std_logic;
		BER : OUT std_logic_vector(31 downto 0);
		BER_SAMPLE_CLK : OUT std_logic;
		TP : OUT std_logic_vector(10 downto 1)
		);
	END COMPONENT;

	COMPONENT CLEAN_CLK2
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		CLK_PULSE_IN : IN std_logic;          
		CLK_50DUTY_OUT : OUT std_logic;
		CLK_PULSE_OUT : OUT std_logic;
		ERROR: out std_logic
		);
	END COMPONENT;

	COMPONENT STREAM_2_PACKETS2
	GENERIC (
		NBUFS: integer;
		TIMEOUT: integer range 1 to 262144;
		MAX_PACKET_SIZE: std_logic_vector(13 downto 0);
		SIMULATION: std_logic
	);
	PORT(
		SYNC_RESET : IN std_logic;
		CLK : IN std_logic;
		TICK_4us : IN std_logic;
		DATA_IN : IN std_logic_vector(7 downto 0);
		DATA_VALID_IN : IN std_logic;
		PREAMBLE_IN : IN std_logic_vector(111 downto 0);
		CTS_IN : IN std_logic;
		ACK_IN : IN std_logic;
		NAK_IN : IN std_logic;          
		RTS_OUT: out std_logic;	
		CTS_OUT : OUT std_logic;
		PACKET_TX_PULSE : OUT std_logic;
		DATA_OUT : OUT std_logic_vector(7 downto 0);
		DATA_VALID_OUT : OUT std_logic;
		SOF_OUT : OUT std_logic;
		EOF_OUT : OUT std_logic;
		TP : OUT std_logic_vector(10 downto 1)
		);
	END COMPONENT;

	COMPONENT COM5401
	GENERIC (
		MII_SEL: std_logic;  
		PHY_ADDR: std_logic_vector(4 downto 0);
		CLK_FREQUENCY: integer; 
		PLATFORM: integer;
		TARGET_PHY: integer;
		NO_1000: std_logic;	
		INTERNAL_PHY_TX_CLKS_DELAYS: std_logic;
		INTERNAL_PHY_RX_CLKS_DELAYS: std_logic;
		SIMULATION: std_logic
	);
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		CLK125_0: in std_logic;
		CLK125_1: in std_logic;
		CLK25: in std_logic;	
		MAC_TX_CONFIG : IN std_logic_vector(15 downto 0);
		MAC_RX_CONFIG : IN std_logic_vector(15 downto 0);
		MAC_ADDR : IN std_logic_vector(47 downto 0);
		PHY_CONFIG_CHANGE : IN std_logic;
		PHY_RESET : IN std_logic;
		SPEED : IN std_logic_vector(1 downto 0);
		DUPLEX : IN std_logic;
		TEST_MODE : IN std_logic_vector(1 downto 0);
		POWER_DOWN : IN std_logic;
		CLK_SKEW1: in std_logic_vector(15 downto 0);
		CLK_SKEW2: in std_logic_vector(15 downto 0);
		MAC_TX_DATA : IN std_logic_vector(7 downto 0);
		MAC_TX_DATA_VALID : IN std_logic;
		MAC_TX_EOF : IN std_logic;
		MAC_RX_CTS : IN std_logic;
		RXC : IN std_logic;
		RXD : IN std_logic_vector(3 downto 0);
		RX_CTL : IN std_logic;
		MII_TX_CLK : IN std_logic;
		GMII_MII_CRS : IN std_logic;
		GMII_MII_COL : IN std_logic;
		GMII_MII_RX_CLK : IN std_logic;
		GMII_MII_RXD : IN std_logic_vector(7 downto 0);
		GMII_MII_RX_DV : IN std_logic;
		GMII_MII_RX_ER : IN std_logic;    
		MDIO : INOUT std_logic;      
		MAC_TX_CTS : OUT std_logic;
		MAC_RX_DATA : OUT std_logic_vector(7 downto 0);
		MAC_RX_DATA_VALID : OUT std_logic;
		MAC_RX_SOF : OUT std_logic;
		MAC_RX_EOF : OUT std_logic;
		TXC : OUT std_logic;
		TXD : OUT std_logic_vector(3 downto 0);
		TX_CTL : OUT std_logic;
		RESET_N : OUT std_logic;
		MCLK : OUT std_logic;
		GMII_TX_CLK : OUT std_logic;
		GMII_MII_TXD : OUT std_logic_vector(7 downto 0);
		GMII_MII_TX_EN : OUT std_logic;
		GMII_MII_TX_ER : OUT std_logic;
		LINK_STATUS : OUT std_logic;
		SPEED_STATUS : OUT std_logic_vector(1 downto 0);
		DUPLEX_STATUS : OUT std_logic;
		PHY_ID: out std_logic_vector(15 downto 0);
		N_RX_FRAMES: out  std_logic_vector(15 downto 0);
		N_RX_BAD_CRCS: out  std_logic_vector(15 downto 0);
		N_RX_FRAMES_TOO_SHORT: out  std_logic_vector(15 downto 0);
		N_RX_FRAMES_TOO_LONG: out  std_logic_vector(15 downto 0);
		N_RX_WRONG_ADDR: out  std_logic_vector(15 downto 0);
		N_RX_LENGTH_ERRORS: out  std_logic_vector(15 downto 0);
		CS_CLKG: out std_logic;	
		CS1: out std_logic_vector(7 downto 0);
		CS1_CLK: out std_logic;
		CS2: out std_logic_vector(7 downto 0);
		CS2_CLK: out std_logic;
		CT1: out std_logic;
		CT1_CLK: out std_logic;
		TP: out std_logic_vector(10 downto 1)
		);
	END COMPONENT;

	COMPONENT COM5402
	GENERIC (
		NUDPTX: integer range 0 to 1;
		NUDPRX: integer range 0 to 1;
		IGMP_EN: std_logic;
		NTCPSTREAMS: integer range 0 to 255 := 1;  
		CLK_FREQUENCY: integer;
		TX_IDLE_TIMEOUT: integer range 0 to 50;	
		TCP_KEEPALIVE_PERIOD: integer ;
		SIMULATION: std_logic
	);	
	PORT(
		CLK : IN std_logic;
		SYNC_RESET: in std_logic;
		MAC_ADDR : IN std_logic_vector(47 downto 0);
		IPv4_ADDR : IN std_logic_vector(31 downto 0);
		IPv6_ADDR : IN std_logic_vector(127 downto 0);
		SUBNET_MASK: in std_logic_vector(31 downto 0);
		MULTICAST_IP_ADDR: in std_logic_vector(31 downto 0); 
		GATEWAY_IP_ADDR: in std_logic_vector(31 downto 0);
		CONNECTION_RESET: in std_logic_vector((NTCPSTREAMS-1) downto 0);
		TCP_KEEPALIVE_EN: in std_logic_vector((NTCPSTREAMS-1) downto 0);	
		MAC_TX_CTS : IN std_logic;
		MAC_RX_DATA : IN std_logic_vector(7 downto 0);
		MAC_RX_DATA_VALID : IN std_logic;
		MAC_RX_SOF : IN std_logic;
		MAC_RX_EOF : IN std_logic;          
		MAC_TX_DATA : OUT std_logic_vector(7 downto 0);
		MAC_TX_DATA_VALID : OUT std_logic;
		MAC_TX_SOF: out std_logic;
		MAC_TX_EOF : OUT std_logic;
		UDP_RX_DATA: out std_logic_vector(7 downto 0);
		UDP_RX_DATA_VALID: out std_logic;
		UDP_RX_SOF: out std_logic;	
		UDP_RX_EOF: out std_logic;	
		UDP_RX_DEST_PORT_NO_IN: in std_logic_vector(15 downto 0);
		CHECK_UDP_RX_DEST_PORT_NO: in std_logic;
		UDP_RX_DEST_PORT_NO_OUT: out std_logic_vector(15 downto 0);
		UDP_TX_DATA : IN std_logic_vector(7 downto 0);
		UDP_TX_DATA_VALID : IN std_logic;
		UDP_TX_SOF : IN std_logic;
		UDP_TX_EOF : IN std_logic;
		UDP_TX_CTS: out std_logic;	
		UDP_TX_ACK: out std_logic;	
		UDP_TX_NAK: out std_logic;	
		UDP_TX_DEST_IP_ADDR: in std_logic_vector(127 downto 0);
		UDP_TX_DEST_PORT_NO: in std_logic_vector(15 downto 0);
		UDP_TX_SOURCE_PORT_NO: in std_logic_vector(15 downto 0);
		TCP_RX_DATA: out SLV8xNTCPSTREAMStype;
		TCP_RX_DATA_VALID: out std_logic_vector((NTCPSTREAMS-1) downto 0);
		TCP_RX_RTS: out std_logic_vector((NTCPSTREAMS-1) downto 0);	
		TCP_RX_CTS: in std_logic_vector((NTCPSTREAMS-1) downto 0);	
		TCP_TX_DATA: in SLV8xNTCPSTREAMStype;
		TCP_TX_DATA_VALID: in std_logic_vector((NTCPSTREAMS-1) downto 0);
		TCP_TX_CTS: out std_logic_vector((NTCPSTREAMS-1) downto 0);	
		TCP_CONNECTED_FLAG: out std_logic_vector((NTCPSTREAMS-1) downto 0);
		CS1 : OUT std_logic_vector(7 downto 0);
		CS1_CLK : OUT std_logic;
		CS2 : OUT std_logic_vector(7 downto 0);
		CS2_CLK : OUT std_logic;
		TP : OUT std_logic_vector(10 downto 1)
		);
	END COMPONENT;

	COMPONENT PACKETS_2_STREAM
	GENERIC (
        NBUFS: integer
    );
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		PACKET_DATA_IN : IN std_logic_vector(7 downto 0);
		PACKET_DATA_VALID_IN : IN std_logic;
		PACKET_EOF_IN : IN std_logic;
		STREAM_CTS_IN : IN std_logic;          
		PACKET_CTS_OUT : OUT std_logic;
		STREAM_DATA_OUT : OUT std_logic_vector(7 downto 0);
		STREAM_DATA_VALID_OUT : OUT std_logic;
	    STREAM_SOF_OUT: out std_logic;
        STREAM_EOF_OUT: out std_logic;
		BAD_PACKET : OUT std_logic;
		TP : OUT std_logic_vector(10 downto 1)
		);
	END COMPONENT;


	COMPONENT ELASTIC_BUFFER_NRAMB2
	GENERIC (
		DATA_WIDTH: integer;
		ADDR_WIDTH: integer;
		READ_AHEAD_1ADDRESS: std_logic
	);	
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		DATA_IN: in std_logic_vector((DATA_WIDTH-1) downto 0);
		SAMPLE_CLK_IN : IN std_logic;
		SAMPLE_CLK_IN_REQ : OUT std_logic;
		DATA_OUT: out std_logic_vector((DATA_WIDTH-1) downto 0);
		SAMPLE_CLK_OUT : OUT std_logic;
		SAMPLE_CLK_OUT_E : OUT std_logic;
		SAMPLE_CLK_OUT_REQ : IN std_logic;          
		BUFFER_EMPTY: out std_logic;
		USED: out std_logic_vector((ADDR_WIDTH-1) downto 0)
		);
	END COMPONENT;

	COMPONENT CLOCK_RECOVERY
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		CLK_IN : IN std_logic;          
		CLK_IN_VALID: in std_logic;	
		CLK_OUT : OUT std_logic;
		CLKx2_OUT : OUT std_logic;
		CLKx4_OUT : OUT std_logic;
		CLKx8_OUT : OUT std_logic;
		CLK_FREQ_OUT : OUT std_logic_vector(31 downto 0);
      OUTPUT_READY: out std_logic;
		TP : OUT std_logic_vector(10 downto 1)
		);
	END COMPONENT;

	COMPONENT LFSR11P
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		SAMPLE_CLK_OUT_REQ : IN std_logic;          
		DATA_OUT : OUT std_logic_vector(7 downto 0);
		SAMPLE_CLK_OUT : OUT std_logic;
		SOF_OUT : OUT std_logic
		);
	END COMPONENT;

	COMPONENT P8_TO_S1_CONVERSION
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		DATA8_IN : IN std_logic_vector(7 downto 0);
		SAMPLE8_CLK_IN : IN std_logic;
		SAMPLE1_CLK_OUT_REQ : IN std_logic;          
		SAMPLE8_CLK_IN_REQ : OUT std_logic;
		DATA1_OUT : OUT std_logic;
		SAMPLE1_CLK_OUT : OUT std_logic;
		BUF_EMPTY : OUT std_logic
		);
	END COMPONENT;

	COMPONENT NRZ1
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		DATA_IN : IN std_logic;
		DATA_VALID_IN : IN std_logic;
		CONTROL : IN std_logic_vector(2 downto 0);          
		DATA_OUT : OUT std_logic;
		DATA_VALID_OUT : OUT std_logic
		);
	END COMPONENT;

	COMPONENT ELASTIC_BUFFER16b
	PORT(
		CLK : IN std_logic;
		SYNC_RESET: in std_logic;
		DATA_IN : IN std_logic;
		SAMPLE_CLK_IN : IN std_logic;
		SAMPLE_CLK_OUT_REQ : IN std_logic;          
		SAMPLE_CLK_IN_REQ : OUT std_logic;
		DATA_OUT : OUT std_logic;
		SAMPLE_CLK_OUT : OUT std_logic
		);
	END COMPONENT;

	COMPONENT TC_ENCODER_DVB_RCS2
	generic (
		SIMULATION: std_logic
	);
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		DATA_IN : IN std_logic_vector(1 downto 0);
		DATA_IN_VALID : IN std_logic;
		SOF_IN : IN std_logic;
		CTS_OUT : OUT std_logic;
		BURST_PAYLOAD_SIZE : IN std_logic_vector(9 downto 0);
		R1: in std_logic_vector(2 downto 0);
		R2: in std_logic_vector(3 downto 0);
		P : IN std_logic_vector(6 downto 0);
		Q0 : IN std_logic_vector(3 downto 0);
		Q1 : IN std_logic_vector(3 downto 0);
		Q2 : IN std_logic_vector(3 downto 0);
		Q3 : IN std_logic_vector(2 downto 0);
		Y_PUNCTURING_PERIOD : IN std_logic_vector(4 downto 0);
		Y_PUNCTURING_PATTERN : IN std_logic_vector(27 downto 0);
		W_PUNCTURING_PATTERN : IN std_logic;          
		CRC16_EN: in std_logic;
		DATA_OUT: out std_logic_vector(1 downto 0);
		DATA_OUT_VALID: out std_logic;
		SOF_OUT: out std_logic;
		EOF_OUT: out std_logic;
		CTS_IN: in std_logic;
		N_PARITY_BITS: out std_logic_vector(11 downto 0);
		N_PARITY_BITS_RDY: out std_logic;
		TP: out std_logic_vector(10 downto 1)  
		);
	END COMPONENT;

	COMPONENT ENCODER_ROOT
	PORT(
		CLK : IN std_logic;
		ASYNC_RESET : IN std_logic;
		DATA_IN : IN std_logic;
		SAMPLE_CLK_IN : IN std_logic;
		SOF_RESET : IN std_logic;
		SAMPLE_CLK_OUT_REQ : IN std_logic;
		CONTROL : IN std_logic_vector(15 downto 0);          
		SAMPLE_CLK_IN_REQ : OUT std_logic;
		DATA_OUT : OUT std_logic_vector(3 downto 0);
		SAMPLE_CLK_OUT : OUT std_logic;
		TP : OUT std_logic_vector(4 downto 0)
		);
	END COMPONENT;

	COMPONENT S1_TO_P8_CONVERSION
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		DATA1_IN : IN std_logic;
		SAMPLE1_CLK_IN : IN std_logic;
		SOF1_IN : IN std_logic;
		EOF1_IN : IN std_logic;          
		DATA8_OUT : OUT std_logic_vector(7 downto 0);
		SAMPLE8_CLK_OUT : OUT std_logic;
		SOF8_OUT : OUT std_logic;
		EOF8_OUT : OUT std_logic
		);
	END COMPONENT;

	COMPONENT COM1827_TX
	GENERIC(
		FIRST_PREAMBLE_EXTENSION: integer; 
		SYNC_LENGTH: integer range 0 to 128;	 
		SYNC_WORD: std_logic_vector(127 downto 0);
		GAP_LENGTH: integer;
		SIMULATION: std_logic
	);
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		TX_DATA : IN std_logic_vector(7 downto 0);
		TX_DATA_SAMPLE_CLK : IN std_logic;
		TX_SOF : IN std_logic;
		SYMBOL_RATE_NDIV: in std_logic_vector(3 downto 0);
		MODULATION_INDEX : IN std_logic_vector(15 downto 0);
		GAIN : IN std_logic_vector(15 downto 0);
		TX_WINDOW : IN std_logic;
		CENTER_FREQ : IN std_logic_vector(31 downto 0);
		MASTER_SLAVEN : IN std_logic;
		BURST_LENGTH : IN std_logic_vector(12 downto 0);
		CONTROL : IN std_logic_vector(15 downto 0);
		TX_CTS : OUT std_logic;
		DATA_I_OUT : OUT std_logic_vector(15 downto 0);
		DATA_Q_OUT : OUT std_logic_vector(15 downto 0);
		TX_EN_OUT : OUT std_logic;
		SYMBOL_CLKx4_OUT: OUT std_logic;
		CS1 : OUT std_logic_vector(7 downto 0);
		CS1_CLK : OUT std_logic;
		SATURATION: out std_logic_vector(1 downto 0);
		TP : OUT std_logic_vector(20 downto 1)
		);
	END COMPONENT;

	COMPONENT AWGN
	PORT(
		CLK : IN std_logic;
		SAMPLE_CLK_REQ : IN std_logic;
		SYNC_RESET : IN std_logic;          
		SAMPLE_CLK_OUT : OUT std_logic;
		NOISE_SAMPLE1_OUT : OUT std_logic_vector(15 downto 0);
		NOISE_SAMPLE2_OUT : OUT std_logic_vector(15 downto 0)
		);
	END COMPONENT;

	COMPONENT POWER_MEASUREMENT
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		SAMPLE_CLK_IN : IN std_logic;
		DATA_I_IN : IN std_logic_vector(17 downto 0);
		DATA_Q_IN : IN std_logic_vector(17 downto 0);          
		SAMPLE_CLK_OUT : OUT std_logic;
		POWER_OUT : OUT std_logic_vector(23 downto 0)
		);
	END COMPONENT;

	COMPONENT CROSS_CLK_DOMAINS is
	generic (
		NBITS: in integer
	);
	PORT(
		CLK_A : in std_logic;				-- 'from' clock domain
		CLK_B : in std_logic;				-- 'to' clock domain
		ASYNC_RESET: in std_logic;
		DATA_IN: in std_logic_vector((NBITS-1) downto 0);
		DATA_OUT: out std_logic_vector((NBITS-1) downto 0)
	);
	END COMPONENT;

	COMPONENT AUX_DACS_ADC
	generic (
		CLK_FREQUENCY: integer 
	);
	PORT(
		CLK : IN std_logic;
		ASYNC_RESET : IN std_logic;
		AUXDAC1_DIN : IN std_logic_vector(11 downto 0);
		AUXDAC2_DIN : IN std_logic_vector(11 downto 0);    
		AUXADC1_DOUT : OUT std_logic_vector(11 downto 0);
		TIMESLOTS_AUXDAC1: in std_logic_vector(15 downto 0);
		TIMESLOTS_AUXDAC2: in std_logic_vector(15 downto 0);
		TIMESLOTS_AUXADC1: in std_logic_vector(15 downto 0);
		AUX_SPI1 : INOUT std_logic;      
		AUX_SPI2 : OUT std_logic;
		AUX_SPI3 : OUT std_logic;
		AUX_SPI4 : OUT std_logic;
		AUX_SPI5 : OUT std_logic
		);
	END COMPONENT;

 	COMPONENT DNA_ID
	GENERIC (
		CLK_FREQUENCY: integer
	);	
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;          
		ID_OUT : OUT std_logic_vector(56 downto 0) := (others => '0');
		ID_VALID_OUT : OUT std_logic;
		ID_SAMPLE_CLK_OUT : OUT std_logic
		);
	END COMPONENT;

	COMPONENT COMSCOPE2
	generic (
		TRACE1_ENABLED: std_logic;	
		TRACE2_ENABLED: std_logic;	
		TRACE3_ENABLED: std_logic;	
		TRACE4_ENABLED: std_logic;
		DATA_WIDTH1A: integer;
		ADDR_WIDTH1A: integer;
		ADDR_WIDTH1B: integer;
		DATA_WIDTH2A: integer;
		ADDR_WIDTH2A: integer;
		ADDR_WIDTH2B: integer;
		DATA_WIDTH3A: integer;
		ADDR_WIDTH3A: integer;
		ADDR_WIDTH3B: integer;
		DATA_WIDTH4A: integer;
		ADDR_WIDTH4A: integer;
		ADDR_WIDTH4B: integer
	);	
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		REG238 : IN std_logic_vector(7 downto 0);
		REG239 : IN std_logic_vector(7 downto 0);
		REG240 : IN std_logic_vector(7 downto 0);
		REG241 : IN std_logic_vector(7 downto 0);
		REG242 : IN std_logic_vector(7 downto 0);
		REG243 : IN std_logic_vector(7 downto 0);
		REG244 : IN std_logic_vector(7 downto 0);
		REG245 : IN std_logic_vector(7 downto 0);
		REG246 : IN std_logic_vector(7 downto 0);
		REG247 : IN std_logic_vector(7 downto 0);
		REG248 : IN std_logic_vector(7 downto 0);
		REG249 : IN std_logic_vector(7 downto 0);
		S1_1 : IN std_logic_vector(7 downto 0);
		S1_1_VALID : IN std_logic;
		S1_2 : IN std_logic_vector(7 downto 0);
		S1_2_VALID : IN std_logic;
		S1_3 : IN std_logic_vector(7 downto 0);
		S1_3_VALID : IN std_logic;
		S1_4 : IN std_logic_vector(7 downto 0);
		S1_4_VALID : IN std_logic;
		S2_1 : IN std_logic_vector(7 downto 0);
		S2_1_VALID : IN std_logic;
		S2_2 : IN std_logic_vector(7 downto 0);
		S2_2_VALID : IN std_logic;
		S2_3 : IN std_logic_vector(7 downto 0);
		S2_3_VALID : IN std_logic;
		S2_4 : IN std_logic_vector(7 downto 0);
		S2_4_VALID : IN std_logic;
		S3_1 : IN std_logic_vector(7 downto 0);
		S3_1_VALID : IN std_logic;
		S3_2 : IN std_logic_vector(7 downto 0);
		S3_2_VALID : IN std_logic;
		S3_3 : IN std_logic_vector(7 downto 0);
		S3_3_VALID : IN std_logic;
		S3_4 : IN std_logic_vector(7 downto 0);
		S3_4_VALID : IN std_logic;
		S4_1 : IN std_logic_vector(7 downto 0);
		S4_1_VALID : IN std_logic;
		S4_2 : IN std_logic_vector(7 downto 0);
		S4_2_VALID : IN std_logic;
		S4_3 : IN std_logic_vector(7 downto 0);
		S4_3_VALID : IN std_logic;
		S4_4 : IN std_logic_vector(7 downto 0);
		S4_4_VALID : IN std_logic;
		T16b_1 : IN std_logic_vector(15 downto 0);
		T16b_1_VALID : IN std_logic;
		T16b_2 : IN std_logic_vector(15 downto 0);
		T16b_2_VALID : IN std_logic;
		T16b_3 : IN std_logic_vector(15 downto 0);
		T16b_3_VALID : IN std_logic;
		T16b_4 : IN std_logic_vector(15 downto 0);
		T16b_4_VALID : IN std_logic;
		TRIGGER_REARM_TOGGLE : IN std_logic;
		FORCE_TRIGGER_TOGGLE : IN std_logic;
		SREG250_READ_TOGGLE : IN std_logic;
		START_CAPTURE_TOGGLE : IN std_logic;          
		SREG250 : OUT std_logic_vector(7 downto 0);
		SREG251 : OUT std_logic_vector(7 downto 0);
		TP : OUT std_logic_vector(10 downto 1)
		);
	END COMPONENT;

	component SIM2OUTFILE is
		 Generic (
			FILENAME: string
		 );
		 Port ( 
			--// CLK, RESET
			CLK: in std_logic;
				-- Reference clock
			DATA1: in std_logic_vector(11 downto 0);
			DATA2: in std_logic_vector(11 downto 0);
			DATA3: in std_logic_vector(11 downto 0);
			SAMPLE_CLK_IN: in std_logic
				-- DATA_IN is read at the rising edge of CLK when SAMPLE_CLK_IN = '1'

	);
	END COMPONENT;

--------------------------------------------------------
--     SIGNALS
--------------------------------------------------------
-- Suffix _D indicates a one CLK delayed version of the net with the same name
-- Suffix _X indicates an extended precision version of the net with the same name
-- Suffix _N indicates an inverted version of the net with the same name


--// CLOCKS, RESETS
signal CLKREF_TCXOg: std_logic := '0';
signal CLK125_LOCKED: std_logic := '0';
signal CLK25_INPUT_CLK_STOPPED: std_logic := '0';
signal CLK160: std_logic := '0';
signal CLK160g: std_logic := '0';
signal CLK160_LOCKED: std_logic := '0';
signal CLK160_LOCKED_D: std_logic := '0';
signal CLK160_INPUT_CLK_STOPPED: std_logic := '0';
signal CLK10: std_logic := '0';
signal CLK10g: std_logic := '0';
signal CLK10g0: std_logic := '0';
signal CLK10g1: std_logic := '0';
signal CLK10g2: std_logic := '0';
signal CLK125_FB: std_logic := '0';
signal CLK10_INPUT_CLK_STOPPED: std_logic := '0';
signal CLK10_LOCKED: std_logic := '0';
signal CLK125: std_logic := '0';
signal CLK125_1: std_logic := '0';
signal CLK25g: std_logic := '0';
signal CLK25_LOCKED: std_logic := '0';
signal CLK_P: std_logic := '0';
constant CLK_P_FREQUENCY: integer := 125; -- processing clock frequency CLK_P in MHz, as time reference
--signal CLK_TX_GEN_EN: std_logic := '0';
signal MMCM2F_CLKFBOUT : std_logic := '0';	
signal MMCM2F_CLKOUT0 : std_logic := '0';	 
signal CLK_TX_GEN_M: std_logic_vector(9 downto 0) := (others => '0');
signal CLK_TX_GEN_D: std_logic_vector(6 downto 0) := (others => '0');
signal CLK_TX_GEN_O: std_logic_vector(10 downto 0) := (others => '0');
signal CLK_TXRX_GEN_PROGRAM: std_logic := '0';
signal CLK_TXRX_GEN_SYNC_RESET: std_logic := '0';
signal CLK_TX_GEN_INPUT_STOPPED: std_logic := '0';
signal CLK_TX_GEN_LOCKED: std_logic := '0';
signal CLK_TXg: std_logic := '0';
signal TICK_100MS: std_logic := '0';
signal TOGGLE_1S: std_logic := '0';
signal TOGGLE_1S_D: std_logic := '0';
signal TOGGLE_1S_D2: std_logic := '0';
signal TICK_1S: std_logic := '0';
signal TICK_4US: std_logic := '0';
signal TICK_100MS_CNTR: unsigned(3 downto 0) := (others => '0');
signal RESET_COUNTER: unsigned(23 downto 0) := (others => '0');
	-- spans 2^23/10MHz = 838ms
signal RESET_STATE: integer range 0 to 1 := 0;
signal ASYNC_RESET: std_logic := '1';
signal CLK_P_DIV2: std_logic := '0';
signal SYNC_RESET_CLK160: std_logic := '0';
signal SYNC_RESET_CLK_P: std_logic := '0';
signal SYNC_RESET_CLK_TX: std_logic := '0';
signal ASYNC_RESET1_D: std_logic := '0';
signal ASYNC_RESET1_D2: std_logic := '0';
signal ASYNC_RESET2_D: std_logic := '0';
signal ASYNC_RESET2_D2: std_logic := '0';
signal ASYNC_RESET3_D: std_logic := '0';
signal ASYNC_RESET3_D2: std_logic := '0';
signal ASYNC_RESET4_D: std_logic := '0';
signal ASYNC_RESET4_D2: std_logic := '0';
	-- asynchronous reset
signal READY_FLAG_CLK160: std_logic := '0';
signal READY_FLAG_CLK_P: std_logic := '0';
signal READY_FLAG_CLK_TX: std_logic := '0';
signal RECEIVER_RESET_CLK_P: std_logic := '0';
signal LCB1g: std_logic := '0';

--//-- ETHERNET MAC#2-----------------------------------
signal CLK_SKEW21: std_logic_vector(15 downto 0) := (others => '0');
signal CLK_SKEW22: std_logic_vector(15 downto 0) := (others => '0');
signal LAN2_MAC_ADDR: std_logic_vector(47 downto 0) := (others => '0');
signal LAN2_TP: std_logic_vector(10 downto 1) := (others => '0');
signal LAN2_PHY_ID: std_logic_vector(15 downto 0) := (others => '0');
signal LAN2_MAC_RX_DATA: std_logic_vector(7 downto 0) := (others => '0');
signal LAN2_MAC_RX_DATA_VALID: std_logic:= '0';
signal LAN2_MAC_RX_SOF: std_logic:= '0';
signal LAN2_MAC_RX_EOF: std_logic:= '0';
signal LAN2_MAC_TX_DATA: std_logic_vector(7 downto 0) := (others => '0');
signal LAN2_MAC_TX_DATA_VALID: std_logic:= '0';
signal LAN2_MAC_TX_EOF: std_logic:= '0';
signal LAN2_MAC_TX_CTS: std_logic:= '0';
signal LAN2_LINK_STATUS: std_logic:= '0';
signal LAN2_SPEED_STATUS: std_logic_vector(1 downto 0) := (others => '0');
signal LAN2_DUPLEX_STATUS: std_logic:= '0';
signal LAN2_N_RX_FRAMES:  std_logic_vector(15 downto 0);
signal LAN2_N_RX_BAD_CRCS:  std_logic_vector(15 downto 0);
signal LAN2_N_RX_FRAMES_TOO_SHORT:  std_logic_vector(15 downto 0);
signal LAN2_N_RX_FRAMES_TOO_LONG:  std_logic_vector(15 downto 0);
signal LAN2_N_RX_WRONG_ADDR:  std_logic_vector(15 downto 0);
signal LAN2_N_RX_LENGTH_ERRORS:  std_logic_vector(15 downto 0);

--//-- IP STACK #2  -----------------------------------
constant NTCPSTREAMS2: integer := 3;  -- number of concurrent TCP streams handled by this component
signal IP2_ADDRv4: std_logic_vector(31 downto 0) := (others => '0');	
signal SUBNET_MASK: std_logic_vector(31 downto 0) := (others => '0');	
signal GATEWAY_IP_ADDR: std_logic_vector(31 downto 0) := (others => '0');	
signal IPSTACK2_TP: std_logic_vector(10 downto 1) := (others => '0');
signal LAN2_UDP_RX_DATA: std_logic_vector(7 downto 0) := (others => '0');
signal LAN2_UDP_RX_DATA2: std_logic_vector(7 downto 0) := (others => '0');
signal LAN2_UDP_RX_DATA_VALID: std_logic := '0';
signal LAN2_UDP_RX_DATA_VALID2: std_logic := '0';
signal LAN2_UDP_RX_SOF: std_logic := '0';
signal LAN2_UDP_RX_EOF: std_logic := '0';
signal LAN2_UDP_TX_DATA1: std_logic_vector(7 downto 0) := (others => '0');
signal LAN2_UDP_TX_DATA2: std_logic_vector(7 downto 0) := (others => '0');
signal LAN2_UDP_TX_DATA: std_logic_vector(7 downto 0) := (others => '0');
signal LAN2_UDP_TX_DATA_VALID: std_logic := '0';
signal LAN2_UDP_TX_SOF: std_logic := '0';
signal LAN2_UDP_TX_EOF: std_logic := '0';
signal LAN2_UDP_TX_CTS: std_logic := '0';
signal LAN2_UDP_TX_ACK: std_logic := '0';
signal LAN2_UDP_TX_NAK: std_logic := '0';
signal LAN2_UDP_TX_RTS: std_logic := '0';
signal LAN2_UDP_TX_DEST_IP_ADDR: std_logic_vector(127 downto 0) := (others => '0');
signal LAN2_UDP_TX_DEST_PORT_NO: std_logic_vector(15 downto 0) := (others => '0');
signal LAN2_TCP_RX_DATA: SLV8xNTCPSTREAMStype;
signal LAN2_TCP_RX_DATA_VALID: std_logic_vector((NTCPSTREAMS2-1) downto 0) := (others => '0');
signal LAN2_TCP_RX_CTS: std_logic_vector((NTCPSTREAMS2-1) downto 0) := (others => '0');
signal LAN2_TCP_TX_DATA: SLV8xNTCPSTREAMStype;
signal LAN2_TCP_TX_DATA_VALID: std_logic_vector((NTCPSTREAMS2-1) downto 0) := (others => '0');
signal LAN2_TCP_TX_CTS: std_logic_vector((NTCPSTREAMS2-1) downto 0) := (others => '0');
signal LAN2_TCP_CONNECTED_FLAG: std_logic_vector((NTCPSTREAMS2-1) downto 0) := (others => '0');
signal LAN2_RX_DATA0: std_logic_vector(7 downto 0) := (others => '0');
signal LAN2_RX_SAMPLE0_CLK: std_logic := '0';
signal LAN2_RX_SAMPLE1_CLK: std_logic := '0';

--// LAN#2 TCP-IP Interface for M&C (port 1028)
signal EB1_SAMPLE_CLK_OUT_E: std_logic := '0';
signal RX_LAN: std_logic_vector(7 downto 0) := (others => '0'); 
signal RX_LAN_SAMPLE_CLK_REQ: std_logic := '0';
signal RX_LAN_BUFFER_EMPTY: std_logic := '1';
signal RX_LAN_BUFFER_EMPTY_D: std_logic := '1';
signal RX_LAN_BUFFER_EMPTY_D2: std_logic := '1';
signal TX_LAN_TOGGLE: std_logic := '0';
signal TX_LAN_TOGGLE_D: std_logic := '0';
signal TX_LAN_TOGGLE_D2: std_logic := '0';

--//-- DDR3 SODIMM CONTROLLER  -----------------------------------------------
-- optional/future
constant DDR3_ENABLED : std_logic := '0';    -- 0/1 to instantiate DDR3 SDRAM memory controller
signal DDR3_PLL_LOCKED_OUT: std_logic := '0';

--//-- SERIAL INPUT (TX) ASYNC -------------------------------
signal CR_SYNC_RESET: std_logic := '0';
signal TX_BIT_CLK1_IN: std_logic := '0';
signal TX_DATA1_VALID_IN: std_logic := '0';
signal TX_DATA1B_VALID_IN: std_logic := '0';
signal TX_DATA1_IN: std_logic := '0';
signal TX_BIT_RATE: std_logic_vector(31 downto 0) := (others => '0');

--//-- SERIAL INPUTS (TX) -------------------------------------
signal CLK_INg: std_logic := '0';
signal DATA_IN: std_logic := '0';
signal DATA_IN_x: std_logic_vector(0 downto 0) := (others => '0');
signal DATA_IN_VALID: std_logic := '0';
signal SOF_IN: std_logic := '0';
signal DATA_IN_CTS: std_logic := '0';
signal CCD1_DATA_OUT: std_logic_vector(0 downto 0) := (others => '0');
signal CCD1_SAMPLE_CLK_OUT: std_logic := '0';
signal CCD1_SOF_OUT: std_logic := '0';
signal CCD1_SAMPLE_CLK_OUT_REQ: std_logic := '0';

--//-- INPUTS SELECTION -------------------------------------
signal INPUTS_SEL: unsigned(3 downto 0) := (others => '0');
signal PRBS11_SYNC_RESET1: std_logic := '0';
signal PRBS11_DATA1_VALID: std_logic := '0';
signal PRBS11_CTS1: std_logic := '0';
signal PRBS11_DATA1: std_logic_vector(7 downto 0) := (others => '0');

--//-- PARALLEL TO SERIAL CONVERSION ----------------------------
signal TX_DATA8b1: std_logic_vector(7 downto 0) := (others => '0');
signal TX_DATA8b1_VALID: std_logic := '0';
signal TX_DATA8b1_CTS: std_logic := '0';
signal P2S_BUF_EMPTY1: std_logic := '0';
signal TX_DATA1b1: std_logic := '0';
signal TX_DATA1b1_VALID: std_logic := '0';
signal TX_DATA1b1_CTS: std_logic := '0';
signal TX_DATA1b2: std_logic := '0';
signal TX_DATA1b2_VALID: std_logic := '0';
signal TX_SOF1b2: std_logic := '0';
signal TX_DATA1b2_CTS: std_logic := '0';


--//-- DATA FORMAT CONVERTER (TX) --------------------------------------
signal NRZ1_TX_CONTROL: std_logic_vector(2 downto 0) := (others => '0');
signal NRZ1_TX_DATA1_IN: std_logic := '0';
signal NRZ1_TX_DATA1_VALID_IN: std_logic := '0';

--// TURBO CODE ENCODER -----------------------------------------------------------
-- encoder configuration
signal ENCODER_ENABLED: std_logic := '0';
signal TC_ENC_R1: std_logic_vector(2 downto 0) := (others => '0');
signal TC_ENC_R2: std_logic_vector(3 downto 0) := (others => '0');
signal TC_ENC_BURST_PAYLOAD_SIZE : std_logic_vector(7 downto 0) := (others => '0');
signal TC_ENC_BURST_PAYLOAD_SIZEx : std_logic_vector(9 downto 0) := (others => '0');
signal TX_FRAME_LENGTH: std_logic_vector(12 downto 0) := (others => '0'); -- frame length in symbols 
signal TC_E_BLOCK_SIZE : std_logic_vector(14 downto 0) := (others => '0');
signal TC_E_BLOCK_SIZE2 : std_logic_vector(14 downto 0) := (others => '0');
signal TC_ENC_N: unsigned(9 downto 0):= (others => '0');
signal TC_ENC_P : std_logic_vector(6 downto 0) := (others => '0');
signal TC_ENC_Q0 : std_logic_vector(3 downto 0) := (others => '0');
signal TC_ENC_Q1 : std_logic_vector(3 downto 0) := (others => '0');
signal TC_ENC_Q2 : std_logic_vector(3 downto 0) := (others => '0');
signal TC_ENC_Q3 : std_logic_vector(2 downto 0) := (others => '0');
signal TC_ENC_Y_PUNCTURING_PERIOD : std_logic_vector(4 downto 0) := (others => '0');
signal TC_ENC_Y_PUNCTURING_PATTERN : std_logic_vector(27 downto 0) := (others => '0');
signal TC_ENC_W_PUNCTURING_PATTERN : std_logic := '0';
signal TC_ENC_SYNC_RESET: std_logic := '0';

signal ENC_DATA_IN2: std_logic := '0';
signal ENC_SAMPLE_CLK_IN2: std_logic := '0';
signal ENC_SAMPLE_CLK_IN2_REQ: std_logic := '0';
signal TC_ENC_CNTR: unsigned(10 downto 0):= (others => '0');
signal TC_U_DATA : std_logic_vector(1 downto 0) := (others => '0');
signal TC_U_DATA_VALID : std_logic := '0';
signal TC_U_SOF : std_logic := '0';
signal TC_U_EOF_E : std_logic := '0';
signal TC_U_EOF : std_logic := '0';
signal TC_U_CTS : std_logic := '0';

signal TC_E_DATA: std_logic_vector(1 downto 0) := (others => '0');
signal TC_E_DATA_D1: std_logic := '0';
signal TC_E_DATA_VALID: std_logic := '0';
signal TC_E_DATA_VALID_D: std_logic := '0';
signal TC_E_SOF: std_logic := '0';
signal TC_E_EOF: std_logic := '0';
signal TC_E_EOF_D: std_logic := '0';
signal TC_E_CTS: std_logic := '0';
signal TC_E_CTS_D: std_logic := '0';
signal TC_ENC_N_PARITY_BITS: std_logic_vector(11 downto 0) := (others => '0'); 
signal TC_ENC_N_PARITY_BITS_RDY: std_logic := '0';
signal TC_TP: std_logic_vector(10 downto 1) := (others => '0');

signal TX_SOF1b3: std_logic := '0';
signal TX_EOF1b3: std_logic := '0';
signal TX_SAMPLE1b3_CLK: std_logic := '0';
signal TX_SAMPLE1b3_CLK_REQ: std_logic := '0';

signal TX_DATA8b2: std_logic_vector(7 downto 0) := x"00";
signal TX_SAMPLE8b2_CLK: std_logic := '0';
signal TX_SOF8b2: std_logic := '0';
signal TX_EOF8b2: std_logic := '0';
signal TX_SAMPLE8b2_CLK_REQ: std_logic := '0';
signal TC_ENC_FRAME_CNTR: unsigned(2 downto 0) := (others => '0');
signal TC_ENC_FRAME_CNTR_MAX: unsigned(2 downto 0) := (others => '0');

--//-- CONVOLUTIONAL ENCODING ----------------------------------
signal ENC_DATA_IN: std_logic := '0';
signal ENC_SAMPLE_CLK_IN: std_logic := '0';
signal ENC_SAMPLE_CLK_IN_REQ: std_logic := '0';
signal CENC1_DATA_OUT: std_logic_vector(3 downto 0) := (others => '0');
signal CENC1_SAMPLE_CLK_OUT: std_logic := '0';
signal CENC_CONTROL:  std_logic_vector(15 downto 0) := (others => '0');

signal TX_DATA1b3: std_logic := '0';
signal TX_DATA1b3_VALID: std_logic := '0';
signal TX_DATA8b3: std_logic_vector(7 downto 0) := (others => '0');
signal TX_DATA8b3_VALID: std_logic := '0';
signal TX_DATA8b3_CTS: std_logic := '0';
signal TX_DATA8b4: std_logic_vector(7 downto 0) := (others => '0');
signal TX_DATA8b4_VALID: std_logic := '0';
signal TX_DATA8b4_CTS: std_logic := '0';
signal TX_SOF8b4: std_logic := '0';
signal TX_EOF8b4: std_logic := '0';

--//-- CPM MODULATOR -------------------------------------
signal MOD_RESET: std_logic := '0';
signal MOD_SYMBOL_RATE_NDIV: std_logic_vector(3 downto 0) := (others => '0');
signal MOD_CENTER_FREQ: std_logic_vector(31 downto 0) := (others => '0');
signal MOD_SIGNAL_SCALING: std_logic_vector(15 downto 0) := (others => '0');
signal MOD_BURST_LENGTH: std_logic_vector(12 downto 0) := (others => '0');
signal MOD_INDEX: std_logic_vector(15 downto 0) := (others => '0');
signal MOD_CONTROL: std_logic_vector(15 downto 0) := (others => '0');
signal FAKE_TX_SOF: std_logic := '0';
signal FAKE_TX_SOF_FLAG: std_logic := '0';
signal FAKE_TX_SOF_CNTR: unsigned(7 downto 0) := (others => '0');
signal TX_SOF: std_logic := '0';
signal MOD_DATA1_I: std_logic_vector(15 downto 0) := (others => '0');
signal MOD_DATA1_Q: std_logic_vector(15 downto 0) := (others => '0');
signal MOD_SYMBOL_CLKx4: std_logic := '0';
signal TP_MOD: std_logic_vector(20 downto 1);
signal MOD_DATA2_I: std_logic_vector(17 downto 0) := (others => '0');	
signal MOD_DATA2_Q: std_logic_vector(17 downto 0) := (others => '0');
signal MOD_SATURATION: std_logic_vector(1 downto 0) := (others => '0');
signal MOD_SATURATION2: std_logic_vector(1 downto 0) := (others => '0');
signal MOD_TX_EN: std_logic := '0';

--//-- FSK/MSK/GFSK/GMSK MODULATOR -------------------------------------
signal MOD_SAMPLE_CLK_SHIFT: std_logic_vector(9 downto 0) := (others => '0');
signal NCO_MOD_SAMPLING_CNTR: integer range 0 to 20 := 0;
	
--// ADDITIVE WHITE GAUSSIAN NOISE -------------------------------------
signal NOISE_GAIN: std_logic_vector(16 downto 0) := (others => '0');
signal NOISE_DATA1_I: std_logic_vector(15 downto 0) := (others => '0');
signal NOISE_DATA1_Q: std_logic_vector(15 downto 0) := (others => '0');
signal NOISE_DATA1_I_D: signed(15 downto 0) := (others => '0');
signal NOISE_DATA1_Q_D: signed(15 downto 0) := (others => '0');
signal NOISE_DATA2_I: signed(32 downto 0) := (others => '0');
signal NOISE_DATA2_Q: signed(32 downto 0) := (others => '0');
signal NOISE_DATA3_I: signed(17 downto 0) := (others => '0');
signal NOISE_DATA3_Q: signed(17 downto 0) := (others => '0');
signal NOISE_GAIN_I_SATURATION: std_logic := '0';
signal NOISE_GAIN_Q_SATURATION: std_logic := '0';
signal SN1_I: signed(18 downto 0) := (others => '0');
signal SN1_Q: signed(18 downto 0) := (others => '0');
signal SN2_I: std_logic_vector(17 downto 0) := (others => '0');
signal SN2_Q: std_logic_vector(17 downto 0) := (others => '0');
signal SN_I_SATURATION: std_logic := '0';
signal SN_Q_SATURATION: std_logic := '0';
signal MOD_SIGNAL_POWER: std_logic_vector(23 downto 0) := (others => '0');
signal NOISE_POWER: std_logic_vector(23 downto 0) := (others => '0');

--//-- COM-3504 BASEBAND TRANSCEIVER DRIVER 
signal TX_GAIN_DAC: std_logic_vector(11 downto 0) := (others => '0');	
signal COM3504_ADC1_DIN: std_logic_vector(11 downto 0) := (others => '0');
signal COM3504_ADC2_DIN: std_logic_vector(11 downto 0) := (others => '0');

--// COM-4009 RF MODULATOR DRIVER ------------------
signal DAC_REFCLK: std_logic := '0'; 
signal DAC_DCI: std_logic := '0'; 
signal DAC_DCO: std_logic := '0'; 
signal DAC_D: std_logic_vector(15 downto 0) := (others => '0');

--//	RIGHT CONNECTOR COM-4004 interface (Options E)
signal MOD_OUTPUT_CLK_REQ: std_logic:= '0';
signal MOD_OUTPUT_A_BN: std_logic := '0';
signal MOD_OUTPUT_A_BN_DF: std_logic:= '0';
signal MOD_OUTPUT_DATA2_I_A: std_logic_vector(13 downto 0) := (others => '0');
signal MOD_OUTPUT_DATA2_I_B: std_logic_vector(13 downto 0) := (others => '0');
signal MOD_OUTPUT_DATA2_I_D: std_logic_vector(13 downto 0) := (others => '0');
signal MOD_OUTPUT_DATA2_Q_A: std_logic_vector(13 downto 0) := (others => '0');
signal MOD_OUTPUT_DATA2_Q_B: std_logic_vector(13 downto 0) := (others => '0');
signal MOD_OUTPUT_DATA2_Q_D: std_logic_vector(13 downto 0) := (others => '0');
signal MOD_OUTPUT_DATA2_IQ_D: std_logic_vector(13 downto 0) := (others => '0');
signal TX_ENABLE: std_logic:= '0';
signal I_QN: std_logic:= '0';

--//	LEFT/RIGHT CONNECTOR COM-30XX interface
signal RX_SAMPLE1_CLK: std_logic := '0';
signal RX_DATA1_I: std_logic_vector(11 downto 0) := (others => '0');
signal RX_DATA1_Q: std_logic_vector(11 downto 0) := (others => '0');
signal AUX_DAC1_OP_MODE: std_logic_vector(1 downto 0) := (others => '0');

--//-- RECLOCKED INPUTS ---------------------
signal ADC_DATA_I_IN: std_logic_vector(13 downto 0) := (others => '0');
signal ADC_DATA_Q_IN: std_logic_vector(13 downto 0) := (others => '0');
signal LOOPBACK_MODE: std_logic := '0';
signal SN2x: std_logic_vector(31 downto 0) := (others => '0');
signal SN3x: std_logic_vector(31 downto 0) := (others => '0');
signal SN3_I: std_logic_vector(15 downto 0) := (others => '0');
signal SN3_Q: std_logic_vector(15 downto 0) := (others => '0');
	
--//-- CPM DEMODULATOR ----------------------------------------
signal AGC_DAC: std_logic_vector(11 downto 0) := (others => '0');	
signal AGC_DAC_SAMPLE_CLK: std_logic := '0';
signal RX_DATA2_I: std_logic_vector(15 downto 0) := (others => '0');	
signal RX_DATA2_Q: std_logic_vector(15 downto 0) := (others => '0');	
signal RX_SAMPLE2_CLK: std_logic := '0'; 
signal ISR_CNTR: unsigned(28 downto 0) := (others => '0');
signal ISR: std_logic_vector(28 downto 0) := (others => '0');
signal CIC_R: std_logic_vector(15 downto 0) := (others => '0');	
signal DEMOD_SYMBOL_RATE: std_logic_vector(31 downto 0) := (others => '0');
signal DEMOD_M_SEL: std_logic_vector(2 downto 0) := (others => '0'); 
signal DEMOD_FILT_SEL: std_logic_vector(3 downto 0) := (others => '0'); 
signal DEMOD_MODULATION_INDEX: std_logic_vector(15 downto 0) := (others => '0');

signal AFC_LOCK_OUT: std_logic := '0';
signal CARRIER_LOCK_OUT: std_logic := '0';
signal SIGNAL_PRESENT_OUT: std_logic := '0';

signal RECEIVER_AGC_RESPONSE: std_logic_vector(4 downto 0) := (others => '0');	
signal RECEIVER_CENTER_FREQ: std_logic_vector(31 downto 0) := (others => '0');	
signal DEMOD_CONTROL: std_logic_vector(15 downto 0) := (others => '0');
signal DATA10: std_logic_vector(3 downto 0) := (others => '0');
signal SAMPLE10_CLK: std_logic := '0';
signal CARRIER_FREQUENCY_ERROR: std_logic_vector(31 downto 0) := (others => '0');
signal POWER_S_AVERAGE_OUT: std_logic_vector(17 downto 0) := (others => '0');
signal POWER_N_AVERAGE_OUT: std_logic_vector(17 downto 0) := (others => '0');
signal SNR_LOCKED_OUT: std_logic_vector(17 downto 0) := (others => '0');
signal DEMOD_TP: std_logic_vector(20 downto 1) := (others => '0');
signal DATA11: std_logic_vector(3 downto 0) := (others => '0');
signal SAMPLE11_CLK: std_logic := '0';
signal SOF11: std_logic := '0';
signal DATA12: std_logic_vector(3 downto 0) := (others => '0');
signal SAMPLE12_CLK: std_logic := '0';
signal SOF12: std_logic := '0';
signal DATA_ENABLE12: std_logic := '0';
signal BER12: std_logic_vector(16 downto 0) := (others => '0');
signal SOF_LOCK_DETECT12: std_logic := '0';
signal PHASE12: std_logic_vector(1 downto 0) := (others => '0');
signal TP_MRC_SOF12: std_logic_vector(3 downto 0) := (others => '0');
signal DATA13: std_logic := '0';
signal SAMPLE13_CLK: std_logic := '0';

--//-- TURBO CODE DECODER -----------------------------------------------------------
-- decoder configuration
signal DECODER_ENABLED: std_logic := '0';
signal SYNC_DETECT_ENABLED: std_logic := '0';
signal TC_DEC_BURST_PAYLOAD_SIZE: std_logic_vector(7 downto 0) := (others => '0');
signal TC_C_BLOCK_SIZE: std_logic_vector(12 downto 0) := (others => '0');
signal TC_DEC_N_ITER: std_logic_vector(3 downto 0) := "0111";
signal TC_DEC_P : std_logic_vector(6 downto 0) := (others => '0');
signal TC_DEC_Q0 : std_logic_vector(3 downto 0) := (others => '0');
signal TC_DEC_Q1 : std_logic_vector(3 downto 0) := (others => '0');
signal TC_DEC_Q2 : std_logic_vector(3 downto 0) := (others => '0');
signal TC_DEC_Q3 : std_logic_vector(2 downto 0) := (others => '0');
signal TC_DEC_Y_PUNCTURING_PERIOD : std_logic_vector(4 downto 0) := (others => '0');
signal TC_DEC_Y_PUNCTURING_PATTERN : std_logic_vector(27 downto 0) := (others => '0');
signal TC_DEC_W_PUNCTURING_PATTERN : std_logic := '0';
signal UW1_PERIOD: unsigned(12 downto 0) := (others => '0');
signal TC_DEC_SYNC_RESET: std_logic := '0';

-- reconstruct implied SOFs/EOFs, serial to parallel conversion
signal TC_C_BIT_CNTR: unsigned(12 downto 0) := (others => '0');
signal TC_C_BIT_CNTR_INC: unsigned(12 downto 0) := (others => '0');
signal TC_C_DATA: std_logic_vector(7 downto 0) := x"00";
signal TC_C_DATA_VALID: std_logic := '0';
signal TC_C_SOF: std_logic := '0';
signal TC_C_EOF: std_logic := '0';
signal TC_C_SOFEOF: std_logic_vector(1 downto 0) := "00";
-- Received data dual port RAM
signal TC_C_DATA2: std_logic_vector(7 downto 0) := (others => '0');
signal TC_C_DATA2_VALID_E: std_logic := '0';
signal TC_C_DATA2_VALID: std_logic := '0';
signal TC_C_SOFEOF2: std_logic_vector(1 downto 0) := "00";
signal TC_C_SOF2: std_logic := '0';
signal TC_C_EOF2: std_logic := '0';
signal TC_C_WPTR: unsigned(11 downto 0) := (others => '0');
signal TC_C_RPTR: unsigned(11 downto 0) := (others => '0');
signal TC_DEC_BUF_SIZE: unsigned(11 downto 0) := (others => '0');
signal TC_DEC_BUF_EMPTY: std_logic := '0';
signal TC_C_CTS: std_logic := '0';

signal TC_D_DATA: std_logic_vector(1 downto 0) := "00";
signal TC_D_DATA_VALID: std_logic := '0';
signal TC_D_DATA_VALID_D: std_logic := '0';
signal TC_D_SOF: std_logic := '0';
signal TC_D_CTS: std_logic := '0';
signal TC_DEC_FRAME_ERROR_CNTR: std_logic_vector(31 downto 0) := (others => '0');

--//-- VITERBI FEC DECODER -------------------------------------------
signal FEC_DEC_G: std_logic_vector(62 downto 0) := (others => '0');
signal FEC_DEC_R1: integer range 1 to 7 := 1;
signal FEC_DEC_R2: integer range 2 to 8 := 2;
signal FEC_DEC_STANDARD: integer range 0 to 2 := 0;
signal FEC_DEC_DIFF_ENC_ON: std_logic := '0';
signal FEC_G1_INVERSION: std_logic := '0';

signal FEC_DEC_HIGH_SNR: std_logic := '0';
signal FEC_DEC_HIGH_SNR_D: std_logic := '0';
signal FEC_DEC_DATAIN: std_logic_vector(31 downto 0) := (others => '0');
signal FEC_DEC_DATAIN_VALID: std_logic := '0';
signal FEC_DEC_DATAIN_CNTR: unsigned(2 downto 0) := (others => '0');
signal FEC_DEC_BIT_VALID: std_logic := '0';
signal FEC_DEC_BIT: std_logic := '0';
signal FEC_DEC8b1: std_logic_vector(7 downto 0) := (others => '0');
signal FEC_DEC8b1_VALID: std_logic := '0';
signal FEC_DEC_LOCK_STATUS: std_logic := '0';
signal FEC_DEC_BER_COUNT: std_logic_vector(23 downto 0) := (others => '0');
signal FEC_DEC_BER_VALID: std_logic := '0';
signal FEC_DEC_BIT_ERROR: std_logic := '0';
signal FEC_DEC_IN_SYNC: std_logic := '0';
signal FEC_DEC_OUT_OF_SYNC: std_logic := '0';
signal FEC_DEC_LOCK_CONFIDENCE: unsigned(2 downto 0) := (others => '0');
signal FEC_DEC_CONFIRMED_LOCK: std_logic := '0';

--//-- DATA FORMAT CONVERTER (RX) --------------------------------------
signal NRZ1_RX_CONTROL: std_logic_vector(2 downto 0) := (others => '0');
signal NRZ1_RX_DATA1_IN: std_logic := '0';
signal NRZ1_RX_DATA1_VALID_IN: std_logic := '0';
signal NRZ1_RX_DATA1_OUT: std_logic := '0';
signal NRZ1_RX_DATA1_VALID_OUT: std_logic := '0';

--//-- BER MEASUREMENT  ---------------------------------------------------------
signal BER2_DATA_IN: std_logic_vector(7 downto 0) := (others => '0');
signal BER2_SAMPLE_CLK_IN: std_logic := '0';
signal BER_CONTROL: std_logic_vector(7 downto 0) := (others => '0');
signal BER_MF_DETECT: std_logic := '0';
signal BER_MF_DETECT_CONFIRMED: std_logic := '0';
signal BER_SYNC: std_logic := '0';
signal BER_BYTE_ERROR: std_logic := '0';
signal BER_ERROR_COUNT: std_logic_vector(31 downto 0) := (others => '0');
signal BER_TEST_POINT: std_logic_vector(10 downto 1) := (others => '0');

--// UDP OUTPUTS ------------------------------	
signal FIRST_BYTE1_FLAG: std_logic := '0';
signal S2P1_CNTR: unsigned(2 downto 0) := (others => '0');
signal S2P2_CNTR: unsigned(2 downto 0) := (others => '0');
signal S2P1_DATA_IN: std_logic_vector(7 downto 0) := (others => '0');
signal S2P2_DATA_IN: std_logic_vector(7 downto 0) := (others => '0');
signal S2P1_DATA_VALID_IN: std_logic := '0';
signal S2P1_DATA_VALID_INB: std_logic := '0';
signal TX_FRAME_CNTR1: unsigned(15 downto 0) := (others => '0');
signal TX_PREAMBLE1: std_logic_vector(111 downto 0) := (others => '0');
signal PACKET_TX_PULSE1: std_logic := '0';
signal LAN2_UDP_TX_MUX_STATE: integer range 0 to 2 := 0;

--//-- SERIAL OUTPUT (RX)  -------------------------------
signal RX_DATA1b0: std_logic_vector(0 downto 0) := "0";
signal RX_DATA1b1: std_logic_vector(0 downto 0) := "0";
signal RX_SAMPLE1b1_CLK_REQ: std_logic := '0';
signal RX_SAMPLE1b1_CLK_REQ_D: std_logic := '0';
signal RX_SAMPLE1b1_CLK_REQ_D2: std_logic := '0';
signal RX_SAMPLE1b1_CLK: std_logic := '0';
signal DEMOD_CLK1: std_logic := '0';
signal DEMOD_CLK1_D: std_logic := '0';
signal SERIAL_RX_DATA: std_logic := '0';
signal SERIAL_RX_EN: std_logic := '0';
signal SERIAL_RX_CLK: std_logic := '0';
signal CLEAN_CLK2_ERROR: std_logic := '0';

--// USB Interface for M&C
signal SREG254_READ_TOGGLE_D: std_logic := '0';
signal SREG254_READ_TOGGLE_D2: std_logic := '0';

--// ComScope traces
signal S1_1: std_logic_vector(7 downto 0) := (others => '0');	
signal S1_1_CLK: std_logic := '0';
signal S1_2: std_logic_vector(7 downto 0) := (others => '0');	
signal S1_2_CLK: std_logic := '0';
signal S1_3: std_logic_vector(7 downto 0) := (others => '0');	
signal S1_3_CLK: std_logic := '0';
signal S1_4: std_logic_vector(7 downto 0) := (others => '0');	
signal S1_4_CLK: std_logic := '0';
signal S2_1: std_logic_vector(7 downto 0) := (others => '0');	
signal S2_1_CLK: std_logic := '0';
signal S2_2: std_logic_vector(7 downto 0) := (others => '0');	
signal S2_2_CLK: std_logic := '0';
signal S2_3: std_logic_vector(7 downto 0) := (others => '0');	
signal S2_3_CLK: std_logic := '0';
signal S2_4: std_logic_vector(7 downto 0) := (others => '0');	
signal S2_4_CLK: std_logic := '0';
signal S3_1: std_logic_vector(7 downto 0) := (others => '0');	
signal S3_1_CLK: std_logic := '0';
signal S3_2: std_logic_vector(7 downto 0) := (others => '0');	
signal S3_2_CLK: std_logic := '0';
signal S3_3: std_logic_vector(7 downto 0) := (others => '0');	
signal S3_3_CLK: std_logic := '0';
signal S3_4: std_logic_vector(7 downto 0) := (others => '0');	
signal S3_4_CLK: std_logic := '0';
signal S4_1: std_logic_vector(7 downto 0) := (others => '0');	
signal S4_1_CLK: std_logic := '0';
signal S4_2: std_logic_vector(7 downto 0) := (others => '0');	
signal S4_2_CLK: std_logic := '0';
signal S4_3: std_logic_vector(7 downto 0) := (others => '0');	
signal S4_3_CLK: std_logic := '0';
signal S4_4: std_logic_vector(7 downto 0) := (others => '0');	
signal S4_4_CLK: std_logic := '0';

signal T1: std_logic := '0';
signal T1_CLK: std_logic := '0';
signal T2: std_logic := '0';
signal T2_CLK: std_logic := '0';

signal TRIGGER_REARM_TOGGLE: std_logic:= '0';
signal FORCE_TRIGGER_TOGGLE: std_logic:= '0';
signal START_CAPTURE_TOGGLE: std_logic:= '0';
signal SREG250_READ_TOGGLE: std_logic := '0';

--//-- DNA Port ------------------------------------
signal DNA_ID_DATA: std_logic_vector(56 downto 0) := (others => '0');
signal DNA_ID_SAMPLE_CLK: std_logic := '0';

--// ARM co-processor interface
signal UC_WEBG: std_logic := '0';  -- WE# through global buffer
signal UC_REBG: std_logic := '0';	-- RE# through global buffer
signal UC_ADDRESS: unsigned(7 downto 0) := (others => '0');
signal UC_AD_LOCAL: std_logic_vector(7 downto 0) := (others => '0');
signal UC_RDN_D: std_logic := '0';
signal UC_RDN_D2: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE0_D: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE0_D2: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE1_D: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE1_D2: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE2_D: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE2_D2: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE3_D: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE3_D2: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE5_D: std_logic := '0';
signal CONFIG_CHANGE_TOGGLE5_D2: std_logic := '0';
signal CONFIG_CHANGE_PULSE_P: std_logic := '0';
signal CONFIG_CHANGE_PULSE_P_D: std_logic := '0';
signal CONFIG_CHANGE_PULSE_P_D2: std_logic := '0';
signal CONFIG_CHANGE_PULSE_TX: std_logic := '0';
signal CONFIG_CHANGE_PULSE_TX_D: std_logic := '0';
signal CONFIG_CHANGE_PULSE_160: std_logic := '0';
signal CONFIG_CHANGE_PULSE_E: std_logic := '0';

signal RX_USB_LAN: std_logic_vector(7 downto 0) := (others => '0'); 
signal LAN_ADDR_CHANGE_TOGGLE: std_logic := '0';
signal LAN_ADDR_CHANGE_TOGGLE_D: std_logic := '0';
signal LAN_ADDR_CHANGE_TOGGLE_D2: std_logic := '0';
signal LAN_ADDR_CHANGE_PULSE: std_logic := '0';

--// Control Registers
constant NCREGS: integer := 74;	-- number of control registers.
constant NCREG_IMIN: integer := 0;	-- starting at this index
constant NCREG_IMAX: integer := (NCREG_IMIN+NCREGS-1);
type SLV8xNCREGStype is array (integer range NCREG_IMIN to NCREG_IMAX) of std_logic_vector(7 downto 0);
signal CREG: SLV8xNCREGStype;
signal REG255: std_logic_vector(7 downto 0) := (others => '0');
signal REG236: std_logic_vector(7 downto 0) := (others => '0');	-- MAC address LSB (to be defined at manufacturing)

--// Status Registers
constant NSREGS: integer := 46;	-- number of status registers.
constant NSREG_IMIN: integer := 7;	-- starting at this index
constant NSREG_IMAX: integer := (NSREG_IMIN+NSREGS-1);
type SLV8xNSREGStype is array (integer range NSREG_IMIN to NSREG_IMAX) of std_logic_vector(7 downto 0);
signal SREG: SLV8xNSREGStype := (others => (others => '0'));

signal SREG7_READ_TOGGLE: std_logic := '0';
signal SREG7_READ_TOGGLE_D: std_logic := '0';
signal SREG7_READ_TOGGLE_D2: std_logic := '0';
signal SREG7_READ_TOGGLE2_D: std_logic := '0';
signal SREG7_READ_TOGGLE2_D2: std_logic := '0';
signal LATCH_MONITORING_PULSE: std_logic := '0';
signal LATCH_MONITORING_PULSE_TX: std_logic := '0';
signal SREG254_READ_TOGGLE: std_logic := '0';			

--// ComScope control registers
signal REG237: std_logic_vector(7 downto 0):= "00000000";
signal REG238: std_logic_vector(7 downto 0):= "00000000";
signal REG239: std_logic_vector(7 downto 0):= "00000000";
signal REG240: std_logic_vector(7 downto 0):= "00001101";	-- Trace 1 signal selection
signal REG241: std_logic_vector(7 downto 0):= "00000000";	-- Trigger position, decimation
signal REG242: std_logic_vector(7 downto 0):= "00001110";	-- Trace 2 signal selection
signal REG243: std_logic_vector(7 downto 0):= "00000000";	-- Trigger position, decimation
signal REG244: std_logic_vector(7 downto 0):= "00000000";	-- Trace 3 signal selection
signal REG245: std_logic_vector(7 downto 0):= "00000000";	-- Trigger position, decimation
signal REG246: std_logic_vector(7 downto 0):= "00000000";	-- Trace 4 signal selection
signal REG247: std_logic_vector(7 downto 0):= "00000000";	-- Trigger position, decimation
signal REG248: std_logic_vector(7 downto 0):= "10001101";	-- Trigger edge, trigger signal
signal REG249: std_logic_vector(7 downto 0):= "10111111";	-- Trigger threshold
signal REG250: std_logic_vector(7 downto 0):= "00000000";
signal REG251: std_logic_vector(7 downto 0):= "00000000";






--------------------------------------------------------
--      IMPLEMENTATION
--------------------------------------------------------
begin
--//--------------------------------------------------------------------------
--// CLOCKS, RESETS 
--//--------------------------------------------------------------------------
-- Frequency plan: 
-- 19.2 MHz TCXO or 10 MHz external -> 160 MHz (one of several possible CLK_TX) 
-- -> 125 MHz with multiple phases (CLK_P, Ethernet LAN PHY)

SIM_001: if(SIMULATION = '1') generate
	 -- 10 MHz
    process
    begin
        CLK10g <= '0';
        wait for 50 ns;
        CLK10g <= '1';
        wait for 50 ns;
    end process;

    -- 19.2 MHz
    process
    begin
        CLKREF_TCXOg <= '0';
        wait for 26.04 ns;
        CLKREF_TCXOg <= '1';
        wait for 26.04 ns;
    end process; 
end generate;

REF_CLK_GEN_002: if(SIMULATION = '0') generate
   BUFG_001: BUFG port map(I => CLKREF_TCXO, O=> CLKREF_TCXOg);
   BUFG_002: BUFG port map (I => CLKREF_EXT, O => CLK10g1);

    -- generate alternative 10MHz clock from the always-present 19.2MHz TCXO clock 
     CLKGEN7C_001: CLKGEN7_MMCM_ADJ 
    GENERIC MAP(
		CLKFBOUT_MULT_F => 50.000,
		CLKOUT0_DIVIDE_F => 96.000,
		CLKIN1_PERIOD => 52.083
    ) 
    PORT MAP(
		CLK_IN1 => CLKREF_TCXOg,    -- 19.2 MHz TCXO clock 
		CLK_OUT1 => CLK10g0,    -- 10 MHz global
		PHASE_SHIFT_VAL => x"00",
		PHASE_SHIFT_TRIGGER_TOGGLE => '0',
		INPUT_CLK_STOPPED => CLK10_INPUT_CLK_STOPPED,
		LOCKED => CLK10_LOCKED,
		TP => open
    );

	-- select reference clock
	BUFGMUX_001 : BUFGMUX
	port map (
		O => CLK10g,   -- 1-bit output: Clock output
		I0 => CLK10g0, -- 1-bit input: Clock input (S=0)
		I1 => CLK10g1, -- 1-bit input: Clock input (S=1)
		S => CREG(0)(7)    -- 1-bit input: Clock select
	);

end generate;

-- generate 25 MHz from 10 MHz
CLKGEN7D_001: CLKGEN7_MMCM_ADJ 
GENERIC MAP(
	CLKFBOUT_MULT_F => 63.750,
	CLKOUT0_DIVIDE_F => 25.500,
	CLKIN1_PERIOD => 100.00
) 
PORT MAP(
	CLK_IN1 => CLK10g,    -- 10 MHz TCXO clock 
	CLK_OUT1 => CLK25g,    -- 25 MHz global
	PHASE_SHIFT_VAL => x"00",
	PHASE_SHIFT_TRIGGER_TOGGLE => '0',
	INPUT_CLK_STOPPED => CLK25_INPUT_CLK_STOPPED,
	LOCKED => CLK25_LOCKED,
	TP => open
);

-- generate 160 MHz from 10 MHz
CLKGEN7E_001: CLKGEN7_MMCM_ADJ 
GENERIC MAP(
	CLKFBOUT_MULT_F => 64.000,
	CLKOUT0_DIVIDE_F => 4.000,
	CLKIN1_PERIOD => 100.00
) 
PORT MAP(
	CLK_IN1 => CLK10g,    -- 10 MHz TCXO clock 
	CLK_OUT1 => CLK160g,    -- 160 MHz global
	PHASE_SHIFT_VAL => x"00",
	PHASE_SHIFT_TRIGGER_TOGGLE => '0',
	INPUT_CLK_STOPPED => CLK160_INPUT_CLK_STOPPED,
	LOCKED => CLK160_LOCKED,
	TP => open
);

-- generate multiple offsets for the 125 MHz clock 
-- Includes several delayed versions for LAN PHY  
  PLLE2_ADV_001 : PLLE2_ADV
  generic map
   (BANDWIDTH            => "LOW",

    
    COMPENSATION         => "ZHOLD",
    DIVCLK_DIVIDE        => 1,
    CLKFBOUT_MULT        => 40,
    CLKFBOUT_PHASE       => 0.000,
    CLKOUT0_DIVIDE       => 8,
    CLKOUT0_PHASE        => 0.000,
    CLKOUT0_DUTY_CYCLE   => 0.500,
    CLKOUT1_DIVIDE       => 8,
    CLKOUT1_PHASE        => 123.75,	-- (delay ns / 8ns)*360 deg*8 (because phase delay at vco) modulo 45 deg
    CLKOUT1_DUTY_CYCLE   => 0.500,
    CLKOUT2_DIVIDE       => 8,
    CLKOUT2_PHASE        => 0.000,
    CLKOUT2_DUTY_CYCLE   => 0.500,
    CLKOUT3_DIVIDE       => 8,
    CLKOUT3_PHASE        => 0.000,
    CLKOUT3_DUTY_CYCLE   => 0.500,
    CLKIN1_PERIOD        => 40.0)
  port map
    -- Output clocks
   (
    CLKFBOUT            => CLK125_FB,
    CLKOUT0             => CLK125,	-- reference 125MHz for LAN PHY 
    CLKOUT1             => CLK125_1,	-- controlled delay
    CLKOUT2             => open,
    CLKOUT3             => open,	
    CLKOUT4             => open,
    CLKOUT5             => open,
    -- Input clock control
    CLKFBIN             => CLK125_FB,
    CLKIN1              => CLK25g,
    CLKIN2              => '0',
    -- Tied to always select the primary input clock
    CLKINSEL            => '1',
    -- Ports for dynamic reconfiguration
    DADDR               => (others => '0'),
    DCLK                => '0',
    DEN                 => '0',
    DI                  => (others => '0'),
    DO                  => open,
    DRDY                => open,
    DWE                 => '0',
    -- Other control and status signals
    LOCKED              => CLK125_LOCKED,
    PWRDWN              => '0',
    RST                 => not CLK25_LOCKED);

BUFG_004: BUFG port map(I => CLK125, O => CLK_P);


--//-- TX PLL ------------------------------------------------
-- generate the programmable DAC sampling clock CLK_TXg from a 160 MHz 
-- Note: this code only works on series-7 Xilinx FPGA, using a runtime-programmable MMCM clock manager (or PLL with some minor modifications).
-- For older platforms, use HIGH_SPEED_NCO3 component.

CLK_TX_GEN_001: process(CLK160g)
begin
	if rising_edge(CLK160g) then
		CLK_TX_GEN_D <= CREG(1)(6 downto 0);  -- range 1 - 106
		CLK_TX_GEN_M <= CREG(3)(1 downto 0) & CREG(2);  -- range 2.0 - 64.0 in increment steps of 0.125 fixed point format 7.3 
		CLK_TX_GEN_O <= CREG(5)(2 downto 0) & CREG(4);  -- range 2.0 to 128.0 in increment steps of 0.125 fixed point format 8.3
		CLK160_LOCKED_D <= CLK160_LOCKED;
		if(CONFIG_CHANGE_PULSE_160 = '1') or ((CLK160_LOCKED = '1') and (CLK160_LOCKED_D = '0')) then
			CLK_TXRX_GEN_PROGRAM <= '1';
		else
			CLK_TXRX_GEN_PROGRAM <= '0';
		end if;
    end if;
end process;

CLK_TXRX_GEN_SYNC_RESET <= (not CLK125_LOCKED);
CLK_TX_GEN_002: CLKGEN7_MMCM_DYNAMIC 
GENERIC MAP(
  CLKIN1_PERIOD => 6.250,        -- 160 MHz frequency reference
  CLK_OUT2_PHASE => 225.000        -- phase offset from CLK_OUT1 to CLK_OUT2
)    
PORT MAP(
	CLK_IN1 => CLK160g,	-- 160 MHz frequency reference
	SYNC_RESET => CLK_TXRX_GEN_SYNC_RESET,	-- keep in reset until CLK_IN1 is stable (otherwise unknown state)
	D => CLK_TX_GEN_D,  -- range 1 - 106
	M => CLK_TX_GEN_M,   -- range 2.0 - 64.0 in increment steps of 0.125 fixed point format 7.3 
	O => CLK_TX_GEN_O,   -- range 2.0 to 128.0 in increment steps of 0.125 fixed point format 8.3
	PROGRAM => CLK_TXRX_GEN_PROGRAM, 
	CLK_OUT1 => CLK_TXg,	-- transmit clock (2^n * modulation symbol rate), GLOBAL
	CLK_OUT2 => open,
	INPUT_CLK_STOPPED => CLK_TX_GEN_INPUT_STOPPED,
	LOCKED => CLK_TX_GEN_LOCKED
);

-- report PLLs lock status and presence of input frequency reference(s)
SREG(9)(4 downto 0) <= '0' & CLK_TX_GEN_LOCKED & CLK125_LOCKED & CLK160_LOCKED & (not CLK25_INPUT_CLK_STOPPED);

 -- Generate miscellaneous global clocks and resets from the 
 -- reference clock 
 RESET_STATE_MACHINE_001: process(CLK10g)
 begin
	  if rising_edge(CLK10g) then
			-- PLL need time to lock. The reset of the application is still in reset
			if(RESET_COUNTER(17) = '0') and (SIMULATION = '0') then
				 -- wait a bit before asserting the PLL lock
				 RESET_COUNTER <= RESET_COUNTER + 1;
			elsif(RESET_COUNTER(5) = '0') and (SIMULATION = '1') then  
				 -- make it short during simulations
				 -- wait a bit before asserting the PLL lock
				 RESET_COUNTER <= RESET_COUNTER + 1;
			elsif(CLK125_LOCKED = '1') and (CLK160_LOCKED = '1') then
--			((CLK_TX_GEN_LOCKED = '1') or (MODULATOR_EN = '0')) and 
				 -- wait until all used PLLs are locked (however, do not wait for tx/rx clocks as 
				 -- bad configuration would prevent LAN communication.
				 RESET_STATE <= 1;
			end if;
			
			if(RESET_STATE = 1) then
				 ASYNC_RESET <= '0';
			else
				 ASYNC_RESET <= '1';
			end if;
	  end if;
end process;

-- generate a reset synchronous with CLK_160 at the end of the ASYNC_RESET
SYNC_RESET_CLK_160_GEN: process(ASYNC_RESET, CLK160g)
begin
	if rising_edge(CLK160g) then
		ASYNC_RESET1_D <= ASYNC_RESET;
		ASYNC_RESET1_D2 <= ASYNC_RESET1_D;
		
		if(ASYNC_RESET1_D = '0') and (ASYNC_RESET1_D2 = '1')  then
			SYNC_RESET_CLK160 <= '1';
		else
			SYNC_RESET_CLK160 <= '0';
		end if;
		
		-- '0' from power-up/async_reset until FPGA is ready
		if(SYNC_RESET_CLK160 = '1') then
			READY_FLAG_CLK160 <= '1';
		end if;
	end if;
end process;

-- generate a reset synchronous with CLK_P at the end of the ASYNC_RESET
SYNC_RESET_CLK_P_GEN: process(ASYNC_RESET, CLK_P)
begin
	if rising_edge(CLK_P) then
		ASYNC_RESET2_D <= ASYNC_RESET;
		ASYNC_RESET2_D2 <= ASYNC_RESET2_D;
		
		if(ASYNC_RESET2_D = '0') and (ASYNC_RESET2_D2 = '1')  then
			SYNC_RESET_CLK_P <= '1';
		else
			SYNC_RESET_CLK_P <= '0';
		end if;
		
		-- '0' from power-up/async_reset until FPGA is ready
		if(SYNC_RESET_CLK_P = '1') then
			READY_FLAG_CLK_P <= '1';
		end if;
		
	end if;
end process;

-- generate a reset synchronous with CLK_TXg as soon as PLL is locked
SYNC_RESET_CLK_TX_GEN: process(ASYNC_RESET, CLK_TXg)
begin
	if rising_edge(CLK_TXg) then
		ASYNC_RESET3_D <= ASYNC_RESET;
		ASYNC_RESET3_D2 <= ASYNC_RESET3_D;
		
		if(ASYNC_RESET3_D = '0') and (ASYNC_RESET3_D2 = '1')  then
			SYNC_RESET_CLK_TX <= '1';
		else
			SYNC_RESET_CLK_TX <= '0';
		end if;
		
		-- '0' from power-up/async_reset until FPGA is ready
		if(SYNC_RESET_CLK_TX = '1') then
			READY_FLAG_CLK_TX <= '1';
		end if;
	end if;
end process;

RECEIVER_RESET_CLK_P <= SYNC_RESET_CLK_P or CONFIG_CHANGE_PULSE_P;








	-- external input clock
BUFG_005: BUFG  port map (I=> UC_WEB_IN, O=> UC_WEBG);	
	-- ARM WE#
BUFG_006: BUFG  port map (I=> UC_REB_IN, O=> UC_REBG);	
	-- ARM RE#

-- 1s tick
TICK1S_001: TIMER_4US 
GENERIC MAP(
	CLK_FREQUENCY => CLK_P_FREQUENCY
)
PORT MAP(
	CLK => CLK_P,
	SYNC_RESET => SYNC_RESET_CLK_P,
	TICK_4US => TICK_4US,
	TICK_100MS => TICK_100MS
);
	
-- modulo-10 counter. 1s tick
TICK1S_002: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		if(SYNC_RESET_CLK_P = '1') then
			TICK_100MS_CNTR <= "0000";
			TOGGLE_1S <= '0';
		elsif(TICK_100MS = '1') then
			if(TICK_100MS_CNTR = 0) then
				TICK_100MS_CNTR <= "1001";
				TOGGLE_1S <= not TOGGLE_1S;
			else
				TICK_100MS_CNTR <= TICK_100MS_CNTR - 1;
			end if;
		end if;
	end if;
end process;

--//-- ETHERNET MAC#2  -----------------------------------
-- Interface with on-board GbE PHY: Micrel KSZ9031
-- Support 10/100/1000 Ethernet LAN.
-- Note: COM-1800 hardware rev 0 and 1 are limited to 100 Mbps unless the 25 MHz MEMS oscillator is replaced with
-- a low-jitter crystal-based oscillator (done in hw rev2)
CLK_SKEW21 <= x"0310"; 	 --(INTERNAL_PHY_CLKS_DELAYS => '0')
CLK_SKEW22 <= x"0000";    -- future	

-- new: MAC address automatically generated from unique DNA_ID
LAN2_MAC_ADDR <= x"02" & DNA_ID_DATA(31 downto 0) & REG236(7 downto 1) & "0";    -- possible race condition: ARM vs DNA_ID?
LAN_002: COM5401 
GENERIC MAP(
	MII_SEL => '0',   	   -- select which MII interface: 0 = RGMII, 1 = GMII/MII
	PHY_ADDR => "00111",   -- PHY_AD0/1 pulled-up, PHY_AD2 pulled-up in .xdc file.
	CLK_FREQUENCY => CLK_P_FREQUENCY,
	PLATFORM => 7,	       -- 7 series Xilinx FPGA
	TARGET_PHY => 3,       -- target PHY: KSZ9031
	NO_1000 => '0',	-- advertize full 10/100/1000 Mbps
	INTERNAL_PHY_TX_CLKS_DELAYS => '0',
	INTERNAL_PHY_RX_CLKS_DELAYS => '0',
	SIMULATION => SIMULATION
)
PORT MAP(
	CLK => CLK_P,
	SYNC_RESET => not READY_FLAG_CLK_P,	-- new 12/9/15 more reliable start
	CLK125_0 => CLK_P,
	CLK125_1 => CLK125_1, 
	CLK25 => CLK25g,
	MAC_TX_CONFIG => X"0003",	-- MAC must must provide pad + crc32
	MAC_RX_CONFIG => x"000F",	-- promiscuous mode, strip crc32, accept broadcast/multicast
	MAC_ADDR => LAN2_MAC_ADDR,
	PHY_CONFIG_CHANGE => LAN_ADDR_CHANGE_PULSE,		-- *080416
	PHY_RESET => '0',
	SPEED => "11",	-- supersedes defaults within if PHY_CONFIG_CHANGE = '1'
	DUPLEX => '1',	-- supersedes defaults within if PHY_CONFIG_CHANGE = '1'
	TEST_MODE => "00",	-- supersedes defaults within if PHY_CONFIG_CHANGE = '1'
	POWER_DOWN => '0', -- supersedes defaults within if PHY_CONFIG_CHANGE = '1'
	CLK_SKEW1 => CLK_SKEW21, -- supersedes defaults within if PHY_CONFIG_CHANGE = '1'
	CLK_SKEW2 => CLK_SKEW22, -- supersedes defaults within if PHY_CONFIG_CHANGE = '1'
	MAC_TX_DATA => LAN2_MAC_TX_DATA,
	MAC_TX_DATA_VALID => LAN2_MAC_TX_DATA_VALID,
	MAC_TX_EOF => LAN2_MAC_TX_EOF,
	MAC_TX_CTS => LAN2_MAC_TX_CTS,
	MAC_RX_DATA => LAN2_MAC_RX_DATA,	
	MAC_RX_DATA_VALID => LAN2_MAC_RX_DATA_VALID,
	MAC_RX_SOF => LAN2_MAC_RX_SOF,
	MAC_RX_EOF => LAN2_MAC_RX_EOF,
	MAC_RX_CTS => '1',  -- follow-on processing is expected to always accept data even at max speed.
	-- RGMII interface ----------------
	TXC => LAN_TXC,	
	TXD => LAN_TXD,
	TX_CTL => LAN_TX_CTL,
	RXC => LAN_RXC,
	RXD => LAN_RXD,
	RX_CTL => LAN_RX_CTL,
	RESET_N => LAN_RESET_N,
	MCLK => LAN_MCLK,
	MDIO => LAN_MDIO,	
	-- end of RGMII interface --------
	MII_TX_CLK => '0',	-- MII interface is unused -----
	GMII_TX_CLK => open,
	GMII_MII_TXD => open,
	GMII_MII_TX_EN => open,
	GMII_MII_TX_ER => open,
	GMII_MII_CRS => '0',
	GMII_MII_COL => '0',
	GMII_MII_RX_CLK => '0',
	GMII_MII_RXD => x"00",
	GMII_MII_RX_DV => '0',
	GMII_MII_RX_ER => '0',  -- end of MII interface ------
	LINK_STATUS => LAN2_LINK_STATUS,
	SPEED_STATUS => LAN2_SPEED_STATUS,
	DUPLEX_STATUS => LAN2_DUPLEX_STATUS,
	PHY_ID => LAN2_PHY_ID,
	N_RX_FRAMES => LAN2_N_RX_FRAMES,
	N_RX_BAD_CRCS => LAN2_N_RX_BAD_CRCS,
	N_RX_FRAMES_TOO_SHORT => LAN2_N_RX_FRAMES_TOO_SHORT,
	N_RX_FRAMES_TOO_LONG => LAN2_N_RX_FRAMES_TOO_LONG,
	N_RX_WRONG_ADDR => LAN2_N_RX_WRONG_ADDR,
	N_RX_LENGTH_ERRORS => LAN2_N_RX_LENGTH_ERRORS,
	CS_CLKG => open,
	CS1 => open,
	CS1_CLK => open,
	CS2 => open,
	CS2_CLK => open,
	CT1 => open,
	CT1_CLK => open,
	TP => LAN2_TP
);

SREG(8) <= LAN2_PHY_ID(7 downto 0);
-- fake input (to prevent optimization out). We need the pu/pd in .xdc
SREG(9)(7) <= LAN_CLK125;

--//-- IP STACK #2  -----------------------------------
-- 3 TCP connections
-- TCP Port 1028 for monitoring & control
-- TCP Port 1024 for modulator input data stream
-- TCP Port 1025 for demodulator output data stream
-- 1 transmit UDP 
-- reclock with CLK_P for easier P&R
RECLOCK_IP2: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		if(CONFIG_CHANGE_PULSE_P = '1') then
			IP2_ADDRv4(31 downto 0) <= CREG(47) & CREG(48) & CREG(49) & CREG(50);	-- local IP address
			SUBNET_MASK <= CREG(51) & CREG(52) & CREG(53) & CREG(54);
			GATEWAY_IP_ADDR <= CREG(55) & CREG(56) & CREG(57) & CREG(58);
			LAN2_UDP_TX_DEST_IP_ADDR(31 downto 0) <= CREG(59) & CREG(60) & CREG(61) & CREG(62); 
			LAN2_UDP_TX_DEST_PORT_NO <= CREG(64) & CREG(63);
		end if;
	end if;
end process;

IPSTACK_002: COM5402 
GENERIC MAP(
		NUDPTX => 1,
		NUDPRX => 1,
		IGMP_EN => '1',
		NTCPSTREAMS => NTCPSTREAMS2,  
		CLK_FREQUENCY => CLK_P_FREQUENCY,	-- CLK_P 125 MHz, as time reference
		TX_IDLE_TIMEOUT => 50,	-- 50*4us = 200us 
		TCP_KEEPALIVE_PERIOD => 60,		
		SIMULATION => SIMULATION
)
PORT MAP(
	CLK => CLK_P,
	SYNC_RESET => SYNC_RESET_CLK_P,
	MAC_ADDR => LAN2_MAC_ADDR,
	IPv4_ADDR => IP2_ADDRv4,
	IPv6_ADDR => x"00000000000000000000000000000000",
	MULTICAST_IP_ADDR => x"00000000",  -- no multicast
	SUBNET_MASK => SUBNET_MASK,
   GATEWAY_IP_ADDR => GATEWAY_IP_ADDR,
	CONNECTION_RESET => "000",
	TCP_KEEPALIVE_EN => "111",
	-- MAC interface
	MAC_TX_DATA => LAN2_MAC_TX_DATA,
	MAC_TX_DATA_VALID => LAN2_MAC_TX_DATA_VALID,
	MAC_TX_SOF => open,
	MAC_TX_EOF => LAN2_MAC_TX_EOF,
	MAC_TX_CTS => LAN2_MAC_TX_CTS,
	MAC_RX_DATA => LAN2_MAC_RX_DATA,
	MAC_RX_DATA_VALID => LAN2_MAC_RX_DATA_VALID,
	MAC_RX_SOF => LAN2_MAC_RX_SOF,
	MAC_RX_EOF => LAN2_MAC_RX_EOF,
	-- UDP rx
	UDP_RX_DATA => LAN2_UDP_RX_DATA,
	UDP_RX_DATA_VALID => LAN2_UDP_RX_DATA_VALID,
	UDP_RX_SOF => LAN2_UDP_RX_SOF, -- unused
	UDP_RX_EOF => LAN2_UDP_RX_EOF, 
	UDP_RX_DEST_PORT_NO_IN => x"0405",    -- port 1029  backdoor for reset command over UDP
	CHECK_UDP_RX_DEST_PORT_NO => '1',
	UDP_RX_DEST_PORT_NO_OUT => open,

	-- UDP tx
	UDP_TX_DATA => LAN2_UDP_TX_DATA,
	UDP_TX_DATA_VALID => LAN2_UDP_TX_DATA_VALID,
	UDP_TX_SOF => LAN2_UDP_TX_SOF,
	UDP_TX_EOF => LAN2_UDP_TX_EOF,
	UDP_TX_CTS => LAN2_UDP_TX_CTS,
	UDP_TX_ACK => LAN2_UDP_TX_ACK,
	UDP_TX_NAK => LAN2_UDP_TX_NAK,
	UDP_TX_DEST_IP_ADDR => LAN2_UDP_TX_DEST_IP_ADDR,
	UDP_TX_DEST_PORT_NO => LAN2_UDP_TX_DEST_PORT_NO,
	UDP_TX_SOURCE_PORT_NO => x"0402",	-- 1026
	-- TCP rx streams
	TCP_RX_DATA => LAN2_TCP_RX_DATA,
	TCP_RX_DATA_VALID => LAN2_TCP_RX_DATA_VALID,
	TCP_RX_RTS => open,
	TCP_RX_CTS => LAN2_TCP_RX_CTS,	
	-- TCP tx streams
	TCP_TX_DATA => LAN2_TCP_TX_DATA,
	TCP_TX_DATA_VALID => LAN2_TCP_TX_DATA_VALID,
	TCP_TX_CTS => LAN2_TCP_TX_CTS,	
	-- Monitoring
	TCP_CONNECTED_FLAG => LAN2_TCP_CONNECTED_FLAG,
--	CS1 => S1_1,
--	CS1_CLK => S1_1_CLK,
--	CS2 => S2_1,
--	CS2_CLK => S2_1_CLK,
	TP => IPSTACK2_TP	
);
LAN2_TCP_TX_DATA_VALID(1) <= '0';	-- port 1024 for modulation direction only

-- main taks is to reject bad UDP frames
PACKETS_2_STREAM_002: PACKETS_2_STREAM 
GENERIC MAP(
		NBUFS => 1    
)
PORT MAP(
    CLK => CLK_P,
    SYNC_RESET => not READY_FLAG_CLK_P,
    PACKET_DATA_IN => LAN2_UDP_RX_DATA,
    PACKET_DATA_VALID_IN => LAN2_UDP_RX_DATA_VALID,
    PACKET_EOF_IN => LAN2_UDP_RX_EOF,
    PACKET_CTS_OUT => open, -- no flow control here
    STREAM_DATA_OUT => LAN2_UDP_RX_DATA2,
    STREAM_DATA_VALID_OUT => LAN2_UDP_RX_DATA_VALID2,
    STREAM_SOF_OUT => open, 
    STREAM_EOF_OUT => open,
    STREAM_CTS_IN => LAN2_TCP_RX_CTS(0),
    BAD_PACKET => open,
    TP => open
);

-- one elastic buffer for each tcp rx stream
-- M&C, TCP port 1028 (port is defined within COM5402 component) OR UDP port 1029 
LAN2_RX_DATA0 <= LAN2_UDP_RX_DATA2 when (LAN2_UDP_RX_DATA_VALID2 = '1') else LAN2_TCP_RX_DATA(0);
LAN2_RX_SAMPLE0_CLK <= LAN2_UDP_RX_DATA_VALID2 or LAN2_TCP_RX_DATA_VALID(0);

ELASTIC_BUFFER_NRAMB2_001: ELASTIC_BUFFER_NRAMB2 
generic map(
	DATA_WIDTH => 8,
	ADDR_WIDTH => 11,	-- 16Kb buffer 
	READ_AHEAD_1ADDRESS => '1'	-- no read latency, tricky timing ok because ARM is slower.
)
PORT MAP(
	CLK => CLK_P,
	SYNC_RESET => not READY_FLAG_CLK_P,
	DATA_IN => LAN2_RX_DATA0,
	SAMPLE_CLK_IN => LAN2_RX_SAMPLE0_CLK,
	SAMPLE_CLK_IN_REQ => LAN2_TCP_RX_CTS(0),
	DATA_OUT => RX_LAN,	
	SAMPLE_CLK_OUT => open,
	SAMPLE_CLK_OUT_E => EB1_SAMPLE_CLK_OUT_E,
	SAMPLE_CLK_OUT_REQ => RX_LAN_SAMPLE_CLK_REQ,
	BUFFER_EMPTY => RX_LAN_BUFFER_EMPTY,
	USED => open
);

--//==============================================================================
--//==============================================================================
--// TRANSMITTER SECTION
--//==============================================================================
--//==============================================================================

--//-- FSK/MSK/GFSK/GMSK MODULATOR -------------------------------------
MODULATOR_GEN: if(MODULATOR_EN = '1') generate
	--//-- INPUTS SELECTION -------------------------------------
	CONTROLS_001: process(CLK_P)
	begin
	  if rising_edge(CLK_P) then
			INPUTS_SEL <= unsigned(CREG(0)(3 downto 0));
				-- tx input selection 
				-- 0 = no input
				-- 1 = LAN TCP, port 1024
				-- 2 N/A
				-- 3 = PRBS11 test sequence
				-- 4 = zero test sequence
				-- 5 = synchronous serial data bit + bit clock, left connector
				-- 6 = synchronous serial data bit + data enable + high-speed clock + flow control, left connector
				-- 7 = unmodulated test mode
	  end if;
	end process;

	-- Generate a pseudo-random binary sequence PRBS11 (to compute BER at the receiving end)
	-- two PRBS11 sequence generators
	PRBS11_SYNC_RESET1 <= '1' when (INPUTS_SEL /= 3) else (not READY_FLAG_CLK_P);
	LFSR11P_001: LFSR11P PORT MAP(
		CLK => CLK_P,
		SYNC_RESET => PRBS11_SYNC_RESET1,
		DATA_OUT => PRBS11_DATA1,
		SAMPLE_CLK_OUT => PRBS11_DATA1_VALID,
		SOF_OUT => open,
		SAMPLE_CLK_OUT_REQ => PRBS11_CTS1
	);

	-- input mux for 8-bit wide sources
	INPUT_SEL_001: process(CLK_P)
	begin
	  if rising_edge(CLK_P) then
		if(READY_FLAG_CLK_P = '0') then
			TX_DATA8b1_VALID <= '0';
		elsif(INPUTS_SEL = 1) then
			-- LAN TCP input, port 1024
			TX_DATA8b1 <= LAN2_TCP_RX_DATA(1);
			TX_DATA8b1_VALID <= LAN2_TCP_RX_DATA_VALID(1);
		elsif(INPUTS_SEL = 3) then
			-- PRBS11 test sequence
			TX_DATA8b1 <= PRBS11_DATA1;
			TX_DATA8b1_VALID <= PRBS11_DATA1_VALID;
		elsif(INPUTS_SEL = 4) then
			-- zeros
			TX_DATA8b1 <= (others => '0');
			TX_DATA8b1_VALID <= TX_DATA8b1_CTS;
		else
			-- disabled
			--TX_DATA8b1 <= (others => '0');
			TX_DATA8b1_VALID <= '0';
		end if;
	  end if;
	end process;
	PRBS11_CTS1 <= TX_DATA8b1_CTS when (INPUTS_SEL = 3) else '0';
	LAN2_TCP_RX_CTS(1) <= TX_DATA8b1_CTS when (INPUTS_SEL = 1) else '0';


--//-- PARALLEL TO SERIAL CONVERSION ----------------------------
	P8_TO_S1_CONVERSION_001: P8_TO_S1_CONVERSION PORT MAP(
		CLK => CLK_P,
		SYNC_RESET => SYNC_RESET_CLK_P,
		DATA8_IN => TX_DATA8b1,
		SAMPLE8_CLK_IN => TX_DATA8b1_VALID,
		SAMPLE8_CLK_IN_REQ => TX_DATA8b1_CTS,
		DATA1_OUT => TX_DATA1b1,
		SAMPLE1_CLK_OUT => TX_DATA1b1_VALID,
		SAMPLE1_CLK_OUT_REQ => TX_DATA1b1_CTS,
		BUF_EMPTY => P2S_BUF_EMPTY1	-- unused
	);

	-- input mux for 1-bit wide sources
	INPUT_SEL_002: process(CLK_P)
	begin
	  if rising_edge(CLK_P) then
		if(READY_FLAG_CLK_P = '0') then
			TX_DATA1b2_VALID <= '0';
			TX_SOF1b2 <= '0';
		elsif(INPUTS_SEL = 5) then
			-- from one-bit serial data plus bit clock input, left connector
			TX_DATA1b2_VALID <= TX_DATA1B_VALID_IN;
			TX_DATA1b2 <= TX_DATA1_IN;
			TX_SOF1b2 <= '0';
		elsif(INPUTS_SEL = 6) then
			-- from one-bit serial input with flow control, left connector
			TX_DATA1b2_VALID <= CCD1_SAMPLE_CLK_OUT;
			TX_DATA1b2 <= CCD1_DATA_OUT(0);
			TX_SOF1b2 <= CCD1_SOF_OUT;
		else
			-- from 8-bit serialized source (see 8-bit signal mux above)
			TX_DATA1b2_VALID <= TX_DATA1b1_VALID;
			TX_DATA1b2 <= TX_DATA1b1;
			TX_SOF1b2 <= '0';
		end if;
	  end if;
	end process;

	CCD1_SAMPLE_CLK_OUT_REQ <= TX_DATA1b2_CTS when (INPUTS_SEL = 6) else '0';
	TX_DATA1b1_CTS <= TX_DATA1b2_CTS when ((INPUTS_SEL /= 6) and (INPUTS_SEL /= 5)) else '0';

--//-- DATA FORMAT CONVERTER --------------------------------------
-- converts NRZ-L to NRZ-L/M/S
	NRZ1_TX_DATA1_VALID_IN <= TX_DATA1b2_VALID;
	NRZ1_TX_DATA1_IN <= TX_DATA1b2;


	NRZ_TX_CONTROL_001: process(CLK_P)
	begin
		if rising_edge(CLK_P) then
			case CREG(0)(6 downto 4) is
				when "000" => NRZ1_TX_CONTROL <= "000";	-- NRZ-L unchanged
				when "001" => NRZ1_TX_CONTROL <= "001";	-- NRZ-L to NRZ_M
				when others => NRZ1_TX_CONTROL <= "010";	-- NRZ-L to NRZ_S
			end case;
		end if;
	end process;

	NRZ1_TX_001: NRZ1 PORT MAP(
		CLK => CLK_P,
		SYNC_RESET => SYNC_RESET_CLK_P,
		DATA_IN => NRZ1_TX_DATA1_IN,
		DATA_VALID_IN => NRZ1_TX_DATA1_VALID_IN,
		CONTROL => NRZ1_TX_CONTROL,
		DATA_OUT => ENC_DATA_IN,
		DATA_VALID_OUT => ENC_SAMPLE_CLK_IN
	);

--//-- TURBO CODE ENCODER --------------------------------------------
TC_ENCODER_001: if(TC_CONVN_CODEC = '1') generate
    -- select TC codec

-- encoder configuration
TC_ENC_CONFIG_001: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		TC_ENC_SYNC_RESET <= SYNC_RESET_CLK_P or CONFIG_CHANGE_PULSE_P;
		
		TC_ENC_BURST_PAYLOAD_SIZE <= CREG(65);
			-- preferred sizes 14,63,250 BYTES
			-- Limit size to <256 bytes to keep decoder size reasonably small
		case CREG(66)(3 downto 0) is
			when "0000" => TC_ENC_R1 <= "001"; TC_ENC_R2 <= "0011";	-- rate 1/3
			when "0001" => TC_ENC_R1 <= "001"; TC_ENC_R2 <= "0010";	-- rate 1/2
			when "0010" => TC_ENC_R1 <= "010"; TC_ENC_R2 <= "0011";	-- rate 2/3
			when "0011" => TC_ENC_R1 <= "011"; TC_ENC_R2 <= "0100";	-- rate 3/4
			when "0100" => TC_ENC_R1 <= "100"; TC_ENC_R2 <= "0101";	-- rate 4/5
			when "0101" => TC_ENC_R1 <= "101"; TC_ENC_R2 <= "0110";	-- rate 5/6
			when "0110" => TC_ENC_R1 <= "110"; TC_ENC_R2 <= "0111";	-- rate 6/7
			when others => TC_ENC_R1 <= "111"; TC_ENC_R2 <= "1000";	-- rate 7/8
		end case;
		TC_E_BLOCK_SIZE <= CREG(68)(6 downto 0) & CREG(67);
			-- encoded block size in bits. Does not include unique word
	end if;
end process;
TC_ENC_BURST_PAYLOAD_SIZEx <= "00" & TC_ENC_BURST_PAYLOAD_SIZE;

TC_ENC_CONFIG_002: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		if(unsigned(CREG(66)(3 downto 0)) = 0) then
			-- Rate 1/3. Only case when W parity bit is enabled
			TC_ENC_W_PUNCTURING_PATTERN <= '1';
		else
			TC_ENC_W_PUNCTURING_PATTERN <= '0';
		end if;
		
		case CREG(66)(3 downto 0) is
			when "0000" => -- rate 1/3
				TC_ENC_Y_PUNCTURING_PERIOD <= "00001";	-- 1
				TC_ENC_Y_PUNCTURING_PATTERN <= "0000000000000000000000000001";  -- flipped punct. pattern.
			when "0001" => -- rate 1/2
				TC_ENC_Y_PUNCTURING_PERIOD <= "00001";	-- 1
				TC_ENC_Y_PUNCTURING_PATTERN <= "0000000000000000000000000001";  -- flipped punct. pattern.
			when "0010" => -- rate 2/3
				TC_ENC_Y_PUNCTURING_PERIOD <= "00010";	-- 2
				TC_ENC_Y_PUNCTURING_PATTERN <= "0000000000000000000000000001";  -- flipped punct. pattern.
			when "0011" => -- rate 3/4
				TC_ENC_Y_PUNCTURING_PERIOD <= "00110";	-- 6
				TC_ENC_Y_PUNCTURING_PATTERN <= "0000000000000000000000000101";  -- flipped punct. pattern.
			when "0100" => -- rate 4/5
				TC_ENC_Y_PUNCTURING_PERIOD <= "00100";	-- 4
				TC_ENC_Y_PUNCTURING_PATTERN <= "0000000000000000000000000001";  -- flipped punct. pattern.
			when "0101" => -- rate 5/6
				TC_ENC_Y_PUNCTURING_PERIOD <= "10100";	-- 20
				TC_ENC_Y_PUNCTURING_PATTERN <= "0000000000000001000100010001";  -- flipped punct. pattern.
			when "0110" => -- rate 6/7
				TC_ENC_Y_PUNCTURING_PERIOD <= "01100";	-- 12
				TC_ENC_Y_PUNCTURING_PATTERN <= "0000000000000000000000010001";  -- flipped punct. pattern.
			when others => -- rate 7/8
				TC_ENC_Y_PUNCTURING_PERIOD <= "11100";	-- 28
				TC_ENC_Y_PUNCTURING_PATTERN <= "0000000100000001000000010001";  -- flipped punct. pattern.
		end case;
	end if;
end process;

TC_ENC_N(9 downto 2) <= unsigned(TC_ENC_BURST_PAYLOAD_SIZE);
TC_ENC_N(1 downto 0) <= "00";	-- number of N couples (K/2)
TC_ENC_P <= "0011101";
TC_ENC_Q0 <= "0001";
TC_ENC_Q1 <= "0100";
TC_ENC_Q2 <= "0001";
TC_ENC_Q3 <= "001";

-- safe coding. Add a small elastic buffer to ensure proper gap between successive frames
-- when the source is slow in responding to the clear-to-send flow control signal
ELASTIC_BUFFER16b_001: ELASTIC_BUFFER16b PORT MAP(
	CLK => CLK_P,
	SYNC_RESET => SYNC_RESET_CLK_P,
	DATA_IN => ENC_DATA_IN,
	SAMPLE_CLK_IN => ENC_SAMPLE_CLK_IN,
	SAMPLE_CLK_IN_REQ => ENC_SAMPLE_CLK_IN_REQ,
	DATA_OUT => ENC_DATA_IN2,
	SAMPLE_CLK_OUT => ENC_SAMPLE_CLK_IN2,
	SAMPLE_CLK_OUT_REQ => ENC_SAMPLE_CLK_IN2_REQ
);
ENC_SAMPLE_CLK_IN2_REQ <= TC_U_CTS when (TC_U_EOF = '0') and (TC_U_EOF_E = '0') else '0';

-- 1-bit serial to 2-bit parallel conversion
TC_U_EOF_E <= '1' when (ENC_SAMPLE_CLK_IN2 = '1') and (TC_ENC_CNTR(TC_ENC_CNTR'left downto 1) = TC_ENC_N-1) and (TC_ENC_CNTR(0) = '1') else '0';
CNTR_GEN: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		if(TC_ENC_SYNC_RESET = '1') then
			TC_ENC_CNTR <= (others => '0');
			TC_U_DATA_VALID <= '0';
			TC_U_SOF <= '0';
			TC_U_EOF <= '0';
		elsif(ENC_SAMPLE_CLK_IN2 = '1') then
			TC_ENC_CNTR <= TC_ENC_CNTR + 1;
			TC_U_DATA(0) <= TC_U_DATA(1);		-- A
			TC_U_DATA(1) <= ENC_DATA_IN2;		-- B
				-- ENC_DATA_IN2 sequence is A0, B0, A1, B1, etc
			
			if(TC_ENC_CNTR(TC_ENC_CNTR'left downto 1) < TC_ENC_N) and (TC_ENC_CNTR(0) = '1') then
				TC_U_DATA_VALID <= '1';
			else
				TC_U_DATA_VALID <= '0';
			end if;
			if(TC_ENC_CNTR(TC_ENC_CNTR'left downto 1) = 0) and (TC_ENC_CNTR(0) = '1') then
				TC_U_SOF <= '1';
			else
				TC_U_SOF <= '0';
			end if;
			if(TC_ENC_CNTR(TC_ENC_CNTR'left downto 1) = TC_ENC_N-1) and (TC_ENC_CNTR(0) = '1') then
				TC_U_EOF <= '1';
				TC_ENC_CNTR <= (others => '0');
			else
				TC_U_EOF <= '0';
			end if;
		else
			TC_U_DATA_VALID <= '0';
			TC_U_SOF <= '0';
			TC_U_EOF <= '0';
		end if;	
	end if;
end process;

TC_ENCODER_DVB_RCS2_001: TC_ENCODER_DVB_RCS2 
GENERIC MAP	(
	SIMULATION => SIMULATION
)
PORT MAP(
	CLK => CLK_P,
	SYNC_RESET => TC_ENC_SYNC_RESET,
	DATA_IN => TC_U_DATA,
	DATA_IN_VALID => TC_U_DATA_VALID,
	SOF_IN => TC_U_SOF,
	CTS_OUT => TC_U_CTS,
	BURST_PAYLOAD_SIZE => TC_ENC_BURST_PAYLOAD_SIZEx,
	R1 => TC_ENC_R1,
	R2 => TC_ENC_R2,
	P => TC_ENC_P,
	Q0 => TC_ENC_Q0,
	Q1 => TC_ENC_Q1,
	Q2 => TC_ENC_Q2,
	Q3 => TC_ENC_Q3,
	Y_PUNCTURING_PERIOD => TC_ENC_Y_PUNCTURING_PERIOD,
	Y_PUNCTURING_PATTERN => TC_ENC_Y_PUNCTURING_PATTERN,
	W_PUNCTURING_PATTERN => TC_ENC_W_PUNCTURING_PATTERN,
	CRC16_EN => '0',
	DATA_OUT => TC_E_DATA,
	DATA_OUT_VALID => TC_E_DATA_VALID, 
	SOF_OUT => TC_E_SOF, 
	EOF_OUT => TC_E_EOF, 
	CTS_IN => TC_E_CTS,
	N_PARITY_BITS => TC_ENC_N_PARITY_BITS,
	N_PARITY_BITS_RDY => TC_ENC_N_PARITY_BITS_RDY,
	TP => TC_TP
);
TC_E_CTS <= '1' when (TX_SAMPLE8b2_CLK_REQ = '1') and (TC_E_CTS_D = '0') and (TC_E_EOF = '0') else '0';
	-- encoder output flow control. Insert a 1 CLK gap between two output symbols so that we can serialize the 2 bits.

-- TC encoder output state machine
UW_GEN_001: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		TC_E_CTS_D <= TC_E_CTS;
		TC_E_DATA_VALID_D <= TC_E_DATA_VALID;
		TC_E_EOF_D <= TC_E_EOF;
		TC_E_DATA_D1 <= TC_E_DATA(1);	-- B bit
		
		-- count frames as the unique word is transmitted only once every 1,2,4,8 frames.
		if(SYNC_RESET_CLK_P = '1') then
			TC_ENC_FRAME_CNTR <= (others => '0');
		elsif(TC_E_SOF = '1') then
			-- end of encoded frame. Insert a UW next? depends on frame size
			if(TC_ENC_FRAME_CNTR >= TC_ENC_FRAME_CNTR_MAX) then
				TC_ENC_FRAME_CNTR <= (others => '0');
			else
				TC_ENC_FRAME_CNTR <= TC_ENC_FRAME_CNTR + 1;
			end if;
		end if;
	end if;
end process;

-- Special cases if short frame: unique word is transmitted only once every 1,2,4,8 frames.
UW_GEN_002: process(TC_E_BLOCK_SIZE)
begin
	if(unsigned(TC_E_BLOCK_SIZE) < 256) then	-- < 256 bit long encoded block size
		TC_ENC_FRAME_CNTR_MAX <= "111";
		TC_E_BLOCK_SIZE2 <= TC_E_BLOCK_SIZE(11 downto 0) & "000";
	elsif(unsigned(TC_E_BLOCK_SIZE) < 512) then	-- < 512 bit long encoded block size
		TC_ENC_FRAME_CNTR_MAX <= "011";
		TC_E_BLOCK_SIZE2 <= TC_E_BLOCK_SIZE(12 downto 0) & "00";
	elsif(unsigned(TC_E_BLOCK_SIZE) < 1024) then	-- < 1024 bit long encoded block size
		TC_ENC_FRAME_CNTR_MAX <= "001";
		TC_E_BLOCK_SIZE2 <= TC_E_BLOCK_SIZE(13 downto 0) & "0";
	else	-- >= 1024 bit long payload size
		TC_ENC_FRAME_CNTR_MAX <= "000";
		TC_E_BLOCK_SIZE2 <= TC_E_BLOCK_SIZE;
	end if;
end process;

-- Also serialize encoded data and unique word. Bit order is A0, B0, A1, B1, etc
-- bypass TC encoder? 
TX_DATA1b3 <= 	ENC_DATA_IN when (ENCODER_ENABLED = '0') else	-- bypass case
					TC_E_DATA(0) when (TC_E_DATA_VALID = '1') else
					TC_E_DATA_D1 when (TC_E_DATA_VALID_D = '1') else 
					'0';
TX_SAMPLE1b3_CLK <= 	ENC_SAMPLE_CLK_IN when (ENCODER_ENABLED = '0') else	-- bypass case
							'1' when (TC_E_DATA_VALID = '1') else 
							'1' when (TC_E_DATA_VALID_D = '1') else 
							'0';

TX_SOF1b3 <= 	TC_E_SOF when (ENCODER_ENABLED = '1') and (TC_ENC_FRAME_CNTR = 0) else	'0';
	-- if short frame: unique word is transmitted only once every 1,2,4,8 frames.
TX_EOF1b3 <= 	TC_E_EOF_D when (ENCODER_ENABLED = '1') else	'0';
	
-- 1-bit serial to 8-bit parallel conversion
-- first bit in a frame aligned with MSb
S1_TO_P8_CONVERSION_001: S1_TO_P8_CONVERSION PORT MAP(
	CLK => CLK_P,
	SYNC_RESET => SYNC_RESET_CLK_P,
	DATA1_IN => TX_DATA1b3,
	SAMPLE1_CLK_IN => TX_SAMPLE1b3_CLK,
	SOF1_IN => TX_SOF1b3,
	EOF1_IN => TX_EOF1b3,
	DATA8_OUT => TX_DATA8b2,
	SAMPLE8_CLK_OUT => TX_SAMPLE8b2_CLK,
	SOF8_OUT => TX_SOF8b2,
	EOF8_OUT => TX_EOF8b2
);

TX_DATA1b2_CTS <= ENC_SAMPLE_CLK_IN_REQ when (ENCODER_ENABLED = '1') else TX_SAMPLE8b2_CLK_REQ;
	
-- The modulator operates with a different synchronous clock
X_CLK_DOMAINS_NODATALOSS_004: CROSS_CLK_DOMAINS_NODATALOSS 
GENERIC MAP(
	DATA_WIDTH => 8,
	ADDR_WIDTH => 7,
	LOW_LATENCY => '0'	
)
PORT MAP(
	CLK_A => CLK_P,
	CLK_B => CLK_TXg,
	ASYNC_RESET => SYNC_RESET_CLK_P,
	DATA_IN => TX_DATA8b2,
	SAMPLE_CLK_IN => TX_SAMPLE8b2_CLK,
	SOF_IN => TX_SOF8b2,
	EOF_IN => TX_EOF8b2,
	SAMPLE_CLK_IN_REQ => TX_SAMPLE8b2_CLK_REQ,	
	DATA_OUT => TX_DATA8b4,
	SAMPLE_CLK_OUT => TX_DATA8b4_VALID,
	SOF_OUT => TX_SOF8b4,
	EOF_OUT => TX_EOF8b4,	-- unused
	SAMPLE_CLK_OUT_REQ => TX_DATA8b4_CTS
);
end generate;

--//-- CONVOLUTIONAL ENCODING ----------------------------------
-- Current implementation is serial. However, plan for 8-bit interface component at higher speeds.
-- For the moment, the ENCODER_ROOT is surrounded by parallel to serial and serial to parallel conversions.
CONV_ENCODER_001: if(TC_CONVN_CODEC = '0') generate
	CENC_CONTROL(0) <= '0';	-- N/A
	CENC_CONTROL(4 downto 1) <= "1011";	-- K=7,R=1/2, CCSDS
	CENC_CONTROL(5) <= '0';	-- no differential encoding
	CENC_CONTROL(6) <= '0';	-- continuous mode only
	CENC_CONTROL(7) <= '0';	-- N/A
	CENC_CONTROL(9 downto 8) <= "00";	-- 1-bit wide output
	CENC_CONTROL(11 downto 10) <= "00";	-- N/A
	CENC_CONTROL(12) <= '0';	-- flow control set by modulator symbol rate
	CENC_CONTROL(15 downto 13) <= "000";	-- N/A
	
	ENCODER_ROOT_1: ENCODER_ROOT PORT MAP(
		CLK => CLK_P,
		ASYNC_RESET => ASYNC_RESET,
		DATA_IN => ENC_DATA_IN,	
		SAMPLE_CLK_IN => ENC_SAMPLE_CLK_IN,	
		SAMPLE_CLK_IN_REQ => ENC_SAMPLE_CLK_IN_REQ, 
		SOF_RESET => '0',
		DATA_OUT => CENC1_DATA_OUT,
		SAMPLE_CLK_OUT => CENC1_SAMPLE_CLK_OUT,
		SAMPLE_CLK_OUT_REQ => TX_DATA8b3_CTS,
		CONTROL => CENC_CONTROL,
		TP => open
	);

	
	-- bypass encoder? 
	TX_DATA1b3 <= CENC1_DATA_OUT(0) when (ENCODER_ENABLED = '1') else ENC_DATA_IN;
	TX_DATA1b3_VALID <= CENC1_SAMPLE_CLK_OUT when (ENCODER_ENABLED = '1') else ENC_SAMPLE_CLK_IN;
	TX_DATA1b2_CTS <= ENC_SAMPLE_CLK_IN_REQ when (ENCODER_ENABLED = '1') else TX_DATA8b3_CTS;


	-- 1-bit serial to 8-bit parallel conversion
	-- first bit in a frame aligned with MSb
	S1_TO_P8_CONVERSION_001: S1_TO_P8_CONVERSION PORT MAP(
		CLK => CLK_P,
		SYNC_RESET => SYNC_RESET_CLK_P,
		DATA1_IN => TX_DATA1b3,
		SAMPLE1_CLK_IN => TX_DATA1b3_VALID,
		SOF1_IN => '0',
		EOF1_IN => '0',
		DATA8_OUT => TX_DATA8b3,		-- 8-bit parallel output,
		SAMPLE8_CLK_OUT => TX_DATA8b3_VALID,
		SOF8_OUT => open,
		EOF8_OUT => open
	);

	-- The modulator operates with a different synchronous clock
	X_CLK_DOMAINS_NODATALOSS_004: CROSS_CLK_DOMAINS_NODATALOSS 
	GENERIC MAP(
		DATA_WIDTH => 8,
		ADDR_WIDTH => 10,	-- TBC
		LOW_LATENCY => '0'	
	)
	PORT MAP(
		CLK_A => CLK_P,
		CLK_B => CLK_TXg,
		ASYNC_RESET => ASYNC_RESET,
		DATA_IN => TX_DATA8b3,
		SAMPLE_CLK_IN => TX_DATA8b3_VALID,
		SOF_IN => '0',
		EOF_IN => '0',
		SAMPLE_CLK_IN_REQ => TX_DATA8b3_CTS,	
		DATA_OUT => TX_DATA8b4,
		SAMPLE_CLK_OUT => TX_DATA8b4_VALID,
		SOF_OUT => open,
		EOF_OUT => open,
		SAMPLE_CLK_OUT_REQ => TX_DATA8b4_CTS
	);
end generate;


	--//---------------------------------------------------------
	--// CPM MODULATOR 
	--//---------------------------------------------------------
	MOD_CONTROLS_GEN: process(CLK_TXg)
	begin
		if rising_edge(CLK_TXg) then
			CONFIG_CHANGE_PULSE_TX_D <= CONFIG_CHANGE_PULSE_TX;
			
			-- design note: it may take several clocks for ALL parameters to be configured (check dependencies)
			ENCODER_ENABLED <= CREG(45)(0);
			MOD_SYMBOL_RATE_NDIV <= CREG(5)(7 downto 4);
				-- Symbol rate expressed as (modulator processing clock) / 2^MOD_SYMBOL_RATE_NDIV
			if(CREG(6)(7 downto 4) = x"5") or (CREG(6)(7 downto 4) = x"6") then
				-- SOQPSK. M=3
				MOD_CONTROL(2 downto 0) <= "011";
			else
				-- M=2 for all other modulation types
				MOD_CONTROL(2 downto 0) <= "000";
			end if;
			MOD_CONTROL(7 downto 4) <= CREG(6)(7 downto 4); -- frequency shaping filter
			if(INPUTS_SEL = 7) then	
				MOD_CONTROL(9 downto 8) <= "11"; -- unmodulated carrier
			else
				MOD_CONTROL(9 downto 8) <= "00"; 
			end if;
			if(CREG(6)(7 downto 4) = x"5") or (CREG(6)(7 downto 4) = x"6") then
				-- SOQPSK. need a sync word to resolve phase ambiguity 
				MOD_CONTROL(10) <= '1';	-- sync word insertion needed 
				if(TC_CONVN_CODEC =  '1') and (ENCODER_ENABLED = '1')then
					MOD_BURST_LENGTH <= TC_E_BLOCK_SIZE2(12 downto 0);
				else
					MOD_BURST_LENGTH <= "0100000000000";	-- 2048 payload symbols
				end if;
			elsif(TC_CONVN_CODEC =  '1') and (ENCODER_ENABLED = '1')then
				-- turbo code is a block code: sync word insertion needed
				MOD_CONTROL(10) <= '1';	-- sync word insertion needed 
				MOD_BURST_LENGTH <= TC_E_BLOCK_SIZE2(12 downto 0);
			else
				MOD_CONTROL(10) <= '0';	-- no sync word insertion needed for other cases
				MOD_BURST_LENGTH <= (others => '0');
			end if;
			MOD_CONTROL(11) <= CREG(7)(6);	-- spectrum inversion
			MOD_INDEX <= CREG(9) & CREG(8);	-- unsigned format 4.12  Range [0,8[
			MOD_SIGNAL_SCALING <= CREG(11) & CREG(10);
			MOD_CENTER_FREQ <= CREG(17) & CREG(16) & CREG(15) & CREG(14);
				-- Modulator center frequency (fine tuning)
		end if;
	end process;
	
	-- fake TX_SOF when not using turbo code (once every 2048 symbols)
	FAKE_TX_SOF_GEN: process(CLK_TXg)
	begin
		if rising_edge(CLK_TXg) then
			if(TX_DATA8b4_VALID = '1') then
				FAKE_TX_SOF_CNTR <= FAKE_TX_SOF_CNTR + 1;
				if(FAKE_TX_SOF_CNTR = 255) then
					FAKE_TX_SOF_FLAG <= '1';
				else
					FAKE_TX_SOF_FLAG <= '0';
				end if;
			end if;
		end if;
	end process;
	FAKE_TX_SOF <= FAKE_TX_SOF_FLAG and TX_DATA8b4_VALID;
	
	TX_SOF <= TX_SOF8b4 when (TC_CONVN_CODEC =  '1') and (ENCODER_ENABLED = '1') else FAKE_TX_SOF;

	MOD_RESET <= SYNC_RESET_CLK_TX or CONFIG_CHANGE_PULSE_TX_D;
		
	COM1827_TX_001: COM1827_TX 
	GENERIC MAP(
       FIRST_PREAMBLE_EXTENSION => 0,	
		 SYNC_LENGTH => 32,	
       SYNC_WORD => x"5A0FBE66000000000000000000000000",
		 GAP_LENGTH => 0,	
       SIMULATION => SIMULATION
   )
	PORT MAP(
		CLK => CLK_TXg,
		SYNC_RESET => MOD_RESET,
		TX_DATA => TX_DATA8b4,
		TX_DATA_SAMPLE_CLK => TX_DATA8b4_VALID,
		TX_SOF => TX_SOF,
		TX_CTS => TX_DATA8b4_CTS,
		SYMBOL_RATE_NDIV => MOD_SYMBOL_RATE_NDIV,
		MODULATION_INDEX => MOD_INDEX,
		CENTER_FREQ => MOD_CENTER_FREQ,
		GAIN => MOD_SIGNAL_SCALING,
		TX_WINDOW => '1',
		MASTER_SLAVEN => '1',
		BURST_LENGTH => MOD_BURST_LENGTH,
		CONTROL => MOD_CONTROL,
		DATA_I_OUT => MOD_DATA1_I,
		DATA_Q_OUT => MOD_DATA1_Q,
		TX_EN_OUT => MOD_TX_EN,	-- goes to '0' when there is no data to transmit
		SYMBOL_CLKx4_OUT => MOD_SYMBOL_CLKx4,
		CS1 => open,
		CS1_CLK => open,
		SATURATION => MOD_SATURATION,
		TP => TP_MOD
	);
	
	

	-- report saturation
	MONITORING_003: process(CLK_TXg)
	begin
		if rising_edge(CLK_TXg) then
			if(LATCH_MONITORING_PULSE_TX = '1') then
				-- latch in multi-byte status registers upon reading status register SREG(7)
				SREG(10)(1 downto 0) <= MOD_SATURATION2;
				MOD_SATURATION2 <= (others => '0');	-- clear 
			else
				MOD_SATURATION2(1 downto 0) <= MOD_SATURATION2(1 downto 0) or MOD_SATURATION;
			end if;
		end if;
	end process;
	

	 -- enable/disable the modulated signal based on CREG(7)(7)
	 MOD_DATA2_I <= (MOD_DATA1_I & "00") when (CREG(7)(7) = '1') else (others => '0');
	 MOD_DATA2_Q <= (MOD_DATA1_Q & "00") when (CREG(7)(7) = '1') else (others => '0');

    -- measure power (modulated signal)
    POWER_MEASUREMENT_001: POWER_MEASUREMENT PORT MAP(
        CLK => CLK_TXg,
        SYNC_RESET => SYNC_RESET_CLK_TX,
        SAMPLE_CLK_IN => '1',
        DATA_I_IN => MOD_DATA2_I,
        DATA_Q_IN => MOD_DATA2_Q,
        SAMPLE_CLK_OUT => open,
        POWER_OUT => MOD_SIGNAL_POWER
    );

    -- report power measurements through status registers
    -- monitoring
   MONITORING_002a: process(CLK_TXg)
    begin
        if rising_edge(CLK_TXg) then
            if(LATCH_MONITORING_PULSE_TX = '1') then
                SREG(11) <= MOD_SIGNAL_POWER(7 downto 0);
                SREG(12) <= MOD_SIGNAL_POWER(15 downto 8);
                SREG(13) <= MOD_SIGNAL_POWER(23 downto 16);
            end if;
        end if;
    end process;
    
    --// ADDITIVE WHITE GAUSSIAN NOISE -------------------------------------
	AWGN_001: if(AWGN_EN = '1') generate
		 RECLOCK_002: process(CLK_TXg)
		 begin
			  if rising_edge(CLK_TXg) then
					-- maximum gain: x4.0
					NOISE_GAIN <= "0" & CREG(13) & CREG(12);   
			  end if;
		 end process;

		 -- Add noise for test purposes. 
		 -- latency 6 CLKs
		 AWGN_001: AWGN PORT MAP(
			  CLK => CLK_TXg,
			  SAMPLE_CLK_REQ => MOD_SYMBOL_CLKx4,    -- independent noise sample (complex). Defines the noise bandwidth. 
			  SYNC_RESET => SYNC_RESET_CLK_TX,
			  SAMPLE_CLK_OUT => open,
			  NOISE_SAMPLE1_OUT => NOISE_DATA1_I,
			  NOISE_SAMPLE2_OUT => NOISE_DATA1_Q
		 );

		 -- reclock before multiplier for better timing
		 GAIN_000: process(CLK_TXg)
		 begin
			  if rising_edge(CLK_TXg) then
					MOD_SAMPLE_CLK_SHIFT(9 downto 1) <= MOD_SAMPLE_CLK_SHIFT(8 downto 0);	-- TODO: is delay correct??????
					MOD_SAMPLE_CLK_SHIFT(0) <= MOD_SYMBOL_CLKx4;
					
					if(SIMULATION = '0') or (NOISE_DATA1_I(0) /= 'X') then
						NOISE_DATA1_I_D <= signed(NOISE_DATA1_I);  
					end if;
					if(SIMULATION = '0') or (NOISE_DATA1_Q(0) /= 'X') then
						NOISE_DATA1_Q_D <= signed(NOISE_DATA1_Q); 
					end if;
			  end if;
		 end process;
		 
		 NOISE_DATA2_I <= NOISE_DATA1_I_D * signed(NOISE_GAIN);
		 NOISE_DATA2_Q <= NOISE_DATA1_Q_D * signed(NOISE_GAIN);
		 
		 -- reclock for better timing
		 NOISE_RECLOCK_I1: process(CLK_TXg)
		 begin
			  if rising_edge(CLK_TXg) then
					if(NOISE_DATA2_I(32) = '0') and (NOISE_DATA2_I(31 downto 29) /= 0) then
						 -- positive saturation
						 NOISE_DATA3_I <= (17 => '0', others => '1');
						 NOISE_GAIN_I_SATURATION <= '1';
					elsif(NOISE_DATA2_I(32) = '1') and ((not NOISE_DATA2_I(31 downto 29)) /= 0) then
						 -- negative saturation
						 NOISE_DATA3_I <= (17 => '1', 0 => '1', others => '0');
						 NOISE_GAIN_I_SATURATION <= '1';
					else
						 NOISE_DATA3_I <= NOISE_DATA2_I(29 downto 12);
						 NOISE_GAIN_I_SATURATION <= '0';
					end if;
			  end if;
		 end process;
	 
		 NOISE_RECLOCK_Q1: process(CLK_TXg)
		 begin
			  if rising_edge(CLK_TXg) then
					if(NOISE_DATA2_Q(32) = '0') and (NOISE_DATA2_Q(31 downto 29) /= 0) then
						 -- positive saturation
						 NOISE_DATA3_Q <= (17 => '0', others => '1');
						 NOISE_GAIN_Q_SATURATION <= '1';
					elsif(NOISE_DATA2_Q(32) = '1') and ((not NOISE_DATA2_Q(31 downto 29)) /= 0) then
						 -- negative saturation
						 NOISE_DATA3_Q <= (17 => '1', 0 => '1', others => '0');
						 NOISE_GAIN_Q_SATURATION <= '1';
					else
						 NOISE_DATA3_Q <= NOISE_DATA2_Q(29 downto 12);
						 NOISE_GAIN_Q_SATURATION <= '0';
					end if;
			  end if;
		 end process;

		 SIGNAL_PLUS_NOISE: process(CLK_TXg)
		 begin
			  if rising_edge(CLK_TXg) then
					-- add signal and noise
					SN1_I <= resize(NOISE_DATA3_I,19) + resize(signed(MOD_DATA2_I),19);
					SN1_Q <= resize(NOISE_DATA3_Q,19) + resize(signed(MOD_DATA2_Q),19);
					
					-- detect saturation if any
					if(SN1_I(18) = '0') and (SN1_I(17) = '1') then  -- positive saturation
						 SN2_I <= (17 => '0', others => '1');
						 SN_I_SATURATION <= '1';
					elsif(SN1_I(18) = '1') and (SN1_I(17) = '0') then  -- negative saturation
						 SN2_I <= (17 => '1', 0 => '1', others => '0');
						 SN_I_SATURATION <= '1';
					else
						 SN2_I <= std_logic_vector(SN1_I(17 downto 0));
						 SN_I_SATURATION <= '0';
					end if;
					if(SN1_Q(18) = '0') and (SN1_Q(17) = '1') then  -- positive saturation
						 SN2_Q <= (17 => '0', others => '1');
						 SN_Q_SATURATION <= '1';
					elsif(SN1_Q(18) = '1') and (SN1_Q(17) = '0') then  -- negative saturation
						 SN2_Q <= (17 => '1', 0 => '1', others => '0');
						 SN_Q_SATURATION <= '1';
					else
						 SN2_Q <= std_logic_vector(SN1_Q(17 downto 0));
						 SN_Q_SATURATION <= '0';
					end if;
					
			  end if;
		 end process;
		 
		 -- measure powers (noise, modulated signal)
		 POWER_MEASUREMENT_002b: POWER_MEASUREMENT PORT MAP(
			  CLK => CLK_TXg,
			  SYNC_RESET => SYNC_RESET_CLK_TX,
			  SAMPLE_CLK_IN => MOD_SAMPLE_CLK_SHIFT(7),	-- MOD_SAMPLE_CLK_D8
			  DATA_I_IN => std_logic_vector(NOISE_DATA3_I),
			  DATA_Q_IN => std_logic_vector(NOISE_DATA3_Q),
			  SAMPLE_CLK_OUT => open,
			  POWER_OUT => NOISE_POWER
		 );

		 -- report power measurements through status registers
		 -- monitoring
		MONITORING_002: process(CLK_TXg)
		 begin
			  if rising_edge(CLK_TXg) then
					if(LATCH_MONITORING_PULSE_TX = '1') then
						 SREG(14) <= NOISE_POWER(7 downto 0);
						 SREG(15) <= NOISE_POWER(15 downto 8);
						 SREG(16) <= NOISE_POWER(23 downto 16);
					end if;
			  end if;
		 end process;
	end generate;	-- AWGN_EN = '1'

	AWGN_OFF: if(AWGN_EN = '0') generate
		-- no AWGN
		SN2_I <= MOD_DATA2_I;
		SN2_Q <= MOD_DATA2_Q;
	end generate;
    
end generate;

--//--------------------------------------------------------------------------
--//	RIGHT CONNECTOR COM-4004 interface (Options E)
--//--------------------------------------------------------------------------
-- interface with COM-4004
-- Manage Tx enable signal and I/Q multiplexer
-- Note: COM-4004 modules comes up before this module.
-- Code inherited from COM-1202

	BUFG_007: BUFG port map(I=> LCB1, O => LCB1g);
		-- 100 MHz external reference clock from COM-4004 (pin B1)


	-- shift clock 90 deg (2.5ns) to minimize glitches
  MMCM2F : MMCME2_ADV
  generic map
   (BANDWIDTH            => "OPTIMIZED",
    CLKOUT4_CASCADE      => FALSE,
    COMPENSATION         => "ZHOLD",
    STARTUP_WAIT         => FALSE,
    DIVCLK_DIVIDE        => 1,
    CLKFBOUT_MULT_F      => 10.0,	
    CLKFBOUT_PHASE       => 0.000,
    CLKFBOUT_USE_FINE_PS => FALSE,
    CLKOUT0_DIVIDE_F     => 10.0,
    CLKOUT0_PHASE        => 135.000,
    CLKOUT0_DUTY_CYCLE   => 0.500,
    CLKOUT0_USE_FINE_PS  => FALSE,
    CLKIN1_PERIOD        => 10.00,
    REF_JITTER1          => 0.001)
  port map
    -- Output clocks
   (CLKFBOUT            => MMCM2F_CLKFBOUT,
    CLKFBOUTB           => open,
    CLKOUT0             => MMCM2F_CLKOUT0,
    CLKOUT0B            => open,
    CLKOUT1             => open,
    CLKOUT1B            => open,
    CLKOUT2             => open,
    CLKOUT2B            => open,
    CLKOUT3             => open,
    CLKOUT3B            => open,
    CLKOUT4             => open,
    CLKOUT5             => open,
    CLKOUT6             => open,
    -- Input clock control
    CLKFBIN             => MMCM2F_CLKFBOUT,
    CLKIN1              => LCB1g,
    CLKIN2              => '0',
    -- Tied to always select the primary input clock
    CLKINSEL            => '1',
    -- Ports for dynamic reconfiguration
    DADDR               => (others => '0'),
    DCLK                => '0',
    DEN                 => '0',
    DI                  => (others => '0'),
    DO                  => open,
    DRDY                => open,
    DWE                 => '0',
    -- Ports for dynamic phase shift
    PSCLK               => '0',
    PSEN                => '0',
    PSINCDEC            => '0',
    PSDONE              => open,
    -- Other control and status signals
    LOCKED              => open,
    CLKINSTOPPED        => open,
    CLKFBSTOPPED        => open,
    PWRDWN              => '0',
    RST                 => '0');
	
	BUFG_003: BUFG port map(I=> MMCM2F_CLKOUT0, O => MOD_OUTPUT_CLK_REQ);

	
	-- write to A side or B side
	RECLOCK_MOD_OUTPUT_001: process(CLK_TXg)
	begin
		if rising_edge(CLK_TXg) then
			MOD_OUTPUT_A_BN <= not MOD_OUTPUT_A_BN;
			if(MOD_OUTPUT_A_BN = '0') then
				-- direct to A side
				MOD_OUTPUT_DATA2_I_A <= SN2_I(17 downto 4);
				MOD_OUTPUT_DATA2_Q_A <= SN2_Q(17 downto 4);
			end if;
			if(MOD_OUTPUT_A_BN = '1') then
				-- direct to B side
				MOD_OUTPUT_DATA2_I_B <= SN2_I(17 downto 4);
				MOD_OUTPUT_DATA2_Q_B <= SN2_Q(17 downto 4);
			end if;
		end if;
	end process;

	-- reclock A_BN flag at the falling edge of CLK_P
	RECLOCK_MOD_OUTPUT_002: process(CLK_TXg)
	begin
		if falling_edge(CLK_TXg) then
			MOD_OUTPUT_A_BN_DF <= MOD_OUTPUT_A_BN;
		end if;
	end process;

	-- reclock input samples with processing clock when input samples are 
	-- stable in the A or B buffer.
	RECLOCK_MOD_OUTPUT_003: process(MOD_OUTPUT_CLK_REQ, MOD_OUTPUT_A_BN_DF, MOD_OUTPUT_DATA2_I_A, 
		MOD_OUTPUT_DATA2_I_B, MOD_OUTPUT_DATA2_Q_A, MOD_OUTPUT_DATA2_Q_B)
	begin
		if rising_edge(MOD_OUTPUT_CLK_REQ) then
			if(MOD_OUTPUT_A_BN_DF = '1') then
				-- read from stable A side
				MOD_OUTPUT_DATA2_I_D <= MOD_OUTPUT_DATA2_I_A;
				MOD_OUTPUT_DATA2_Q_D <= MOD_OUTPUT_DATA2_Q_A;
			else
				-- read from stable B side
				MOD_OUTPUT_DATA2_I_D <= MOD_OUTPUT_DATA2_I_B;
				MOD_OUTPUT_DATA2_Q_D <= MOD_OUTPUT_DATA2_Q_B;
			end if;
		end if;
	end process;

	-- multiplex I / Q to the COM-4004
	IQMUX_001: process(MOD_OUTPUT_CLK_REQ)
	begin
		if rising_edge(MOD_OUTPUT_CLK_REQ) then
			if(TX_ENABLE = '0') then
				MOD_OUTPUT_DATA2_IQ_D <= (others => '0');	-- Not necessary, but makes it look good
																-- (all data signals are zero when TX_ENABLE
			elsif(I_QN = '0') then
				MOD_OUTPUT_DATA2_IQ_D <= MOD_OUTPUT_DATA2_I_D;
			else
				MOD_OUTPUT_DATA2_IQ_D <= MOD_OUTPUT_DATA2_Q_D;
			end if;
		end if;
	end process;

	RECLOCK_MOD_OUTPUT_004: process(MOD_OUTPUT_CLK_REQ, CONFIG_CHANGE_TOGGLE)
	begin
		if rising_edge(MOD_OUTPUT_CLK_REQ) then
			CONFIG_CHANGE_TOGGLE5_D <= CONFIG_CHANGE_TOGGLE;
			CONFIG_CHANGE_TOGGLE5_D2 <= CONFIG_CHANGE_TOGGLE5_D;
			if(CONFIG_CHANGE_TOGGLE5_D /= CONFIG_CHANGE_TOGGLE5_D2) then
				CONFIG_CHANGE_PULSE_E <= '1';
			else
				CONFIG_CHANGE_PULSE_E <= '0';
			end if;

			if(CONFIG_CHANGE_PULSE_E = '1') then
				-- reset COM-1827 -> COM-4004 interface to make sure
				-- it starts with I sample. 
				-- Usage: write to the last COM-1202 register after reconfiguring
				-- the COM-4004.
				TX_ENABLE <= '0';
				I_QN <= '0';
			else
				TX_ENABLE <= '1';
				I_QN <= not I_QN;	-- '1' during the first period when TX_ENABLE = '1'
			end if;
		end if;
	end process;

	-- Right connector used to output modulated samples
	-- COM-4004 interface
	-- with 2*14-BIT complex signed output, time-shared
	-- timing critical (100MHz)
	LEFT_CONNECTOR_A(2) <= MOD_OUTPUT_DATA2_IQ_D(13);
	LEFT_CONNECTOR_B1(2) <= MOD_OUTPUT_DATA2_IQ_D(12);
	LEFT_CONNECTOR_A(3) <= MOD_OUTPUT_DATA2_IQ_D(11);
	LEFT_CONNECTOR_B1(3) <= MOD_OUTPUT_DATA2_IQ_D(10);
	LEFT_CONNECTOR_A(4) <= MOD_OUTPUT_DATA2_IQ_D(9);
	LEFT_CONNECTOR_B1(4) <= MOD_OUTPUT_DATA2_IQ_D(8);
	LEFT_CONNECTOR_A(5) <= MOD_OUTPUT_DATA2_IQ_D(7);
	LEFT_CONNECTOR_A(6) <= MOD_OUTPUT_DATA2_IQ_D(6);
	LEFT_CONNECTOR_B2(6) <= MOD_OUTPUT_DATA2_IQ_D(5);
	LEFT_CONNECTOR_A(7) <= MOD_OUTPUT_DATA2_IQ_D(4);
	LEFT_CONNECTOR_B2(7) <= MOD_OUTPUT_DATA2_IQ_D(3);
	LEFT_CONNECTOR_A(8) <= MOD_OUTPUT_DATA2_IQ_D(2);
	LEFT_CONNECTOR_B2(8) <= MOD_OUTPUT_DATA2_IQ_D(1);
	LEFT_CONNECTOR_A(9) <= MOD_OUTPUT_DATA2_IQ_D(0);

	LEFT_CONNECTOR_B2(9) <= TX_ENABLE;
	LEFT_CONNECTOR_A(10) <= 'Z';


--// RECEIVER OUTPUT SELECTION ------------------
RX_OUTPUT_SEL_001: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		if(CREG(45)(6 downto 4) = "001") and (LAN2_TCP_TX_CTS(2) = '1') then
			-- to TCP server, when cleared to send
			LAN2_TCP_TX_DATA(2) <= S2P1_DATA_IN;
			LAN2_TCP_TX_DATA_VALID(2) <= S2P1_DATA_VALID_IN;
		else
			LAN2_TCP_TX_DATA_VALID(2) <= '0';
		end if;
	end if;
end process;

S2P1_DATA_VALID_INB <= S2P1_DATA_VALID_IN when (CREG(45)(6 downto 4) = "010") else '0';
	-- to UDP server

--// UDP OUTPUTS ------------------------------	
-- demod data
TX_PREAMBLE1 <= std_logic_vector(TX_FRAME_CNTR1) & x"000000000000000000000000";	-- preamble

STREAM_2_PACKETS_001: STREAM_2_PACKETS2 
generic map(
	NBUFS => 2,  -- number of 16Kb dual-port RAM buffers instantiated within.
	TIMEOUT => 125000, 	-- latency should always be less than 0.5s, even when data rate is low
	MAX_PACKET_SIZE => "00" & x"400",	-- in bytes. 1024 bytes
	SIMULATION => SIMULATION
	) 
PORT MAP(
	CLK => CLK_P,
	SYNC_RESET => RECEIVER_RESET_CLK_P,
	TICK_4us => TICK_4US,
	DATA_IN => S2P1_DATA_IN,
	DATA_VALID_IN => S2P1_DATA_VALID_INB,
	CTS_OUT => open,
	PACKET_TX_PULSE => PACKET_TX_PULSE1,
	PREAMBLE_IN => TX_PREAMBLE1,
	DATA_OUT => LAN2_UDP_TX_DATA,
	DATA_VALID_OUT => LAN2_UDP_TX_DATA_VALID,
	SOF_OUT => LAN2_UDP_TX_SOF,
	EOF_OUT => LAN2_UDP_TX_EOF,
	RTS_OUT => LAN2_UDP_TX_RTS,
	CTS_IN => LAN2_UDP_TX_CTS,
	ACK_IN => LAN2_UDP_TX_ACK,
	NAK_IN => LAN2_UDP_TX_NAK,
	TP => open
);

-- latch next tx frame counter and timestamp (to send as preamble to the data packet)
UDP_TX2_003: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		-- increment the tx frame counter
		if(RECEIVER_RESET_CLK_P = '1') then
			TX_FRAME_CNTR1 <= (others => '0');
			FIRST_BYTE1_FLAG <= '0';
		elsif(FIRST_BYTE1_FLAG = '0') and (S2P1_DATA_VALID_IN = '1') then
		  -- first byte in first output frame
			FIRST_BYTE1_FLAG <= '1';
		elsif(LAN2_UDP_TX_EOF = '1') then
		    -- shortly before the first byte in the next output frame
			TX_FRAME_CNTR1 <= TX_FRAME_CNTR1 + 1;
		end if;
		
	end if;
end process;

-- monitoring
MONITORING_005: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		if(LATCH_MONITORING_PULSE = '1') then
			-- latch in multi-byte status registers upon reading status register SREG7
			SREG(40) <= LAN2_MAC_ADDR(47 downto 40);
			SREG(41) <= LAN2_MAC_ADDR(39 downto 32);
			SREG(42) <= LAN2_MAC_ADDR(31 downto 24);
			SREG(43) <= LAN2_MAC_ADDR(23 downto 16);
			SREG(44) <= LAN2_MAC_ADDR(15 downto 8);
			SREG(45) <= LAN2_MAC_ADDR(7 downto 0);
			SREG(46) <= LAN2_N_RX_BAD_CRCS(7 downto 0);
			SREG(47) <= LAN2_N_RX_BAD_CRCS(15 downto 8);
			SREG(48)(3 downto 0) <= TC_CONVN_CODEC & AWGN_EN & DEMODULATOR_EN & MODULATOR_EN;	
				-- report FPGA generic configuration options
				-- let the GUI know which FPGA configuration (TC or convolutional FEC) is currently active
		end if;
	end if;
end process;



--// TEST POINTS  -----------------------------------------------
-- Warning: test points can make timing much worse!
LEFT_CONNECTOR_A(11) <= CONFIG_CHANGE_TOGGLE;
LEFT_CONNECTOR_A(12) <= CONFIG_CHANGE_PULSE_E;
LEFT_CONNECTOR_A(13) <= I_QN;


--LEFT_CONNECTOR_A(19) <= BER_MF_DETECT;
--LEFT_CONNECTOR_A(20) <= BER_BYTE_ERROR;
--LEFT_CONNECTOR_A(21) <= TX_SOF;
--LEFT_CONNECTOR_A(22) <= '1' when (unsigned(MOD_SATURATION) /= 0) else SN_I_SATURATION or SN_Q_SATURATION;
--LEFT_CONNECTOR_A(23) <= SOF_LOCK_DETECT12;
--LEFT_CONNECTOR_A(24) <= SIGNAL_PRESENT_OUT;
--LEFT_CONNECTOR_A(25) <= DEMOD_TP(3);	-- freq error
--LEFT_CONNECTOR_A(26) <= DEMOD_TP(8);	-- timing error



--// COMSCOPE2 -----------------------------------------------------
COMSCOPE_GEN: if (SIMULATION = '0') generate
	--  Comment in/out as needed. unused during simulation
	-- 
	-- Define Comscope traces here 
	-- Trace 1
	S1_1 <= RX_DATA2_I(15 downto 8);		-- input samples
	S1_1_CLK <= RX_SAMPLE2_CLK;
	S1_2 <= AGC_DAC(11 downto 4);		-- input samples
	S1_2_CLK <= AGC_DAC_SAMPLE_CLK;
	--S1_3 reserved 
	--S1_4 reserved 

	-- Trace 2
	S2_1 <= RX_DATA2_Q(15 downto 8);		-- input samples
	S2_1_CLK <= RX_SAMPLE2_CLK;
	
	--S2_2 reserved	
	--S2_3 reserved 
--	S2_4 <=  POWER_S_AVERAGE_OUT(14 downto 7);	-- UNDEFINED??
--	S2_4_CLK <= '1';

	-- Trace 3
	--S3_1  reserved 
	--S3_2  reserved 
	--S3_3  reserved  
--	S3_4 <=  POWER_N_AVERAGE_OUT(11 downto 4);	-- UNDEFINED??
--	S3_4_CLK <= '1';

	-- Trigger (1-bit format)


	COMSCOPE2_001: COMSCOPE2 
	generic map(
		TRACE1_ENABLED => '1',    -- enable as many simultaneous traces as needed
		TRACE2_ENABLED => '1',
		TRACE3_ENABLED => '0',
		TRACE4_ENABLED => '0',
		DATA_WIDTH1A => 8,
		ADDR_WIDTH1A => 9,
		ADDR_WIDTH1B => 9,
		DATA_WIDTH2A => 8,
		ADDR_WIDTH2A => 9,
		ADDR_WIDTH2B => 9,
		DATA_WIDTH3A => 8,
		ADDR_WIDTH3A => 9,
		ADDR_WIDTH3B => 9,
		DATA_WIDTH4A => 8,
		ADDR_WIDTH4A => 9,
		ADDR_WIDTH4B => 9
	)
	PORT MAP(
		CLK => CLK_TXg,
		SYNC_RESET => SYNC_RESET_CLK_TX,
		REG238 => REG238,
		REG239 => x"00", --REG239,  acquire mode: sample
		REG240 => REG240,
		REG241 => REG241,
		REG242 => REG242,
		REG243 => REG243,
		REG244 => REG244,
		REG245 => REG245,
		REG246 => REG246,
		REG247 => REG247,
		REG248 => REG248,
		REG249 => REG249,
		S1_1 => S1_1,
		S1_1_VALID => S1_1_CLK,
		S1_2 => S1_2,
		S1_2_VALID => S1_2_CLK,
		S1_3 => S1_3,
		S1_3_VALID => S1_3_CLK,
		S1_4 => S1_4,
		S1_4_VALID => S1_4_CLK,
		S2_1 => S2_1,
		S2_1_VALID => S2_1_CLK,
		S2_2 => S2_2,
		S2_2_VALID => S2_2_CLK,
		S2_3 => S2_3,
		S2_3_VALID => S2_3_CLK,
		S2_4 => S2_4,
		S2_4_VALID => S2_4_CLK,
		S3_1 => S3_1,
		S3_1_VALID => S3_1_CLK,
		S3_2 => S3_2,
		S3_2_VALID => S3_2_CLK,
		S3_3 => S3_3,
		S3_3_VALID => S3_3_CLK,
		S3_4 => S3_4,
		S3_4_VALID => S3_4_CLK,
		S4_1 => (others => '0'),
		S4_1_VALID => '0',
		S4_2 => (others => '0'),
		S4_2_VALID => '0',
		S4_3 => (others => '0'),
		S4_3_VALID => '0',
		S4_4 => (others => '0'),
		S4_4_VALID => '0',
		T16b_1 => (others => '0'),
		T16b_1_VALID => '0',
		T16b_2 => (others => '0'),
		T16b_2_VALID => '0',
		T16b_3 => (others => '0'),
		T16b_3_VALID => '0',
		T16b_4 => (others => '0'),
		T16b_4_VALID => '0',
		SREG250 => REG250,
		SREG251 => REG251,
		TRIGGER_REARM_TOGGLE => TRIGGER_REARM_TOGGLE,
		FORCE_TRIGGER_TOGGLE => FORCE_TRIGGER_TOGGLE,
		SREG250_READ_TOGGLE => SREG250_READ_TOGGLE,
		START_CAPTURE_TOGGLE => START_CAPTURE_TOGGLE,
		TP => open
	);
end generate;


--// ARM CO-PROCESSOR INTERFACE ---------------------------------------------------
-- Primarily used for monitoring and control.
-- 8-bit shared address/data bus. clock synchronous.
-- PART OF THE FRAMEWORK. DO NOT CHANGE unless you want to add more control registers 
--(see UC_WRITE_001) or status registers (see UC_READ_001).
-- 
-- Address latch
UC_ADDR_001: process(UC_CSIB_IN, UC_WEBG, UC_ALE_IN, UC_AD)
begin
	if rising_edge(UC_WEBG) then
		if (UC_CSIB_IN = '0') and (UC_ALE_IN = '1') then
			UC_ADDRESS <= unsigned(UC_AD);
	  	end if;
  	end if;
end process;

-- Read status registers 
-- User can define additional control registers using the same pattern. 
UC_READ_001: process(UC_ADDRESS, REG255, RX_USB_LAN, REG251, REG250, SREG)
begin
	case(UC_ADDRESS) is
		-- ComBlock-reserved addresses ----
		when "11111111" => UC_AD_LOCAL <= REG255;		-- reg 255. Async serial from 3 connectors
		when "11111110" => UC_AD_LOCAL <= RX_USB_LAN;-- reg 254 = 8-bit data from USB or LAN M&C channel
		when "11111101" => UC_AD_LOCAL <= REVISION;	-- reg 253 = fpga revision
		when "11111100" => UC_AD_LOCAL <= OPTION;		-- reg 252 = fpga option
		when "11111011" => UC_AD_LOCAL <= REG251;		-- reg 251 =comscope  status
		when "11111010" => UC_AD_LOCAL <= REG250;		-- reg 250 = comscope data byte
		
		-- User-defined status registers -------
		-- SREG0-6 reserved for use by the ARM microcontroller
		when "00000111" => UC_AD_LOCAL <= SREG(7);
		when "00001000" => UC_AD_LOCAL <= SREG(8);
		when "00001001" => UC_AD_LOCAL <= SREG(9);
		when "00001010" => UC_AD_LOCAL <= SREG(10);
		when "00001011" => UC_AD_LOCAL <= SREG(11);
		when "00001100" => UC_AD_LOCAL <= SREG(12);
		when "00001101" => UC_AD_LOCAL <= SREG(13);
		when "00001110" => UC_AD_LOCAL <= SREG(14);
		when "00001111" => UC_AD_LOCAL <= SREG(15);
		when "00010000" => UC_AD_LOCAL <= SREG(16);
		when "00010001" => UC_AD_LOCAL <= SREG(17);
		when "00010010" => UC_AD_LOCAL <= SREG(18);
		when "00010011" => UC_AD_LOCAL <= SREG(19);
		when "00010100" => UC_AD_LOCAL <= SREG(20);
		when "00010101" => UC_AD_LOCAL <= SREG(21);
		when "00010110" => UC_AD_LOCAL <= SREG(22);
		when "00010111" => UC_AD_LOCAL <= SREG(23);
		when "00011000" => UC_AD_LOCAL <= SREG(24);
		when "00011001" => UC_AD_LOCAL <= SREG(25);
		when "00011010" => UC_AD_LOCAL <= SREG(26);
		when "00011011" => UC_AD_LOCAL <= SREG(27);
		when "00011100" => UC_AD_LOCAL <= SREG(28);
		when "00011101" => UC_AD_LOCAL <= SREG(29);
		when "00011110" => UC_AD_LOCAL <= SREG(30);
		when "00011111" => UC_AD_LOCAL <= SREG(31);
		when "00100000" => UC_AD_LOCAL <= SREG(32);
		when "00100001" => UC_AD_LOCAL <= SREG(33);
		when "00100010" => UC_AD_LOCAL <= SREG(34);
		when "00100011" => UC_AD_LOCAL <= SREG(35);
		when "00100100" => UC_AD_LOCAL <= SREG(36);
		when "00100101" => UC_AD_LOCAL <= SREG(37);
		when "00100110" => UC_AD_LOCAL <= SREG(38);
		when "00100111" => UC_AD_LOCAL <= SREG(39);
		when "00101000" => UC_AD_LOCAL <= SREG(40);
		when "00101001" => UC_AD_LOCAL <= SREG(41);
		when "00101010" => UC_AD_LOCAL <= SREG(42);
		when "00101011" => UC_AD_LOCAL <= SREG(43);
		when "00101100" => UC_AD_LOCAL <= SREG(44);
		when "00101101" => UC_AD_LOCAL <= SREG(45);
		when "00101110" => UC_AD_LOCAL <= SREG(46);
		when "00101111" => UC_AD_LOCAL <= SREG(47);
		when "00110000" => UC_AD_LOCAL <= SREG(48);
		when "00110001" => UC_AD_LOCAL <= SREG(49);
		when "00110010" => UC_AD_LOCAL <= SREG(50);
		when "00110011" => UC_AD_LOCAL <= SREG(51);
		when "00110100" => UC_AD_LOCAL <= SREG(52);
--		when "00110101" => UC_AD_LOCAL <= SREG(53);
--		when "00110110" => UC_AD_LOCAL <= SREG(54);
--		when "00110111" => UC_AD_LOCAL <= SREG(55);
--		when "00111000" => UC_AD_LOCAL <= SREG(56);
--		when "00111001" => UC_AD_LOCAL <= SREG(57);
--		when "00111010" => UC_AD_LOCAL <= SREG(58);
--		when "00111011" => UC_AD_LOCAL <= SREG(59);
--		when "00111100" => UC_AD_LOCAL <= SREG(60);
--		when "00111101" => UC_AD_LOCAL <= SREG(61);
--		when "00111110" => UC_AD_LOCAL <= SREG(62);
--		when "00111111" => UC_AD_LOCAL <= SREG(63);
--		when "01000000" => UC_AD_LOCAL <= SREG(64);
--		when "01000001" => UC_AD_LOCAL <= SREG(65);
--		when "01000010" => UC_AD_LOCAL <= SREG(66);
		
		-- user can add more status registers as needed (200+)
		when others => UC_AD_LOCAL <= (others => '0');
	end case;
end process;

UC_AD <= UC_AD_LOCAL when (UC_CSIB_IN = '0') and (UC_REB_IN = '0') else (others => 'Z');
	-- when to drive the data bus between ARM and FPGA
	
-- toggle a few flags upon reading specific status registers
UC_READ_002: process(ASYNC_RESET, UC_REBG, UC_CSIB_IN, UC_ADDRESS, 
						SREG250_READ_TOGGLE, SREG254_READ_TOGGLE)
begin
	if(ASYNC_RESET = '1') then
		SREG250_READ_TOGGLE <= '0';
		SREG254_READ_TOGGLE <= '0';
	elsif rising_edge(UC_REBG) then
		if (UC_CSIB_IN = '0')  then
			if (UC_ADDRESS = 7) then
				SREG7_READ_TOGGLE <= not SREG7_READ_TOGGLE;
			end if;
			if (UC_ADDRESS = 250) then
				SREG250_READ_TOGGLE <= not SREG250_READ_TOGGLE;
			end if;
			if (UC_ADDRESS = 254) then
				SREG254_READ_TOGGLE <= not SREG254_READ_TOGGLE;
			end if;
		end if;
	end if;
end process;

-- reclock with CLK_P
RECLOCK_SREG7_TOGGLE: process(CLK_P,SREG7_READ_TOGGLE)
begin
	if rising_edge(CLK_P) then
		SREG7_READ_TOGGLE_D <= SREG7_READ_TOGGLE;
		SREG7_READ_TOGGLE_D2 <= SREG7_READ_TOGGLE_D;
		if(SREG7_READ_TOGGLE_D /= SREG7_READ_TOGGLE_D2) then
			LATCH_MONITORING_PULSE <= '1';
		else
			LATCH_MONITORING_PULSE <= '0';
		end if;
	end if;
end process;

-- reclock with CLK_TXg
RECLOCK_SREG7_TOGGLE_002: process(CLK_TXg,SREG7_READ_TOGGLE)
begin
	if rising_edge(CLK_TXg) then
		SREG7_READ_TOGGLE2_D <= SREG7_READ_TOGGLE;
		SREG7_READ_TOGGLE2_D2 <= SREG7_READ_TOGGLE2_D;
		if(SREG7_READ_TOGGLE2_D /= SREG7_READ_TOGGLE2_D2) then
			LATCH_MONITORING_PULSE_TX <= '1';
		else
			LATCH_MONITORING_PULSE_TX <= '0';
		end if;
	end if;
end process;

-- write to FPGA control registers
UC_WRITE_001ax: if (SIMULATION = '0') generate
	UC_WRITE_001a: process(UC_WEBG)
	begin
		if rising_edge(UC_WEBG) then
			if (UC_CSIB_IN = '0') and (UC_ALE_IN = '0') and (UC_REB_IN = '1')  then
				for I in NCREG_IMIN to NCREG_IMAX loop
					if(UC_ADDRESS = I) then
						CREG(I) <= UC_AD;
					end if;
				end loop;
				
				-- special case: MAC address LSB, at an address not erased when importing new settings
				if (UC_ADDRESS = 236) then
					REG236 <= UC_AD;	
					LAN_ADDR_CHANGE_TOGGLE <= not LAN_ADDR_CHANGE_TOGGLE;
				end if;

				if (UC_ADDRESS = NCREG_IMAX) then
					-- dummy write to last control register
					CONFIG_CHANGE_TOGGLE <= not CONFIG_CHANGE_TOGGLE;	
					-- Configuration change toggles upon writing the last control register
					-- This happens invisibly to the user (only the ARM uC writes to this last control register
					-- which is invible to the user and to the ComBlock Control Center).
				end if;

				-- Reserved:
				-- REG254 reserved for output serial
				-- REG255 write reserved for output serial (8-bit parallel format)
				if (UC_ADDRESS = 255) then
					-- REG255 write reserved for output serial (8-bit parallel format)
					-- route response to host query over LAN/TCP-IP
					LAN2_TCP_TX_DATA(0) <= UC_AD;
					TX_LAN_TOGGLE <= not TX_LAN_TOGGLE;
				end if;				
			end if;
		end if;
	end process;
end generate;

UC_WRITE_001y: if (SIMULATION = '1') generate
	-- initialize the control registers during simulation
--	-- 10 MS/s PCM/FM h=0.7
--	CREG(0) <= x"03";	-- NRZ, tx input selection, internal frequency reference
--	CREG(1) <= x"01";	-- tx clock frequency, mod symbol rate 
--	CREG(2) <= x"20";	
--	CREG(3) <= x"00";	
--	CREG(4) <= x"28";	
--	CREG(5) <= x"40";	
--	CREG(6) <= x"10";	-- modulation order M, premodulation frequency shaping filter
--	CREG(7) <= x"80";	-- mod output on/off, spectrum inversion, test mode
--	CREG(8) <= x"33";	-- modulation index (LSB)  fixed-point format 4.12
--	CREG(9) <= x"0b";	-- modulation index (MSB)
--	CREG(10) <= x"10";	-- mod signal level (LSB)
--	CREG(11) <= x"27";	-- mod signal level (MSB)
--	CREG(12) <= x"00";	-- AWGN level (LSB)
--	CREG(13) <= x"00";	-- AWGN level (MSB)
--	CREG(14) <= x"00";	-- mod center frequency (LSB)
--	CREG(15) <= x"00";	
--	CREG(16) <= x"00";	
--	CREG(17) <= x"00";	-- mod center frequency (MSB)
--	
--	CREG(24) <= x"81";	-- rx clock frequency
--	CREG(25) <= x"20";	
--	CREG(26) <= x"00";	
--	CREG(27) <= x"20";	
--	CREG(28) <= x"70";	-- rx clock gen + loopback
--	CREG(29) <= x"0a";	-- RECEIVER_AGC_RESPONSE
--	CREG(30) <= x"00";	-- receiver center frequency (LSB)
--	CREG(31) <= x"00";	
--	CREG(32) <= x"00";	
--	CREG(33) <= x"00";	-- receiver center frequency (MSB)
--	CREG(34) <= x"CE";	-- demod symbol rate (LSB)
--	CREG(35) <= x"CC";	
--	CREG(36) <= x"CC";	
--	CREG(37) <= x"0C";	-- demod symbol rate (MSB)
--	CREG(38) <= x"02";	-- CIC (LSB)
--	CREG(39) <= x"00";	-- CIC (MSB)
--	CREG(40) <= x"10";	-- modulation order M, premodulation frequency shaping filter
--	CREG(41) <= x"33";	-- demod modulation index (LSB)  fixed-point format 4.12
--	CREG(42) <= x"0b";	-- demod modulation index (MSB)
--	CREG(43) <= x"20";	-- spectrum inversion, AFC
--	CREG(44) <= x"00";	-- FEC decoding, NRZ
--	CREG(45) <= x"00";	-- FEC encoding
	
	-- 8 Mb/s SOQPSK-MIL h=0.5
	CREG(0) <= x"03";	-- NRZ, tx input selection, internal frequency reference
	CREG(1) <= x"01";	-- tx clock frequency, mod symbol rate 
	CREG(2) <= x"20";	
	CREG(3) <= x"00";	
	CREG(4) <= x"28";	
	CREG(5) <= x"40";	
	CREG(6) <= x"50";	-- premodulation frequency shaping filter
	CREG(7) <= x"80";	-- mod output on/off, spectrum inversion, test mode
	CREG(8) <= x"00";	-- modulation index (LSB)  fixed-point format 4.12
	CREG(9) <= x"08";	-- modulation index (MSB)
	CREG(10) <= x"10";	-- mod signal level (LSB)
	CREG(11) <= x"27";	-- mod signal level (MSB)
	CREG(12) <= x"01";	-- AWGN level (LSB)
	CREG(13) <= x"00";	-- AWGN level (MSB)
	CREG(14) <= x"00";	-- mod center frequency (LSB)  +8 KHz
	CREG(15) <= x"00";	
	CREG(16) <= x"00";	
	CREG(17) <= x"00";	-- mod center frequency (MSB)
	
	CREG(24) <= x"81";	-- rx clock frequency
	CREG(25) <= x"20";	
	CREG(26) <= x"00";	
	CREG(27) <= x"20";	
	CREG(28) <= x"70";	-- rx clock gen + loopback
	CREG(29) <= x"0a";	-- RECEIVER_AGC_RESPONSE
	CREG(30) <= x"00";	-- receiver center frequency (LSB)
	CREG(31) <= x"00";	
	CREG(32) <= x"00";	
	CREG(33) <= x"00";	-- receiver center frequency (MSB)
--	CREG(34) <= x"CE";	-- demod symbol rate (LSB)
--	CREG(35) <= x"CC";	
--	CREG(36) <= x"CC";	
--	CREG(37) <= x"0C";	-- demod symbol rate (MSB)
	CREG(34) <= x"BE";	-- demod symbol rate (LSB) + 50ppm
	CREG(35) <= x"F6";	
	CREG(36) <= x"CC";	
	CREG(37) <= x"0C";	-- demod symbol rate (MSB)
	CREG(38) <= x"02";	-- CIC (LSB)
	CREG(39) <= x"00";	-- CIC (MSB)
	CREG(40) <= x"50";	-- premodulation frequency shaping filter
	CREG(41) <= x"00";	-- demod modulation index (LSB)  fixed-point format 4.12
	CREG(42) <= x"08";	-- demod modulation index (MSB)
	CREG(43) <= x"00";	-- spectrum inversion, AFC
	CREG(44) <= x"01";	-- FEC decoding, NRZ
	CREG(45) <= x"01";	-- FEC encoding
	
	CREG(47) <= x"AC";	-- IP address
	CREG(48) <= x"10";
	CREG(49) <= x"01";
	CREG(50) <= x"80";
	CREG(51) <= x"ff";	-- Subnet mask
	CREG(52) <= x"ff";
	CREG(53) <= x"ff";
	CREG(54) <= x"00";
	CREG(55) <= x"AC";	-- Gateway
	CREG(56) <= x"10";
	CREG(57) <= x"01";
	CREG(58) <= x"03";
	
--	CREG(65) <= x"FA";	-- TC encoder payload size in bytes
--	CREG(66) <= x"00";	-- TC encoder rate
--	CREG(67) <= x"70";	-- TC encoder frame size in bits (LSB)
--	CREG(68) <= x"17";	-- TC encoder frame size in bits (MSB)
--	CREG(69) <= x"FA";	-- TC decoder payload size in bytes
--	CREG(70) <= x"00";	-- TC decoder rate
--	CREG(71) <= x"70";	-- TC decoder frame size in bits (LSB)
--	CREG(72) <= x"17";	-- TC decoder frame size in bits (MSB)
--	CREG(73) <= x"07";	-- TC decoder iterations

	-- shorter frame for simulation
	CREG(65) <= x"0e";	-- TC encoder payload size in bytes
	CREG(66) <= x"00";	-- TC encoder rate
	CREG(67) <= x"50";	-- TC encoder frame size in bits (LSB)
	CREG(68) <= x"01";	-- TC encoder frame size in bits (MSB)
	CREG(69) <= x"0e";	-- TC decoder payload size in bytes
	CREG(70) <= x"00";	-- TC decoder rate
	CREG(71) <= x"50";	-- TC decoder frame size in bits (LSB)
	CREG(72) <= x"01";	-- TC decoder frame size in bits (MSB)
	CREG(73) <= x"07";	-- TC decoder iterations
	
	process
	begin
		CONFIG_CHANGE_TOGGLE <= '0';
		wait for 71.570us;
		CONFIG_CHANGE_TOGGLE <= '1';
		wait;
	end process;
end generate;

--UC_WRITE_001y: if (SIMULATION = '1') generate
--	-- initialize the control registers during simulation
--	CREG(0) <= x"03";	-- NRZ, tx input selection, internal frequency reference
--	CREG(1) <= x"01";	-- tx clock frequency, mod symbol rate 
--	CREG(2) <= x"30";	
--	CREG(3) <= x"00";	
--	CREG(4) <= x"40";	
--	CREG(5) <= x"20";	
--	CREG(6) <= x"10";	-- modulation order M, premodulation frequency shaping filter
--	CREG(7) <= x"80";	-- mod output on/off, spectrum inversion, test mode
--	CREG(8) <= x"33";	-- modulation index (LSB)  fixed-point format 4.12
--	CREG(9) <= x"0b";	-- modulation index (MSB)
--	CREG(10) <= x"40";	-- mod signal level (LSB)
--	CREG(11) <= x"1f";	-- mod signal level (MSB)
--	CREG(12) <= x"00";	-- AWGN level (LSB)
--	CREG(13) <= x"00";	-- AWGN level (MSB)
--	CREG(14) <= x"00";	-- mod center frequency (LSB)
--	CREG(15) <= x"00";	
--	CREG(16) <= x"00";	
--	CREG(17) <= x"00";	-- mod center frequency (MSB)
--	
--	CREG(24) <= x"01";	-- rx clock frequency
--	CREG(25) <= x"20";	
--	CREG(26) <= x"00";	
--	CREG(27) <= x"20";	
--	CREG(28) <= x"70";	-- rx clock gen + loopback
--	CREG(29) <= x"06";	-- RECEIVER_AGC_RESPONSE
--	CREG(30) <= x"00";	-- receiver center frequency (LSB)
--	CREG(31) <= x"00";	
--	CREG(32) <= x"00";	
--	CREG(33) <= x"00";	-- receiver center frequency (MSB)
--	CREG(34) <= x"00";	-- demod symbol rate (LSB)
--	CREG(35) <= x"00";	
--	CREG(36) <= x"00";	
--	CREG(37) <= x"30";	-- demod symbol rate (MSB)
--	CREG(38) <= x"01";	-- CIC (LSB)
--	CREG(39) <= x"00";	-- CIC (MSB)
--	CREG(40) <= x"10";	-- modulation order M, premodulation frequency shaping filter
--	CREG(41) <= x"33";	-- demod modulation index (LSB)  fixed-point format 4.12
--	CREG(42) <= x"0b";	-- demod modulation index (MSB)
--	CREG(43) <= x"00";	-- spectrum inversion
--	CREG(44) <= x"00";	-- FEC decoding, NRZ
--	CREG(45) <= x"00";	-- FEC encoding
--	
--	CREG(47) <= x"AC";	-- IP address
--	CREG(48) <= x"10";
--	CREG(49) <= x"01";
--	CREG(50) <= x"80";
--	CREG(51) <= x"ff";	-- Subnet mask
--	CREG(52) <= x"ff";
--	CREG(53) <= x"ff";
--	CREG(54) <= x"00";
--	CREG(55) <= x"AC";	-- Gateway
--	CREG(56) <= x"10";
--	CREG(57) <= x"01";
--	CREG(58) <= x"03";
--	
--	CREG(65) <= x"FA";	-- TC encoder payload size in bytes
--	CREG(66) <= x"00";	-- TC encoder rate
--	CREG(67) <= x"70";	-- TC encoder frame size in bits (LSB)
--	CREG(68) <= x"17";	-- TC encoder frame size in bits (MSB)
--	CREG(69) <= x"FA";	-- TC decoder payload size in bytes
--	CREG(70) <= x"00";	-- TC decoder rate
--	CREG(71) <= x"70";	-- TC decoder frame size in bits (LSB)
--	CREG(72) <= x"17";	-- TC decoder frame size in bits (MSB)
--	CREG(73) <= x"07";	-- TC decoder iterations
--
----	-- shorter frame for simulation
----	CREG(65) <= x"0e";	-- TC encoder payload size in bytes
----	CREG(66) <= x"00";	-- TC encoder rate
----	CREG(67) <= x"50";	-- TC encoder frame size in bits (LSB)
----	CREG(68) <= x"01";	-- TC encoder frame size in bits (MSB)
----	CREG(69) <= x"0e";	-- TC decoder payload size in bytes
----	CREG(70) <= x"00";	-- TC decoder rate
----	CREG(71) <= x"50";	-- TC decoder frame size in bits (LSB)
----	CREG(72) <= x"01";	-- TC decoder frame size in bits (MSB)
----	CREG(73) <= x"07";	-- TC decoder iterations
--	
--	process
--	begin
--		CONFIG_CHANGE_TOGGLE <= '0';
--		wait for 100 us;
--		CONFIG_CHANGE_TOGGLE <= '1';
--		wait;
--	end process;
--end generate;
	
--// reserved COMSCOPE -------------------------------------------------------
-- Comment out if ComScope feature is unused
UC_WRITE_003: process(UC_CSIB_IN, UC_WEBG, UC_ADDRESS, UC_AD, 
	FORCE_TRIGGER_TOGGLE, TRIGGER_REARM_TOGGLE, START_CAPTURE_TOGGLE)
begin
	if rising_edge(UC_WEBG) then
		if (UC_CSIB_IN = '0') and (UC_ALE_IN = '0') and (UC_REB_IN = '1')  then
			-- Reserved for ComScope			
			if (UC_ADDRESS = 237) then
				REG237 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 238) then
				REG238 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 239) then
				REG239 <= UC_AD;
			end if;
			if (UC_ADDRESS = 240) then
				REG240 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 241) then
				REG241 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 242) then
				REG242 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 243) then
				REG243 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 244) then
				REG244 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 245) then
				REG245 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 246) then
				REG246 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 247) then
				REG247 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 248) then
				REG248 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 249) then
				REG249 <= UC_AD;	
			end if;
			if (UC_ADDRESS = 250) then 
				-- detect one-shot force trigger	
				if(UC_AD(0) = '1') then	
					FORCE_TRIGGER_TOGGLE <= not(FORCE_TRIGGER_TOGGLE);
				end if;	
				-- detect one-shot re-arm	
				if(UC_AD(1) = '1') then	
					TRIGGER_REARM_TOGGLE <= not(TRIGGER_REARM_TOGGLE);
				end if;	
				-- start capturing again
				if(UC_AD(2) = '1') then	
					START_CAPTURE_TOGGLE <= not (START_CAPTURE_TOGGLE);
				end if;	
			end if;
		end if;
	end if;
end process;

--// end of COMSCOPE section -------------------------------------------------------

-- Reclock CONFIG_CHANGE_TOGGLE to be synchronous with various processing clocks

CONFIG_CHANGE_PULSE_GEN_001: process(CLK160g)
begin
	if rising_edge(CLK160g) then
		CONFIG_CHANGE_TOGGLE1_D <= CONFIG_CHANGE_TOGGLE;
		CONFIG_CHANGE_TOGGLE1_D2 <= CONFIG_CHANGE_TOGGLE1_D;
		if(CONFIG_CHANGE_TOGGLE1_D /= CONFIG_CHANGE_TOGGLE1_D2) then
			CONFIG_CHANGE_PULSE_160 <= '1';
		else
			CONFIG_CHANGE_PULSE_160 <= '0';
		end if;
	end if;
end process;

CONFIG_CHANGE_PULSE_GEN_002: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		CONFIG_CHANGE_TOGGLE2_D <= CONFIG_CHANGE_TOGGLE;
		CONFIG_CHANGE_TOGGLE2_D2 <= CONFIG_CHANGE_TOGGLE2_D;
		CONFIG_CHANGE_PULSE_P_D <= CONFIG_CHANGE_PULSE_P;
		CONFIG_CHANGE_PULSE_P_D2 <= CONFIG_CHANGE_PULSE_P_D;
		if(CONFIG_CHANGE_TOGGLE2_D /= CONFIG_CHANGE_TOGGLE2_D2) then
			CONFIG_CHANGE_PULSE_P <= '1';
		else
			CONFIG_CHANGE_PULSE_P <= '0';
		end if;
	end if;
end process;

CONFIG_CHANGE_PULSE_GEN_003: process(CLK_TXg)
begin
	if rising_edge(CLK_TXg) then
		CONFIG_CHANGE_TOGGLE3_D <= CONFIG_CHANGE_TOGGLE;
		CONFIG_CHANGE_TOGGLE3_D2 <= CONFIG_CHANGE_TOGGLE3_D;
		if(CONFIG_CHANGE_TOGGLE3_D /= CONFIG_CHANGE_TOGGLE3_D2) then
			CONFIG_CHANGE_PULSE_TX <= '1';
		else
			CONFIG_CHANGE_PULSE_TX <= '0';
		end if;
	end if;
end process;

LAN_ADDR_CHANGE_PULSE_GEN: process(CLK_P)
begin
	if rising_edge(CLK_P) then
		LAN_ADDR_CHANGE_TOGGLE_D <= LAN_ADDR_CHANGE_TOGGLE;
		LAN_ADDR_CHANGE_TOGGLE_D2 <= LAN_ADDR_CHANGE_TOGGLE_D;
		if(LAN_ADDR_CHANGE_TOGGLE_D /= LAN_ADDR_CHANGE_TOGGLE_D2) then
			LAN_ADDR_CHANGE_PULSE <= '1';
		else
			LAN_ADDR_CHANGE_PULSE <= '0';
		end if;
	end if;
end process;


-- DNA Port ------------------------------------
-- Read FPGA unique DNA ID
DNA_ID_001: DNA_ID 
	GENERIC MAP(
		CLK_FREQUENCY => CLK_P_FREQUENCY	-- CLK_P in MHz, as time reference
	)
	PORT MAP(
		CLK => CLK_P,
		SYNC_RESET => SYNC_RESET_CLK_P,
		ID_OUT => DNA_ID_DATA,
		ID_VALID_OUT => open,
		ID_SAMPLE_CLK_OUT => DNA_ID_SAMPLE_CLK 
);


-- M&C USB interface --------------------------
-- REG255 reserved for reading serial port inputs
-- These signals are pulled high (to mimic stop bit).
REG255 <= "1111" & RX_LAN_BUFFER_EMPTY & "111";
	-- M&C port through LAN 
	-- indicates AVAILABILITY of 8-bit byte from LAN. Not actual data.
	-- When low, uC must read byte from LAN

-- Reclock TX_LAN_TOGGLE
RECLOCK_TX_LAN_TOGGLE: process(CLK_P,TX_LAN_TOGGLE)
begin
	if rising_edge(CLK_P) then
		TX_LAN_TOGGLE_D <= TX_LAN_TOGGLE;
		TX_LAN_TOGGLE_D2 <= TX_LAN_TOGGLE_D;
		if(TX_LAN_TOGGLE_D /= TX_LAN_TOGGLE_D2) then
			LAN2_TCP_TX_DATA_VALID(0) <= '1';
		else
			LAN2_TCP_TX_DATA_VALID(0) <= '0';
		end if;
	end if;
end process;

-- Immediately upon completing reading a M&C byte from the USB or LAN, ask for the 
-- next one. 
-- RACE CONDITION??????? ARM IS FAST!!!!
RECLOCK_RDN_D: process(CLK_P, SREG254_READ_TOGGLE)
begin
	if rising_edge(CLK_P) then
		SREG254_READ_TOGGLE_D <= SREG254_READ_TOGGLE;
		SREG254_READ_TOGGLE_D2 <= SREG254_READ_TOGGLE_D;

		RX_LAN_BUFFER_EMPTY_D <= RX_LAN_BUFFER_EMPTY;
		RX_LAN_BUFFER_EMPTY_D2 <= RX_LAN_BUFFER_EMPTY_D;


		if (SREG254_READ_TOGGLE_D2 /= SREG254_READ_TOGGLE_D) then
			-- end of M&C byte read from ARM uC.
			if(RX_LAN_BUFFER_EMPTY_D2 = '0') then
				-- last M&C byte read was over LAN. Increment LAN elastic buffer read pointer
				RX_LAN_SAMPLE_CLK_REQ <= '1';
					-- identifies LAN as the media through which	this module exchanges 
					-- M&C information. Response will be directed the same way.
			end if;
		else
			RX_LAN_SAMPLE_CLK_REQ <= '0';
		end if;
	end if;
end process;

-- read byte received over LAN
RX_USB_LAN <= RX_LAN;


--// MONITORING ----------------------------------


--// simulation. send to a tab-delimited text file for subsequent (Matlab) plot.
SIM2OUTFILE_X: if(SIMULATION = '1') generate
--	Inst_SIM2OUTFILE1: SIM2OUTFILE 
--	generic map(
--		FILENAME => "C:\Users\Alain\Documents\1VHDL\com-1827 FSK modem 000\matlab\sn2.txt"
--	)
--	PORT MAP(
--		CLK => CLK_P,
--		DATA1 => SN2_I(17 downto 6),
--		DATA2 => SN2_Q(17 downto 6),
--		DATA3 => x"000",	
--		SAMPLE_CLK_IN => '1'
--	);
end generate;

end Behavioral;
