~ruther/vhdl-i2c

b9b3fcea757ffdf6e98f0bb550606e38642635e6 — Rutherther 1 year, 3 months ago 0f8e8a5
chore: get rid of "pulse" from scl names
M src/i2c/address_detector.vhd => src/i2c/address_detector.vhd +5 -5
@@ 9,7 9,7 @@ entity address_detector is
    clk_i       : in  std_logic;        -- Input clock
    rst_in      : in  std_logic;        -- Reset the detection
    address_i   : in  std_logic_vector(6 downto 0);
    scl_pulse_i : in  std_logic;
    scl_rising : in  std_logic;
    scl_falling_delayed_i : in  std_logic;
    sda_enable_o : out std_logic;
    sda_i      : in  std_logic;   -- The data that could contain the address


@@ 42,14 42,14 @@ begin  -- architecture a1
  success_o <= '1' when curr_state = MATCH else '0';
  rw_o <= curr_read_rw when curr_state = MATCH else '0';

  next_read_rw <= sda_i when scl_pulse_i = '1' and curr_index = 7 else
  next_read_rw <= sda_i when scl_rising = '1' and curr_index = 7 else
                  curr_read_rw;

  next_index <= (curr_index + 1) when curr_state = CHECKING and scl_pulse_i = '1' and curr_index < 7 else
  next_index <= (curr_index + 1) when curr_state = CHECKING and scl_rising = '1' and curr_index < 7 else
                curr_index when curr_state = CHECKING else
                0;

  mismatch <= '1' when curr_index <= 6 and address_i(6 - curr_index) /= sda_i and scl_pulse_i = '1' else '0';
  mismatch <= '1' when curr_index <= 6 and address_i(6 - curr_index) /= sda_i and scl_rising = '1' else '0';

  sda_enable_o <= '1' when curr_state = ACK_ON else '0';



@@ 64,7 64,7 @@ begin  -- architecture a1
    if curr_state = CHECKING then
      if mismatch = '1' then
        next_state <= FAIL;
      elsif curr_index = 7 and scl_pulse_i = '1' then
      elsif curr_index = 7 and scl_rising = '1' then
        next_state <= ACK;
      end if;
    end if;

M src/i2c/rx.vhd => src/i2c/rx.vhd +5 -5
@@ 1,5 1,5 @@
-- i2c interface
    -- scl_pulse_i
    -- scl_rising
    -- scl_stretch_o
    -- sda_o



@@ 26,7 26,7 @@ entity rx is
    start_read_i   : in  std_logic;     -- Start reading with next scl_pulse
    rst_i2c_i      : in  std_logic;     -- Reset rx circuitry

    scl_pulse_i    : in  std_logic;     -- SCL rising edge pulse
    scl_rising    : in  std_logic;     -- SCL rising edge pulse
    scl_falling_delayed_i    : in  std_logic;     -- SCL rising edge pulse
    scl_stretch_o  : out std_logic;     -- Stretch SCL (keep SCL 0)
    sda_i          : in  std_logic;     -- SDA data line state


@@ 96,7 96,7 @@ begin  -- architecture a1
        start_receive := '1';
      end if;
    elsif curr_state = RECEIVING then
      if curr_rx_buffer(7) = '1' and scl_pulse_i = '1' then
      if curr_rx_buffer(7) = '1' and scl_rising = '1' then
        next_state <= ACK;
      end if;
    elsif curr_state = ACK then


@@ 132,7 132,7 @@ begin  -- architecture a1

  curr_receiving <= '1' when curr_state = RECEIVING else '0';

  next_saving <= '1' when curr_rx_buffer(7) = '1' and scl_pulse_i = '1' and curr_state = RECEIVING else
  next_saving <= '1' when curr_rx_buffer(7) = '1' and scl_rising = '1' and curr_state = RECEIVING else
                 '1' when curr_saving = '1' and curr_read_data_filled = '1' and confirm_read_i = '0' else
                 '0';



@@ 149,7 149,7 @@ begin  -- architecture a1
                           '1' when curr_saving = '1' else
                           '0';

  next_rx_buffer <= curr_rx_buffer(6 downto 0) & sda_i when curr_receiving = '1' and scl_pulse_i = '1' else
  next_rx_buffer <= curr_rx_buffer(6 downto 0) & sda_i when curr_receiving = '1' and scl_rising = '1' else
                    curr_rx_buffer when curr_receiving = '1' else
                    curr_rx_buffer when curr_saving = '1' and confirm_read_i = '0' else
                    "00000001";

