library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

library work;
    use work.reg32.all;
    use work.avalon_slave.all;

package test_avalon_slave is

    procedure read( signal clk : in std_logic;
        variable address : in std_logic_vector;
        signal req : out work.avalon_slave.Request;
        signal rsp : in work.avalon_slave.Response;
        variable data : out std_logic_vector );

    procedure assert_readdata_eq( signal clk : in std_logic;
        variable address : in std_logic_vector;
        signal req : out work.avalon_slave.Request;
        signal rsp : in work.avalon_slave.Response;
        variable expected : in std_logic_vector;
        constant message : in string );

    procedure write( signal clk : in std_logic;
        variable address : in std_logic_vector;
        signal req : out work.avalon_slave.Request;
        variable data : in std_logic_vector );

end package test_avalon_slave;

package body test_avalon_slave is

    procedure read( signal clk : in std_logic;
        variable address : in std_logic_vector;
        signal req : out work.avalon_slave.Request;
        signal rsp : in work.avalon_slave.Response;
        variable data : out std_logic_vector ) is
    begin

        req.read <= '1';
        req.write <= '0';
        req.address <= address;
        wait until falling_edge( clk );
        wait until falling_edge( clk );
        req.read <= '0';
        data := rsp.readdata;
        wait until falling_edge( clk );

    end procedure read;

    procedure assert_readdata_eq( signal clk : in std_logic;
        variable address : in std_logic_vector;
        signal req : out work.avalon_slave.Request;
        signal rsp : in work.avalon_slave.Response;
        variable expected :in std_logic_vector;
        constant message : in string ) is

        variable readdata : std_logic_vector( expected'range );
    begin

        read( clk => clk,
            address => address,
            req => req,
            rsp => rsp,
            data => readdata );

        assert( readdata = expected )
            report message & LF &
                "    expected: " & to_string( expected ) & LF &
                "    actual:   " & to_string( readdata ) & LF
                severity error;
    end procedure assert_readdata_eq;

    procedure write( signal clk : in std_logic;
        variable address : in std_logic_vector;
        signal req : out work.avalon_slave.Request;
        variable data : in std_logic_vector ) is
    begin

        req.read <= '0';
        req.write <= '1';
        req.address <= address;
        req.writedata <= data;
        wait until falling_edge( clk );
        req.write <= '0';

    end procedure write;

end package body test_avalon_slave;
