--
 Implantable Sensor with Lamp (A3030) Firmware, Toplevel Unit
library ieee;  
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- Version X10, 17-SEP-14. Command Reception and Stimulus Controller working,
-- use in the A3030A for delivery ISL4C.

-- Version B02, 29-SEP-14. Add data transmission but without transmission
-- scatter. Re-assign command code 2 as configure_sensor, was formerly
-- set_polarity.

-- Version B03, 02-OCT-14. Add transmission scatter, but ring oscillator
-- is erratic and we cannot get good reception. Slow down the ring oscillator with 
-- two extra gates. Simplifiy FCK and TCK logic. Assign high routing priority to 
-- FCK divider bits. 

-- Version B04, 24-OCT-14. Correct error by which ring oscillator turns on when
-- we assert OND without enabling transmission. This error was adding to the power
-- consumed during command reception.

-- Version B05, 12-NOV-14. We remove one gate from the ring oscillator so as to
-- give us better resolution in obtaining TCK.

-- Version C01, 25-MAR-15. We stop transmitting when we receive an initiate command
-- pulse, and start again when we see a terminate command pulse.

-- Version C02, 10-APR-15. We turn off the lamp power boost regulator between
-- so as to reduce interference with the EEG amplifier.

-- Version C03, 21-APR-15. We add the acknowledgment command, whereby a byte sent
-- from the Command Transmitter gets sent back on the SCT slow communications 
-- as an acknowledgement.

-- Version D01, 18-JUN-15. Move the acknowledgement time farther from the sample
-- transmit time. Transform the stimulus generator into one that provides random
-- pulse generation at the specified frequency.

-- Version D02, 02-JUL-15. We add the Receive Command signal, which we use to 
-- stop data transmission while a command is being received, but permit data 
-- transmission while the command processor is reading command bytes out of the 
-- command memory and executing them. We change the acknowledgement timing so
-- it is prompt after the acknowldegement instruction is executed by the 
-- Command Receiver. We no longer run the ring oscillator during an entire 
-- stimulus, but only when the lamp pulses are active.

-- Version D03. Add transmit pulse counter for diagnostic purposes. Add 
-- flag to disable transmit scatter. Add routing priority for all nets in the
-- fast clock process. Add placement group for ring oscillator and fast clock
-- nets.

entity main is port (
		RCK, -- Reference Clock
		RP, -- Radio Frequency Power Detected
		SDO -- Serial Data Out, from ADC
		: in std_logic; 
		OND, -- On Device, keeps power turned on.
		ENL, -- Enable Lamp, enables boost regulator.
		ONL, -- On Lamp, closes the lamp's mosfet switch.
		CONV, -- Convert, initiates ADC conversion
		SDI, -- Serial Data In, for ADC channel configuration
		SCK, -- Serial Clock, for ADC communication
		XEN, -- Transmit Enable, for data transmission
		TP1, -- Test Point One, available on the programming extension.
		TP2, -- Test Point Two, available on the programming extension.
		TP3 -- Test Point Three, a dummy output for code retention. 
		: out std_logic;
		xdac -- Transmit DAC Output, to set data transmit frequency
		: out std_logic_vector(4 downto 0));

-- Configuration and Calibration Constants.
	constant device_id : integer := 7; -- The identifier for this device.
	constant fck_divisor : integer := 11; -- Divisor to give 10 MHz on FCK, 5 MHz on TCK.
	constant frequency_low : integer := 12; -- Low frequency code for data transmission.
	constant sample_rate : integer := 512; -- Data sampling rate.
	
-- Stable Calibration Constants
	constant frequency_step : integer := 3; -- High minus low frequency code
	
-- Operation Codes for the Command Processor
	constant stop_stimulus : integer := 0;
	constant start_stimulus : integer := 1;
	constant configure_sensor : integer := 2;
	constant set_brightness : integer := 3;
	constant set_pulse_len_hi : integer := 4;
	constant set_pulse_len_lo : integer := 5;
	constant set_interval_len_hi : integer := 6;
	constant set_interval_len_lo : integer := 7;
	constant set_stimulus_len_hi : integer := 8;
	constant set_stimulus_len_lo : integer := 9;
	constant enable_randomizer : integer := 10;
	constant select_device : integer := 11;
	constant command_acknowledge : integer := 12;

-- Other Constants
	constant select_all : integer := 15; -- The all-device select id code.
	constant device_id_max : integer := 15; -- Defines range of id codes.
	constant max_brightness : integer := 5; -- For lamp full power.
	constant aux_id : integer := 15; -- The channel to use for acknowledgement
	constant ack_code : integer := 1; -- The acknowledgement code in the acknowledge message
	constant scatter_enable : boolean := true; -- Enable transmission scatter.
end;


architecture behavior of main is
	
-- Attributes to guide the compiler.
	attribute syn_keep : boolean;
	attribute nomerge : string;

-- Power Controller
	signal USERSTDBY, CLRFLAG, STDBY : std_logic;
	attribute syn_keep of STDBY : signal is true;
	
-- Ring Oscillator and Transmit Clock
	component BUFBA is port (A : in std_logic; Z : out std_logic); end component;
	signal R1, R2, R3, R4, R5, ROCK, TCK, FCK : std_logic;
	attribute syn_keep of R1, R2, R3, R4, R5, TCK, FCK : signal is true;
	attribute nomerge of R1, R2, R3, R4, R5, TCK, FCK : signal is "";  
	
-- Byte Receiver
	signal RPS, -- Radio Frequency Power Synchronized
		IC, -- Initiate Command Reception
		TC, -- Terminate Command Reception
		RC, -- Receiveing Command
		RBI, -- Receive Command Byte Initiate
		RBD, -- Receive Command Byte Done
		CRCERR, -- Cyclic Redundancy Checksum Error
		BYTERR, -- Byte Error
		BYTS, -- Command Byte Strobe
		BITS -- Command Bit Strobe
		: boolean := false; 
	signal cmd : std_logic_vector(7 downto 0); -- Command Byte
	
-- Command Memory
	constant addr_max : integer := 511;
	signal cm_addr : std_logic_vector(8 downto 0); -- Command Memory Address
	signal cm_out : std_logic_vector(7 downto 0); -- Command Memory Data Out
	signal BYTSEL, -- Command Memory Select
		CMWR  -- Command Memory Write
		: std_logic; 
	
