--------------------------------------------------------------------------------
-- Company:   University of Connecticut
-- Engineer:  Igor Senderovich
--
-- Create Date:   01:46:07 02/15/2008
-- Design Name:   FPGA_test
-- Module Name:   FPGA_test.vhd
-- Project Name:  TotalTest
-- Target Device:  
-- Tool versions:  
-- Description:   Container for all FPGA and emulators for ethernet controller, 
--		  DAC, ADC, temperature sensor
--
--------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

library std;
use std.textio.all;
use IEEE.std_logic_textio.all;

entity FPGA_test is
end FPGA_test;

architecture behavioral of FPGA_test is 

	component FPGA_main is
 	 port ( ExtClk : in  std_logic;			-- external crystal clock
		ExtRst_low : in std_logic;		-- external jumper, active low
		LocStamp : in std_logic_vector (4 downto 0);	-- geographical address jumpers
		StateCode : out std_logic_vector (2 downto 0);	-- global state
		-- SPI bus (with ADC and Temp sensors) lines
		SPI_SCLK : out std_logic;		-- 10 MHz clock for SPI bus
		SPI_T_CE : out std_logic;		-- clock enable for temperature sensor
		SPI_A_CS_low : out std_logic;		-- chip select (bar) for ADC
		SPI_SDI_tri : out std_logic;		-- bus device read line
		SPI_SDO	: in std_logic;			-- bus device write line
		-- AD5535 serial bus (DAC) lines
		DAC_SCLK : out std_logic;		-- 20 MHz clock for AD5535 serial bus
		DAC_RESET_low : out std_logic;		-- reset (bar) for AD5535 DAC
		DAC_SYNC_low : out std_logic;	 	-- sync (bar) line for AD5535 serial bus
		DAC_DIN	: out std_logic;		-- data line for AD5535 serial bus
		-- CP2201 parallel MuxIntel bus (ethernet controller) lines
		Eth_CLK : out std_logic;		-- 20 MHz clock for MuxIntel bus
		Eth_RST_low : inout std_logic;		-- reset (bar) for CP2201
		Eth_INT_low : in std_logic;		-- active-low interrupt from CP2201
		Eth_ALE : out std_logic;		-- address latch enable for MuxIntel bus
		Eth_AD : inout std_logic_vector (7 downto 0); -- 8-bit MuxIntel bus data lines
		Eth_RD_low : out std_logic;		-- data latch enable (bar) for read from device buffer
		Eth_WR_low : out std_logic;		-- data latch enable (bar) for write to device buffer
		Eth_CS_low : out std_logic;		-- chip select (bar) for MuxIntel bus
		-- RS-232 transmit line (for debugging)
		Serial_port : out std_logic		-- output pin for RS-232 stream
	 );
	end component;

	component Eth_emulator
	 port ( CLK : in std_logic;
		RST_low : in std_logic;
		-- puppet signals to the emulator from simulator
           	Go_GetPacket : in std_logic_vector (2 downto 0);
		INT_request : in std_logic;
		INT_type : in std_logic_vector (15 downto 0);
		INT_low : out std_logic;
		-- Eth_emulator control lines ------------------------
		ALE : in std_logic;
		AD : inout std_logic_vector (7 downto 0);
		RD_low : in std_logic;
		WR_low : in std_logic;
		CS_low : in std_logic
	 );
	end component;

	component Temp_emulator is -- emulator for the Temp. sensor
	 port ( SCLK : in std_logic;			-- clock
 		RST_low : in std_logic;			-- async /reset
           	SDO : out std_logic;			-- serial data out
           	CE : in std_logic;			-- chip enable
           	DIN : in std_logic_vector (9 downto 0);	-- parallel data in
           	Error : out std_logic			-- error flag
	 );
	end component;
	
	component ADC_emulator is  -- emulator for the ADC
	 port ( SCLK : in  std_logic;			-- clock
           	RST_low : in std_logic;			-- async /reset
           	CS_low : in std_logic;			-- chip select
           	DIN : in std_logic;			-- 12 bit serial instruction
           	ch0 : in std_logic_vector (11 downto 0);-- fake voltage data input
           	ch1 : in std_logic_vector (11 downto 0);-- for debugging purposes
           	ch2 : in std_logic_vector (11 downto 0);
           	ch3 : in std_logic_vector (11 downto 0);
           	ch4 : in std_logic_vector (11 downto 0);
           	ch5 : in std_logic_vector (11 downto 0);
           	ch6 : in std_logic_vector (11 downto 0);
           	ch7 : in std_logic_vector (11 downto 0);
           	ch8 : in std_logic_vector (11 downto 0);
           	ch9 : in std_logic_vector (11 downto 0);
           	ch10 : in std_logic_vector (11 downto 0);
           	ch11 : in std_logic_vector (11 downto 0);
           	ch12 : in std_logic_vector (11 downto 0);
           	ch13 : in std_logic_vector (11 downto 0);
           	ch14 : in std_logic_vector (11 downto 0);
           	ch15 : in std_logic_vector (11 downto 0);
           	DOUT : out std_logic;			-- serial data output
           	Error : out std_logic
	 );
	end component;
	
	component DAC_emulator is -- declare a DAC emulator wrapper
	    port ( SCLK : in std_logic;
           	   RESET_low : in std_logic;
           	   SYNC_low : in std_logic;
           	   DIN : in std_logic;
		   -- 32 14-bit output channels
           	   ch00 : out  std_logic_vector (13 downto 0);
           	   ch01 : out  std_logic_vector (13 downto 0);
           	   ch02 : out  std_logic_vector (13 downto 0);
           	   ch03 : out  std_logic_vector (13 downto 0);
           	   ch04 : out  std_logic_vector (13 downto 0);
           	   ch05 : out  std_logic_vector (13 downto 0);
           	   ch06 : out  std_logic_vector (13 downto 0);
           	   ch07 : out  std_logic_vector (13 downto 0);
           	   ch08 : out  std_logic_vector (13 downto 0);
           	   ch09 : out  std_logic_vector (13 downto 0);
           	   ch10 : out  std_logic_vector (13 downto 0);
           	   ch11 : out  std_logic_vector (13 downto 0);
           	   ch12 : out  std_logic_vector (13 downto 0);
           	   ch13 : out  std_logic_vector (13 downto 0);
           	   ch14 : out  std_logic_vector (13 downto 0);
           	   ch15 : out  std_logic_vector (13 downto 0);
           	   ch16 : out  std_logic_vector (13 downto 0);
           	   ch17 : out  std_logic_vector (13 downto 0);
           	   ch18 : out  std_logic_vector (13 downto 0);
           	   ch19 : out  std_logic_vector (13 downto 0);
           	   ch20 : out  std_logic_vector (13 downto 0);
           	   ch21 : out  std_logic_vector (13 downto 0);
           	   ch22 : out  std_logic_vector (13 downto 0);
           	   ch23 : out  std_logic_vector (13 downto 0);
           	   ch24 : out  std_logic_vector (13 downto 0);
           	   ch25 : out  std_logic_vector (13 downto 0);
           	   ch26 : out  std_logic_vector (13 downto 0);
           	   ch27 : out  std_logic_vector (13 downto 0);
           	   ch28 : out  std_logic_vector (13 downto 0);
           	   ch29 : out  std_logic_vector (13 downto 0);
           	   ch30 : out  std_logic_vector (13 downto 0);
           	   ch31 : out  std_logic_vector (13 downto 0)
	 );
	end component;

	signal Clk : std_logic := '0';
	signal Rst : std_logic := '0';
	signal ExtRst_low : std_logic := '1';

	signal state_Qout : std_logic_vector (2 downto 0);
	signal Serial_port : std_logic;

	signal Eth_CLK : std_logic;
	signal Eth_ALE : std_logic;
	signal Eth_RD_low : std_logic;
	signal Eth_WR_low : std_logic;
	signal Eth_AD : std_logic_vector(7 downto 0);
	signal Eth_CS_low : std_logic;

	signal INT_request : std_logic := '0';
	signal INT_type : std_logic_vector (15 downto 0) := (others => '0');
	signal Eth_INT_low : std_logic := '1';
	signal Eth_RST_low : std_logic;
	signal Eth_RSTX_low : std_logic;
	signal LocStamp : std_logic_vector(4 downto 0) := "01110";
	signal Go_GetPacket : std_logic_vector (2 downto 0) := "000";
	
	-- SPI lines --
	signal SPI_SDO : std_logic;
	signal SPI_SCLK : std_logic;
	signal SPI_RST_low : std_logic;
	signal SPI_T_CE	: std_logic;
	signal SPI_A_CS_low : std_logic;
	signal SPI_SDI_tri : std_logic;
	signal SPI_A_error : std_logic;
	signal SPI_T_error : std_logic;
	--emulator signals
	signal A_ch0 : std_logic_vector (11 downto 0):="100000000001";
	signal A_ch1 : std_logic_vector (11 downto 0):="100000000011";
	signal A_ch2 : std_logic_vector (11 downto 0):="100000000101";
	signal A_ch3 : std_logic_vector (11 downto 0):="100000000111";
	signal A_ch4 : std_logic_vector (11 downto 0):="100000001001";
	signal A_ch5 : std_logic_vector (11 downto 0):="100000001011";
	signal A_ch6 : std_logic_vector (11 downto 0):="100000001101";
	signal A_ch7 : std_logic_vector (11 downto 0):="100000001111";
	signal A_ch8 : std_logic_vector (11 downto 0):="100000010001";
	signal A_ch9 : std_logic_vector (11 downto 0):="100000010011";
	signal A_ch10 : std_logic_vector (11 downto 0):="100000010101";
	signal A_ch11 : std_logic_vector (11 downto 0):="100000010111";
	signal A_ch12 : std_logic_vector (11 downto 0):="100000011001";
	signal A_ch13 : std_logic_vector (11 downto 0):="100000011011";
	signal A_ch14 : std_logic_vector (11 downto 0):="100000011101";
	signal A_ch15 : std_logic_vector (11 downto 0):="100000011111";
	signal T_DIN : std_logic_vector (9 downto 0) :="1011001101";

	-- DAC signals
	signal DAC_SCLK : std_logic;
	signal DAC_RESET_low : std_logic;
	signal DAC_SYNC_low : std_logic;
	signal DAC_DIN  : std_logic;
	signal DAC_ch00 : std_logic_vector (13 downto 0) := "00" & X"001";
	signal DAC_ch01 : std_logic_vector (13 downto 0) := "00" & X"002";
	signal DAC_ch02 : std_logic_vector (13 downto 0) := "00" & X"003";
	signal DAC_ch03 : std_logic_vector (13 downto 0) := "00" & X"004";
	signal DAC_ch04 : std_logic_vector (13 downto 0) := "00" & X"005";
	signal DAC_ch05 : std_logic_vector (13 downto 0) := "00" & X"006";
	signal DAC_ch06 : std_logic_vector (13 downto 0) := "00" & X"007";
	signal DAC_ch07 : std_logic_vector (13 downto 0) := "00" & X"008";
	signal DAC_ch08 : std_logic_vector (13 downto 0) := "00" & X"009";
	signal DAC_ch09 : std_logic_vector (13 downto 0) := "00" & X"00A";
	signal DAC_ch10 : std_logic_vector (13 downto 0) := "00" & X"00C";
	signal DAC_ch11 : std_logic_vector (13 downto 0) := "00" & X"00B";
	signal DAC_ch12 : std_logic_vector (13 downto 0) := "00" & X"00D";
	signal DAC_ch13 : std_logic_vector (13 downto 0) := "00" & X"00E";
	signal DAC_ch14 : std_logic_vector (13 downto 0) := "00" & X"00F";
	signal DAC_ch15 : std_logic_vector (13 downto 0) := "00" & X"010";
	signal DAC_ch16 : std_logic_vector (13 downto 0) := "00" & X"011";
	signal DAC_ch17 : std_logic_vector (13 downto 0) := "00" & X"012";
	signal DAC_ch18 : std_logic_vector (13 downto 0) := "00" & X"013";
	signal DAC_ch19 : std_logic_vector (13 downto 0) := "00" & X"014";
	signal DAC_ch20 : std_logic_vector (13 downto 0) := "00" & X"015";
	signal DAC_ch21 : std_logic_vector (13 downto 0) := "00" & X"016";
	signal DAC_ch22 : std_logic_vector (13 downto 0) := "00" & X"017";
	signal DAC_ch23 : std_logic_vector (13 downto 0) := "00" & X"018";
	signal DAC_ch24 : std_logic_vector (13 downto 0) := "00" & X"019";
	signal DAC_ch25 : std_logic_vector (13 downto 0) := "00" & X"01A";
	signal DAC_ch26 : std_logic_vector (13 downto 0) := "00" & X"01B";
	signal DAC_ch27 : std_logic_vector (13 downto 0) := "00" & X"01C";
	signal DAC_ch28 : std_logic_vector (13 downto 0) := "00" & X"01D";
	signal DAC_ch29 : std_logic_vector (13 downto 0) := "00" & X"01E";
	signal DAC_ch30 : std_logic_vector (13 downto 0) := "00" & X"01F";
	signal DAC_ch31 : std_logic_vector (13 downto 0) := "00" & X"020";
