From 4b483a5b6e72335f720515624f3a1903b771bd6a Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 29 Dec 2023 10:56:06 +0100 Subject: [PATCH] tests: add startstop condition detector tests, fix behavior --- src/i2c/startstop_condition_detector.vhd | 30 +++--- tb/i2c/startstop_condition_detector_tb.vhd | 116 +++++++++++++++++++++ 2 files changed, 133 insertions(+), 13 deletions(-) create mode 100644 tb/i2c/startstop_condition_detector_tb.vhd diff --git a/src/i2c/startstop_condition_detector.vhd b/src/i2c/startstop_condition_detector.vhd index 1c18cbf..2bd7b85 100644 --- a/src/i2c/startstop_condition_detector.vhd +++ b/src/i2c/startstop_condition_detector.vhd @@ -13,28 +13,32 @@ entity startstop_condition_detector is end entity startstop_condition_detector; architecture a1 of startstop_condition_detector is - signal reg_start, reg_stop : std_logic; - signal next_start, next_stop : std_logic; + -- signal curr_start, curr_stop : std_logic; + -- signal next_start, next_stop : std_logic; - signal reg_prev_sda : std_logic; - signal next_prev_sda : std_logic; + signal curr_prev_sda, curr_prev_scl : std_logic; + signal next_prev_sda, next_prev_scl : std_logic; begin -- architecture a1 + -- start_o <= curr_start; + -- stop_o <= curr_stop; next_prev_sda <= sda_i; + next_prev_scl <= scl_i; - next_start <= '0' when reg_start = '1' else - '1' when reg_prev_sda = '0' and sda_i = '1' and scl_i = '1' else - '0'; - next_stop <= '0' when reg_stop = '1' else - '1' when reg_prev_sda = '1' and sda_i = '0' and scl_i = '1' else - '0'; + start_o <= -- '0' when curr_start = '1' else + '1' when curr_prev_sda = '1' and sda_i = '0' and curr_prev_scl = '1' and scl_i = '1' else + '0'; + stop_o <= -- '0' when curr_stop = '1' else + '1' when curr_prev_sda = '0' and sda_i = '1' and curr_prev_scl = '1' and scl_i = '1' else + '0'; set_next: process (clk_i) is begin -- process set_next if rising_edge(clk_i) then -- rising clock edge - reg_prev_sda <= next_prev_sda; - reg_start <= next_start; - reg_stop <= next_stop; + curr_prev_sda <= next_prev_sda; + curr_prev_scl <= next_prev_scl; + -- curr_start <= next_start; + -- curr_stop <= next_stop; end if; end process set_next; diff --git a/tb/i2c/startstop_condition_detector_tb.vhd b/tb/i2c/startstop_condition_detector_tb.vhd new file mode 100644 index 0000000..35f69bf --- /dev/null +++ b/tb/i2c/startstop_condition_detector_tb.vhd @@ -0,0 +1,116 @@ +library ieee; +use ieee.std_logic_1164.all; + +library i2c; + +library vunit_lib; +context vunit_lib.vunit_context; + +entity startstop_condition_detector is + + generic ( + runner_cfg : string); + +end entity startstop_condition_detector; + +architecture tb of startstop_condition_detector is + signal clk : std_logic := '0'; + constant CLK_PERIOD : time := 10 ns; + + signal rst_n : std_logic := '0'; + + signal sda, scl : std_logic; + + signal start, stop : std_logic; +begin -- architecture tb + uut: entity i2c.startstop_condition_detector + port map ( + clk_i => clk, + sda_i => sda, + scl_i => scl, + start_o => start, + stop_o => stop); + + clk <= not clk after CLK_PERIOD / 2; + rst_n <= '1' after 2 * CLK_PERIOD; + + main: process is + begin -- process + sda <= '1'; + wait until rising_edge(clk); + scl <= '1'; + 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("scl_high_start_stop") then + -- start + sda <= '0'; + wait until rising_edge(clk); + check_equal(start, '1'); + check_equal(stop, '0'); + sda <= '1'; + wait until rising_edge(clk); + check_equal(start, '0'); + check_equal(stop, '1'); + sda <= '1'; + wait until rising_edge(clk); + check_equal(start, '0'); + check_equal(stop, '0'); + sda <= '1'; + elsif run("scl_low") then + scl <= '0'; + sda <= '0'; + wait until falling_edge(clk); + check_equal(start, '0'); + check_equal(stop, '0'); + sda <= '1'; + wait until falling_edge(clk); + check_equal(start, '0'); + check_equal(stop, '0'); + sda <= '1'; + wait until falling_edge(clk); + check_equal(start, '0'); + check_equal(stop, '0'); + sda <= '1'; + elsif run("scl_low_then_high") then + scl <= '0'; + sda <= '0'; + wait until rising_edge(clk); + check_equal(start, '0'); + check_equal(stop, '0'); + sda <= '1'; + wait until rising_edge(clk); + check_equal(start, '0'); + check_equal(stop, '0'); + sda <= '1'; + wait until rising_edge(clk); + check_equal(start, '0'); + check_equal(stop, '0'); + sda <= '1'; + wait until rising_edge(clk); + scl <= '1'; + wait until rising_edge(clk); + sda <= '0'; + wait until rising_edge(clk); + check_equal(start, '1'); + check_equal(stop, '0'); + sda <= '1'; + wait until rising_edge(clk); + check_equal(start, '0'); + check_equal(stop, '1'); + sda <= '1'; + wait until rising_edge(clk); + check_equal(start, '0'); + check_equal(stop, '0'); + sda <= '1'; + end if; + end loop; + + test_runner_cleanup(runner); + end process main; + +end architecture tb; -- 2.48.1