library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; entity pullup is port (net_out : out std_logic); end pullup; architecture Behavioral of pullup is begin net_out <= 'H'; end Behavioral; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; use IEEE.std_logic_arith.all; use work.usefuls.all; entity i2cmux_test is end i2cmux_test; architecture behavior of i2cmux_test is -- Component Declaration for the Unit Under Test (UUT) component i2c_mux is generic ( slave_width : integer := 1); port( scl : inout std_logic; sda : inout std_logic; clk : in std_logic; reset : in std_logic; scl_slave : inout std_logic_vector(slave_width - 1 downto 0); sda_slave : inout std_logic_vector(slave_width - 1 downto 0); slave_oe : in std_logic_vector(slave_width - 1 downto 0); transaction : out std_logic; -- keep '1' in the same transaction slave2master : out std_logic); -- M2S => '0', S2M => '1' end component; component pullup is port ( net_out : out std_logic); end component; --clock signal sysclk : std_logic; signal reset : std_logic := '1'; -- Clock period definitions constant sysclk_f : time := (1000.0/60) * 1ns; -- 60MHz constant sysclk_h : time := sysclk_f / 2; constant i2cclk_f : time := 200ns; -- 5 MHz constant i2cclk_h : time := i2cclk_f / 2; constant i2cclk_q : time := i2cclk_f / 4; signal scl_master : std_logic := 'Z'; signal sda_master : std_logic := 'Z'; signal scl_slave : std_logic := 'Z'; signal sda_slave : std_logic := 'Z'; signal address_rw : std_logic_vector(7 downto 0) := conv_std_logic_vector(16#3D#, 8); signal i2c_data : std_logic_vector(7 downto 0) := conv_std_logic_vector(16#A5#, 8); begin -- Instantiate the Unit Under Test (UUT) uut: i2c_mux generic map( slave_width => 1) port map ( scl => scl_master, sda => sda_master, clk => sysclk, reset => reset, scl_slave(0) => scl_slave, sda_slave(0) => sda_slave, slave_oe(0) => '1' --transaction, --slave2master, -- M2S => '0', S2M => '1'); ); pullup_scl_master : pullup port map ( net_out => scl_master); pullup_sda_master : pullup port map ( net_out => sda_master); pullup_scl_slave : pullup port map ( net_out => scl_slave); pullup_sda_slave : pullup port map ( net_out => sda_slave); -- Clock process definitions process_clk: process begin sysclk <= '0'; wait for sysclk_h; sysclk <= '1'; wait for sysclk_h; end process; -- Stimulus process process_stim: process begin -- START cond. -- hold reset state for 1000 clk cycles. wait for 0.1us; -- insert stimulus here reset <= '0'; wait for 0.1us; -- start_cond sda_master <= '0'; -- address & R/-W for i in address_rw'range loop wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; if address_rw(i) = '0' then sda_master <= '0'; else sda_master <= 'Z'; end if; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; end loop; -- ack from slave to master wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; sda_slave <= '0'; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; -- data from slave to master for i in i2c_data'range loop wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; if i2c_data(i) = '0' then sda_slave <= '0'; else sda_slave <= 'Z'; end if; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; end loop; -- ack from master to slave wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; sda_slave <= 'Z'; sda_master <= '0'; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; -- data from slave to master for i in i2c_data'range loop wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; sda_master <= 'Z'; if i2c_data(i) = '0' then sda_slave <= '0'; else sda_slave <= 'Z'; end if; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; end loop; -- nack from master to slave wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; sda_slave <= 'Z'; sda_master <= 'Z'; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; -- stop_cond sda_master <= '0'; wait for i2cclk_q; sda_master <= 'Z'; wait for 2us; address_rw(0) <= '0'; -- start_cond sda_master <= '0'; -- address & R/-W for i in address_rw'range loop wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; if address_rw(i) = '0' then sda_master <= '0'; else sda_master <= 'Z'; end if; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; end loop; -- ack from slave to master wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; sda_slave <= '0'; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; -- data from master to slave for i in i2c_data'range loop wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; sda_slave <= 'Z'; if i2c_data(i) = '0' then sda_master <= '0'; else sda_master <= 'Z'; end if; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; end loop; -- ack from slave to master wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; sda_master <= 'Z'; sda_slave <= '0'; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; -- data from master to slave for i in i2c_data'range loop wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; sda_slave <= 'Z'; if i2c_data(i) = '0' then sda_master <= '0'; else sda_master <= 'Z'; end if; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; end loop; -- nack from slave to master wait for i2cclk_q; scl_master <= '0'; wait for i2cclk_q; sda_master <= 'Z'; sda_slave <= 'Z'; wait for i2cclk_q; scl_master <= 'Z'; wait for i2cclk_q; -- stop_cond sda_master <= '0'; wait for i2cclk_q; sda_master <= 'Z'; wait; end process; end;