M src/i2c/slave.vhd => src/i2c/slave.vhd +7 -7
@@ 50,7 50,7 @@ end entity slave;
architecture a1 of slave is
  signal sync_sda, sync_scl                  : std_logic;
  signal start_condition, stop_condition     : std_logic;
  signal scl_rising_pulse, scl_falling_pulse : std_logic;
  signal scl_rising, scl_falling : std_logic;

  signal transmitting, receiving : std_logic;



@@ 94,15 94,15 @@ begin  -- architecture a1
    port map (
      clk_i    => clk_i,
      rst_in   => rst_in,
      signal_i => scl_falling_pulse,
      signal_i => scl_falling,
      signal_o => scl_falling_delayed);

  scl_edge_detector: entity utils.sync_edge_detector
    port map (
      clk_i          => clk_i,
      signal_i       => sync_scl,
      rising_edge_o  => scl_rising_pulse,
      falling_edge_o => scl_falling_pulse);
      rising_edge_o  => scl_rising,
      falling_edge_o => scl_falling);

  sda_sync: entity utils.metastability_filter
    port map (


@@ 132,7 132,7 @@ begin  -- architecture a1
      start_read_i          => receiving,
      generate_ack_i        => generate_ack_i,
      rst_i2c_i             => rst_i2c,
      scl_pulse_i           => scl_rising_pulse,
      scl_rising           => scl_rising,
      scl_falling_delayed_i => scl_falling_delayed,
      scl_stretch_o         => rx_scl_stretch,
      sda_i                 => sda_i,


@@ 150,7 150,7 @@ begin  -- architecture a1
      clear_buffer_i        => tx_clear_buffer_i,
      start_write_i         => transmitting,
      rst_i2c_i             => rst_i2c,
      scl_rising_pulse_i    => scl_rising_pulse,
      scl_rising_i    => scl_rising,
      scl_falling_delayed_i => scl_falling_delayed,
      scl_stretch_o         => tx_scl_stretch,
      sda_i                 => sda_i,


@@ 166,7 166,7 @@ begin  -- architecture a1
      clk_i                 => clk_i,
      rst_in                => rst_in,
      address_i             => address_i,
      scl_pulse_i           => scl_rising_pulse,
      scl_rising           => scl_rising,
      scl_falling_delayed_i => scl_falling_delayed,
      sda_enable_o          => address_detect_sda_enable,
      sda_i                 => sync_sda,

M src/i2c/tx.vhd => src/i2c/tx.vhd +7 -7
@@ 1,6 1,6 @@

-- i2c interface
    -- scl_pulse_i
    -- scl_rising
    -- scl_stretch_o
    -- sda_o



@@ 30,7 30,7 @@ entity tx is
    unexpected_sda_o    : out std_logic;
    noack_o             : out std_logic;

    scl_rising_pulse_i  : in  std_logic;
    scl_rising_i  : in  std_logic;
    scl_falling_delayed_i : in  std_logic;

    scl_stretch_o       : out std_logic;


@@ 80,14 80,14 @@ begin  -- architecture a1
  scl_stretch_o <= '1' when curr_state = WAITING_FOR_DATA else '0';
  ready_o <= ready;
  sda_enable_o <= not tx_buffer(8) when curr_state = SENDING else '0';
  unexpected_sda_o <= '1' when curr_state = SENDING and sda_i /= tx_buffer(8) and scl_rising_pulse_i = '1' else '0';
  noack_o <= '1' when curr_state = ACK and sda_i = '1' and scl_rising_pulse_i = '1' else '0';
  unexpected_sda_o <= '1' when curr_state = SENDING and sda_i /= tx_buffer(8) and scl_rising_i = '1' else '0';
  noack_o <= '1' when curr_state = ACK and sda_i = '1' and scl_rising_i = '1' else '0';

  ready <= '0' when curr_tx_buffers_filled(curr_saving_buffer_index) = '1' or curr_err_noack = '1' else '1';
  tx_buffer <= curr_tx_buffers(curr_tx_buffer_index);
  tx_buffer_filled <= curr_tx_buffers_filled(curr_tx_buffer_index);

  next_scl <= '1' when scl_rising_pulse_i = '1' else
  next_scl <= '1' when scl_rising_i = '1' else
              '0' when scl_falling_delayed_i = '1' else
              curr_scl;



@@ 142,7 142,7 @@ begin  -- architecture a1
        next_state <= ACK;
      end if;
    elsif curr_state = ACK then
      if scl_rising_pulse_i = '1' then
      if scl_rising_i = '1' then
        if start_write_i = '1' then
          override_tx_buffer_filled := curr_tx_buffers_filled(next_tx_buffer_index);
          start_sending := '1';


@@ 159,7 159,7 @@ begin  -- architecture a1
    if start_sending = '1' then
      if override_tx_buffer_filled = '0' and valid_i = '0' then
        next_state <= WAITING_FOR_DATA;
      elsif curr_scl = '0' and scl_rising_pulse_i = '0' then
      elsif curr_scl = '0' and scl_rising_i = '0' then
        next_state <= SENDING;
      else
        next_state <= WAITING_FOR_FALLING_EDGE;

M tb/i2c/address_detector_tb.vhd => tb/i2c/address_detector_tb.vhd +10 -11
@@ 19,10 19,9 @@ architecture tb of address_detector_tb is

  signal rst_n : std_logic := '0';

  signal scl_pulse : std_logic := '0';
  signal scl_falling_pulse : std_logic := '0';
  signal scl_rising : std_logic := '0';
  signal scl_falling : std_logic := '0';
  signal sda : std_logic;
  signal scl : std_logic := '0';

  signal start : std_logic;



@@ 46,8 45,8 @@ begin  -- architecture tb
      clk_i                 => clk,
      rst_in                => rst_n,
      address_i             => address,
      scl_pulse_i           => scl_pulse,
      scl_falling_delayed_i => scl_falling_pulse,
      scl_rising           => scl_rising,
      scl_falling_delayed_i => scl_falling,
      sda_i                 => sda,
      sda_enable_o          => sda_enable,
      start_i               => start,


@@ 59,15 58,15 @@ begin  -- architecture tb
  begin  -- process trigger_scl_pulse
    wait until rising_edge(clk);
    if trigger_scl_pulse = '1' then
        scl_pulse <= '1';
        scl_falling_pulse <= '0';
        scl_rising <= '1';
        scl_falling <= '0';
        wait until rising_edge(clk);
        scl_pulse <= '0';
        scl_rising <= '0';
        wait until rising_edge(clk);
        wait until rising_edge(clk);
        scl_falling_pulse <= '1';
        scl_falling <= '1';
        wait until rising_edge(clk);
        scl_falling_pulse <= '0';
        scl_falling <= '0';
        trigger_scl_pulse := '0';

        wait until rising_edge(clk);


@@ 468,5 467,5 @@ begin  -- architecture tb
    test_runner_cleanup(runner);
  end process main;

  stability_check: check_stable(clk, one, scl_pulse, scl_falling_pulse, sda_enable);
  stability_check: check_stable(clk, one, scl_rising, scl_falling, sda_enable);
end architecture tb;

M tb/i2c/rx_tb.vhd => tb/i2c/rx_tb.vhd +23 -23
@@ 20,7 20,7 @@ architecture a1 of rx_tb is
  signal rst_n : std_logic := '0';

  signal sda : std_logic := '0';
  signal scl_rising_pulse, scl_falling_pulse : std_logic := '0';
  signal scl_rising, scl_falling : std_logic := '0';

  signal start_read : std_logic := '0';
  signal valid, ready : std_logic;


@@ 33,19 33,19 @@ architecture a1 of rx_tb is
  signal one : std_logic := '1';

  procedure trigger_scl_pulse(
    signal scl_rising_pulse : inout std_logic;
    signal scl_falling_pulse : inout std_logic) is
    signal scl_rising : inout std_logic;
    signal scl_falling : inout std_logic) is
  begin  -- procedure trigger_scl_pulse
    scl_rising_pulse <= '0';
    scl_falling_pulse <= '0';
    scl_rising <= '0';
    scl_falling <= '0';
    wait until falling_edge(clk);
    scl_rising_pulse <= '1';
    scl_rising <= '1';
    wait until falling_edge(clk);
    scl_rising_pulse <= '0';
    scl_falling_pulse <= '1';
    scl_rising <= '0';
    scl_falling <= '1';
    wait until falling_edge(clk);
    scl_rising_pulse <= '0';
    scl_falling_pulse <= '0';
    scl_rising <= '0';
    scl_falling <= '0';
  end procedure trigger_scl_pulse;

  procedure transmit (


@@ 54,8 54,8 @@ architecture a1 of rx_tb is
    constant check_ready     : in    std_logic;
    signal start_read        : inout std_logic;
    signal sda               : inout std_logic;
    signal scl_rising_pulse  : inout std_logic;
    signal scl_falling_pulse : inout std_logic) is
    signal scl_rising  : inout std_logic;
    signal scl_falling : inout std_logic) is
  begin  -- procedure a
    start_read <= '1';
    wait until falling_edge(clk);


