library IEEE, work;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.AddressMap.all;
use work.BusSignalTypes.all;
use work.AddressBook.all;

entity VirtualEvent is
	port(
		rst	: in std_logic;
		clk	: in std_logic;
		-- Module output --
		dataEvent	: out std_logic_vector(7 downto 0);
		enEvent		: out std_logic;
		-- Local bus --
		addrLocalBus		: in LocalAddressType;
		dataLocalBusIn		: in LocalBusInType;
		dataLocalBusOut	: out LocalBusOutType;
		reLocalBus			: in std_logic;
		weLocalBus			: in std_logic;
		readyLocalBus		: out std_logic
	);
end VirtualEvent;

architecture RTL of VirtualEvent is
	-- internal signal declaration ----------------------------------------
	type EventType is (
		Idle, data1, data2, data3, data4, done
	);
	signal state_event	: EventType;
	signal state_lbus	: BusProcessType;

	signal exec_command, done_command	: std_logic;
	signal en_event	: std_logic;
	signal data_event : std_logic_vector(7 downto 0);

	-- =============================== body ===============================
begin	
	enEvent	<= en_event;
	dataEvent	<= data_event;


	u_BusProcess : process(clk, rst)
	begin
		if(rst = '1') then
			exec_command	<= '0';
			state_lbus	<= Init;
		elsif(clk'event and clk = '1') then
			case state_lbus is
			when Init =>
				dataLocalBusOut	<= x"00";
				readyLocalBus		<= '0';
				exec_command	<= '0';
				state_lbus			<= Idle;
				
			when Idle =>
				readyLocalBus	<= '0';
				if(weLocalBus = '1' or reLocalBus = '1') then
					state_lbus	<= Connect;
				end if;
			
			when Connect =>
				if(weLocalBus = '1') then
					state_lbus	<= Write;
				else
					state_lbus	<= Read;
				end if;
				
			when Write =>
				case addrLocalBus is
				when VEV_send =>
					state_lbus	<= Execute;
				when others => 
					state_lbus	<= Done;
				end case;
				
			when Read =>
				state_lbus	<= Done;

			when Execute =>
				exec_command	<= '1';
				state_lbus	<= Finalize;
				
			when Finalize =>
				exec_command	<= '0';
				if(done_command = '1') then
					state_lbus	<= Done;
				end if;

			when Done =>
				readyLocalBus	<= '1';
				if(weLocalBus = '0' and reLocalBus = '0') then
					state_lbus	<= Idle;
				end if;
			
			-- probably this is error --
			when others =>
				state_lbus	<= Init;
			end case;
		end if;
	end process u_BusProcess;

	u_EventProcess : process(clk, rst)
	begin
		if(rst = '1') then
			done_command	<= '0';
			en_event	<= '0';
			data_event	<= (others => '0');
			state_event	<= Idle;
		elsif(clk'event and clk = '1') then
		case state_event is
		when Idle =>
			done_command	<= '0';
			en_event	<= '0';
			if(exec_command = '1') then
				state_event	<= data1;
			end if;


		when data1 =>
			en_event	<= '1';
			data_event	<= "01010101";
			state_event	<= data2;

		when data2 =>
			en_event	<= '1';
			data_event	<= "01010101";
			state_event	<= data3;

		when data3 =>
			en_event	<= '1';
			data_event	<= "01010101";
			state_event	<= data4;

		when data4 =>
			en_event	<= '1';
			data_event	<= "01010101";
			state_event	<= Done;

		when Done =>
			en_event	<= '0';
			done_command	<= '1';
			state_event	<= Idle;

		when others =>
			state_event	<= Idle;

		end case;
		end if;
	end process u_EventProcess;

end RTL;

