--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:   12:31:47 06/20/2012
-- Design Name:   
-- Module Name:   /media/BACKUP/CERN/contrib/ohwr/conv-ttl-blo/hdl/spi_master_multifield/test/spi_master_core_tb.vhd
-- Project Name:  spi_master_multifield
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: spi_master_core
-- 
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes: 
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test.  Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation 
-- simulation model.
--------------------------------------------------------------------------------

library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.spi_master_pkg.ALL;
use work.spi_analyser_pkg.ALL;
 
entity spi_master_core_tb is
end spi_master_core_tb;
 
architecture Behavioral of spi_master_core_tb is 

   component spi_master_core
      generic(
         g_INST_LENGTH     : NATURAL := c_INST_LENGTH;
         g_ADDR_LENGTH     : NATURAL := c_ADDR_LENGTH;
         g_DATA_LENGTH     : NATURAL := c_DATA_LENGTH;
         g_READ_LENGTH     : NATURAL := c_READ_LENGTH;
         g_CLK_I_PERIOD    : NATURAL := c_CLK_I_PERIOD);
      port(
         rst_i          : in  STD_LOGIC;
         clk_i          : in  STD_LOGIC;
      
         inst_i         : in  STD_LOGIC_VECTOR (8*g_INST_LENGTH - 1 downto 0);
         addr_i         : in  STD_LOGIC_VECTOR (8*g_ADDR_LENGTH - 1 downto 0);
         data_i         : in  STD_LOGIC_VECTOR (8*g_DATA_LENGTH - 1 downto 0);

         data_o         : out STD_LOGIC_VECTOR (8*g_READ_LENGTH - 1 downto 0);

         SPI0_i         : in  STD_LOGIC_VECTOR (r_SPI0'a_length - 1 downto 0);
         SPI1_i         : in  STD_LOGIC_VECTOR (r_SPI1'a_length - 1 downto 0);
         SPI2_o         : out STD_LOGIC_VECTOR (r_SPI2'a_length - 1 downto 0);
         SPI3_o         : out STD_LOGIC_VECTOR (r_SPI3'a_length - 1 downto 0);

         spi_mosi_o     : out STD_LOGIC;
         spi_miso_i     : in  STD_LOGIC;
         spi_clk_o      : out STD_LOGIC;
         spi_cs_n_o     : out STD_LOGIC);
    end component;


    -- Component Declaration for the Unit Under Test (UUT)
    
   signal rst_i      : STD_LOGIC := '0';
   signal clk_i      : STD_LOGIC := '0';

   signal s_inst     : STD_LOGIC_VECTOR (8*c_INST_LENGTH - 1 downto 0) := (others => '0');
   signal s_addr     : STD_LOGIC_VECTOR (8*c_ADDR_LENGTH - 1 downto 0) := (others => '0');
   signal s_data     : STD_LOGIC_VECTOR (8*c_DATA_LENGTH - 1 downto 0) := (others => '0');
   signal data_o     : STD_LOGIC_VECTOR (8*c_READ_LENGTH - 1 downto 0);

   signal inst_i     : STD_LOGIC_VECTOR (8*c_INST_LENGTH - 1 downto 0) := (others => '0');
   signal addr_i     : STD_LOGIC_VECTOR (8*c_ADDR_LENGTH - 1 downto 0) := (others => '0');
   signal data_i     : STD_LOGIC_VECTOR (8*c_DATA_LENGTH - 1 downto 0) := (others => '0');

   --Inputs
   signal s_SPI0          : r_SPI0; 
   signal s_SPI0_slv      : STD_LOGIC_VECTOR(r_SPI0'a_length - 1  downto 0);
   signal s_SPI1          : r_SPI1; 
   signal s_SPI1_slv      : STD_LOGIC_VECTOR(r_SPI1'a_length - 1  downto 0);
   signal s_SPI2          : r_SPI2; 
   signal s_SPI2_slv      : STD_LOGIC_VECTOR(r_SPI2'a_length - 1  downto 0);

   signal s_spi_mosi      : STD_LOGIC;
   signal s_spi_miso      : STD_LOGIC := '0';
   signal s_spi_clk       : STD_LOGIC;
   signal s_spi_cs_n      : STD_LOGIC;

   signal s_inst_check    : STD_LOGIC_VECTOR (8*c_INST_LENGTH - 1 downto 0) :=
                                                                (others => '0');
   signal s_addr_check    : STD_LOGIC_VECTOR (8*c_ADDR_LENGTH - 1 downto 0) :=
                                                                (others => '0');
   signal s_data_check    : STD_LOGIC_VECTOR (8*c_DATA_LENGTH - 1 downto 0) :=
                                                                (others => '0');

   signal s_end_inst_flag : STD_LOGIC; 
   signal s_end_addr_flag : STD_LOGIC; 
   signal s_end_data_flag : STD_LOGIC;

   --Outputs
   signal s_spi_count        : NATURAL;
   signal s_rst_spi_analyser : STD_LOGIC := '0';


   -- Clock period definitions
   constant c_WISHBONE_PERIOD : TIME := 10 ns;

--   file file_handler    : TEXT;
--   constant log_path    : STRING := "../test/log/spi_master_core_tb.log";
--   constant sep         : CHARACTER := ht;


begin

   s_SPI0_slv   <= f_STD_LOGIC_VECTOR(s_SPI0); 
   s_SPI1_slv   <= f_STD_LOGIC_VECTOR(s_SPI1); 
   s_SPI2       <= f_SPI2(s_SPI2_slv); 

   -- Instantiate the Unit Under Test (UUT)
   uut: spi_master_core port map (
          rst_i      => rst_i,
          clk_i      => clk_i,
          inst_i     => inst_i,
          addr_i     => addr_i,
          data_i     => data_i,
          SPI0_i     => s_SPI0_slv,
          SPI1_i     => s_SPI1_slv,
          SPI2_o     => s_SPI2_slv,
          spi_mosi_o => s_spi_mosi,
          spi_miso_i => s_spi_miso,
          spi_clk_o  => s_spi_clk,
          spi_cs_n_o => s_spi_cs_n);

   tester : spi_analyser port map(
          rst_i            => s_rst_spi_analyser, 
          SPI0_i           => s_SPI0, 
          SPI1_i           => s_SPI1, 

          spi_mosi_o       => s_spi_mosi, 
          spi_miso_i       => s_spi_miso, 
          spi_clk_o        => s_spi_clk, 
          spi_cs_n_o       => s_spi_cs_n, 
                                             
          inst_check_o     => s_inst_check, 
          addr_check_o     => s_addr_check, 
          data_check_o     => s_data_check,
                                             
          end_inst_flag_o  => s_end_inst_flag, 
          end_addr_flag_o  => s_end_addr_flag, 
          end_data_flag_o  => s_end_data_flag);


   -- Clock process definitions
   clk_i_process :process
   begin
      clk_i <= '0';
         wait for c_WISHBONE_PERIOD/2;
      clk_i <= '1';
         wait for c_WISHBONE_PERIOD/2;
   end process;

   -- Stimulus process
   p_simulation: process

      procedure init_cond is
      begin
         inst_i <= (others => '0'); 
         addr_i <= (others => '0'); 
         data_i <= (others => '0'); 
         s_SPI0 <= c_SPI0_default; 
         s_SPI1 <= c_SPI1_default; 
      end procedure;

      procedure set_FIFO_contents(
                   inst   : STD_LOGIC_VECTOR(8*c_INST_LENGTH - 1 downto 0);
                   addr   : STD_LOGIC_VECTOR(8*c_ADDR_LENGTH - 1 downto 0);
                   data   : STD_LOGIC_VECTOR(8*c_DATA_LENGTH - 1 downto 0)) is
      begin
         --! set_FIFO_contents found in work.spi_analyser_pkg
         set_FIFO_contents (clk_i,
                      inst_i, addr_i, data_i,
                      inst, addr, data);
      end procedure;

      procedure spi_command(
                cpol          : in STD_LOGIC; cpha          : in STD_LOGIC;
                clk_div       : in NATURAL;
                inst_length   : in NATURAL;
                addr_length   : in NATURAL;
                data_length   : in NATURAL;
                read_length   : in NATURAL;
                send_inst     : in STD_LOGIC;
                send_addr     : in STD_LOGIC;
                send_data     : in STD_LOGIC;
                read_mosi     : in STD_LOGIC;
                inst    : in STD_LOGIC_VECTOR(8*c_INST_LENGTH - 1 downto 0);
                addr    : in STD_LOGIC_VECTOR(8*c_ADDR_LENGTH - 1 downto 0);
                data    : in STD_LOGIC_VECTOR(8*c_DATA_LENGTH - 1 downto 0)) is
      begin
         --! spi_command found in work.spi_analyser_pkg
         spi_command (clk_i, s_rst_spi_analyser,
                      s_SPI0, s_SPI1, s_SPI2,
                      cpol, cpha, clk_div,
                      inst_length, addr_length, data_length, read_length,
                      send_inst, send_addr, send_data, read_mosi, 
                      inst_i, addr_i, data_i,
                      inst, addr, data);
      end procedure;


   begin		

      init_cond;
         wait until rising_edge(clk_i);
         wait for c_WISHBONE_PERIOD*10;
      rst_i  <= '1';
      s_rst_spi_analyser <= '1';
         wait for c_WISHBONE_PERIOD*10;
      rst_i  <= '0';
      s_rst_spi_analyser <= '0';
         wait for c_WISHBONE_PERIOD*10;

      set_FIFO_contents(X"AB", X"123456", (others => '0'));


        s_inst <= X"AB";
        s_addr <= X"123456";
        s_data <= (others => '0');

      spi_command(  '0', '0',
                     2,
                     2,    6,   3,  0,
                    '1',  '1', '1', '1',
                   s_inst, s_addr, s_data);
         wait for c_WISHBONE_PERIOD*10;


      spi_command(  '0', '1',
                     2,
                     1,    0,   7,  0,
                    '1',  '1', '1', '1',
                   s_inst, s_addr, s_data);
         wait for c_WISHBONE_PERIOD*10;

      spi_command(  '1', '0',
                     15,
                     1,    1,   1,  1,
                    '1',  '1', '1', '1',
                   s_inst, s_addr, s_data);
         wait for c_WISHBONE_PERIOD*10;

      spi_command(  '1', '1',
                     2,
                     1,    1,   1,  1,
                    '1',  '1', '1', '1',
                   s_inst, s_addr, s_data);
         wait for c_WISHBONE_PERIOD*10;

      spi_command(  '0', '0',
                     2,
                     1,    1,   1,  1,
                    '0',  '1', '1', '1',
                   s_inst, s_addr, s_data);
         wait for c_WISHBONE_PERIOD*10;

      spi_command(  '0', '0',
                     2,
                     1,    1,   1,  1,
                    '1',  '1', '1', '1',
                   s_inst, s_addr, s_data);
         wait for c_WISHBONE_PERIOD*10;


--
--      spi_command(  '0', '0',
--                     1,    3,   256, 4,
--                    '1',  '1', '1', '1',
--                   s_inst, s_addr, s_data);
--         wait for c_WISHBONE_PERIOD*10;

         assert false report "No error. Simulation ends." severity failure;
   end process;

END;
