----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    19:15:49 11/19/2009 
-- Design Name: 
-- Module Name:    KCPSM3_s_UART - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

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

entity KCPSM3_s_UART is
		port (
			UART_OUT : out std_logic;
			UART_IN : in std_logic;
			Q_OUT : out std_logic_vector( 7 downto 0);
			CLK : in std_logic
			);
end KCPSM3_s_UART;

architecture Behavioral of KCPSM3_s_UART is

	component preruseni
		port(
			CLK : in std_logic;
			interrupt_ack : in std_logic;
			interrupt : out std_logic
			);
	end component;

	component KCPSM3
		port (
			address : out std_logic_vector( 9 downto 0);
			instruction : in std_logic_vector(17 downto 0);
			port_id : out std_logic_vector( 7 downto 0);
			write_strobe : out std_logic;
			out_port : out std_logic_vector( 7 downto 0);
			read_strobe : out std_logic;
			in_port : in std_logic_vector( 7 downto 0);
			interrupt : in std_logic;
			interrupt_ack : out std_logic;
			reset : in std_logic;
			clk : in std_logic
			);
	end component;
	
	component dekoder_cteni_uartu
		port(
			read_strobe : in std_logic;
			port_id : in std_logic;
			uart_read_data :	out std_logic
			);
	end component;
	
	component uart_tx
		Port (
			data_in : in std_logic_vector(7 downto 0);
         write_buffer : in std_logic;
         reset_buffer : in std_logic;
         en_16_x_baud : in std_logic;
         serial_out : out std_logic;
         buffer_full : out std_logic;
         buffer_half_full : out std_logic;
         clk : in std_logic
			);
   end component;
	
	component pipeline_registr
		port(
			vstup , clk : in std_logic;
			vystup : out std_logic
			);
		
	end component;
	
	component registr_vystupu
		port(
			CLK, ID, W : in std_logic; 			--ID - PORT_ID, W - WRITE STROBE
			D_IN : in std_logic_vector(7 downto 0);
			D_OUT : out std_logic_vector(7 downto 0)
			);
	end component;
	
	component uart_rx
		Port (
			serial_in : in std_logic;
         data_out : out std_logic_vector(7 downto 0);
         read_buffer : in std_logic;
         reset_buffer : in std_logic;
         en_16_x_baud : in std_logic;
         buffer_data_present : out std_logic;
         buffer_full : out std_logic;
         buffer_half_full : out std_logic;
         clk : in std_logic
			);
   end component;
	 
	component registr_vstupu
		port(
			D_IN	:	in std_logic_vector(7 downto 0);
			D_OUT :  out std_logic_vector(7 downto 0);
			CLK 	:	in std_logic
			);
	end component;
	
	component multiplexer_pico 
		port (
			DATA_IN_1 : in std_logic_vector(7 downto 0);
			DATA_IN_2 : in std_logic_vector(7 downto 0);
			adresa : in std_logic;
			DATA_OUT : out std_logic_vector(7 downto 0)
			);
	end component;
	
	component prog_rom
		port (
			address : in std_logic_vector( 9 downto 0);
			instruction : out std_logic_vector(17 downto 0);
			clk : in std_logic
			);
	end component;
	
	component generator_resynchronizacnih_impulsu
		port (
			CLK : in std_logic;
			en_16_x_baud : out std_logic
			);			
	end component;

signal Q_OUT_signal : std_logic_vector( 7 downto 0) := (OTHERS => '0');
signal in_port_signal : std_logic_vector( 7 downto 0) := (OTHERS => '0');
signal out_port_signal : std_logic_vector( 7 downto 0) := (OTHERS => '0');
signal port_id_signal : std_logic_vector( 7 downto 0) := (OTHERS => '0');

type RegArr is array (7 downto 0) of std_logic_vector (7 downto 0);
type RegArrIn is array (1 downto 0) of std_logic_vector (7 downto 0);
signal data_signal:RegArr;
signal data_signal_in:RegArrIn; 

