@@ 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;
@@ 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;