-- Control Registers
	signal stimulus_len, -- Number of pulses in a stimulus, 0 for infinite.
		interval_len, -- Number of RCK periods in each pulse interval.
		pulse_len -- Number of RCK periods in each pulse.
		: std_logic_vector(15 downto 0) := "0000000000000000";
	signal brightness -- A code to set the lamp high-speed duty cycle.
		: std_logic_vector(2 downto 0) := std_logic_vector(
			to_unsigned(max_brightness,3));
	signal sensor_config -- A code to configure the sensor.
		: std_logic_vector(7 downto 0) := "00000000";
		
-- Acknowledgement Registers and Signals
	signal ack_key -- The byte we send back on command acknowledge.
		: std_logic_vector(7 downto 0) := "00000000";
	signal TXA, -- Transmit Acknowledgment
		TXAD -- Transmit Acknowledgment Delayed
		: boolean := false;
		
-- Command Processor
	signal CPA -- Command Processor Active
		: boolean := false;

-- Stimulus Generator and Brightness Controller
	constant rck_per_ms : integer := 33;
	signal PA, -- Pulse Active
		STARTS, -- Start Stimulus
		STOPS, -- Stop Stimulus
		SRUN, -- Stimulus Running
		RAND, -- Enable Pulse Randomizer
		ISC, -- Initiate Stimulus Cycle
		ILP, -- Initiate Lamp Pulse
		SCRATCHBIT
		: boolean := false;
	signal STCK  -- Stimulus Clock
		: std_logic;

-- Sensor Sampling and Transmission
	signal TXEN, -- Sample Transmission Enabled
		TXI, -- Sample Transmit Initiate
		TXD, -- Sample Transmit Done
		TXB, -- Transmit Bit
		SCKEN, -- Enable SCK
		FHI, -- Frequency hi
		SSDO -- Synchronized SDO
		: boolean := false;
	signal scatter -- The transmission scatter value
		: std_logic_vector(3 downto 0) := "0000";
	signal sample -- The ADC sample value
		: std_logic_vector(15 downto 0) := "0000000000000000";
	signal TXCNT : boolean := false;

-- Functions and Procedures	
	function to_std_logic (v: boolean) return std_ulogic is
	begin if v then return('1'); else return('0'); end if; end function;

begin

-- We turn off the logic chip bandgap references and other unecessary
-- circuits with the power controller unit. Within a few milliseconds
-- of power-up, the chip is fully operational and ready to enter its
-- standby mode, which is the mode we run it in all the time. The PCU
-- entity has two outputs: USERSTDBY and SFLAG. We don't connect 
-- SFLAG, but we do connect USERSTDBY to a keeper output pin on the 
-- chip. We find that the compiler eliminates the PCU unless one of
-- its outputs is connected to a pin or a state machine.
	Power_Controller: entity PCU port map (
		USERSTDBY => USERSTDBY, 
		CLRFLAG => CLRFLAG, 
		STDBY => STDBY);
	PowerUp: process is
		constant PowerUpEnd : integer := 3;
		variable counter : integer range 0 to PowerUpEnd := 0;
	begin
		wait until (RCK = '1');
		if (counter = PowerUpEnd) then 
			counter := counter;
			USERSTDBY <= '1';
			CLRFLAG <= '0';
		else
			counter := counter + 1;
			USERSTDBY <= '0';
			if (counter = PowerUpEnd-1) then 
				CLRFLAG <= '1'; 
			else 
				CLRFLAG <= '0'; 
			end if;
		end if;
		OND <= to_std_logic(SRUN or CPA or TXEN);
	end process;
	
-- The Receive Power signal must be synchronized with the RCK clock.
	Synchronize_RP: process is 
	begin
		wait until (RCK = '0');
		RPS <= (RP = '1');
	end process;
	
-- We detect a long enough burst of command power to initiate
-- command reception, and set the IC signal.
	Initiate_Command: process is 
		constant endcount : integer := 65;
		variable counter : integer range 0 to endcount := 0;
	begin
		wait until (RCK = '1');
		if RPS then 
			if (counter = endcount) then 
				counter := endcount;
				IC <= true;
			else 
				counter := counter + 1;
				IC <= false;
			end if;
		else
			counter := 0;
			IC <= false;
		end if;
	end process;
	
-- We detect a long enough period without command power to 
-- terminate command reception, and set the TC signal.
	Terminate_Command: process is 
		constant endcount : integer := 328;
		variable counter : integer range 0 to endcount := 0;
	begin
		wait until (RCK = '1');
		if not RPS then 
			if (counter = endcount) then 
				counter := endcount;
				TC <= true;
			else 
				counter := counter + 1;
				TC <= false;
			end if;
		else
			counter := 0;
			TC <=  false;
		end if;
	end process;
	
-- The Receive Command (RC) signal indicates that a command is being 
-- received. We set RC when Initiate Command (IC) occurs, and we clear
-- RC when Terminate Command (TC) occurs.
	Receive_Command: process is
	begin
		wait until (RCK = '1');
		if not RC then
			RC <= IC;
		else 
			RC <= not TC;
		end if;
	end process;

