LIBRARY ieee;
USE ieee.numeric_std.all;
USE ieee.std_logic_1164.all;

ENTITY sci IS
	PORT 
	(
		CLK				:	IN std_logic;								--! Interni hodinovy signal
		RST				:	IN std_logic;								--! Signal reset

		SCLK			:	IN std_logic;								--! Hodinovy signal SPI
		CS_N			:	IN std_logic;								--! Chip select signal SPI
		MOSI			:	IN std_logic;								--! Master Out Slave In SPI 
		MISO			:	OUT std_logic;								--! Master In Slave Out SPI

		OUTPUT1			:	OUT std_logic_vector(15 DOWNTO 0);			--! vystup slouzici pro kontrolu dat
		
		TX				:	OUT std_logic_vector(8 DOWNTO 0);			--! TX Seriove linky
		SCI_ERR			:	OUT std_logic
	);
END sci;

ARCHITECTURE Behavioral OF sci IS

	CONSTANT SCI_CNT:  	positive := 9;

	SIGNAL DOUT		:	std_logic_vector(7 DOWNTO 0) := (OTHERS => '0');
	SIGNAL DOUT_VLD	:	std_logic := '0';
	SIGNAL DOUT_ERR	:	std_logic := '0';

	type sci_input is array (0 to SCI_CNT-1) of std_logic_vector(7 downto 0);
	SIGNAL DIN: sci_input;

	SIGNAL SEND		:	std_logic_vector(SCI_CNT-1 DOWNTO 0) := (OTHERS => '0');
	SIGNAL READY	:	std_logic_vector(SCI_CNT-1 DOWNTO 0) := (OTHERS => '0');

	SIGNAL SCI_add	:	std_logic_vector(7 DOWNTO 0) := (OTHERS => '0');
	SIGNAL SCI_val	:	std_logic_vector(7 DOWNTO 0) := (OTHERS => '0');
	SIGNAL SCI_vld	:	std_logic := '0';

BEGIN

	-- mapovani periferii

	sci_parser: ENTITY work.sci_parser
		PORT MAP
		(
			CLK			=> CLK,
			RST			=> RST,

			SCLK		=> SCLK,
			CS_N 		=> CS_N,
			MOSI		=> MOSI,
			MISO		=> MISO,
			
			SCI_add		=> SCI_add,
			SCI_val		=> SCI_val,
			SCI_vld		=> SCI_vld
		);

	GenerateSCI: FOR i IN 0 TO SCI_CNT-1 GENERATE
		sci_master: ENTITY work.sci_master
			GENERIC MAP
			(
				BAUD_RATE	=>	9600,
				CLK_FREQ	=>	50_000_000
			)

			PORT MAP
			(
				CLK			=> CLK,
				RST			=> RST,
				TX			=> TX(i),
				DIN			=> DIN(i),
				SEND		=> SEND(i),
				READY		=> READY(i)
			);	
	END GENERATE GenerateSCI;


	PROCESS (CLK)
	BEGIN
		IF rising_edge(CLK) THEN
			IF (RST = '1') THEN
				FOR i IN 0 TO SCI_CNT-1 LOOP
					SEND(i) <= '0';
				END LOOP;
				SCI_ERR <= '0';				
			ELSE
				IF (SCI_vld = '1') THEN
					IF (to_integer(unsigned(SCI_add)) <= SCI_CNT) THEN
						SEND(to_integer(unsigned(SCI_add))) <= '1';
						DIN(to_integer(unsigned(SCI_add))) <= SCI_val;
						OUTPUT1 <= SCI_add & SCI_val;
						SCI_ERR <= '0';
					ELSE
						SCI_ERR <= '1';
					END IF;
				ELSE
					FOR i IN 0 TO SCI_CNT-1 LOOP
						SEND(i) <= '0';
					END LOOP;
				END IF;
			END IF;
		END IF;
	END PROCESS;

END Behavioral;