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', "Wrong cannot comply"); 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', "Wrong cannot comply"); 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;