-- We watch for a start bit and receive serial bytes when instructed
-- to do so by the Command Processor with the RBI signal.
	Byte_Receiver: process is
		variable state, next_state : integer range 0 to 63 := 0;
		variable no_stop_bit : boolean := false;
	begin
		wait until (RCK = '1');
		
		-- Idle state, waiting for Receive Byte Initiate.
		if (state = 0) then
			if RBI and (not RPS) then 
				next_state := 1;
			else 
				next_state := 0;
			end if;
		end if;
		
		-- Wait for a start bit. If we wait long enough, we will see the 
		-- termination signal, in which case we abort and wait for not RPI.
		-- We clear no stop bit variable, which clears the global BYTERR 
		-- signal.
		if (state = 1) then
			if TC then 
				next_state := 63; 
			else 
				if RPS then 
					next_state := 2;
				else 
					next_state := 1; 
				end if;
			end if;
			no_stop_bit := false;
		end if;
		BYTERR <= no_stop_bit;
		
		-- Once we have a start bit, we proceed through the eight bits of
		-- a command byte, each bit taking four states. The first bit occurs
		-- at state 7 and the stop bit at state 39.
		if (state >= 2) and (state <= 38) then 
			next_state := state + 1; 
		end if;
		
		-- If the stop bit is present, we go to our end state. If it's missing,
		-- we go to our byte error state. The stop bit is zero, so RPS should 
		-- at this point be false.
		if (state = 39) then
			if not RPS then 
				next_state := 63;
			else 
				next_state := 62;
			end if;
		end if;
		
		-- Here we deal with unused states by directing them towards the byte
		-- error state.
		if (state > 39) and (state < 62) then 
			next_state := 62; 
		end if;
		
		-- In the byte error state, we set the "no stop bit" flag, which asserts the 
		-- global BYTERR signal. We will not reset this flag until the Byte Receiver
		-- starts a new byte reception. This flag tells the Command Processor to ignore
		-- the entire command. We wait in the byte error state until RBI is unasserted. 
		-- Because we do not assert RBD, the un-assertion of RBI will occur only when
		-- the Command Receiver encounters a Terminate Command signal.
		if (state = 62) then
			if not RBI then 
				next_state := 0;
			else 
				next_state := 62;
			end if;
			no_stop_bit := true;
		end if;
		
		-- In the end state, we assert Receive Byte Done and we wait for the command
		-- processor to un-assert Receive Byte Initiate. When we see not RBI, we return
		-- to the idle state. We stop asserting RBD, or refrain from asserting it, when
		-- we have Terminate Command.
		if (state = 63) then 
			if not RBI then 
				next_state := 0; 
			else 
				next_state := 63; 
			end if;
		end if;
		RBD <= (state = 63) and (not TC);
				
		-- The eight bits of the command are set every four states during
		-- the command reception.
		for i in 0 to 7 loop
			if (state = 35 - i * 4) then 
				if RPS then 
					cmd(i) <= '1'; 
				else 
					cmd(i) <= '0'; 
				end if;
			else 
				cmd(i) <= cmd(i); 
			end if;
		end loop;
		
		-- We assert Command Bit Strobe one RCK period before the best moment
		-- to sample each bit value.
		if (state = 34) or (state = 30) or (state = 26) or (state = 22) 
			or (state = 18) or (state = 14) or (state = 10) or (state = 6) then
			BITS <= true;
		else 
			BITS <= false;
		end if;
		
		-- The Byte Strobe signal indicates that we have a start bit and is 
		-- useful as a test point trigger. It provides a pulse of two RCK 
		-- periods.
		BYTS <= (state = 2) or (state = 3);
		
		-- Assert the new state.
		state := next_state;
	end process;

-- This process runs all the bits of a command through a sixteen-bit linear shift 
-- register, with local name "crc" for "cyclic redundancy check". We preset crc 
-- to all ones. The final sixteen bits of every command are chosen so that they 
-- reset the crc register to all zeros. If crc is not zero at the end of a command,
-- there was some error during reception. We use the Bit Strobe (BITS) signal to 
-- clock crc, because BITS is asserted only when a command data bit is receive,
-- not when we receive a start or stop bit.
	Error_Check : process is
		variable crc, next_crc : std_logic_vector(15 downto 0) := "1111111111111111";
	begin
		wait until (RCK = '1');
		
		if IC then
			-- When a new command transmission starts, we preload the cyclic redundancy
			-- check register to all ones.
			crc := "1111111111111111";
		else
			-- We use Command Bit Strobe to clock each command bit into the CRC.
			-- The transmitter calculates the checksum with zeros in the last
			-- sixteen bits, reverses the order of these checksum bits, and sends
			-- them as the last two bytes of the actual transmission, instead of the
			-- zeros it used when it calculated its own checksum. These last sixteen
			-- bits, thus obtained, will reset the receiver CRC to zero, provided there
			-- has been no corruption of the data on the way.
			if BITS then
				for i in 0 to 9 loop next_crc(i) := crc(i+1); end loop;
				next_crc(10) := crc(11) xor crc(0);
				next_crc(11) := crc(12);
				next_crc(12) := crc(13) xor crc(0);
				next_crc(13) := crc(14) xor crc(0);
				next_crc(14) := crc(15);
				next_crc(15) := to_std_logic(RPS) xor crc(0);	
				crc := next_crc;
			end if;		
		end if;
		
		-- The CRCERR flag tells us when the CRC is not zero. It will be zero when it
		-- has been reset by the two bytes of a correct checksum.
		CRCERR <= (crc /= "0000000000000000");
	end process;
	
-- Command Memory
	Command_Memory : entity RAM_512Byte port map (
		Clock => not RCK,
		ClockEn => '1',
		Reset => '0', 
		WE => CMWR,
		Address => cm_addr, 
		Data => cmd,
		Q => cm_out);
		