@@ 72,13 72,13 @@ architecture a1 of rx_tb is
      check(scl_stretch = '0', "Cannot send when stretch is active", failure);

      sda <= data(i);
      trigger_scl_pulse(scl_rising_pulse, scl_falling_pulse);
      trigger_scl_pulse(scl_rising, scl_falling);
    end loop;  -- i

    -- ack
    check_equal(sda_enable, '1');

    trigger_scl_pulse(scl_rising_pulse, scl_falling_pulse);
    trigger_scl_pulse(scl_rising, scl_falling);

    check_equal(sda_enable, '0');
  end procedure transmit;


@@ 90,8 90,8 @@ begin  -- architecture a1
      rst_i2c_i             => '0',
      generate_ack_i        => '1',
      start_read_i          => start_read,
      scl_pulse_i           => scl_rising_pulse,
      scl_falling_delayed_i => scl_falling_pulse,
      scl_rising           => scl_rising,
      scl_falling_delayed_i => scl_falling,
      sda_i                 => sda,
      sda_enable_o          => sda_enable,
      scl_stretch_o         => scl_stretch,


@@ 112,7 112,7 @@ begin  -- architecture a1

    while test_suite loop
      if run("simple") then
        transmit("11010100", '0', '1', start_read, sda, scl_rising_pulse, scl_falling_pulse);
        transmit("11010100", '0', '1', start_read, sda, scl_rising, scl_falling);
        check_equal(valid, '1');
        check_equal(ready, '1');
        check_equal(scl_stretch, '0');


