-- Company: BUSE
-- Engineer: PAVEL SUNKA
-- 
-- Create Date:   8.6.2017
-- Module Name:   Top modul 
-- Project Name:  Micomp
-- Target Devices: 10M08
-----------------------------         ----------------------------
-- precte velikost retezce, pohlida konec a odesle potvrzujici byt, pocita crc !!!!!! neni dodelane response z nadrazeneho mista
-----------------------------         ----------------------------
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_signed.all;
--	use IEEE.std_logic_signed.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Micomp_top is
	Generic(
		UART_DIV   : natural := (35000000 / 9600); -- vstup. frekvence, pozadovana frekvence
		UART_CNT_B : natural := 12      -- pocet potrebnych bitu na citac zmenseny o 1: 13b= (12 downto 0)
	);
	Port(
		ARST          : in  STD_LOGIC;
		CLK           : in  std_logic;
		RX            : in  std_logic;
		TEST_SIZE_END : in  std_logic;
		SIZE_COL      : in  std_logic_vector(7 downto 0);
		SIZE_ROW      : in  std_logic_vector(4 downto 0);
		TEST_SIZE     : out std_logic;
		BRIGHT        : out std_logic_vector(7 downto 0);
		BRIGHT_EN     : out std_logic;
		TX            : out std_logic
	);
end Micomp_top;

architecture Behavioral of Micomp_top is

	component Micomp
		generic(
			UART_DIV     : natural := (35000000 / 9600); -- vstup. frekvence, pozadovana frekvence
			UART_CNT_B   : natural := 12; -- pocet potrebnych bitu na citac zmenseny o 1: 13b= (12 downto 0)
			MESSAGE_SIZE : natural := 3;
			MESSAGE_B    : natural := 1
		);
		Port(
			ARST     : in  STD_LOGIC;
			ClK      : in  std_logic;
			RX       : in  std_logic;
			SEND_MSG : in  std_logic;
			MSG      : in  std_logic_vector(MESSAGE_SIZE * 8 - 1 downto 0);
			MSG_SIZE : in  std_logic_vector(MESSAGE_B downto 0);
			DAT_O    : out std_logic_vector(7 downto 0);
			DAT_O_EN : out std_logic;
			RIGHT_RE : out std_logic_vector(1 downto 0);
			TX       : out std_logic
		);
	end component Micomp;

	component D_ren
		generic(STOP_BITS : natural);
		port(
			ARST : in  STD_LOGIC;
			CLK  : in  stD_loGic;
			EN   : in  stD_loGic;
			D    : in  STD_LOGIC_VECTOR(STOP_BITS Downto 0);
			Q    : out STD_LOGIC_VECTOR(STOP_BITS Downto 0)
		);
	end component D_ren;

	-- uart-
	signal byte_en : std_logic;         -- enable prichozich dat
	signal micd    : std_logic_vector(7 downto 0); -- prichozi data
	signal mic_wr  : std_logic_vector(1 downto 0); -- spravna komunikace

	signal cmd_en : std_logic;          --povoleni zapisu povelu
	signal cmd    : std_logic_vector(7 downto 0) := x"09"; --povel

	signal mem_en : std_logic;          --povoleni zapisu do pameti
	signal memd   : std_logic_vector(7 downto 0); --vystup z pameti

	-- message--
	signal send_msg : std_logic;
	signal msg      : std_logic_vector(8 * 3 - 1 downto 0);
	signal msg_size : std_logic_vector(1 downto 0);

	type stat is (sCmd, s08, s09, sWait, sRight, sResp);
	signal state : stat := s09;        --s09;

begin
	uMicomp : Micomp
		generic map(
			UART_DIV     => UART_DIV,
			UART_CNT_B   => UART_CNT_B,
			MESSAGE_SIZE => 3,
			MESSAGE_B    => 1
		)
		port map(
			ARST     => ARST,
			ClK      => ClK,
			RX       => RX,
			SEND_MSG => send_msg,
			MSG      => msg,
			MSG_SIZE => msg_size,
			DAT_O    => micd,
			DAT_O_EN => byte_en,
			TX       => TX,
			RIGHT_RE => mic_wr
		);

	uMem : D_ren
		generic map(
			STOP_BITS => 7
		)
		port map(
			ARST => ARST,
			CLK  => CLK,
			EN   => mem_en,
			D    => micd,
			Q    => memd
		);

-- pmaet pro cmd vytvorena kvuli pocatku
	process(CLK, ARST) is
	begin
		if ARST = '1' then
			cmd <= x"09";
		elsif rising_edge(CLK) then
			if cmd_en = '1' then
				cmd <= micd;
			end if;
		end if;
	end process;

	process(CLK, ARST) is
	begin
		if ARST = '1' then
			state <= s09;
		elsif rising_edge(CLK) then
			case state is
				when sCmd =>
					if byte_en = '1' then
						case micd is
							when x"08" =>
								state <= s08;
							when x"09" =>
								state <= sWait;
							when others =>
								state <= sCmd;
						end case;
					end if;
				when s08 =>
					if byte_en = '1' then
						state <= sWait;
					end if;
				when sWait =>
					if mic_wr = "00" then
						if cmd = x"08" then
							state <= sRight;
						elsif cmd = x"09" then
							state <= s09;
						else
							state <= sCmd;
						end if;
					elsif mic_wr = "01" then
						state <= sCmd;
					end if;
				when sRight =>
					state <= sCmd;
				when s09 =>
					if TEST_SIZE_END = '1' then
						state <= sResp;
					end if;
				when sResp =>
					state <= sCmd;
				when others =>
					state <= sCmd;
			end case;
		end if;
	end process;

	process(state, cmd, SIZE_COL, SIZE_ROW) is
	begin
		cmd_en    <= '0';
		mem_en    <= '0';
		BRIGHT_EN <= '0';

		send_msg  <= '0';
		msg       <= (others => '1');
		msg_size  <= "00";
		TEST_SIZE <= '0';

		case state is
			when sCmd =>
				cmd_en <= '1';
			when s08 =>
				mem_en <= '1';
			when sWait =>
				null;
			when sRight =>
				case cmd is
					when x"08" =>
						BRIGHT_EN <= '1';
					when others =>
						null;
				end case;
			when s09 =>
				TEST_SIZE <= '1';
			when sResp =>
				send_msg <= '1';
				if cmd = x"09" then
					msg      <= x"09" & SIZE_COL & "000" & SIZE_ROW;
					msg_size <= "11";
				end if;
			when others =>
				null;
		end case;
	end process;

	BRIGHT <= memd;
end Behavioral;