-- This Command Processor detects Inititiate Command (IC) and activates the Byte Receiver. 
-- It stores command bytes in the Command Memory until it detects Terminate Command (TC). If
-- the Error Check reports no error, the Command Processor reads the commands out of command
-- memory one at a time and executes them. The Command Processor runs on the reference clock,
-- which is 32.768 kHz, and proceeds to a new state every clock cycle. Each command byte takes
-- roughly two clock cycles to process. If the Command Memory is 512 bytes long, the maximum
-- time taken by command processing will be 30 ms. The Command Processor does not respond to
-- Initiate Command (IC) during the execution time, so the Command Transmitter must refrain
-- from sending consecutive long commands to the same device without inserting sufficient dealay
-- for execution.
	Command_Processor: process is
		
		-- General-purpose state names for the Command Processor
		constant idle_s : integer := 0;
		constant receive_cmd_s : integer := 1;
		constant store_cmd_s : integer := 2;
		constant inc_addr_s : integer := 3;
		constant check_cmd_s : integer := 4;
		constant opcode_s : integer := 5;
		constant dec_count_s : integer := 6;
		constant check_count_s : integer := 7;
		
		-- Opcode-specific state names for the Command Processor
		constant k : integer := 10;
		constant stop_stimulus_s : integer := stop_stimulus + k;
		constant start_stimulus_s : integer := start_stimulus + k;
		constant configure_sensor_s : integer := configure_sensor + k;
		constant set_brightness_s : integer := set_brightness + k;
		constant set_pulse_len_hi_s : integer := set_pulse_len_hi + k;
		constant set_pulse_len_lo_s : integer := set_pulse_len_lo + k;
		constant set_interval_len_hi_s : integer := set_interval_len_hi + k;
		constant set_interval_len_lo_s : integer := set_interval_len_lo + k;
		constant set_stimulus_len_hi_s : integer := set_stimulus_len_hi + k;
		constant set_stimulus_len_lo_s : integer := set_stimulus_len_lo + k;
		constant enable_randomizer_s : integer := enable_randomizer + k;
		constant select_device_s : integer := select_device + k;
		constant command_acknowledge_s : integer := command_acknowledge + k;
		
		-- Variables for the Command Processor
		variable opcode : integer range 0 to 255 := 0;
		variable select_id : integer range 0 to device_id_max := 0;
		variable state, next_state : integer range 0 to 31 := 0;
		variable count, addr : integer range 0 to addr_max := 0;
		variable randomizer_enabled : boolean := false;
		
	begin
		wait until (RCK = '1');
	
		-- Idle State.
		if (state = idle_s) then
			if IC then 
				next_state := receive_cmd_s; 
			else 
				next_state := idle_s;
			end if;
			addr := 0;
			count := 0;
		end if;
		
		-- Receive a command byte. We assert RBI and wait for RBD. If we see 
		-- terminate command (TC), we look at the number of command bytes we have 
		-- received so far. If we have less than three, we have only the checksum,
		-- so we go back to the idle state. If we have three or more, we move on.
		-- Note that the Byte Receiver aborts on TC also.
		if (state = receive_cmd_s) then 
			if TC then 
				if (addr <= 2) then 
					next_state := idle_s;
				else 
					next_state := check_cmd_s;
				end if;
			else 
				if RBD then 
					next_state := store_cmd_s;
				else 
					next_state := receive_cmd_s;
				end if;
			end if;
		end if;
		RBI <= (state = receive_cmd_s);
		
		-- Store the new command byte in the command memory. We assert CMWR.
		if (state = store_cmd_s) then 
			if not RBD then 
				next_state := inc_addr_s;
			else 
				next_state := store_cmd_s;
			end if;
		end if;
		CMWR <= to_std_logic(state = store_cmd_s);
		
		-- Increment the command address. If we have run out of space in the
		-- Command Memory, we abort our attempt to process the command, and wait
		-- for the next command.
		if (state = inc_addr_s) then
			addr := addr + 1;
			count := count + 1;
			if (addr = addr_max) then
				next_state := idle_s;
			else
				next_state := receive_cmd_s;
			end if;
		end if;		
		
		-- There are two possible sources of error: a failure in the cyclic redundancy
		-- check (CRCERR) or an error in the structure of a command byte (BYTERR). If either
		-- is asserted, we go back to idle. Otherwise, we proceed to execution of the commands
		-- that are now stored in memory. We set the command memory address to zero in 
		-- anticipation of reading out the first command byte. But before we clear the 
		-- memory address, we save the number of data bytes in count so we will know 
		-- how many bytes to read out and execute. By construction, the count must be at 
		-- least 3 at this stage.
		if (state = check_cmd_s) then
			if CRCERR or BYTERR then 
				next_state := idle_s;
			else 
				next_state := opcode_s;
			end if;
			addr := 0;
		end if;
		
		-- We read a byte from the command memory and interpret it. We increment the
		-- command memory address so as to retrieve the next byte, which may be a 
		-- parameter.
		if (state = opcode_s) then
			case to_integer(unsigned(cm_out)) is
				when stop_stimulus => next_state := stop_stimulus_s;
				when start_stimulus => next_state := start_stimulus_s;
				when configure_sensor => next_state := configure_sensor_s;
				when set_brightness => next_state := set_brightness_s;
				when set_pulse_len_hi => next_state := set_pulse_len_hi_s;
				when set_pulse_len_lo => next_state := set_pulse_len_lo_s;
				when set_interval_len_hi => next_state := set_interval_len_hi_s;
				when set_interval_len_lo => next_state := set_interval_len_lo_s;
				when set_stimulus_len_hi => next_state := set_stimulus_len_hi_s;
				when set_stimulus_len_lo => next_state := set_stimulus_len_lo_s;
				when enable_randomizer => next_state := enable_randomizer_s;
				when select_device => next_state := select_device_s;
				when command_acknowledge => next_state := command_acknowledge_s;
				when others => next_state := check_count_s;
			end case;
			addr := addr + 1;
			count := count - 1;
		end if;
		
		-- This state causes all settings to be cleared to zero.
		if (state = stop_stimulus_s) then
			next_state := check_count_s;
		end if;
		
		-- We start a new stimulus with the SS signal. 
		if (state = start_stimulus_s) then
			next_state := check_count_s;
		end if;
		
		-- The Start Stimulus and Stop Stimulus signals are asserted for one
		-- RCK period when we are in the start and stop stimulus states 
		-- respectively.
		STARTS <= (state = start_stimulus_s);
		STOPS <= (state = stop_stimulus_s);
		
		-- We set the select identifier, which we then compare to this device's id.
		-- If the device select number is not select_all and is not device_id, we
		-- abort command execution and await the next string of commands.
		if (state = select_device_s) then
			select_id := to_integer(unsigned(cm_out));
			if (select_id = select_all) or (select_id = device_id) then
				next_state := dec_count_s;
			else 
				next_state := idle_s;
			end if;
		end if;
		
		-- We set the sensor configuration register.
		if (state = configure_sensor_s) then 
			next_state := dec_count_s;
		end if;
		
		-- Logic to control the sensor configuration register.
		if state = configure_sensor_s then
			for i in 0 to 7 loop
				sensor_config(i) <= cm_out(i);
			end loop;
		else
			sensor_config <= sensor_config;
		end if;

		-- We set brightness register, which controls the lamp's high-frequency
		-- duty cycle.
		if (state = set_brightness_s) then 
			next_state := dec_count_s;
		end if;
		
		-- Logic to control the brightness register. We clear the brightness
		-- to all ones so the default setting is 100% duty cycle, or full power.
		if (state = stop_stimulus_s) then
			brightness <= std_logic_vector(to_unsigned(max_brightness,brightness'length));
		else
			if (state = set_brightness_s) then
				for i in 0 to 2 loop
					brightness(i) <= cm_out(i);
				end loop;
			else
				brightness <= brightness;
			end if;
		end if;
		
		-- We turn on or off the pulse randomizer, based upon the parameter value.
		if (state = enable_randomizer_s) then
			next_state := dec_count_s;
		end if;
		if (state = stop_stimulus_s) then
			randomizer_enabled := false;
		else
			if (state = enable_randomizer_s) then
				randomizer_enabled := (cm_out(0) = '1');
			end if;
		end if;
		RAND <= randomizer_enabled;
		
		-- Set the HI byte of the pulse length.
		if (state = set_pulse_len_hi_s) then
			next_state := dec_count_s;
		end if;
			
		-- Set the LO byte of the pulse length.
		if (state = set_pulse_len_lo_s) then
			next_state := dec_count_s;
		end if;
				
		-- Logic to control the pulse length register.
		for i in 0 to 7 loop
			if (state = set_pulse_len_hi_s) then 
				pulse_len(i+8) <= cm_out(i);
			else 
				pulse_len(i+8) <= pulse_len(i+8);
			end if;
			if (state = set_pulse_len_lo_s) then 
				pulse_len(i) <= cm_out(i);
			else 
				pulse_len(i) <= pulse_len(i);
			end if;
		end loop;
		
		-- Set the HI byte of the interval length.
		if (state = set_interval_len_hi_s) then
			next_state := dec_count_s;
		end if;
			
		-- Set the LO byte of the interval length.
		if (state = set_interval_len_lo_s) then
			next_state := dec_count_s;
		end if;

		-- Logic to control the interval length register.
		for i in 0 to 7 loop
			if (state = set_interval_len_hi_s) then 
				interval_len(i+8) <= cm_out(i);
			else 
				interval_len(i+8) <= interval_len(i+8);
			end if;
			if (state = set_interval_len_lo_s) then 
				interval_len(i) <= cm_out(i);
			else 
				interval_len(i) <= interval_len(i);
			end if;
		end loop;

		-- Set the HI byte of the stimulus length.
		if (state = set_stimulus_len_hi_s) then
			next_state := dec_count_s;
		end if;
			
		-- Set the LO byte of the stimulus length.
		if (state = set_stimulus_len_lo_s) then
			next_state := dec_count_s;
		end if;

		-- Logic to control the stimulus length register.
		for i in 0 to 7 loop
			if (state = set_stimulus_len_hi_s) then 
				stimulus_len(i+8) <= cm_out(i);
			else 
				stimulus_len(i+8) <= stimulus_len(i+8);
			end if;
			if (state = set_stimulus_len_lo_s) then 
				stimulus_len(i) <= cm_out(i);
			else 
				stimulus_len(i) <= stimulus_len(i);
			end if;
		end loop;

		-- Set the echo byte.
		if state = command_acknowledge_s then
			next_state := dec_count_s;
		end if;
		
		-- Initiate transmission of acknowledgement.
		TXA <= (state = command_acknowledge_s);
		
		-- Set the acknowledgement key.
		for i in 0 to 7 loop
			if (state = command_acknowledge_s) then 
				ack_key(i) <= cm_out(i);
			else 
				ack_key(i) <= ack_key(i);
			end if;
		end loop;

		-- We increment the command memory address and decrement the command counter
		-- in preparation for reading the next op-code.
		if (state = dec_count_s) then
			addr := addr + 1;
			count := count - 1;
			next_state := check_count_s;
		end if;
		
		-- We check the command count to see if there are any more codes to be read
		-- from the command memory. The last two are always the checksum, so if they
		-- are all that is left, we will return to the idle state.
		if (state = check_count_s) then
			if (count <= 2) then 
				next_state := idle_s;
			else 
				next_state := opcode_s;
			end if;
		end if;
		
		-- Advance the state variable.
		state := next_state;
		
		-- Command Processor Active is true whenever the state is not idle.
		CPA <= (state /= idle_s);
		
		-- The Command Memory Address is always equal to the Command Processor's
		-- addr variable.
		cm_addr <= std_logic_vector(to_unsigned(addr,cm_addr'length));
	end process;

-- The Stimulus Clock Generator creates the clock that will run the stimulua
-- generator itself. We divide RCK by the interval length, so as to generate
-- a clock that is 1/rck_per_ms of the desired interval frequency. If we want
-- a 10-ms interval, we divide RCK by 10 to create frequency RCK/10. Later, in
-- the Stimulu Generator, we count to rck_per_ms so as to generate a period
-- of interval lenght in milliseconds.
	Stimulus_Clock_Generator : process is
		variable il : integer range 0 to 65535 := 0;
	begin
		wait until (RCK = '1');
		
		if STARTS then
			il := to_integer(unsigned(interval_len));
			ISC <= true;
			STCK <= '0';
		else 
			if (il = 0) or (il = 1) then
				il := to_integer(unsigned(interval_len));
				ISC <= false;
				STCK <= '0';
			else
				il := il - 1;
				ISC <= ISC;
				STCK <= '1';
			end if;
		end if;
	end process;

-- The Stimulus Generator counts the number of pulses and issues the Initiate
-- Lamp Pulse (ILP) signal. When the lamp pulses should be issued at random, this
-- process generates a random number on each of STCK cycle during the interval. 
-- There will be rck_per_ms of these STCK cycles, and the random number has range
-- 0 to rck_per_ms - 2. If this random number equals the STCK cycle number, the
-- Stimulus Generator sets ILP. In this implementation of the generator, we use
-- the fact taht rck_per_ms = 33 to permit us to work with a five-bit random 
-- number 0-31, which we create with a linear shift register. When we are not
-- generating pulses at random, we generate one and only one pulse per interval,
-- on the same STCK cycle.
	Stimulus_Generator : process (STOPS, STCK) is
		variable state, next_state : integer range 0 to 4 := 0;
		variable sl : integer range 0 to 65535 := 0;
		variable il : integer range 0 to 63 := 0;
		variable random, next_random : std_logic_vector(7 downto 0) := 
			std_logic_vector(to_unsigned(rck_per_ms-2,8));

	begin 
		if STOPS then 
			state := 0;
		elsif rising_edge(STCK) then
			if (state = 0) then 
				if ISC then 
					next_state := 1;
				else
					next_state := 0;
				end if;
			end if;
			
			if (state = 1) then
				sl := to_integer(unsigned(stimulus_len));
				il := rck_per_ms - 1;
				next_state := 2;
			end if;
			
			if (state = 2) then
				if (il = 2) then
					next_state := 3;
					sl := sl - 1;
				else
					next_state := 2;
					sl := sl;
				end if;
				il := il - 1;
			end if;
			
			if (state = 3) then
				if (sl = 0) and (to_integer(unsigned(stimulus_len)) /= 0) then 
					next_state := 0;
				else
					next_state := 2;
				end if;
				sl := sl;
				il := rck_per_ms - 1;
			end if;
			
			if (state > 3) then
				next_state := 0;
			end if;

			state := next_state;
		end if;
		
		if rising_edge(STCK) then		
			-- If RAND, we generate a new random number every STCK cycle.
			-- Otherwise, we set th random value to a fixed constant, so
			-- that the lamp pulse will be in the same place on every 
			-- interval.
			if RAND then
				next_random(7) := random(0);
				next_random(6) := random(7);
				next_random(5) := random(6) xor random(0);
				next_random(4) := random(5) xor random(0);
				next_random(3) := random(4) xor random(0);
				next_random(2) := random(3);
				next_random(1) := random(2);
				next_random(0) := random(1);
				random := next_random;
			else 
				random := std_logic_vector(to_unsigned(rck_per_ms - 2,8));
			end if;
			
			-- We assert SRUN to keep the logic chip powered up.
			SRUN <= (state > 0);
		
			-- We assert ILP when il has the correct value.
			ILP <= (state = 2) and (il = to_integer(unsigned(random(4 downto 0))));
		end if;

		SCRATCHBIT <= (state = 3);
end process;
	
-- When ILP is asserted, the Lamp Pulse Generator turns on the lamp power supply,
-- by enabling the boost converter with ENL, and asserts Pulse Active (PA). The
-- Brightness Controller will use PA to modulate ONL.
	Lamp_Pulse_Generator : process (STOPS, RCK) is
		variable pl : integer range 0 to 65535 := 0;
		variable prev_ilp : boolean := false;
	begin
		-- We reset the pulse generator on STOPS. We start
		-- a new pulse on ILP, and count down from the pulse
		-- length to zero on RCK.
		if STOPS then
			pl := 0;
		elsif rising_edge(RCK) then 
			if ILP and (not prev_ilp) then
				pl := to_integer(unsigned(pulse_len));
			elsif (pl > 0) then
				pl := pl -1;
			else
				pl := 0;
			end if;
		end if;

		if rising_edge(RCK) then
			-- We assert PA when we want the lamp to turn on, although its output
			-- may be modulated to reduce brightness.
			PA <= (pl /= 0);
		
			-- We assert ENL to turn on the boost regulator only when we want the
			-- light to turn on. 
			ENL <= to_std_logic(pl /= 0);
		
			-- We want to detect rising edges on ILP, so we save the previous state.
			prev_ilp := ILP;	
		end if;
	end process;

-- Ring Oscillator. 
	R1 <= to_std_logic((PA or TXI or TXD) and (R4 = '0')); 	
	ring1 : BUFBA port map (R1,R2);
	ring2 : BUFBA port map (R2,R3);
	ring3 : BUFBA port map (R3,R4);
	ring4 : BUFBA port map (R4,R5);
	ROCK <= R5;

-- The Fast Clock process divides the ring oscillator by fck_divisor to create
-- a clock as close as we can get it to 10-MHz clock. Selecting fck_divisor is 
-- part of the device calibration.
	Fast_Clock : process is
		constant fck_length : integer := 2;
		variable count : integer range 0 to fck_divisor - 1 := 0;
	begin
		-- We run this state machine off the ring oscillator.
		wait until (ROCK = '1');
		
		-- The fck_divisor is set at the top of the code, and should be such that
		-- FCK is 10 MHz and TCK, which we obtain in the next process, is 5 MHz.
		-- In particular, the period of TCK must be within 195-215 ns.
		if (count = fck_divisor - 1) then 
			count := 0;
		else 
			count := count + 1;
		end if;
		
		-- The Fast Clock is a negative pulse of fck_length periods of ROCK.
		-- We will later use the falling edge of FCK to clock TCK, and the 
		-- rising edge to set outputs that depend upon the state of TCK.
		FCK <= to_std_logic((count >= 0) and (count <= fck_length));
	end process;
	
-- The Transmit Clock proces divides FCK in two so as to produce a clock with
-- exactly 50% duty cycle and frequency close to 5 MHz.
	Transmit_Clock : process is 
	begin
		-- The Transmit Clock, TCK, is FCK divided by two, but clocked by the
		-- falling edge of FCK, not the rising edge.
		wait until (FCK = '0');
		
		if (TCK = '1') then
			TCK <= '0';
		else 
			TCK <= '1';
		end if;
	end process;
	
-- The Brightness Controller takes the Pulse Active (PA) signal and uses it
-- to generate the On Lamp (ONL) output, which drives the gate of the lamp
-- switching transistor. If we are modulating the lamp power to give average
-- power greater than 0% and less than 100%, we use TCK to create an ONL
-- signal with a duty cycle equal to the modulation brightness. 
	Brightness_Controller : process is
		variable c_count, b_count : integer range 0 to max_brightness := 0;
	begin
		-- This TCK is close to 5 MHz.
		wait until (TCK = '1');
		
		-- The cycle count starts at max_brightness-1 and counts down to one.
		-- The brightness count starts at brightness and counts down to zero.
		-- if the brightness is less than max_brightness, or simply to 1 if
		-- they are the same. Thus the brightness counter being zero indicates
		-- that we should turn the lamp off.
		if (c_count = 1) or (not PA) then 
			c_count := max_brightness;
			b_count := to_integer(unsigned(brightness));
		else
			c_count := c_count - 1;
			if (b_count = 0) then
				b_count := 0;
			else
				b_count := b_count -1;
			end if;
		end if;
		
		-- We have the following relationship between the brightness code
		-- and the duty cycle of the lamp power during a pulse. Code 0 = 0%,
		-- 1 = 20%, 2 = 40%, 3 = 60%, 4 = 80%, >=5 = 100%. The default value
		-- of the brightness code is 5, so duty cycle is by default 100%.
		ONL <= to_std_logic(PA and (b_count /= 0));
	end process;

-- The Sample Controller determines when to transmit a message, and what message
-- to transmit. It arbitrates between acknowledgements and samples. It implements
-- transmission scatter, whereby the instant of sample transmission is displaced
-- at random from the nominal instant using the lower four bits of the X-input 
-- sample value.
	Sample_Controller : process (RCK) is
		constant divisor : integer := 32768 / sample_rate;
		variable counter : integer range 0 to divisor - 1 := 0;
		variable xmit_enable : boolean := false;
		variable xmit_moment : boolean := false;
		variable xmit_init : boolean := false;
	begin
		-- These combinatorial variable make our code easier to read.
		xmit_enable := (sensor_config(0) = '1');
		xmit_moment := (scatter_enable and (counter = to_integer(unsigned(scatter))))
			or ((not scatter_enable) and (counter = 0));
		
		if rising_edge(RCK) then
			-- We assert the TXEN signal when the transmit enable bit
			-- is set and when we are waiting to transmit an acknowledgement. 
			-- We use TXEN to keep the logic chip powered up.
			TXEN <= xmit_enable;
		
			-- We divide RCK by divisor to get the sampling frequency. We run
			-- this counter regardless of whether transmission is enabled.
			if (counter = divisor - 1) then
				counter := 0;
			else
				counter := counter + 1;
			end if;
		
			-- When the counter reaches the end of a sample period, we set
			-- the scatter value to the lower bits of the sample value.
			if (counter = divisor - 1) then
				for i in 0 to 3 loop
					scatter(i) <= sample(i);
				end loop;
			else
				scatter <= scatter;
			end if;
		
			-- We issue Transmit Acknowledgement Delayed (TXAD) as soon was we
			-- start to transmit an acknowledgement. By this means, TXA ia
			-- cleared on the next clock cycle. We also use TXAD in the Sample 
			-- Transmitter to detect an acknowlegement transmission.
			TXAD <= TXA;
			
			-- The xmit_init variable indicates a clock cycle in which we 
			-- should initiate a transmission.
			xmit_init := (xmit_enable and xmit_moment) or TXA;
		end if;
		
		-- Here we create a Transmit Initiate pulse that is half an RCK period
		-- long. The TXI signal is combinatorial. There is the possiblity of 
		-- a glitch when RCK rises again, just before xmit_init has time to 
		-- go low. But this glitch would have to be several nanoseconds long
		-- in order to generate a pulse on TCK, which drives the Sample Transmitter.
		-- Once the TXI pulse disappears, the ring oscillator is disabled again.
		TXI <= xmit_init and (RCK = '1');
	end process;

-- The Sample Transmitter responds to Transmit Initiate (TXI) by turning on the 
-- radio-frequency oscillator, transmitting the leading start bits, reading out
-- the ADC and transmitting the ADC bits. In the case of an acknowledgement 
-- transmission, the process transmits an auxilliary message giving the transmitter
-- ID and acknowledgement key. To determine whether to use data or auxilliary bits,
-- the process uses TXAD (Transmit Acknowledgement Delayed), which is a signal that
-- is asserted for one RCK cycle after the TXA (Transmit Acknowledgement) flag has 
-- been cleared. The output of this process is a sequence of bit values TXB (Transmit
-- Bit) changing on the rising edges of TCK. The Sample Transmitter reads the
-- sixteen bits of an ADC sample into the global sample register. As these bits are
-- read out, they are transmitted. The SDO input is the serial data out from the 
-- ADC. The Sample Transmitter synhcronizes SDO to TCK, creating SSDO, which it 
-- uses for transmission and storage.
	Sample_Transmitter : process (TCK) is
		constant num_sync_bits : integer := 11; -- Num synchronizing bits at start.
		constant num_id_bits : integer := 4; -- Number of ID bits.
		constant num_start_bits : integer := 1; -- Num zero start bits.
		constant num_stop_bits : integer := 2; -- For state machine termination only.
		constant num_data_bits : integer := 16; -- Number of ADC data bits.
		constant num_xmit_bits : integer := -- Number of transmission bit periods.
			num_sync_bits + num_start_bits + num_id_bits + num_data_bits + num_id_bits; 
		constant st_done : integer := -- Final state of sample transmit machine.
			num_xmit_bits + num_stop_bits; 
		constant first_sync_bit : integer := 1;
		constant first_start_bit : integer := first_sync_bit + num_sync_bits;
		constant first_id_bit : integer := first_start_bit + num_start_bits;
		constant first_data_bit : integer := first_id_bit + num_id_bits;
		constant first_iid_bit : integer := first_data_bit + num_data_bits;
		constant start_sck : integer := -- Determines when SCK is enabled.
			first_data_bit - 2;
		constant end_sck : integer := -- State for last SCK falling edge.
			start_sck + num_data_bits - 1;
		constant data_id_bits : std_logic_vector(3 downto 0) := 
			std_logic_vector(to_unsigned(device_id,4)); -- The device id bits.
		constant aux_id_bits : std_logic_vector(3 downto 0) := 
			std_logic_vector(to_unsigned(aux_id,4)); -- The acknowledgement id bits.
		constant ack_code_bits : std_logic_vector(3 downto 0) := 
			std_logic_vector(to_unsigned(ack_code,4)); -- The acknowledgement code.
		variable state : integer range 0 to 63 := 0; -- Stample Transmit State
		variable data_bit, aux_bit : boolean := false; -- Transmit Data Bit
	begin
		if rising_edge(TCK) then
			-- We reset the state when TXI is false. Otherwise, we increment the
			-- state until it reaches st_done. At st_done, the state remains fixed 
			-- until not TXI. When we first enable sample transmission, the state is 
			-- zero. When TXI is asserted, the ring oscillator turns on, which starts
			-- TCK, the 5-MHz transmit clock. On the first rising edge of TCK, the 
			-- state becomes 1, and thereafter increments to st_done. Now TXD is true,
			-- which keeps the ring oscillator running while TXI becomes false. Once 
			-- false, the state switches back to zero, TXD is unasserted, and the 
			-- ring oscillator turns off, unless it is kept running by some other
			-- process. With no rising edges on TCK, the state remains zero. If rising
			-- edges on TCK continue because the ring oscillator is still running,
			-- the state will remain zero so long as TXI remains unasserted.
			if (not TXI) then
				state := 0;
			elsif (state < st_done) then 
				state := state + 1;
			else 
				state := st_done;
			end if;
		
			-- We synchronise the SDO input with TCK.
			SSDO <= (SDO = '1');

			-- TXD indicates to other processes that the transmission is complete.
			TXD <= (state = st_done);
		
			-- SCKEN asserts TCK onto SCK.
			SCKEN <= (state >= start_sck) and (state <= end_sck);
		
			-- SDI configures the ADC.
			SDI <= to_std_logic(state = start_sck); 
		
			-- The data bit is the outgoing bit value for data transmission.
			data_bit := ((state >= 0) and (state < first_start_bit))
				or ((state = first_id_bit + 0) and (data_id_bits(3) = '1'))
				or ((state = first_id_bit + 1) and (data_id_bits(2) = '1'))
				or ((state = first_id_bit + 2) and (data_id_bits(1) = '1'))
				or ((state = first_id_bit + 3) and (data_id_bits(0) = '1'))
				or ((state >= first_data_bit) and (state < first_iid_bit) and SSDO)
				or ((state = first_iid_bit + 0) and (data_id_bits(3) = '0'))
				or ((state = first_iid_bit + 1) and (data_id_bits(2) = '0'))
				or ((state = first_iid_bit + 2) and (data_id_bits(1) = '0'))
				or ((state = first_iid_bit + 3) and (data_id_bits(0) = '0'));
			
			-- The ack bit is the outgoing bit value for acknowledgment transmission.
			aux_bit := ((state >= 0) and (state < first_start_bit))
				or ((state = first_id_bit + 0) and (aux_id_bits(3) = '1'))
				or ((state = first_id_bit + 1) and (aux_id_bits(2) = '1'))
				or ((state = first_id_bit + 2) and (aux_id_bits(1) = '1'))
				or ((state = first_id_bit + 3) and (aux_id_bits(0) = '1'))
				or ((state = first_data_bit + 0) and (data_id_bits(3) = '1'))
				or ((state = first_data_bit + 1) and (data_id_bits(2) = '1'))
				or ((state = first_data_bit + 2) and (data_id_bits(1) = '1'))
				or ((state = first_data_bit + 3) and (data_id_bits(0) = '1'))
				or ((state = first_data_bit + 4) and (ack_code_bits(3) = '1'))
				or ((state = first_data_bit + 5) and (ack_code_bits(2) = '1'))
				or ((state = first_data_bit + 6) and (ack_code_bits(1) = '1'))
				or ((state = first_data_bit + 7) and (ack_code_bits(0) = '1'))
				or ((state = first_data_bit + 8) and (ack_key(7) = '1'))
				or ((state = first_data_bit + 9) and (ack_key(6) = '1'))
				or ((state = first_data_bit + 10) and (ack_key(5) = '1'))
				or ((state = first_data_bit + 11) and (ack_key(4) = '1'))
				or ((state = first_data_bit + 12) and (ack_key(3) = '1'))
				or ((state = first_data_bit + 13) and (ack_key(2) = '1'))
				or ((state = first_data_bit + 14) and (ack_key(1) = '1'))
				or ((state = first_data_bit + 15) and (ack_key(0) = '1'))
				or ((state = first_iid_bit + 0) and (aux_id_bits(3) = '0'))
				or ((state = first_iid_bit + 1) and (aux_id_bits(2) = '0'))
				or ((state = first_iid_bit + 2) and (aux_id_bits(1) = '0'))
				or ((state = first_iid_bit + 3) and (aux_id_bits(0) = '0'));
		
			-- We choose between the data_bit and the ack_bit depending upon whether
			-- this is a data or acknowledge tranmsission.
			TXB <= (aux_bit and TXAD) or (data_bit and (not TXAD));
		
			-- Shift the ADC bits into the sample register.
			for i in 0 to 15 loop
				if (state = end_sck - i) then
					sample(i) <= to_std_logic(SSDO);
				else	
					sample(i) <= sample(i);
				end if;
			end loop;	
		end if;
	end process;

-- The following combinatorial signals generate outputs for the ADC and the
-- radio-frequency oscillator. We have CONV, the convert input to the ADC.
-- A rising edge on CONV initiates a conversion. But CONV must be driven LO
-- while the ADC bits are clocked out by SCK. Each falling edge on SCK clocks
-- another bit out of the ADC onto SDO, which is synchronized in the Sample
-- Transmitter to create SSDO. The XEN signal enables the radio frequency 
-- oscillator. We must enable this oscillator whenever we transmit a sample
-- or acknowledgement. We are transmitting when TXI is asserted, but we have
-- not yet asserted TXD. The TXI signal occurs on the rising edge of RCK, and
-- initiates transmission. The TXD signal occurs at the end of the transmission
-- and is clocked by TCK. The TXI signal will not be cleared until the next
-- rising edge of RCK, 20 us later. So we use both TXI and TXD to enable the 
-- oscillator. We must also ensure that we stop all transmission during 
-- command reception.
	CONV <= to_std_logic(not TXI);
	SCK <= to_std_logic((TCK = '0') and SCKEN);
	XEN <= to_std_logic(TXI and (not TXD) and (not RC));
	
-- The Frequency Modulation process takes the transmit bit values provided by
-- the Sample Transmitter, turns them into a sequence of rising and falling
-- edges so as to balance the ratio of HI and LO, and modulates the transmit DAC
-- output (xdac) between the HI and LO frequency values. These values are turned
-- into analog voltages on the TUNE input of the radio frequency oscillator, and
-- so modulate the frequency of the transmission.
	Frequency_Modulation : process is
	begin
		-- Frequency modulation runs off the 10-MHz FCK clock. This clock is
		-- synchronous with TCK. It presents a rising edge over 10 ns after 
		-- both the rising and falling edges of TCK. Thus, when we see a
		-- rising edge on FCK, the value of TCK and TXB are both established.
		wait until (FCK = '1');
	
		-- When we are not transmitting RF power, we set the DAC output to
		-- zero so as to eliminate current consumption by the DAC resistors.
		if (not TXI) or TXD then 
			xdac <= "00000";
			FHI <= false;
		-- If TXB is asserted, we want the modulation frequency to go from low
		-- to high on the falling edge of TCK. When TXB is unasserted, we want
		-- the modulation frequency to go from high to low on the falling edge of
		-- TCK.
		elsif (TXB xor (TCK = '1')) then
			xdac <= std_logic_vector(to_unsigned(frequency_low + frequency_step,5));
			FHI <= true;
		else
			xdac <= std_logic_vector(to_unsigned(frequency_low,5));
			FHI <= false;
		end if;
	end process;

-- Diagnostic Code.
	Transmit_Counter : process is
	variable count : integer range 0 to 31;
	begin
		wait until TXI;
		if (count = 31) then
			count := 0;
		else
			count := count + 1;
		end if;
		TXCNT <= (count = 0);
	end process;
	
-- Test Points. 
	TP1 <= to_std_logic(TXI);
	TP2 <= to_std_logic(TXAD);
	
-- Keeper Outputs. If we don't send these signals to an output, the compiler
-- will eliminate them and all the logic behind them. In the case of STDBY, 
-- for example, all the standy power logic is eliminated and the chip is
-- always in full-power mode. It may be that some combination of attributes
-- will stop the elimination, but we have not found it yet.
	TP3 <= to_std_logic((STDBY = '1'));
		
end behavior;