----------------------------------------------------------------------------------
-- Company: 
-- Engineer: David Makowka
-- 
-- Create Date: 02/01/2020 11:31:08 PM
-- Design Name: 
-- Module Name: spi_slave_logic - 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;

entity spi_slave_logic is
    Port ( clk                      : in std_logic;
           reset                    : in std_logic;
           mosi                     : in std_logic;
           miso                     : out std_logic;
           sclk                     : in std_logic;
           ss_n                     : in std_logic;
           number_to_recieve        : out std_logic_vector(7 downto 0));
end spi_slave_logic;

architecture Behavioral of spi_slave_logic is
    
  constant d_width                  : INTEGER := 8;
  
  signal s_reset_n                  : std_logic := '1';
  signal s_number_to_recieve        : std_logic_vector(7 downto 0);
  
  --INPUT DATA
  signal s_rx_req                   : std_logic;
  signal s_rx_data                  : std_logic_vector(d_width-1 DOWNTO 0);
  
  --OUTPUT DATA
  signal s_tx_load_data             : std_logic_vector(d_width-1 DOWNTO 0);
  signal s_tx_load_en               : std_logic;
  
  signal s_busy                     : std_logic;
  
  --STATUS BITS - CAN BE WRITTEN FROM HERE or BY TRANSACTION
  signal s_trdy                     : std_logic;
  signal s_rrdy                     : std_logic;
  signal s_roe                      : std_logic;
    
  --STATE MACHINES STATES
  signal s_FSM_state                : std_logic_vector(2 downto 0) := "000";
  
    component spi_slave
      GENERIC(
        cpol                        : STD_LOGIC := '0';  --spi clock polarity mode
        cpha                        : STD_LOGIC := '0';  --spi clock phase mode
        d_width                     : INTEGER := 8);     --data width in bits
      PORT(
        sclk                        : IN     STD_LOGIC;  --spi clk from master
        reset_n                     : IN     STD_LOGIC;  --active low reset
        ss_n                        : IN     STD_LOGIC;  --active low slave select
        mosi                        : IN     STD_LOGIC;  --master out, slave in
        rx_req                      : IN     STD_LOGIC;  --'1' while busy = '0' moves data to the rx_data output
        st_load_en                  : IN     STD_LOGIC;  --asynchronous load enable
        st_load_trdy                : IN     STD_LOGIC;  --asynchronous trdy load input
        st_load_rrdy                : IN     STD_LOGIC;  --asynchronous rrdy load input
        st_load_roe                 : IN     STD_LOGIC;  --asynchronous roe load input
        tx_load_en                  : IN     STD_LOGIC;  --asynchronous transmit buffer load enable
        tx_load_data                : IN     STD_LOGIC_VECTOR(d_width-1 DOWNTO 0);  --asynchronous tx data to load
        trdy                        : BUFFER STD_LOGIC := '0';  --transmit ready bit
        rrdy                        : BUFFER STD_LOGIC := '0';  --receive ready bit
        roe                         : BUFFER STD_LOGIC := '0';  --receive overrun error bit
        rx_data                     : OUT    STD_LOGIC_VECTOR(d_width-1 DOWNTO 0) := (OTHERS => '0');  --receive register output to logic
        busy                        : OUT    STD_LOGIC := '0';  --busy signal to logic ('1' during transaction)
        miso                        : OUT    STD_LOGIC := 'Z'); --master in, slave out
    END component;

    attribute DONT_TOUCH : string;
    attribute DONT_TOUCH of  spi_slave_instance : label is "TRUE";

begin
    number_to_recieve <= s_rx_data;

    --**********************************************************************************************
    --      Synchronni proces pro zm?nu dat posilanych jako odpoved                                *
    --**********************************************************************************************
    
    with s_rx_data(2 downto 0) select s_tx_load_data <=
	"00000011" when "001",
	"00001100" when "011",
	"00110000" when "101",
	"11000000" when "111",
	
	"10101010" when "000",
	"10101010" when "010",
	"10101010" when "100",
	"10101010" when "110",
	"11111111" when others;
    
    process(clk)
    begin
        if rising_edge(clk) then
            if(s_busy = '0' AND s_rx_data(0) = '0') then
                s_tx_load_en <= NOT s_tx_load_en;
            else
                s_tx_load_en <= '0';   
            end if;
        end if;
    end process;

    --**********************************************************************************************
    --      Process pro odpovidani masteru                                                         *
    --**********************************************************************************************
    --Generovani pulsu na re_req za ucelem vycteni dat
    process(clk) 
    begin
        if rising_edge(clk) then
            if(s_rrdy = '1') then       --wait for reciving of data
                s_rx_req    <= '1';        --request data to be put on port rx_data
            else
                s_rx_req    <= '0'; 
            end if;
        end if;
    end process;
    
    spi_slave_instance : spi_slave
        GENERIC MAP( cpol                  => '0',
                     cpha                  => '0',
                     d_width               => 8)
        PORT MAP(    sclk                  => sclk,
                     reset_n               => '1',
                     ss_n                  => ss_n,
                     mosi                  => mosi,
                     rx_req                => s_rx_req,
                     st_load_en            => '0',
                     st_load_trdy          => '0',
                     st_load_rrdy          => '0',
                     st_load_roe           => '0',
                     tx_load_en            => s_tx_load_en ,
                     tx_load_data          => s_tx_load_data,
                     trdy                  => s_trdy,
                     rrdy                  => s_rrdy,
                     roe                   => s_roe,
                     rx_data               => s_rx_data,
                     busy                  => s_busy,
                     miso                  => miso);
                     
end Behavioral;