--------------------------------------------------------------------------------
-- Company:       CERN, BE-CO-HT
-- Engineer:      Carlos Gil Soriano
--
-- Create Date:   10:59:15 10/31/2011
-- Design Name:   
-- Module Name:   /media/BACKUP/CERN/contrib/ohwr/conv-ttl-blo/hdl/rtl/i2c_slave_wb_master/test/i2c_slave_top_tb.vhd
-- Project Name:  i2c_slave_wb_master
-- Target Device: Spartan 6
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: i2c_slave_top
-- 
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Revision 0.1  - File Modified. Now the sda_i line is more acurately accessed.
-- 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;
USE ieee.std_logic_1164.ALL;
USE std.textio.ALL;
USE ieee.numeric_std.ALL;
 
ENTITY i2c_slave_top_tb IS
END i2c_slave_top_tb;
 
ARCHITECTURE behavior OF i2c_slave_top_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
   COMPONENT i2c_slave_top
      PORT(
             sda_oen          : out  STD_LOGIC;
             sda_i            : in   STD_LOGIC;
             sda_o            : out  STD_LOGIC;
             scl_oen          : out  STD_LOGIC;
             scl_i            : in   STD_LOGIC;
             scl_o            : out  STD_LOGIC;
             wb_clk           : in   STD_LOGIC;
             wb_rst_i         : in   STD_LOGIC;
             wb_master_stb_o  : out STD_LOGIC;
             wb_master_cyc_o  : out STD_LOGIC;
             wb_master_sel_o  : out STD_LOGIC_VECTOR (3  downto 0);
             wb_master_we_o   : out STD_LOGIC;
             wb_master_data_i : in  STD_LOGIC_VECTOR (31 downto 0);
             wb_master_data_o : out STD_LOGIC_VECTOR (31 downto 0);
             wb_master_addr_o : out STD_LOGIC_VECTOR (15 downto 0);
             wb_master_ack_i  : in  STD_LOGIC;
             wb_master_rty_i  : in  STD_LOGIC;
             wb_master_err_i  : in  STD_LOGIC;
             wb_slave_stb_i   : in   STD_LOGIC;
             wb_slave_cyc_i   : in   STD_LOGIC;
             wb_slave_sel_i   : in   STD_LOGIC_VECTOR(3  downto 0);
             wb_slave_we_i    : in   STD_LOGIC;
             wb_slave_data_i  : in   STD_LOGIC_VECTOR(31 downto 0);
             wb_slave_data_o  : out  STD_LOGIC_VECTOR(31 downto 0);
             wb_slave_addr_i  : in   STD_LOGIC_VECTOR(3  downto 0);
             wb_slave_ack_o   : out  STD_LOGIC;
             wb_slave_rty_o   : out  STD_LOGIC;
             wb_slave_err_o   : out  STD_LOGIC;
             pf_wb_addr_o     : out  STD_LOGIC;
             rd_done_o        : out  STD_LOGIC;
             wr_done_o        : out  STD_LOGIC;
             i2c_addr         : in   STD_LOGIC_VECTOR (6  downto 0)
          );
   END COMPONENT;


   --Inputs
   signal sda_oen       : STD_LOGIC;
   signal sda_i         : STD_LOGIC := '1';
   signal sda_o         : STD_LOGIC;
   signal scl_oen       : STD_LOGIC;
   signal scl_i         : STD_LOGIC := '1';
   signal scl_clk       : STD_LOGIC := '1';
   signal scl_o         : STD_LOGIC;

   signal run_scl       : STD_LOGIC := '0';

   signal wb_clk       : STD_LOGIC := '0';
   signal wb_rst_i     : STD_LOGIC := '0';

   signal wb_master_stb_o     : STD_LOGIC;
   signal wb_master_cyc_o     : STD_LOGIC;
   signal wb_master_sel_o     : STD_LOGIC_VECTOR (3  downto 0);
   signal wb_master_we_o      : STD_LOGIC;
   signal wb_master_data_i    : STD_LOGIC_VECTOR (31 downto 0) := X"00000000";
   signal wb_master_data_o    : STD_LOGIC_VECTOR (31 downto 0);
   signal wb_master_addr_o    : STD_LOGIC_VECTOR (15  downto 0);
   signal wb_master_ack_i     : STD_LOGIC := '0';
   signal wb_master_rty_i     : STD_LOGIC := '0';
   signal wb_master_err_i     : STD_LOGIC := '0';

   signal wb_slave_cyc_i     : STD_LOGIC := '0';
   signal wb_slave_stb_i     : STD_LOGIC;
   signal wb_slave_sel_i     : STD_LOGIC_VECTOR (3  downto 0) := X"0";
   signal wb_slave_we_i      : STD_LOGIC := '0';
   signal wb_slave_data_i    : STD_LOGIC_VECTOR (31 downto 0) := X"00000000";
   signal wb_slave_data_o    : STD_LOGIC_VECTOR (31 downto 0);
   signal wb_slave_addr_i    : STD_LOGIC_VECTOR (3  downto 0) := X"0";
   signal wb_slave_ack_o     : STD_LOGIC;
   signal wb_slave_rty_o     : STD_LOGIC;
   signal wb_slave_err_o     : STD_LOGIC;
   signal pf_wb_addr_o       : STD_LOGIC;
   signal rd_done_o          : STD_LOGIC;
   signal wr_done_o          : STD_LOGIC;

   -- Clock period definitions
   constant wb_clk_period   : time := 50 ns;    -- @ 20 MHz
   constant scl_i_period    : time := 10000 ns;  -- @ 400 KHz

   signal VME_crate_slot   : UNSIGNED(4 downto 0)  := "11110";
   signal i2c_addr         : STD_LOGIC_VECTOR (6 downto 0);
   signal i2c_addr_mask    : STD_LOGIC_VECTOR (6 downto 0);
