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;