@@ 124,7 124,7 @@ begin  -- architecture a1
        check_equal(valid, '0');
        check_equal(ready, '1');
      elsif run("twice") then
        transmit("11010100", '0', '1', start_read, sda, scl_rising_pulse, scl_falling_pulse);
        transmit("11010100", '0', '1', start_read, sda, scl_rising, scl_falling);
        check_equal(valid, '1');
        check_equal(ready, '1');
        check_equal(scl_stretch, '0');


@@ 135,7 135,7 @@ begin  -- architecture a1
        check_equal(valid, '0');
        check_equal(ready, '1');

        transmit("00111100", '0', '1', start_read, sda, scl_rising_pulse, scl_falling_pulse);
        transmit("00111100", '0', '1', start_read, sda, scl_rising, scl_falling);
        check_equal(valid, '1');
        check_equal(ready, '1');
        check_equal(scl_stretch, '0');


@@ 146,13 146,13 @@ begin  -- architecture a1
        check_equal(valid, '0');
        check_equal(ready, '1');
      elsif run("stretching") then
        transmit("11010100", '0', '1', start_read, sda, scl_rising_pulse, scl_falling_pulse);
        transmit("11010100", '0', '1', start_read, sda, scl_rising, scl_falling);
        check_equal(valid, '1');
        check_equal(ready, '1');
        check_equal(scl_stretch, '0');
        check_equal(read_data, std_logic_vector'("11010100"));

        transmit("10000001", '1', '1', start_read, sda, scl_rising_pulse, scl_falling_pulse);
        transmit("10000001", '1', '1', start_read, sda, scl_rising, scl_falling);
        check_equal(valid, '1');
        check_equal(ready, '0');
        check_equal(scl_stretch, '0');


@@ 185,7 185,7 @@ begin  -- architecture a1
        check_equal(ready, '1');
        check_equal(scl_stretch, '0');

        transmit("00000011", '0', '1', start_read, sda, scl_rising_pulse, scl_falling_pulse);
        transmit("00000011", '0', '1', start_read, sda, scl_rising, scl_falling);
        check_equal(read_data, std_logic_vector'("00000011"));
        check_equal(valid, '1');
        check_equal(ready, '1');


@@ 201,5 201,5 @@ begin  -- architecture a1
    test_runner_cleanup(runner);
  end process;

  stability_check: check_stable(clk, one, scl_rising_pulse, scl_falling_pulse, sda_enable);
  stability_check: check_stable(clk, one, scl_rising, scl_falling, sda_enable);
end architecture a1;

M tb/i2c/tx_tb.vhd => tb/i2c/tx_tb.vhd +36 -36
@@ 22,7 22,7 @@ architecture a1 of tx_tb is
  signal sda : std_logic;
  signal sda_override : std_logic := '0';
  signal sda_enable, scl : std_logic := '0';
  signal scl_rising_pulse, scl_falling_pulse : std_logic := '0';
  signal scl_rising, scl_falling : std_logic := '0';

  signal start_write : std_logic := '0';
  signal valid, ready : std_logic := '0';


@@ 42,24 42,24 @@ architecture a1 of tx_tb is

  procedure trigger_scl_pulse(
    signal scl : inout std_logic;
    signal scl_rising_pulse : inout std_logic;
    signal scl_falling_pulse : inout std_logic) is
    signal scl_rising : inout std_logic;
    signal scl_falling : inout std_logic) is
  begin  -- procedure trigger_scl_pulse
    scl_falling_pulse <= scl;
    scl_rising_pulse <= '0';
    scl_falling <= scl;
    scl_rising <= '0';
    scl <= '0';
    wait until falling_edge(clk);
    scl <= '1';
    scl_falling_pulse <= '0';
    scl_rising_pulse <= '1';
    scl_falling <= '0';
    scl_rising <= '1';
    wait until falling_edge(clk);
    scl_rising_pulse <= '0';
    scl_rising <= '0';
    wait until falling_edge(clk);
    scl <= '0';
    scl_falling_pulse <= '1';
    scl_falling <= '1';
    wait until falling_edge(clk);
    scl_rising_pulse <= '0';
    scl_falling_pulse <= '0';
    scl_rising <= '0';
    scl_falling <= '0';
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);