begin
	FPGA_main_inst: FPGA_main
 	port map ( ExtClk => Clk,
		   ExtRst_low => ExtRst_low,
		   LocStamp => LocStamp,
		   StateCode => State_Qout,
		   SPI_SCLK => SPI_SCLK,
		   SPI_T_CE => SPI_T_CE,
		   SPI_A_CS_low => SPI_A_CS_low,
		   SPI_SDI_tri => SPI_SDI_tri,
		   SPI_SDO => SPI_SDO,
		   DAC_SCLK => DAC_SCLK,
	   	   DAC_RESET_low => DAC_RESET_low,
		   DAC_SYNC_low => DAC_SYNC_low,
		   DAC_DIN => DAC_DIN,
		   Eth_CLK => Eth_CLK,
		   Eth_RST_low => Eth_RST_low,
		   Eth_INT_low => Eth_INT_low,
		   Eth_ALE => Eth_ALE,
		   Eth_AD => Eth_AD,
		   Eth_RD_low => Eth_RD_low,
		   Eth_WR_low => Eth_WR_low,
		   Eth_CS_low => Eth_CS_low,
		   Serial_port => Serial_port
		);

	Eth_emulator_inst: Eth_emulator
	port map ( CLK => Eth_CLK,
		   RST_low => Eth_RSTX_low,
		   Go_GetPacket => Go_GetPacket,
		   INT_request => INT_request,
		   INT_type => INT_type,
		   INT_low => Eth_INT_low,
		   ALE => Eth_ALE,
		   AD => Eth_AD,
		   RD_low => Eth_RD_low,
		   WR_low => Eth_WR_low,
		   CS_low => Eth_CS_low
		);
		
	Temp_emulator_inst: Temp_emulator
	port map ( SCLK => SPI_SCLK,
		   RST_low => SPI_RST_low,
           	   SDO => SPI_SDO,
           	   CE => SPI_T_CE,
           	   DIN => T_DIN,
           	   Error => SPI_T_Error
	);

	ADC_emulator_inst: ADC_emulator
	port map ( SCLK => SPI_SCLK,
           	   RST_low => SPI_RST_low,
           	   CS_low => SPI_A_CS_low,
           	   DIN => SPI_SDI_tri,
           	   ch0 => A_ch0,
           	   ch1 => A_ch1,
           	   ch2 => A_ch2,
           	   ch3 => A_ch3,
           	   ch4 => A_ch4,
           	   ch5 => A_ch5,
           	   ch6 => A_ch6,
           	   ch7 => A_ch7,
           	   ch8 => A_ch8,
           	   ch9 => A_ch9,
           	   ch10 => A_ch10,
           	   ch11 => A_ch11,
           	   ch12 => A_ch12,
           	   ch13 => A_ch13,
           	   ch14 => A_ch14,
           	   ch15 => A_ch15,
           	   DOUT => SPI_SDO,
           	   Error => SPI_A_Error
	);

	DAC_emulator_inst: DAC_emulator
	port map ( SCLK => DAC_SCLK,
           	   RESET_low => DAC_RESET_low,
           	   SYNC_low => DAC_SYNC_low,
           	   DIN => DAC_DIN,
           	   ch00 => DAC_ch00,
           	   ch01 => DAC_ch01,
           	   ch02 => DAC_ch02,
           	   ch03 => DAC_ch03,
           	   ch04 => DAC_ch04,
           	   ch05 => DAC_ch05,
           	   ch06 => DAC_ch06,
           	   ch07 => DAC_ch07,
           	   ch08 => DAC_ch08,
           	   ch09 => DAC_ch09,
           	   ch10 => DAC_ch10,
           	   ch11 => DAC_ch11,
           	   ch12 => DAC_ch12,
           	   ch13 => DAC_ch13,
           	   ch14 => DAC_ch14,
           	   ch15 => DAC_ch15,
           	   ch16 => DAC_ch16,
           	   ch17 => DAC_ch17,
           	   ch18 => DAC_ch18,
           	   ch19 => DAC_ch19,
           	   ch20 => DAC_ch20,
           	   ch21 => DAC_ch21,
           	   ch22 => DAC_ch22,
           	   ch23 => DAC_ch23,
           	   ch24 => DAC_ch24,
           	   ch25 => DAC_ch25,
           	   ch26 => DAC_ch26,
           	   ch27 => DAC_ch27,
           	   ch28 => DAC_ch28,
           	   ch29 => DAC_ch29,
           	   ch30 => DAC_ch30,
           	   ch31 => DAC_ch31
	 );

	Startup : process
		variable line_out : line;
	begin
		Rst <= '1';	  -- turn on reset
		wait for 250 ns;
		Rst <= '0';	  -- turn off reset
		wait for 50 ns;
		wait on Eth_RSTX_low;

		-- "Oscillator stabilization" interrupt
		wait for 400 ns;
		INT_request <= '1';  -- interrupt!
		INT_type <= X"0010";  
		wait for 50 ns;
		INT_request <= '0';
		
		wait for 4500 ns;   
		-- "Self-Initialization complete" interrupt
		INT_request <= '1';  -- interrupt!
		INT_type <= X"0020";
		wait for 50 ns;
		INT_request <= '0';

		wait for 4500 ns;   
		-- "Autonegotiation complete" interrupt
		INT_request <= '1';  -- interrupt!
		INT_type <= X"0500";
		wait for 50 ns;
		INT_request <= '0';

		-- Inject "soft reset" (0xD2) packet
		wait for 500000 ns; -- after hard reset processes are complete
		Go_GetPacket <= "001";	
		wait for 50ns;
		Go_GetPacket <= "000";	
		wait for 100000 ns;
		INT_request <= '1';  -- Rx buffer non-empty interrupt (you got mail!)
		INT_type <= X"0001";
		wait for 50 ns;
		INT_request <= '0';
		
		-- Inject a Query (0x51) packet
		wait for 500000 ns;
		Go_GetPacket <= "010";	
		wait for 50ns;
		Go_GetPacket <= "000";	
		wait for 100000 ns;
		INT_request <= '1';  -- Rx buffer non-empty interrupt (you got mail!)
		INT_type <= X"0001";
		wait for 50 ns;
		INT_request <= '0';
		
		-- Inject a Program (0x50) packet
		wait for 500000 ns;
		Go_GetPacket <= "011";	
		wait for 50ns;
		Go_GetPacket <= "000";	
		wait for 100000 ns;
		INT_request <= '1';  -- Rx buffer non-empty interrupt (you got mail!)
		INT_type <= X"0001";
		wait for 50 ns;
		INT_request <= '0';

		-- Inject a wild packet
		wait for 500000 ns;
		Go_GetPacket <= "100";	
		wait for 50ns;
		Go_GetPacket <= "000";	
		wait for 100000 ns;
		INT_request <= '1';  -- Rx buffer non-empty interrupt (you got mail!)
		INT_type <= X"0001";
		wait for 50 ns;
		INT_request <= '0';

		-- Report final DAC values
		wait for 500000 ns;
		write(line_out, "=== Final values in DAC registers ===");
		writeline(output, line_out);
		write(line_out, "ch00 = "); hwrite(line_out, "00" & DAC_ch00); write(line_out, ", ");
		write(line_out, "ch01 = "); hwrite(line_out, "00" & DAC_ch01); write(line_out, ", ");
		write(line_out, "ch02 = "); hwrite(line_out, "00" & DAC_ch02); write(line_out, ", ");
		write(line_out, "ch03 = "); hwrite(line_out, "00" & DAC_ch03); write(line_out, ", ");
		write(line_out, "ch04 = "); hwrite(line_out, "00" & DAC_ch04); write(line_out, ", ");
		write(line_out, "ch05 = "); hwrite(line_out, "00" & DAC_ch05); write(line_out, ", ");
		write(line_out, "ch06 = "); hwrite(line_out, "00" & DAC_ch06); write(line_out, ", ");
		write(line_out, "ch07 = "); hwrite(line_out, "00" & DAC_ch07); writeline(output, line_out);
		write(line_out, "ch08 = "); hwrite(line_out, "00" & DAC_ch08); write(line_out, ", ");
		write(line_out, "ch09 = "); hwrite(line_out, "00" & DAC_ch09); write(line_out, ", ");
		write(line_out, "ch10 = "); hwrite(line_out, "00" & DAC_ch10); write(line_out, ", ");
		write(line_out, "ch11 = "); hwrite(line_out, "00" & DAC_ch11); write(line_out, ", ");
		write(line_out, "ch12 = "); hwrite(line_out, "00" & DAC_ch12); write(line_out, ", ");
		write(line_out, "ch13 = "); hwrite(line_out, "00" & DAC_ch13); write(line_out, ", ");
		write(line_out, "ch14 = "); hwrite(line_out, "00" & DAC_ch14); write(line_out, ", ");
		write(line_out, "ch15 = "); hwrite(line_out, "00" & DAC_ch15); writeline(output, line_out);
		write(line_out, "ch16 = "); hwrite(line_out, "00" & DAC_ch16); write(line_out, ", ");
		write(line_out, "ch17 = "); hwrite(line_out, "00" & DAC_ch17); write(line_out, ", ");
		write(line_out, "ch18 = "); hwrite(line_out, "00" & DAC_ch18); write(line_out, ", ");
		write(line_out, "ch19 = "); hwrite(line_out, "00" & DAC_ch19); write(line_out, ", ");
		write(line_out, "ch20 = "); hwrite(line_out, "00" & DAC_ch20); write(line_out, ", ");
		write(line_out, "ch21 = "); hwrite(line_out, "00" & DAC_ch21); write(line_out, ", ");
		write(line_out, "ch22 = "); hwrite(line_out, "00" & DAC_ch22); write(line_out, ", ");
		write(line_out, "ch23 = "); hwrite(line_out, "00" & DAC_ch23); writeline(output, line_out);
		write(line_out, "ch24 = "); hwrite(line_out, "00" & DAC_ch24); write(line_out, ", ");
		write(line_out, "ch25 = "); hwrite(line_out, "00" & DAC_ch25); write(line_out, ", ");
		write(line_out, "ch26 = "); hwrite(line_out, "00" & DAC_ch26); write(line_out, ", ");
		write(line_out, "ch27 = "); hwrite(line_out, "00" & DAC_ch27); write(line_out, ", ");
		write(line_out, "ch28 = "); hwrite(line_out, "00" & DAC_ch28); write(line_out, ", ");
		write(line_out, "ch29 = "); hwrite(line_out, "00" & DAC_ch29); write(line_out, ", ");
		write(line_out, "ch30 = "); hwrite(line_out, "00" & DAC_ch30); write(line_out, ", ");
		write(line_out, "ch31 = "); hwrite(line_out, "00" & DAC_ch31); writeline(output, line_out);
		write(line_out, "=== End of FPGA_test simulation ===");
		writeline(output, line_out);
		wait;
	end process;

	MakeCLK : process
	begin
		wait for 25ns;
		Clk <= '1';
		wait for 25ns;
		Clk <= '0';		
	end process;

	ExtRst_low <= not Rst;
	SPI_RST_low <= not Rst;
	Eth_RSTX_low <= Eth_RST_low and not Rst;

end behavioral;