--   signal i2c_addr         : STD_LOGIC_VECTOR(6 downto 0) := not(std_logic_vector(VME_crate_slot));

   signal i2c_rcved_data   : STD_LOGIC_VECTOR (7 downto 0);
   constant bytes_ind_addr : STD_LOGIC_VECTOR (7 downto 6) := "10";
   constant bytes_wr_state : STD_LOGIC_VECTOR (7 downto 0) := X"06";
   constant bytes_rd_state : STD_LOGIC_VECTOR (7 downto 0) := X"04";

   constant  STA_addr      : STD_LOGIC_VECTOR(3 downto 0) := X"0";    
   constant  CTR0_addr     : STD_LOGIC_VECTOR(3 downto 0) := X"2";
   constant  CTR1_addr     : STD_LOGIC_VECTOR(3 downto 0) := X"3";   
   constant  DRXl_addr     : STD_LOGIC_VECTOR(3 downto 0) := X"4";
   constant  DRXh_addr     : STD_LOGIC_VECTOR(3 downto 0) := X"5";
   constant  DTX_addr      : STD_LOGIC_VECTOR(3 downto 0) := X"6";
                         
BEGIN
 

   i2c_addr(6 downto 5)   <= "11";
   i2c_addr(4 downto 0)   <= std_logic_vector(VME_crate_slot);

   i2c_addr_mask          <= "0011111";

	-- Instantiate the Unit Under Test (UUT)
   uut: i2c_slave_top PORT MAP (
          sda_oen     => sda_oen,
          sda_i       => sda_i,
          sda_o       => sda_o,
          scl_oen     => scl_oen,
          scl_i       => scl_i,
          scl_o       => scl_o,
          wb_clk      => wb_clk,
          wb_rst_i    => wb_rst_i,
          wb_master_stb_o   => wb_master_stb_o, 
          wb_master_cyc_o   => wb_master_cyc_o, 
          wb_master_sel_o   => wb_master_sel_o, 
          wb_master_we_o    => wb_master_we_o, 
          wb_master_data_i  => wb_master_data_i, 
          wb_master_data_o  => wb_master_data_o, 
          wb_master_addr_o  => wb_master_addr_o, 
          wb_master_ack_i   => wb_master_ack_i, 
          wb_master_rty_i   => wb_master_rty_i, 
          wb_master_err_i   => wb_master_err_i, 
          wb_slave_stb_i    => wb_slave_stb_i,
          wb_slave_cyc_i    => wb_slave_cyc_i,
          wb_slave_sel_i    => wb_slave_sel_i,
          wb_slave_we_i     => wb_slave_we_i,
          wb_slave_data_i   => wb_slave_data_i,
          wb_slave_data_o   => wb_slave_data_o,
          wb_slave_addr_i   => wb_slave_addr_i,
          wb_slave_ack_o    => wb_slave_ack_o,
          wb_slave_rty_o    => wb_slave_rty_o,
          wb_slave_err_o    => wb_slave_err_o,
          pf_wb_addr_o      => pf_wb_addr_o,
          rd_done_o         => rd_done_o,
          wr_done_o         => wr_done_o,
          i2c_addr          => i2c_addr
        );

   -- Clock process definitions
   wb_clk_process :process
   begin
		wb_clk <= '1';
		wait for wb_clk_period/2;
		wb_clk <= '0';
		wait for wb_clk_period/2;
   end process;

   scl_i <= '1' when run_scl = '0' else
            scl_clk;

   scl_clk_process :process
   begin
         scl_clk     <= '1';
         wait for scl_i_period/2;
         scl_clk     <= '0';
         wait for scl_i_period/2;
   end process;



   -- Stimulus process
   stim_proc: process
	   
      procedure init_cond is
      begin
         sda_i   <= '1';
         scl_i   <= 'Z';
      end init_cond;

	
      procedure rst is
      begin
            wait for wb_clk_period*10;
         wb_rst_i   <= '1';
            wait for wb_clk_period*10;
         wb_rst_i   <= '0';
            wait for wb_clk_period*10;
      end rst;

      procedure start is
      begin
         sda_i     <= '1';
         wait until rising_edge(scl_clk);
         wait for scl_i_period/4;
         sda_i     <= '0';
         run_scl   <= '1';
      end start;


      procedure addr_send(addr : STD_LOGIC_VECTOR(6 downto 0)) is
      begin
         for i in 6 downto 0 loop
            wait until falling_edge(scl_i);
            wait for scl_i_period/4;
            sda_i <= addr(i);
         end loop;
      end addr_send;


      procedure rd_wrn_send(rd_wrn_bit: STD_LOGIC) is
      begin
         wait until falling_edge(scl_i);
         wait for scl_i_period/4;
         sda_i <= rd_wrn_bit;
      end rd_wrn_send;


      procedure read_ack (errormsg: string; okmsg: string) is
      begin
         wait until falling_edge(scl_i);
         wait for scl_i_period*3/4;
         assert sda_o = '0' report errormsg severity error;
         if (sda_o = '0') then
            report okmsg;
         end if;
      end read_ack;

      procedure read_nack (errormsg: string; okmsg: string) is
      begin
         wait until falling_edge(scl_i);
         wait for scl_i_period*3/4;
         assert sda_o = '1' report errormsg severity error;
         if (sda_o = '1') then
            report okmsg;
         end if;
      end read_nack;

      procedure write_ACK(ack_bit: STD_LOGIC) is
      begin
         wait until falling_edge(scl_i);
         wait for scl_i_period/4;
         sda_i <= ack_bit;
      end write_ACK;


      procedure write_SDA(byte: STD_LOGIC_VECTOR (7 downto 0)) is
      begin
         for i in 7 downto 0 loop
            wait until falling_edge(scl_i);
            wait for scl_i_period/4;
            sda_i <= byte(i);
         end loop;
      end write_SDA;


      procedure read_SDA is
      begin
         for i in 0 to 7 loop
            wait until falling_edge(scl_i);
            wait for scl_i_period/4;
            i2c_rcved_data(i) <= sda_o;
         end loop;
         wait until falling_edge(scl_i);
         wait for scl_i_period/4;
         sda_i <= '0';
      end read_SDA;

      procedure pause is
      begin
         wait until falling_edge(scl_i);
         wait for scl_i_period/4;
         sda_i   <= '0';
         run_scl <= '0';
         wait for scl_i_period/4;
         sda_i   <= '1';
      end pause;

      -------------------------------------------------------------------------
      -- STA register
      -------------------------------------------------------------------------

      procedure read_STA is
      begin 
        wait until rising_edge(wb_clk);        
        wb_slave_addr_i  <= STA_addr;
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);        
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_ack_o = '1' report "Wishbone read STA not acked" severity ERROR;
      end procedure;

      procedure write_STA(data: STD_LOGIC_VECTOR(31 downto 0)) is 
      begin
        wait until rising_edge(wb_clk);
        wb_slave_addr_i  <= STA_addr;
        wb_slave_data_i  <= data;
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_err_o = '1' report "Wishbone write STA is not signaled as error" severity ERROR;
      end procedure;


      -------------------------------------------------------------------------
      -- CTR0 register
      -------------------------------------------------------------------------

      procedure read_CTR0 is
      begin
        wait until rising_edge(wb_clk);        
        wb_slave_addr_i  <= CTR0_addr;
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_ack_o = '1' report "Wishbone read CTR0 not acked" severity ERROR;
      end procedure;

      procedure write_CTR0(data: STD_LOGIC_VECTOR(15 downto 0)) is
      begin
        wait until rising_edge(wb_clk);
        wb_slave_addr_i  <= CTR0_addr;
        wb_slave_data_i(15 downto 0)  <= data;
        wb_slave_data_i(31 downto 16) <= (others => '0');
        wb_slave_we_i    <= '1';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_ack_o = '1' report "Wishbone write CTR0 not acked" severity ERROR;
      end procedure;

      -------------------------------------------------------------------------
      -- CTR1 register
      -------------------------------------------------------------------------

      procedure read_CTR1 is 
      begin
        wait until rising_edge(wb_clk);        
        wb_slave_addr_i  <= CTR1_addr;
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);        
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_ack_o = '1' report "Wishbone read CTR1 not acked" severity ERROR;
      end procedure;

      procedure write_CTR1(data: STD_LOGIC_VECTOR(15 downto 0)) is
      begin
        wait until rising_edge(wb_clk);
        wb_slave_addr_i  <= CTR1_addr;
        wb_slave_data_i(15 downto 0)  <= data;
        wb_slave_data_i(31 downto 16) <= (others => '0');
        wb_slave_we_i    <= '1';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);        
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_ack_o = '1' report "Wishbone write CTR1 not acked" severity ERROR;
      end procedure;

      -------------------------------------------------------------------------
      -- DRX0, DRX1, DRX2, DRX3 agregate access registers
      -------------------------------------------------------------------------

      procedure read_DRXl is
      begin
        wait until rising_edge(wb_clk);        
        wb_slave_addr_i  <= DRXl_addr;
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);        
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_ack_o = '1' report "Wishbone read DRXl not acked" severity ERROR;
      end procedure;

      procedure write_DRXl(data: STD_LOGIC_VECTOR(31 downto 0)) is 
      begin
        wait until rising_edge(wb_clk);
        wb_slave_addr_i  <= DRXl_addr;
        wb_slave_data_i  <= data;
        wb_slave_we_i    <= '1';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);        
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_err_o = '1' report "Wishbone write DRXl is not signaled as error" severity ERROR;
      end procedure;

      -------------------------------------------------------------------------
      -- DRX4, DRX5 agregate access registers
      -------------------------------------------------------------------------

      procedure read_DRXh is
      begin
        wait until rising_edge(wb_clk);
        wb_slave_addr_i  <= DRXh_addr;
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);        
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_ack_o = '1' report "Wishbone read DRXh not acked" severity ERROR;
      end procedure;

      procedure write_DRXh(data: STD_LOGIC_VECTOR(31 downto 0)) is 
      begin
        wait until rising_edge(wb_clk);
        wb_slave_addr_i  <= DRXh_addr;
        wb_slave_data_i  <= data;
        wb_slave_we_i    <= '1';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);        
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_err_o = '1' report "Wishbone write DRXh is not signaled as error" severity ERROR;
      end procedure;

      -------------------------------------------------------------------------
      -- DTX agregate register access
      -------------------------------------------------------------------------

      procedure read_DTX is
      begin
        wait until rising_edge(wb_clk);
        wb_slave_addr_i  <= DTX_addr;
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);        
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_ack_o = '1' report "Wishbone read DTX not acked" severity ERROR;
      end procedure;

      procedure write_DTX(data: STD_LOGIC_VECTOR(31 downto 0)) is
      begin
        wait until rising_edge(wb_clk);
        wb_slave_addr_i  <= DTX_addr;
        wb_slave_data_i  <= data;
        wb_slave_we_i    <= '1';
        wb_slave_stb_i   <= '1';
        wb_slave_cyc_i   <= '1';
        wait for wb_clk_period*3/2;
        wait until rising_edge(wb_clk);        
        wb_slave_we_i    <= '0';
        wb_slave_stb_i   <= '0';
        wb_slave_cyc_i   <= '0';
        assert wb_slave_ack_o = '1' report "Wishbone write DTX not acked" severity ERROR;
      end procedure;

      -------------------------------------------------------------------------
      -- Procedure for correctly setting up the i2c slave
      -------------------------------------------------------------------------

      procedure init_cfg_i2c_slave(CTR0_data : STD_LOGIC_VECTOR(15 downto 0) ; CTR1_data : STD_LOGIC_VECTOR(15 downto 0)) is
      begin
        write_CTR0(CTR0_data and X"0002");
        wait for wb_clk_period;
        write_CTR0(CTR0_data and X"FF00");
        wait for wb_clk_period;
        write_CTR1(CTR1_data);
        wait for wb_clk_period;
        write_CTR0(CTR0_data); -- Enough to assert enable bit
      end procedure;