@@ 67,17 67,17 @@ architecture a1 of tx_tb is

  procedure trigger_scl_rise(
    signal scl : inout std_logic;
    signal scl_rising_pulse : inout std_logic;
    signal scl_falling_pulse : inout std_logic) is
    signal scl_rising : inout std_logic;
    signal scl_falling : inout std_logic) is
  begin  -- procedure trigger_scl_pulse
    check_equal(scl, '0');
    wait until falling_edge(clk);
    scl <= '1';
    scl_rising_pulse <= '1';
    scl_falling_pulse <= '0';
    scl_rising <= '1';
    scl_falling <= '0';
    wait until falling_edge(clk);
    scl_rising_pulse <= '0';
    scl_falling_pulse <= '0';
    scl_rising <= '0';
    scl_falling <= '0';
  end procedure trigger_scl_rise;

  procedure check_received_data (


@@ 86,19 86,19 @@ architecture a1 of tx_tb is
    constant trigger_ack : in std_logic;
    signal sda_override : inout std_logic;
    signal scl : inout std_logic;
    signal scl_rising_pulse : inout std_logic;
    signal scl_falling_pulse : inout std_logic) is
    signal scl_rising : inout std_logic;
    signal scl_falling : inout std_logic) is
  begin
    check(scl_stretch = '0', "Cannot send when stretch is active", failure);
    wait until falling_edge(clk);

    if scl = '1' then
      scl <= '0';
      scl_falling_pulse <= '1';
      scl_rising_pulse <= '0';
      scl_falling <= '1';
      scl_rising <= '0';
      wait until falling_edge(clk);
      scl_falling_pulse <= '0';
      scl_rising_pulse <= '0';
      scl_falling <= '0';
      scl_rising <= '0';
    end if;

    for i in 7 downto 0 loop


@@ 110,7 110,7 @@ architecture a1 of tx_tb is

      check(scl_stretch = '0', "Cannot send when stretch is active", failure);

      trigger_scl_pulse(scl, scl_rising_pulse, scl_falling_pulse);
      trigger_scl_pulse(scl, scl_rising, scl_falling);
    end loop;  -- i

    -- ack


@@ 118,7 118,7 @@ architecture a1 of tx_tb is
      sda_override <= '1';
    end if;

    trigger_scl_pulse(scl, scl_rising_pulse, scl_falling_pulse);
    trigger_scl_pulse(scl, scl_rising, scl_falling);

    if trigger_ack = '1' then
      sda_override <= '0';


