library ieee;
use ieee.std_logic_1164.all;
library i2c;
library vunit_lib;
context vunit_lib.vunit_context;
entity scl_generator_tb is
generic (
runner_cfg : string);
end entity scl_generator_tb;
architecture tb of scl_generator_tb is
signal clk : std_logic := '0';
constant CLK_PERIOD : time := 10 ns;
signal rst_n : std_logic := '0';
signal scl : std_logic := 'H';
signal slave_scl : std_logic;
signal scl_rising : std_logic := '0';
signal scl_falling : std_logic := '0';
signal scl_enable : std_logic := '0';
signal gen_continuous, gen_rising, gen_falling : std_logic := '0';
signal cannot_comply : std_logic;
signal stable_cannot_comply : std_logic := '1';
constant DELAY : natural := 5;
signal one : std_logic := '1';
signal zero : std_logic := '0';
begin -- architecture tb
clk <= not clk after CLK_PERIOD/2;
rst_n <= '1' after 2*CLK_PERIOD;
scl <= 'H';
scl <= '0' when scl_enable = '1' else 'Z';
slave_scl <= '1' when scl = 'H' else 'Z';
slave_scl <= scl;
cannot_comply_stable: check_stable(clk, stable_cannot_comply, one, zero, cannot_comply);
uut: entity i2c.scl_generator
generic map (
MIN_STABLE_CYCLES => DELAY)
port map (
clk_i => clk,
rst_in => rst_n,
scl_i => slave_scl,
scl_rising_i => scl_rising,
scl_falling_i => scl_falling,
gen_continuous_i => gen_continuous,
gen_rising_i => gen_rising,
gen_falling_i => gen_falling,
scl_enable_o => scl_enable,
cannot_comply_o => cannot_comply);
main: process is
procedure wait_delay(constant delay : in integer) is
begin -- procedure wait_delay
for i in 0 to delay loop
wait until falling_edge(clk);
end loop; -- i
wait until falling_edge(clk);
end procedure wait_delay;
procedure req_clear is
begin -- procedure req_rising
gen_falling <= '0';
gen_continuous <= '0';
gen_rising <= '0';
end procedure req_clear;
procedure req_rising is
begin -- procedure req_rising
req_clear;
gen_rising <= '1';
end procedure req_rising;
procedure req_falling is
begin -- procedure req_falling
req_clear;
gen_falling <= '1';
end procedure req_falling;
procedure req_continuous is
begin -- procedure req_
req_clear;
gen_continuous <= '1';
end procedure req_continuous;
begin -- process main
wait until rst_n = '1';
wait until falling_edge(clk);
check_equal(scl, 'H', "begin SCL not high");
test_runner_setup(runner, runner_cfg);
while test_suite loop
if run("continuous") then
req_continuous;
for i in 0 to 10 loop
wait_delay(DELAY);
check_equal(scl, '0');
wait_delay(DELAY);
check_equal(scl, 'H');
end loop; -- i
elsif run("falling") then
req_falling;
wait_delay(DELAY);
check_equal(scl, '0');
req_clear;
for i in 0 to 10 loop
check_equal(scl, '0');
end loop; -- i
elsif run("falling_rising") then
req_falling;
wait_delay(DELAY);
check_equal(scl, '0');
req_rising;
wait_delay(DELAY);
req_clear;
for i in 0 to 10 loop
check_equal(scl, 'H');
end loop; -- i
elsif run("continuous_rising") then
req_continuous;
for i in 0 to 5 loop
wait_delay(DELAY - 1);
report "Hi" & std_logic'image(scl);
end loop; -- i
check_equal(scl, '0');
req_rising;
wait_delay(DELAY);
check_equal(scl, 'H');
elsif run("continuous_falling") then
req_continuous;
for i in 0 to 6 loop
wait_delay(DELAY - 1);
end loop; -- i
check_equal(scl, 'H');
req_falling;
wait_delay(DELAY);
check_equal(scl, '0');
elsif run("rising_scl_low") then
scl <= '0'; -- pull down
req_rising;
stable_cannot_comply <= '0';
wait_delay(1);
check_equal(cannot_comply, '1');
elsif run("falling_rising_scl_low") then
req_falling;
wait_delay(DELAY);
scl <= '0'; -- pull down
req_rising;
stable_cannot_comply <= '0';
wait_delay(DELAY);
check_equal(cannot_comply, '1');
check_equal(scl_enable, '0');
wait_delay(DELAY);
check_equal(scl_enable, '0');
end if;
end loop;
test_runner_cleanup(runner);
end process main;
set_scl_rising: process is
begin -- process scl_rising
wait until rising_edge(scl);
scl_rising <= '1';
wait until rising_edge(clk);
wait until falling_edge(clk);
scl_rising <= '0';
end process set_scl_rising;
set_scl_falling: process is
begin -- process scl_rising
wait until falling_edge(scl);
scl_falling <= '1';
wait until rising_edge(clk);
wait until falling_edge(clk);
scl_falling <= '0';
end process set_scl_falling;
end architecture tb;