begin

-- ERROR list
----> ACK errors
--    01   Instruction byte
--    02   Internal wishbone address high byte
--    03   Internal wishbone address low byte

   wb_rst_i   <= '0';
   init_cond;
   wait for 100 ns;

   rst;
   read_STA;
   read_CTR0;
     write_CTR0(wb_slave_data_o(15 downto 0));
   read_CTR1;
     write_CTR1(wb_slave_data_o(15 downto 0));
   read_DRXl;
   read_DRXh;
   read_DTX;
     write_DTX(wb_slave_data_o);

   --   init_cfg_i2c_slave(std_logic_vector('0'&i2c_addr&bytes_ind_addr&"0000"&"01", bytes_wr_state&bytes_rd_state);

   -------------------------------------------------------------------------------
   -- Indirect i2c write
   -------------------------------------------------------------------------------   
   start;
   addr_send("1011110");  -- MSB first
   rd_wrn_send('0');
       read_ACK("ACK@01:  NACK received. Sending instruction byte (i2c addres + rd_wrn bit)", "PASS -> Instruction byte ACKED");
   write_SDA(X"21"); -- inverted MSB
      read_ACK("ACK@02:  NACK received. Sending internal wishbone address high byte", "PASS -> Internal Wishbone Address High Byte ACKED");
   write_SDA(X"5A"); -- inverted LSB
      read_ACK("ACK@03:  NACK received. Sending internal wishbone address low byte", "PASS -> Internal Wishbone Address Low Byte ACKED");
   write_SDA("10000000"); -- inverted
      read_ACK("ACK@04:  NACK received. Sending 1st byte", "PASS -> 1st data byte");
   write_SDA("10000000"); -- inverted
      read_ACK("ACK@04:  NACK received. Sending 2nd byte", "PASS -> 2nd data byte");
   write_SDA("10000000"); -- inverted
      read_ACK("ACK@04:  NACK received. Sending 3rd byte", "PASS -> 3rd data byte");
   write_SDA("10000000"); -- inverted
      read_ACK("ACK@04:  NACK received. Sending 4th byte", "PASS -> 4th data byte");
   pause;

   wait for 1000*wb_clk_period;

   -------------------------------------------------------------------------------
   -- Indirect i2c write    BAD ADDRESSING, IT MUST REPORT ONLY ERRORS
   -------------------------------------------------------------------------------   
   start;
   addr_send("1011101");  -- MSB first
   rd_wrn_send('0');
       read_NACK("NACK@01: ACK received. Bad I2C address found", "PASS -> Instruction byte NACKED");
   write_SDA(X"21"); -- inverted MSB
      read_NACK("NACK@02:  ACK received. Wrong state in fsm", "PASS -> NACKed");
   write_SDA(X"5A"); -- inverted LSB
      read_NACK("NACK@03:  ACK received. Wrong state in fsm", "PASS -> NACKed");
   write_SDA("10000000"); -- inverted
      read_NACK("NACK@04:  ACK received. Wrong state in fsm", "PASS -> NACKed");
   write_SDA("10000000"); -- inverted
      read_NACK("NACK@04:  ACK received. Wrong state in fsm", "PASS -> NACKed");
   write_SDA("10000000"); -- inverted
      read_NACK("NACK@04:  ACK received. Wrong state in fsm", "PASS -> NACKed");
   write_SDA("10000000"); -- inverted
      read_NACK("NACK@04:  ACK received. Wrong state in fsm", "PASS -> NACKed");
   pause;
   wait for 1000*wb_clk_period;


   -------------------------------------------------------------------------------
   -- Indirect i2c read
   -- This is divided in a write process to set the Wishbone slave and a i2c read
   -------------------------------------------------------------------------------
   start;
   addr_send("0111110");
   rd_wrn_send('0');
      read_ACK("ACK@01:  NACK received. Sending instruction byte (i2c addres + rd_wrn bit)", "PASS -> Instruction byte ACKED");
   write_SDA("10100101");
      read_ACK("ACK@02:  NACK received. Sending internal wishbone address high byte", "PASS -> Internal Wishbone Address High Byte ACKED");
   write_SDA("00000000");
      read_ACK("ACK@03:  NACK received. Sending internal wishbone address low byte", "PASS -> Internal Wishbone Address Low Byte ACKED");
   -- At this point we must prefetch the data to be sent
   write_DTX(X"DDCCBBAA"); 
   start;
   addr_send("0111110");
   rd_wrn_send('1');
      read_ACK("ACK@01:  NACK received. Sending instruction byte (i2c addres + rd_wrn bit)", "PASS -> Instruction byte ACKED");
   read_SDA;
   read_SDA;
   read_SDA;
   read_SDA;
   pause;

wait;
end process;

END;