@@ 135,8 135,8 @@ begin  -- architecture a1
      clear_buffer_i        => '0',
      noack_o               => noack,
      scl_stretch_o         => scl_stretch,
      scl_rising_pulse_i    => scl_rising_pulse,
      scl_falling_delayed_i => scl_falling_pulse,
      scl_rising_i    => scl_rising,
      scl_falling_delayed_i => scl_falling,
      unexpected_sda_o      => unexpected_sda,
      sda_enable_o          => sda_enable,
      sda_i                 => sda,


@@ 181,7 181,7 @@ begin  -- architecture a1
        start_write <= '1';
        wait until falling_edge(clk);
        valid <= '0';
        check_received_data("11010100", '1', '1', sda_override, scl, scl_rising_pulse, scl_falling_pulse);
        check_received_data("11010100", '1', '1', sda_override, scl, scl_rising, scl_falling);
        check_equal(sda_enable, '0');
      elsif run("twice") then
        valid <= '1';


@@ 195,9 195,9 @@ begin  -- architecture a1
        valid <= '0';
        check_equal(ready, '0');

        check_received_data("11010100", '0', '1', sda_override, scl, scl_rising_pulse, scl_falling_pulse);
        check_received_data("11010100", '0', '1', sda_override, scl, scl_rising, scl_falling);
        wait until falling_edge(clk);
        check_received_data("00101011", '1', '1', sda_override, scl, scl_rising_pulse, scl_falling_pulse);
        check_received_data("00101011", '1', '1', sda_override, scl, scl_rising, scl_falling);
        check_equal(sda_enable, '0');
      elsif run("three") then
        valid <= '1';


@@ 211,15 211,15 @@ begin  -- architecture a1
        valid <= '0';
        check_equal(ready, '0');

        check_received_data("11010100", '0', '1', sda_override,  scl, scl_rising_pulse, scl_falling_pulse);
        check_received_data("11010100", '0', '1', sda_override,  scl, scl_rising, scl_falling);
        wait until falling_edge(clk);
        check_equal(ready, '1');
        write_data <= "00001111";
        valid <= '1';
        wait until falling_edge(clk);
        valid <= '0';
        check_received_data("00101011", '0', '1', sda_override,  scl, scl_rising_pulse, scl_falling_pulse);
        check_received_data("00001111", '1', '1', sda_override,  scl, scl_rising_pulse, scl_falling_pulse);
        check_received_data("00101011", '0', '1', sda_override,  scl, scl_rising, scl_falling);
        check_received_data("00001111", '1', '1', sda_override,  scl, scl_rising, scl_falling);
        check_equal(sda_enable, '0');
      elsif run("stretching") then
        start_write <= '1';


@@ 235,7 235,7 @@ begin  -- architecture a1
        wait until falling_edge(clk);
        valid <= '0';
        check_equal(scl_stretch, '0');
        check_received_data("11001100", '1', '1', sda_override,  scl, scl_rising_pulse, scl_falling_pulse);
        check_received_data("11001100", '1', '1', sda_override,  scl, scl_rising, scl_falling);
      elsif run("no_ack") then
        valid <= '1';
        write_data <= "11010100";


@@ 244,7 244,7 @@ begin  -- architecture a1
        wait until falling_edge(clk);
        valid <= '0';
        check_noerr <= '0'; -- disable no err check
        check_received_data("11010100", '1', '0', sda_override, scl, scl_rising_pulse, scl_falling_pulse);
        check_received_data("11010100", '1', '0', sda_override, scl, scl_rising, scl_falling);
        check_equal(curr_noack, '1');
        check_equal(sda_enable, '0');
      end if;


@@ 255,5 255,5 @@ begin  -- architecture a1

  no_noack_err: check_stable(clk, check_noerr, check_noerr, zero, noack);
  no_sda_unexpected_err: check_stable(clk, check_noerr, check_noerr, zero, unexpected_sda);
  stability_check: check_stable(clk, validate_sda_stable_when_scl_high, scl_rising_pulse, scl_falling_pulse, sda_enable);
  stability_check: check_stable(clk, validate_sda_stable_when_scl_high, scl_rising, scl_falling, sda_enable);
end architecture a1;

Do not follow this link