library ieee;
use ieee.std_logic_1164.all;
library vunit_lib;
-- use vunit_lib.check_pkg.all;
context vunit_lib.vunit_context;
use work.tb_pkg.all;
package tb_i2c_pkg is
signal sda : std_logic := 'H';
signal scl : std_logic := 'H';
signal tx_ready : std_logic;
signal rx_valid : std_logic;
signal rx_data : std_logic_vector(7 downto 0);
procedure scl_fall (
signal scl : inout std_logic);
procedure scl_rise (
signal scl : inout std_logic);
procedure scl_pulse (
signal scl : inout std_logic);
procedure sda_fall (
signal sda : inout std_logic;
constant assert_no_condition : in std_logic := '1');
procedure sda_rise (
signal sda : inout std_logic;
constant assert_no_condition : in std_logic := '1');
procedure tx_write_data (
constant data : in std_logic_vector(7 downto 0);
signal tx_data : inout std_logic_vector(7 downto 0);
signal tx_valid : inout std_logic);
procedure rx_read_data (
constant exp_data : in std_logic_vector(7 downto 0);
signal rx_confirm_read : inout std_logic);
procedure wait_for_start_condition (
constant timeout : in time;
signal scl : in std_logic;
signal sda : in std_logic);
procedure wait_for_stop_condition (
constant timeout : in time;
signal scl : in std_logic;
signal sda : in std_logic);
procedure wait_for_scl_rise (
constant timeout : in time;
signal scl : in std_logic);
procedure wait_for_scl_fall (
constant timeout : in time;
signal scl : in std_logic);
end package tb_i2c_pkg;
package body tb_i2c_pkg is
procedure scl_fall (
signal scl : inout std_logic) is
begin -- procedure scl_rise
scl <= '0';
wait until falling_edge(clk);
wait until falling_edge(clk);
wait until falling_edge(clk);
wait until falling_edge(clk);
end procedure scl_fall;
procedure scl_rise (
signal scl : inout std_logic) is
begin -- procedure scl_rise
wait until falling_edge(clk);
wait until falling_edge(clk);
wait until falling_edge(clk);
scl <= 'Z';
wait until falling_edge(clk);
wait until falling_edge(clk);
wait until falling_edge(clk);
wait until falling_edge(clk);
wait until falling_edge(clk);
wait until falling_edge(clk);
wait until falling_edge(clk);
end procedure scl_rise;
procedure scl_pulse (
signal scl : inout std_logic) is
begin -- procedure scl_rise
scl_rise(scl);
wait until falling_edge(clk);
wait until falling_edge(clk);
scl_fall(scl);
end procedure scl_pulse;
procedure sda_fall (
signal sda : inout std_logic;
constant assert_no_condition : in std_logic := '1') is
begin -- procedure scl_rise
if assert_no_condition = '1' and sda /= '0' then
check_equal(scl, '0', "Cannot change sda as that would trigger start condition.", failure);
end if;
sda <= '0';
wait until falling_edge(clk);
end procedure sda_fall;
procedure sda_rise (
signal sda : inout std_logic;
constant assert_no_condition : in std_logic := '1') is
begin -- procedure scl_rise
if assert_no_condition = '1' and sda /= '0' then
check_equal(scl, '0', "Cannot change sda as that would trigger stop condition.", failure);
end if;
sda <= 'Z';
wait until falling_edge(clk);
end procedure sda_rise;
procedure tx_write_data (
constant data : in std_logic_vector(7 downto 0);
signal tx_data : inout std_logic_vector(7 downto 0);
signal tx_valid : inout std_logic
) is
begin
check_equal(tx_ready, '1', "not ready when trying to write data!");
tx_data <= data;
tx_valid <= '1';
wait until falling_edge(clk);
tx_valid <= '0';
end procedure tx_write_data;
procedure rx_read_data (
constant exp_data : in std_logic_vector(7 downto 0);
signal rx_confirm_read : inout std_logic
) is
begin
check_equal(rx_valid, '1', "not valid when trying to read data!");
check_equal(rx_data, exp_data, "Read rx data not equal to expected");
rx_confirm_read <= '1';
wait until falling_edge(clk);
rx_confirm_read <= '0';
end procedure rx_read_data;
procedure wait_for_start_condition (
constant timeout : in time;
signal scl : in std_logic;
signal sda : in std_logic) is
begin
wait until falling_edge(sda) and scl = 'H' for timeout;
check(sda = '0' and scl = 'H', "Did not get start condition in time.");
end procedure wait_for_start_condition;
procedure wait_for_stop_condition (
constant timeout : in time;
signal scl : in std_logic;
signal sda : in std_logic) is
begin
wait until rising_edge(sda) and scl = 'H' for timeout;
check(sda = 'H' and scl = 'H', "Did not get stop condition in time.");
end procedure wait_for_stop_condition;
procedure wait_for_scl_rise (
constant timeout : in time;
signal scl : in std_logic) is
begin
wait until rising_edge(scl) for timeout;
check_equal(scl, 'H', "Did not get rising scl in time.");
wait until falling_edge(clk);
end procedure wait_for_scl_rise;
procedure wait_for_scl_fall (
constant timeout : in time;
signal scl : in std_logic) is
begin
wait until falling_edge(scl) for timeout;
check_equal(scl, '0', "Did not get falling scl in time.");
wait until falling_edge(clk);
end procedure wait_for_scl_fall;
end package body tb_i2c_pkg;