~ruther/vhdl-i2c

a284ba60d2d7e4b341b5b54e3812ce946d3f5d62 — Rutherther 1 year, 3 months ago d770543
tests: add test for address detector
1 files changed, 376 insertions(+), 0 deletions(-)

A tb/i2c/address_detector_tb.vhd
A tb/i2c/address_detector_tb.vhd => tb/i2c/address_detector_tb.vhd +376 -0
@@ 0,0 1,376 @@
library ieee;
use ieee.std_logic_1164.all;

library vunit_lib;
context vunit_lib.vunit_context;

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 := 10 ns;

  signal rst_n : std_logic := '0';

  signal scl_pulse : std_logic;
  signal sda : std_logic;

  signal start : std_logic;

  signal address : std_logic_vector(6 downto 0);
  signal success, fail, rw : std_logic;

  shared variable trigger_scl_pulse : std_logic := '0';
  shared variable trigger_start : std_logic := '0';
begin  -- architecture tb

  clk <= not clk after CLK_PERIOD / 2;
  rst_n <= '1' after 2 * CLK_PERIOD;

  uut : entity i2c.address_detector
    port map (
      clk_i       => clk,
      rst_in      => rst_n,
      address_i   => address,
      scl_pulse_i => scl_pulse,
      sda_i       => sda,
      start_i     => start,
      rw_o        => rw,
      success_o   => success,
      fail_o      => fail);

  do_trigger_scl_pulse: process is
  begin  -- process trigger_scl_pulse
    wait until rising_edge(clk);
    if trigger_scl_pulse = '1' then
        scl_pulse <= '1';
        wait until rising_edge(clk);
        wait for 0 ns;
        scl_pulse <= '0';
        trigger_scl_pulse := '0';
    end if;
  end process do_trigger_scl_pulse;

  do_trigger_start: process is
  begin  -- process trigger_scl_pulse
    wait until rising_edge(clk);
    if trigger_start = '1' then
        start <= '1';
        wait until rising_edge(clk);
        wait for 0 ns;
        start <= '0';
        trigger_start := '0';
    end if;
  end process do_trigger_start;

  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');

        trigger_start := '1';
        wait for 0 ns;
        wait until falling_edge(start);

        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= 'X'; -- rw
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        check_equal(success, '1');
        check_equal(fail, '0');

      elsif run("read") then
        address <= "1100011";
        check_equal(success, '0');
        check_equal(fail, '0');

        trigger_start := '1';
        wait until falling_edge(start);
        sda <= '1';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '1'; -- rw
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);

        check_equal(rw, '1');
      elsif run("write") then
        address <= "1100011";
        check_equal(success, '0');
        check_equal(fail, '0');

        trigger_start := '1';
        wait until falling_edge(start);
        sda <= '1';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);
        sda <= '0'; -- rw
        trigger_scl_pulse := '1';
        wait until falling_edge(scl_pulse);

        check_equal(rw, '0');
      elsif run("not_matching") then
        address <= "1110011";
        check_equal(success, '0');
        check_equal(fail, '0');

        trigger_start := '1';
        wait until falling_edge(start);
        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);
        sda <= '1'; -- rw
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);

        check_equal(success, '0');
        check_equal(fail, '1');
      elsif run("not_matching_then_matching") then
        address <= "1110011";
        check_equal(success, '0');
        check_equal(fail, '0');

        trigger_start := '1';
        wait until falling_edge(start);
        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);
        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);
        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);
        sda <= '1'; -- rw
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '1');
        wait until falling_edge(scl_pulse);

        check_equal(success, '0');
        check_equal(fail, '1');

        wait until falling_edge(clk);

        trigger_start := '1';

        address <= "1100011";
        check_equal(success, '0');
        check_equal(fail, '1');

        trigger_start := '1';
        wait until falling_edge(start);

        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '0';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= '1';
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        sda <= 'X'; -- rw
        trigger_scl_pulse := '1';
        check_equal(success, '0');
        check_equal(fail, '0');
        wait until falling_edge(scl_pulse);

        check_equal(success, '1');
        check_equal(fail, '0');
      end if;
    end loop;

    test_runner_cleanup(runner);
  end process main;

end architecture tb;

Do not follow this link