-------------------------------------------------------------
-- MSS copyright 2014
-- Filename:  COM1826.VHD
-- Authors: 
--		Alain Zarembowitch / MSS
-- Version: Rev 3
-- Last modified: 4/12/15

-- Inheritance: 	COM1518 6/27/14
--
-- description:  TDRSS DAS receiver 
--
-- Rev 3 4/12/15 AZ
-- Made BER measurement optional
---------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity COM1826 is
	generic (
		BER_EN: std_logic := '0';
			-- instantiate BER2 measurement (1) or not (0)
		SIMULATION: std_logic := '0'
			-- 1 during simulation, 0 for release	
	);
    Port ( 
		--GLOBAL CLOCKS
		CLK: in std_logic;
			-- A/D converter clock. Global (no BUFG used within)
		SYNC_RESET: in std_logic;
			-- Component MUST be reset upon configuration or configuration change
		
		--// ADC interface
		ADC_DATA_I_IN: in std_logic_vector(13 downto 0);	-- ADC data, use MSbs, 2's complement
		ADC_DATA_Q_IN: in std_logic_vector(13 downto 0);	-- ADC data, use MSbs, 2's complement
		ADC_SAMPLE_CLK_IN: in std_logic;
			-- ADC samples, in-phase(I) and quadrature (Q)
			-- Use both I and Q in the case of near-zero center frequency input signal
			-- Use I only (force Q to zero) in the case of IF input signal, IF undesampling for example.
			-- Samples are read at the rising edge of the ADC sampling clock CLK
			-- In the case of lower precision ADCs, align the samples to the left (MSb) and fill the 
			-- the least significant bits with zeros.
			
			-- Trick: if the samples are in binary offset format, just invert the most significant bit.

		--// FRONT-END RECEIVER GAIN CONTROL
		-- When external AGC is enabled, this component can control an external attenuator or 
		-- variable gain amplifier.
		AGC_DAC: out std_logic_vector(11 downto 0);
			-- gain control. May need to be inverted depending on the analog front-end.
			-- Here, maximum AGC_DAC really means minimum gain.
		AGC_DAC_SAMPLE_CLK: out std_logic;
			-- read AGC_DAC at the rising edge of CLK when AGC_DAC_SAMPLE_CLK = 1.
		

		--// CONTROLS 
	   AGC_RESPONSE : IN std_logic_vector(4 downto 0) := "01001";          
			-- Adjust the AGC response time. approximately log2(NSymbols). 
		RECEIVER_CENTER_FREQ: in std_logic_vector(31 downto 0);	
			-- nominal (i.e. expected) center frequency. Expressed as fc/demodulator processing clock * 2^32
			-- This frequency is subtracted from the input signal center frequency. 
			-- Add -fclk/4 when used in conjunction with IF undersampling. 
		NOMINAL_CHIP_RATE: in std_logic_vector(31 downto 0);
			-- = fchip rate / fclk * 2^32
	   CIC_R: in std_logic_vector(15 downto 0);    
			-- CIC Decimation ratio. The output sampling rate is thus fclk/R
			-- 1 to bypass. 0 is illegal, otherwise, nominal range is 1 to 16384.
			-- Usage: be careful not to decimate too much as the CIC decimation filter is not very sharp and thus
			-- can distort the modulated signal. 
			-- Rule of thumb: the CIC filter output sampling rate should be >= 8 samples per symbol.
		NOMINAL_SYMBOL_RATE1: in std_logic_vector(31 downto 0);
		NOMINAL_SYMBOL_RATE2: in std_logic_vector(31 downto 0);
			-- = fsymbol rate / fclk * 2^32 = nominal chip rate / spreading factor
			-- 1 for I channel, 2 for Q channel
	 	SPREADING_FACTOR1: in std_logic_vector(12 downto 0);
	 	SPREADING_FACTOR2: in std_logic_vector(12 downto 0);
			-- spreading factor. Valid range 3 - 8191 = nominal chip rate / nominal symbol rate
			-- Not necessarily equal to the spreading code period.
			-- Channel1/I spreading factor is always less than channel2/Q.
			-- IMPORTANT!!!!
			-- KEY ASSUMPTION: the number of parallel circuits NACQ MUST be less (or equal) than the number of 
			-- CLKs in half a symbol period.
			-- IMPORTANT!!!!   Adjust the NACQ constant within accordingly.
		LFSRA_INIT: in std_logic_vector(10 downto 0);
		LFSRC_INIT: in std_logic_vector(10 downto 0);
			-- LFSR initialization. see definition in Space network interoperable pn code libraries, Appendix A
		CODE_MODE: in std_logic;
			-- 0 = forward command link Gold codes
			-- 1 = return mode 2 link Gold codes
		FREQ_SCAN_N_COARSE_STEPS: in std_logic_vector(7 downto 0);
			-- number of frequency acquisition steps in each direction
			-- total number of frequencies is thus 2*N_STEPS+1
			-- Coarse scan step size is (symbol rate/4)
	   DEMOD_CONTROL: in std_logic_vector(15 downto 0);
			-- bit 0: spectrum inversion off (0), on (1)
			-- bit 1: BPSK (0) vs SQPN(1)
			-- bit 2: SQPN dual source independent symbol rates on I/Q (0),or single source identical data on I/Q(1)
			-- bits 3-5: encoding
			--     0 = NRZ-L
			--     1 = NRZ-M
			-- 	 2 = NRZ-S
			-- 	 4 = Biphase-L
			-- bit 6: 1/2 symbol Q delay
			-- bit 7: alternating I/Q bits (yes = 1, no = 0)

			-- bit 9: Output format (0) 8 demodulated bits packed in a byte, hard-quantized (1) 4-bit soft-quantized, .
		RESET_DEMOD_IN_FALSE_LOCK: in std_logic;
			-- 1 CLK wide pulse to reset frequency scanning, carrier tracking and symbol timing loops, but not the AGC
			-- justification: a more reliable assessment of the demod lock status is generally available at 
			-- components further down the receiver (FEC decoder, HDLC deframing, etc).
			
		--// OUTPUT 
		DATA_I_OUT: out std_logic_vector(7 downto 0);
		DATA_Q_OUT: out std_logic_vector(7 downto 0);
			-- Demodulated data bits, MSb first
			-- Read at rising edge of CLK when SAMPLE_CLK_OUT = '1';
			-- Two output formats, as selected by DEMOD_CONTROL(9):
			--   4-bit soft-quantized, or 8 demodulated bits packed in a byte hard-quantization
		SAMPLE_I_CLK_OUT: out std_logic;
		SAMPLE_Q_CLK_OUT: out std_logic;
			-- one CLK-wide pulse
		SYNC_PULSE: out std_logic;
			-- 1 CLK wide pulse once per code period
			
		--// Monitoring Information
		CARRIER_LOCK_OUT: out std_logic;
		CODE_LOCK_OUT: out std_logic;
		SIGNAL_PRESENT_OUT: out std_logic;
		CARRIER_FREQUENCY_ERROR1: out std_logic_vector(31 downto 0);
            -- report the frequency error in two parts (different units, simpler to do the aggregation outside in a micro)
            -- Center frequency error1: offset with respect to the nominal carrier frequency. 
            -- 32-bit signed integer (2's complement) expressed as cfe1 * 2^32  / fclk. 
        CARRIER_FREQUENCY_ERROR2: out std_logic_vector(31 downto 0);
            -- Center frequency error2: offset with respect to the nominal carrier frequency. 
            -- 32-bit signed integer (2's complement) expressed as cfe2 * 2^32  / fchiprate. 
		POWER_S_AVERAGE_OUT: out std_logic_vector(17 downto 0);
		POWER_N_AVERAGE_OUT: out std_logic_vector(17 downto 0);
			-- averaged on-time signal and noise power. 
			-- Units are irrelevant because of the many AGCs. 
		SNR1_LOCKED_OUT: out std_logic_vector(17 downto 0);
		SNR2_LOCKED_OUT: out std_logic_vector(17 downto 0);
			-- SNR when demod is code-locked. Format 16.2
			-- can be different on each channel
		DESPREAD1_I_OUT: out std_logic_vector(13 downto 0);
		DESPREAD1_Q_OUT: out std_logic_vector(13 downto 0);
		DESPREAD1_SAMPLE_CLK : OUT std_logic;
		BER_SYNC: out std_logic;
			-- BER measurement is synchronized with received PRBS11 test sequence
		BER_ERROR_COUNT: out std_logic_vector(31 downto 0);
			-- BER measurement over the specified window. Valid only when synchronized (BER_SYNC = '1')
			-- with the received PRBS11 test sequence
			-- bit errors expressed in number of BITS
			-- (whereas the window is expressed in bytes)
		BYTE_ERROR: out std_logic;
			-- one pulse for each byte error (helpful in visualizing the bit error distribution with an oscilloscope)
	
		-- COMSCOPE test points
		-- CS0: receiver output I-channel (after open-loop frequency translation to baseband, decimation, lpf, agc)
		-- CS1: spread I-channel after AFC, resampling and channel LPF filter
		-- CS2: despread I-channel after coherent I&D
		-- CS3: despread Q-channel after coherent I&D
		-- CS4: demodulated I
		-- CS5: demodulated Q
		-- CS6: agc18 scaling gain
		-- CS7: code replica
		-- CS8: accumulated code tracking phase correction (8 MSbs)
		-- CS9: carrier NCO phase (8 MSBs)
		-- CS10: accumulated symbol timing phase correction (8 MSbs)
		-- CS11: 2(S+N)/N, valid only if code lock. Linear, not in dBs.
		-- T1: start of code replica
		-- T2: code lock (1-bit). assessed once per code-sweep period
		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 entity;

architecture Behavioral of COM1826 is
--------------------------------------------------------
--      COMPONENTS
--------------------------------------------------------
	COMPONENT RECEIVER1
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		DATA_I_IN : IN std_logic_vector(13 downto 0);
		DATA_Q_IN : IN std_logic_vector(13 downto 0);
		SAMPLE_CLK_IN: IN std_logic;
		CENTER_FREQ : IN std_logic_vector(31 downto 0);
		AGC_RESPONSE : IN std_logic_vector(4 downto 0);
		AGC_INITIAL_GAIN: IN std_logic_vector(11 downto 0); 
	   CIC_R: in std_logic_vector(15 downto 0);    
		CONTROL : IN std_logic_vector(2 downto 0);          
		AGC_DAC : OUT std_logic_vector(11 downto 0);
		AGC_DAC_SAMPLE_CLK : OUT std_logic;
		DATA_I_OUT: out std_logic_vector(13 downto 0);
		DATA_Q_OUT: out std_logic_vector(13 downto 0);
		SAMPLE_CLK_OUT: out std_logic;
		SATURATION: out std_logic;
		TP : OUT std_logic_vector(10 downto 1);
		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
		);
	END COMPONENT;

	COMPONENT DSSS_DEMOD_TDRSS
	generic (
		SIMULATION: std_logic 
	);
	PORT(
		CLK : IN std_logic;
		SYNC_RESET : IN std_logic;
		SYMBOL_CLK: out std_logic;
		DATA_I_IN : IN std_logic_vector(13 downto 0);
		DATA_Q_IN : IN std_logic_vector(13 downto 0);
		SAMPLE_CLK_IN: in std_logic;
		NOMINAL_CHIP_RATE : IN std_logic_vector(31 downto 0);
		NOMINAL_SYMBOL_RATE1: in std_logic_vector(31 downto 0);
		NOMINAL_SYMBOL_RATE2: in std_logic_vector(31 downto 0);
		SPREADING_FACTOR1 : IN std_logic_vector(12 downto 0);
		SPREADING_FACTOR2 : IN std_logic_vector(12 downto 0);
		LFSRA_INIT: in std_logic_vector(10 downto 0);
		LFSRC_INIT: in std_logic_vector(10 downto 0);
		CODE_MODE: in std_logic;
		FREQ_SCAN_N_COARSE_STEPS: in std_logic_vector(7 downto 0);
		CONTROL : IN std_logic_vector(15 downto 0);
		RESET_DEMOD_IN_FALSE_LOCK: in std_logic;
		DATA_I_OUT: out std_logic_vector(3 downto 0);
		DATA_Q_OUT: out std_logic_vector(3 downto 0);
		SAMPLE_I_CLK_OUT: out std_logic;
		SAMPLE_Q_CLK_OUT: out std_logic;
		CODE_START_OUT: out std_logic;
		CARRIER_LOCK_OUT : OUT std_logic;
		CODE_LOCK_OUT : OUT std_logic;
		SIGNAL_PRESENT_OUT: out std_logic;
		CARRIER_FREQUENCY_ERROR1: out std_logic_vector(31 downto 0);
		CARRIER_FREQUENCY_ERROR2: 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);
		SNR1_LOCKED_OUT: out std_logic_vector(17 downto 0);
		SNR2_LOCKED_OUT: out std_logic_vector(17 downto 0);
		DESPREAD1_I_OUT: out std_logic_vector(13 downto 0);
		DESPREAD1_Q_OUT: out std_logic_vector(13 downto 0);
		DESPREAD1_SAMPLE_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 PX_TO_P8_CONVERSION
	PORT(
		CLK : IN std_logic;
		DATA_IN : IN std_logic_vector(7 downto 0);
		SAMPLE_CLK_IN : IN std_logic;
		WIDTH_IN : IN std_logic_vector(2 downto 0);          
		DATA_OUT : OUT std_logic_vector(7 downto 0);
		SAMPLE_CLK_OUT : OUT std_logic
		);
	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 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

--//-- RECLOCK INPUTS ---------------------
signal ADC_DATA_I_IN_D: std_logic_vector(13 downto 0) := (others => '0');
signal ADC_DATA_Q_IN_D: std_logic_vector(13 downto 0) := (others => '0');
signal ADC_SAMPLE_CLK_IN_D: std_logic := '0';

--//-- DIGITAL RECEIVER FRONT-END -------------------------
signal DATA1I: std_logic_vector(13 downto 0) := (others => '0');
signal DATA1Q: std_logic_vector(13 downto 0) := (others => '0');
signal SAMPLE1_CLK: std_logic := '0';
signal RECEIVER1_SATURATION: std_logic := '0';

--//-- DEMODULATOR --------------------------------------------
signal SYMBOL_CLK: std_logic := '0';	-- misnomer: chip clk
signal DATA_I_OUT_local: std_logic_vector(3 downto 0) := (others => '0');
signal DATA_Q_OUT_local: std_logic_vector(3 downto 0) := (others => '0');
signal SAMPLE_I_CLK_OUT_local: std_logic := '0';
signal SAMPLE_Q_CLK_OUT_local: std_logic := '0';
signal ANALOG_DEMOD_SYMBOL_CLK_OUT: std_logic := '0';
signal ANALOG_DEMOD_I_OUT: std_logic_vector(17 downto 0) := (others => '0');
signal ANALOG_DEMOD_Q_OUT: std_logic_vector(17 downto 0) := (others => '0');
signal DSSS_DEMOD_TP: std_logic_vector(20 downto 1) := (others => '0');

--//-- BER MEASUREMENT  ---------------------------------------------------------
signal RX_DATA1b1_X: std_logic_vector(7 downto 0) := (others => '0');
signal RX_SAMPLE1b1_CLK: std_logic := '0';
signal RX_DATA1b2_X: std_logic_vector(7 downto 0) := (others => '0');
signal RX_SAMPLE1b2_CLK: std_logic := '0';
signal RX_DATA8b1: std_logic_vector(7 downto 0) := (others => '0');
signal RX_SAMPLE8b1_CLK: std_logic := '0';
signal RX_DATA8b2: std_logic_vector(7 downto 0) := (others => '0');
signal RX_SAMPLE8b2_CLK: 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';
--------------------------------------------------------
--      IMPLEMENTATION
--------------------------------------------------------
begin

--// RECLOCK INPUTS ---------------------
-- Immediately reclock inputs for best timing.
RECLOCK_IN_001: process(CLK)
begin
	if rising_edge(CLK) then
		ADC_SAMPLE_CLK_IN_D <= ADC_SAMPLE_CLK_IN;
		ADC_DATA_I_IN_D(13 downto 0) <= ADC_DATA_I_IN(13 downto 0);
		ADC_DATA_Q_IN_D(13 downto 0) <= ADC_DATA_Q_IN(13 downto 0);
	end if;
end process;

--//-- DIGITAL RECEIVER FRONT-END -------------------------
-- Includes AGC, frequency translation to baseband, decimation and LPF.
RECEIVER1_001: RECEIVER1 PORT MAP(
	CLK => CLK,
	SYNC_RESET => SYNC_RESET,
	DATA_I_IN => ADC_DATA_I_IN_D,
	DATA_Q_IN => ADC_DATA_Q_IN_D,	-- when IF undersampling. Force Q to zero
	SAMPLE_CLK_IN => ADC_SAMPLE_CLK_IN_D,
	AGC_DAC => AGC_DAC,
	AGC_DAC_SAMPLE_CLK => AGC_DAC_SAMPLE_CLK,
	AGC_RESPONSE => AGC_RESPONSE,
	AGC_INITIAL_GAIN => x"800",	-- mid range
	CENTER_FREQ => RECEIVER_CENTER_FREQ,
	CIC_R => CIC_R,	
	CONTROL => "010",	-- enable both internal + external AGCs 
	   -- changed *0110822 because COM-3010 receiver does not have internal AGC
	DATA_I_OUT => DATA1I,
	DATA_Q_OUT => DATA1Q,
	SAMPLE_CLK_OUT => SAMPLE1_CLK,
	SATURATION => RECEIVER1_SATURATION,
	TP => open,
	CS1 => open,
	CS1_CLK => open,
	CS2 => open,
	CS2_CLK => open,
	CS3 => open,
	CS3_CLK => open,
	CS4 => open,
	CS4_CLK => open
);

--//-- DEMODULATOR --------------------------------------------
DSSS_DEMOD_TDRSS_001: DSSS_DEMOD_TDRSS 
generic map(
	SIMULATION => SIMULATION
)
PORT MAP(
	CLK => CLK,
	SYNC_RESET => SYNC_RESET, 
	SYMBOL_CLK => SYMBOL_CLK,	-- misnomer: chip clk
	DATA_I_IN => DATA1I,	--input sampling rate is CLK. 2's complement,
	DATA_Q_IN => DATA1Q,
	SAMPLE_CLK_IN => SAMPLE1_CLK,
	NOMINAL_CHIP_RATE => NOMINAL_CHIP_RATE,
	NOMINAL_SYMBOL_RATE1 => NOMINAL_SYMBOL_RATE1,
	NOMINAL_SYMBOL_RATE2 => NOMINAL_SYMBOL_RATE2,
	SPREADING_FACTOR1 => SPREADING_FACTOR1,
	SPREADING_FACTOR2 => SPREADING_FACTOR2,
	LFSRA_INIT => LFSRA_INIT,
	LFSRC_INIT => LFSRC_INIT,
	CODE_MODE => CODE_MODE,
	FREQ_SCAN_N_COARSE_STEPS => FREQ_SCAN_N_COARSE_STEPS,
	CONTROL => DEMOD_CONTROL,
	RESET_DEMOD_IN_FALSE_LOCK => RESET_DEMOD_IN_FALSE_LOCK,
	DATA_I_OUT => DATA_I_OUT_local,
	DATA_Q_OUT => DATA_Q_OUT_local,
	SAMPLE_I_CLK_OUT => SAMPLE_I_CLK_OUT_local,
	SAMPLE_Q_CLK_OUT => SAMPLE_Q_CLK_OUT_local,
	CODE_START_OUT => SYNC_PULSE,
	CARRIER_LOCK_OUT => CARRIER_LOCK_OUT,
	CODE_LOCK_OUT => CODE_LOCK_OUT,
	SIGNAL_PRESENT_OUT => SIGNAL_PRESENT_OUT,
	CARRIER_FREQUENCY_ERROR1 => CARRIER_FREQUENCY_ERROR1,
	CARRIER_FREQUENCY_ERROR2 => CARRIER_FREQUENCY_ERROR2,
	POWER_S_AVERAGE_OUT => POWER_S_AVERAGE_OUT,
	POWER_N_AVERAGE_OUT => POWER_N_AVERAGE_OUT,
	SNR1_LOCKED_OUT => SNR1_LOCKED_OUT,
	SNR2_LOCKED_OUT => SNR2_LOCKED_OUT,
	DESPREAD1_I_OUT => DESPREAD1_I_OUT,
	DESPREAD1_Q_OUT => DESPREAD1_Q_OUT,
	DESPREAD1_SAMPLE_CLK => DESPREAD1_SAMPLE_CLK,
	CS1 => CS1,	--  spread I-channel after frequency scanning, resampling and channel LPF filter
	CS1_CLK => CS1_CLK,
	CS2 => CS2,	--  despread I-channel after coherent I&D
	CS2_CLK => CS2_CLK,
	CS3 => CS3,	-- despread Q-channel after coherent I&D
	CS3_CLK => CS3_CLK,
	CS4 =>  CS4,		-- demodulated I
	CS4_CLK => CS4_CLK,
	CS5 => CS5,	-- demodulated Q
	CS5_CLK => CS5_CLK,
	CS6 => CS6,	--  agc18 scaling gain
	CS6_CLK => CS6_CLK,
	CS7 => CS7,	-- code replica
	CS7_CLK => CS7_CLK,
	CS8 =>  CS8,		-- accumulated code tracking phase correction (8 MSbs)
	CS8_CLK => CS8_CLK,
	CS9 => CS9,	-- accumulated carrier phase correction(8 MSBs)
	CS9_CLK => CS9_CLK,
	CS10 =>  CS10,		-- accumulated symbol timing phase correction (8 MSbs)
	CS10_CLK => CS10_CLK,
	CS11 =>  CS11,		-- 2(S+N)/N, valid only if code lock. Linear, not in dBs.
	CS11_CLK => CS11_CLK,
	T1 => T1,			-- start of code replica
	T1_CLK => T1_CLK,
	T2 => T2,			-- code lock (1-bit). assessed once per code-sweep period
	T2_CLK => T2_CLK,
	TP => DSSS_DEMOD_TP
);


-- 1-bit serial to 8-bit parallel conversion
RX_DATA1b1_X <= (0 => DATA_I_OUT_local(3), others => '0');
RX_SAMPLE1b1_CLK <= SAMPLE_I_CLK_OUT_local;
PX_TO_P8_CONVERSION_003: PX_TO_P8_CONVERSION 
PORT MAP(
	CLK => CLK,
	DATA_IN => RX_DATA1b1_X,		-- 1-bit serial input
	SAMPLE_CLK_IN => RX_SAMPLE1b1_CLK,
	WIDTH_IN => "001",
	DATA_OUT => RX_DATA8b1,		-- 8-bit parallel output
	SAMPLE_CLK_OUT => RX_SAMPLE8b1_CLK
);

RX_DATA1b2_X <= (0 => DATA_Q_OUT_local(3), others => '0');
RX_SAMPLE1b2_CLK <= SAMPLE_Q_CLK_OUT_local;
PX_TO_P8_CONVERSION_004: PX_TO_P8_CONVERSION 
PORT MAP(
	CLK => CLK,
	DATA_IN => RX_DATA1b2_X,		-- 1-bit serial input
	SAMPLE_CLK_IN => RX_SAMPLE1b2_CLK,
	WIDTH_IN => "001",
	DATA_OUT => RX_DATA8b2,		-- 8-bit parallel output
	SAMPLE_CLK_OUT => RX_SAMPLE8b2_CLK
);

-- to output
-- select output format:
-- bit 9: Output format (0) 8 demodulated bits packed in a byte, hard-quantized (1) 4-bit soft-quantized, .
OUTPUT_FORMAT_001: process(CLK)
begin
    if rising_edge(CLK) then
        if(DEMOD_CONTROL(9) = '1') then
            -- Output format (1) 4-bit soft-quantized
            DATA_I_OUT <= "0000" & DATA_I_OUT_local;
            DATA_Q_OUT <= "0000" & DATA_Q_OUT_local;
            SAMPLE_I_CLK_OUT <= SAMPLE_I_CLK_OUT_local;
            SAMPLE_Q_CLK_OUT <= SAMPLE_Q_CLK_OUT_local;
        else
            -- Output format (0) 8 demodulated bits packed in a byte, hard-quantized.
            DATA_I_OUT <= RX_DATA8b1;
            DATA_Q_OUT <= RX_DATA8b2;
            SAMPLE_I_CLK_OUT <= RX_SAMPLE8b1_CLK;
            SAMPLE_Q_CLK_OUT <= RX_SAMPLE8b2_CLK;
        end if;
    end if;
end process;

--//-- BER MEASUREMENT  ---------------------------------------------------------
BER2_001: if(BER_EN = '1') generate
	-- Measure BER when a PRSB-11 test sequence is transmitted
	BER_CONTROL(2 downto 0) <= "001"; -- BER measured over 10,000-bit window.
	BER_CONTROL(7 downto 3) <= (others => '0'); -- unused
	
	BER2_001: BER2 PORT MAP(
		CLK => CLK,
		SYNC_RESET => SYNC_RESET,
		DATA_IN => RX_DATA8b1,
		SAMPLE_CLK_IN => RX_SAMPLE8b1_CLK,
		CONTROL => BER_CONTROL,
		MF_DETECT => BER_MF_DETECT,
		MF_DETECT_CONFIRMED => BER_MF_DETECT_CONFIRMED,
		SYNC_LOCK => BER_SYNC,
		BYTE_ERROR => BYTE_ERROR,
		DATA_REPLICA => open,
		SAMPLE_CLK_OUT => open,
		BER => BER_ERROR_COUNT,
		BER_SAMPLE_CLK => open,
		TP => open
	);
end generate;


--// SIM2OUTFILE --------------------------------------------
-- simulation. send to a tab-delimited text file for subsequent (Matlab) plot.
--
SIM2OUTFILE_X: if(SIMULATION = '1') generate
	SIM2OUTFILE_001: SIM2OUTFILE 
	generic map(
		FILENAME => "rx_top1.txt"
	)
	PORT MAP(
		CLK => CLK,
		DATA1 => DATA1I(13 downto 2),	-- receiver1 output I,
		DATA2 => DATA1Q(13 downto 2),	-- receiver1 output Q,
		DATA3 => x"000",
		SAMPLE_CLK_IN => SAMPLE1_CLK
	);

end generate;

--// MONITORING, TEST POINTS --------------------------------------------
CS0 <= DATA1I(13 downto 6);
CS0_CLK <= SAMPLE1_CLK;
TP(19 downto 1) <= DSSS_DEMOD_TP(19 downto 1);
TP(20) <= RECEIVER1_SATURATION;
end Behavioral;