signal interrupt_ack_signal			: std_logic := '0';
signal buffer_data_present_signal	: std_logic := '0';
signal serial_out_signal				: std_logic := '0';
signal read_buffer_signal				: std_logic := '0';
signal write_buff_signal				: std_logic := '0';
signal buffer_in_full_signal			: std_logic := '0';
signal buffer_out_full_signal			: std_logic := '0';
signal buffer_out_half_full_signal	: std_logic := '0';
signal buffer_in_half_full_signal	: std_logic := '0';
signal interrupt_signal					: std_logic := '0';
signal read_strobe_signal				: std_logic := '0';
signal en_16_x_baud_signal				: std_logic := '0';
signal write_strobe_signal				: std_logic := '0';
signal temp_signal			: std_logic := '0';

signal instruction_signal : std_logic_vector( 17 downto 0) := (OTHERS => '0');
signal address_signal : std_logic_vector( 9 downto 0) := (OTHERS => '0');

begin

	processor: kcpsm3
		port map(
			address => address_signal,
			instruction => instruction_signal,
			port_id => port_id_signal,
			write_strobe => write_strobe_signal,
			out_port => out_port_signal,
			read_strobe => read_strobe_signal,
			in_port => in_port_signal,
			interrupt => interrupt_signal,
			interrupt_ack => interrupt_ack_signal,
			reset => '0', --reset_signal,
			clk => CLK
			);
			
	generator: generator_resynchronizacnih_impulsu
		port map(
			CLK => CLK,
			en_16_x_baud => en_16_x_baud_signal
			);		
			
  transmit: uart_tx 
		Port map(
			data_in => data_signal(6),
         write_buffer => write_buff_signal,
         reset_buffer => '0',
         en_16_x_baud => en_16_x_baud_signal,
         serial_out => serial_out_signal,
         buffer_full => buffer_in_full_signal,
         buffer_half_full => buffer_in_half_full_signal,
         clk => clk
			);

-- port_id_signal = X"40" tj. 01000000 a tj. port_id_signal(6), porad plati one hot encoding
	write_buff_signal <= port_id_signal(6) and write_strobe_signal; 
	
-- status port
	data_signal_in(1) <= "000" & buffer_data_present_signal & buffer_out_full_signal & buffer_out_half_full_signal & buffer_in_full_signal & buffer_in_half_full_signal;

	receive: uart_rx
		Port map (
			serial_in => UART_IN,
         data_out => data_signal_in(0),
         read_buffer => read_buffer_signal,
         reset_buffer => '0',
         en_16_x_baud => en_16_x_baud_signal,
         buffer_data_present => buffer_data_present_signal,
         buffer_full => buffer_out_full_signal,
         buffer_half_full => buffer_out_half_full_signal,
         clk => clk
			);
			
	dilek: pipeline_registr
		port map(
			vstup => temp_signal, 
			clk => CLK,
			vystup => read_buffer_signal
			);
			
	read_uart : dekoder_cteni_uartu
		port map(
			--CLK => CLK,
			read_strobe => read_strobe_signal,
			port_id => port_id_signal(0),
			uart_read_data => temp_signal
			);	

--	read_buffer_signal <= read_strobe_signal and port_id_signal(1);				

	program: prog_rom
		port map( address => address_signal,
			instruction => instruction_signal,
			clk => clk
			);

	gen: FOR i IN 0 TO 7 GENERATE
		dekoder : registr_vystupu 
			port map (
				CLK => CLK,
				ID => port_id_signal(i),
				W => write_strobe_signal,
				D_OUT => data_signal(i),
				D_IN => out_port_signal
				);
	end generate gen;
		
	multiplexer : multiplexer_pico
		port map (
			DATA_IN_1 => data_signal_in(1),		--status port
			DATA_IN_2 => data_signal_in(0),			--rx data
			DATA_OUT => Q_out_signal,
			adresa => port_id_signal(0)
			);
			
	dekoder_input_uart : registr_vstupu
		port map(
			D_IN => Q_out_signal,
			D_OUT => in_port_signal,
			CLK => CLK
			);
			
	interrupt : preruseni
		port map (
			CLK => CLK,
			interrupt_ack => interrupt_ack_signal,
			interrupt => interrupt_signal
			);

UART_OUT <= serial_out_signal;
Q_OUT <= data_signal(7);




end Behavioral;

