library ieee;
use ieee.std_logic_1164.all;
library vunit_lib;
context vunit_lib.vunit_context;
context vunit_lib.com_context;
use work.i2c_bus_pkg;
library i2c;
entity address_detector_tb is
generic (
runner_cfg : string);
end entity address_detector_tb;
architecture tb of address_detector_tb is
signal clk : std_logic := '0';
constant CLK_PERIOD : time := 1 us;
constant SCL_FREQ : real := 100_000.0;
signal rst_n : std_logic := '0';
signal dev_sda : std_logic;
signal scl_rising, scl_falling : std_logic := '0';
signal scl : std_logic;
signal sda : std_logic;
signal start : std_logic;
signal address : std_logic_vector(6 downto 0);
signal success, fail, rw : std_logic;
signal sda_enable : std_logic;
signal one : std_logic := '1';
constant bus_inst_name : string := "i2c_bus_mod";
constant bus_actor : actor_t := i2c_bus_pkg.get_actor(bus_inst_name);
constant monitor_inst_name : string := "monitor";
constant monitor_actor : actor_t := i2c_bus_pkg.get_actor(monitor_inst_name);
begin -- architecture tb
clk <= not clk after CLK_PERIOD / 2;
rst_n <= '1' after 2 * CLK_PERIOD;
sda <= 'H';
scl <= 'H';
sda <= '0' when sda_enable = '1' else 'Z';
dev_sda <= '1' when sda = 'H' else sda;
uut : entity i2c.address_detector
port map (
clk_i => clk,
rst_in => rst_n,
store_address_i => '1',
address_i => address,
scl_rising => scl_rising,
scl_falling_delayed_i => scl_falling,
sda_i => dev_sda,
sda_enable_o => sda_enable,
start_i => start,
rw_o => rw,
success_o => success,
fail_o => fail);
bus_mod : entity work.i2c_bus_mod
generic map (
inst_name => bus_inst_name,
default_scl_freq => SCL_FREQ)
port map (
sda_io => sda,
scl_io => scl,
clk_i => clk,
scl_falling_o => scl_falling,
scl_rising_o => scl_rising);
-- monitor_mod : entity work.i2c_bus_mod
-- generic map (
-- inst_name => monitor_inst_name,
-- default_scl_freq => SCL_FREQ)
-- port map (
-- sda_io => sda,
-- scl_io => scl,
-- clk_i => '0',
-- scl_falling_o => open,
-- scl_rising_o => open);
main: process is
begin -- process main
wait until rst_n = '1';
wait until falling_edge(clk);
test_runner_setup(runner, runner_cfg);
set_stop_level(failure);
while test_suite loop
if run("matching") then
address <= "1100011";
check_equal(success, '0');
check_equal(fail, '0');
i2c_bus_pkg.gen_start_cond(net, 1 ms, bus_actor);
i2c_bus_pkg.send_data_and_clock(net, "11000110", 1 ms, bus_actor);
i2c_bus_pkg.check_ack_gen_clock(net, '1', 1 ms, bus_actor);
start <= '1';
wait until falling_edge(clk);
start <= '0';
i2c_bus_pkg.wait_until_idle(net, bus_actor);
check_equal(success, '1');
check_equal(fail, '0');
i2c_bus_pkg.gen_stop_cond(net, 1 ms, bus_actor);
i2c_bus_pkg.wait_until_idle(net, bus_actor);
elsif run("read") then
address <= "1100011";
check_equal(success, '0');
check_equal(fail, '0');
i2c_bus_pkg.gen_start_cond(net, 1 ms, bus_actor);
i2c_bus_pkg.send_data_and_clock(net, "11000111", 1 ms, bus_actor);
i2c_bus_pkg.check_ack_gen_clock(net, '1', 1 ms, bus_actor);
start <= '1';
wait until falling_edge(clk);
start <= '0';
i2c_bus_pkg.wait_until_idle(net, bus_actor);
check_equal(success, '1');
check_equal(fail, '0');
check_equal(rw, '1');
elsif run("write") then
address <= "1100011";
check_equal(success, '0');
check_equal(fail, '0');
i2c_bus_pkg.gen_start_cond(net, 1 ms, bus_actor);
i2c_bus_pkg.send_data_and_clock(net, "11000110", 1 ms, bus_actor);
i2c_bus_pkg.check_ack_gen_clock(net, '1', 1 ms, bus_actor);
start <= '1';
wait until falling_edge(clk);
start <= '0';
i2c_bus_pkg.wait_until_idle(net, bus_actor);
check_equal(success, '1');
check_equal(fail, '0');
check_equal(rw, '0');
elsif run("not_matching") then
address <= "1100011";
check_equal(success, '0');
check_equal(fail, '0');
i2c_bus_pkg.gen_start_cond(net, 1 ms, bus_actor);
i2c_bus_pkg.send_data_and_clock(net, "11100011", 1 ms, bus_actor);
i2c_bus_pkg.check_ack_gen_clock(net, '0', 1 ms, bus_actor);
start <= '1';
wait until falling_edge(clk);
start <= '0';
i2c_bus_pkg.wait_until_idle(net, bus_actor);
check_equal(success, '0');
check_equal(fail, '1');
elsif run("not_matching_then_matching") then
address <= "1100011";
check_equal(success, '0');
check_equal(fail, '0');
i2c_bus_pkg.gen_start_cond(net, 1 ms, bus_actor);
i2c_bus_pkg.send_data_and_clock(net, "11100011", 1 ms, bus_actor);
i2c_bus_pkg.check_ack_gen_clock(net, '0', 1 ms, bus_actor);
i2c_bus_pkg.gen_stop_cond(net, 1 ms, bus_actor);
start <= '1';
wait until rising_edge(clk);
wait until falling_edge(clk);
start <= '0';
i2c_bus_pkg.wait_until_idle(net, bus_actor);
check_equal(success, '0');
check_equal(fail, '1');
i2c_bus_pkg.gen_start_cond(net, 1 ms, bus_actor);
i2c_bus_pkg.send_data_and_clock(net, "11000110", 1 ms, bus_actor);
i2c_bus_pkg.check_ack_gen_clock(net, '1', 1 ms, bus_actor);
i2c_bus_pkg.gen_stop_cond(net, 1 ms, bus_actor);
start <= '1';
wait until rising_edge(clk);
wait until falling_edge(clk);
start <= '0';
i2c_bus_pkg.wait_until_idle(net, bus_actor);
check_equal(success, '1');
check_equal(fail, '0');
end if;
end loop;
test_runner_cleanup(runner);
end process main;
test_runner_watchdog(runner, 10 ms);
end architecture tb;