~ruther/vhdl-i2c

9424c7dd54ee182e7d5b476d8e4bb49650fe05ec — Rutherther 1 year, 6 months ago b1f7048
refactor: use 'H' std_logic state instead of custom pull up type
M src/utils/open_drain_buffer.vhd => src/utils/open_drain_buffer.vhd +2 -1
@@ 20,6 20,7 @@ begin  -- architecture a1
  pad_io <= '0' when enable_i = '1' else
            'Z';

  state_o <= pad_io;
  state_o <= '1' when pad_io = 'H' else
             pad_io;

end architecture a1;

M tb/i2c/slave_tb.vhd => tb/i2c/slave_tb.vhd +15 -4
@@ 23,12 23,14 @@ architecture tb of slave_tb is

  signal sda_override : std_logic := '0';
  signal slave_sda_enable : std_logic;
  signal slave_sda : std_logic;

  signal address : std_logic_vector(6 downto 0);

  signal not_scl : std_logic;
  signal scl_override : std_logic := '0';
  signal slave_scl_enable : std_logic;
  signal slave_scl : std_logic;

  signal dev_busy, bus_busy : std_logic;
  signal err_noack : std_logic;


@@ 46,8 48,17 @@ begin  -- architecture tb
  clk <= not clk after CLK_PERIOD / 2;
  rst_n <= '1' after 2 * CLK_PERIOD;

  scl <= not scl_override and not slave_scl_enable;
  sda <= not sda_override and not slave_sda_enable;
  sda <= 'H';
  scl <= 'H';

  sda <= '0' when sda_override = '1' else 'Z';
  scl <= '0' when scl_override = '1' else 'Z';

  sda <= '0' when slave_sda_enable = '1' else 'Z';
  scl <= '0' when slave_scl_enable = '1' else 'Z';

  slave_sda <= '1' when sda = 'H' else sda;
  slave_scl <= '1' when scl = 'H' else scl;

  not_scl <= not scl;



@@ 76,8 87,8 @@ begin  -- architecture tb
      rw_o           => rw,
      dev_busy_o     => dev_busy,
      bus_busy_o     => bus_busy,
      sda_i          => sda,
      scl_i          => scl,
      sda_i          => slave_sda,
      scl_i          => slave_scl,
      sda_enable_o   => slave_sda_enable,
      scl_enable_o   => slave_scl_enable);


M tb/i2c/tb_i2c_master_pkg.vhd => tb/i2c/tb_i2c_master_pkg.vhd +11 -7
@@ 62,7 62,7 @@ package body tb_i2c_master_pkg is

  begin  -- procedure transmit
    check_equal(scl_override, '0', "Cannot start sending when scl is not in default state (1).", failure);
    check_equal(scl, '1', "Cannot start sending when scl is not in default state (1). Seems like the slave is clock stretching. This is not supported by transmit since data have to be supplied or read.", failure);
    check_equal(scl, 'H', "Cannot start sending when scl is not in default state (1). Seems like the slave is clock stretching. This is not supported by transmit since data have to be supplied or read.", failure);

    scl_fall(scl_override);



@@ 77,7 77,7 @@ package body tb_i2c_master_pkg is
    if exp_ack = '1' then
      check_equal(sda, '0', "No acknowledge");
    elsif exp_ack = '0' then
      check_equal(sda, '1', "There was acknowledge even though there shouldn't have been");
      check_equal(sda, 'H', "There was acknowledge even though there shouldn't have been");
    end if;

    if stop_condition = '1' then


@@ 100,7 100,7 @@ package body tb_i2c_master_pkg is

  begin  -- procedure transmit
    check_equal(scl_override, '0', "Cannot start receiving when scl is not in default state (1).", failure);
    check_equal(scl, '1', "Cannot start receiving when scl is not in default state (1). Seems like the slave is clock stretching. This is not supported by transmit since data have to be supplied or read.", failure);
    check_equal(scl, 'H', "Cannot start receiving when scl is not in default state (1). Seems like the slave is clock stretching. This is not supported by transmit since data have to be supplied or read.", failure);

    scl_fall(scl_override);
    sda_override <= '0';


@@ 108,7 108,11 @@ package body tb_i2c_master_pkg is
    -- data
    for i in 7 downto 0 loop
      scl_rise(scl_override);
      check_equal(sda, exp_data(i), "Received data (sda) not as expected");
      if exp_data(i) = '1' then
        check(sda = '1' or sda = 'H', result("Received data (sda) not as expected."));
      else
        check(sda = '0' or sda = 'L', result("Received data (sda) not as expected."));
      end if;
      scl_fall(scl_override);
    end loop;  -- i



@@ 136,7 140,7 @@ package body tb_i2c_master_pkg is
    signal sda_override : inout std_logic;
    constant exp_ack : in std_logic := '1') is
  begin
    if scl = '1' and sda = '0' then
    if scl = 'H' and sda = '0' then
      scl_fall(scl_override);
    end if;



@@ 148,8 152,8 @@ package body tb_i2c_master_pkg is
      scl_rise(scl_override);
    end if;

    check_equal(sda, '1', "Cannot start sending when sda is not in default state (1).", failure);
    check_equal(scl, '1', "Cannot start sending when scl is not in default state (1).", failure);
    check_equal(sda, 'H', "Cannot start sending when sda is not in default state (1).", failure);
    check_equal(scl, 'H', "Cannot start sending when scl is not in default state (1).", failure);

    -- start condition
    sda_fall(sda_override, '0');

M tb/i2c/tb_i2c_pkg.vhd => tb/i2c/tb_i2c_pkg.vhd +2 -23
@@ 8,15 8,8 @@ context vunit_lib.vunit_context;
use work.tb_pkg.all;

package tb_i2c_pkg is
  type std_logic_arr_t is array (natural range <>) of std_logic;
  function f_resolve_pull_up (
    constant signals : std_logic_arr_t)
    return std_logic;

  subtype pull_up_std_logic is f_resolve_pull_up std_logic;

  signal sda : pull_up_std_logic;
  signal scl : pull_up_std_logic;
  signal sda : std_logic;
  signal scl : std_logic;

  signal tx_ready : std_logic;
  signal rx_valid : std_logic;


@@ 51,20 44,6 @@ package tb_i2c_pkg is
end package tb_i2c_pkg;

package body tb_i2c_pkg is
  function f_resolve_pull_up (
    constant signals : std_logic_arr_t)
    return std_logic is
    variable sig : std_logic := '1';
  begin
    for i in signals'range loop
      if signals(i) = '0' then
        sig := '0';
      end if;
    end loop;  -- i

    return sig;
  end function f_resolve_pull_up;

  procedure scl_fall (
    signal scl_override : inout std_logic) is
  begin  -- procedure scl_rise

M tb/mcu_slave/counter_tb.vhd => tb/mcu_slave/counter_tb.vhd +6 -2
@@ 49,8 49,12 @@ begin  -- architecture tb
      scl_io      => scl
    );

  sda <= not sda_override;
  scl <= not scl_override;
  -- pull up
  sda <= 'H';
  scl <= 'H';

  sda <= '0' when sda_override = '1' else 'Z';
  scl <= '0' when scl_override = '1' else 'Z';
  not_scl <= not scl;

  clk <= not clk after CLK_PERIOD / 2;