-- -----------------------------------------------------------------------------
-- Copyright (c) 2013 Benjamin Krill <benjamin@krll.de>
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.
-- -----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity sim_tb is
end sim_tb;

architecture rtl of sim_tb is
	constant CLK_PERIOD     : time := 10 ns;
	signal clk              : std_logic;
	signal rst              : std_logic;
	signal rst_n            : std_logic;

	component i2c_wrapper is
	generic ( prescale : std_logic_vector(15 downto 0) := x"00c8");
	port (
		wb_clk_i  : in    std_logic;
		wb_rst_i  : in    std_logic;
		wb_adr_i  : in    std_logic_vector(15 downto 0);
		wb_dat_i  : in    std_logic_vector(7 downto 0);
		wb_dat_o  : out   std_logic_vector(7 downto 0);
		wb_we_i   : in    std_logic;
		wb_stb_i  : in    std_logic;
		wb_ack_o  : out   std_logic;
		scl_i     : in    std_logic;
		scl_o     : out   std_logic;
		sda_i     : in    std_logic;
		sda_o     : out   std_logic;
		debug     : out   std_logic_vector(3 downto 0)
	);
	end component;

	component i2c_rom is
	port (
		clk    : in    std_logic;
		rst_n  : in    std_logic;
		sda_i  : in    std_logic;
		sda_o  : out   std_logic;
		scl_i  : in    std_logic
	);
	end component;

	signal wb_clk_i  : std_logic;
	signal wb_rst_i  : std_logic;
	signal wb_adr_i  : std_logic_vector(15 downto 0);
	signal wb_dat_i  : std_logic_vector(7 downto 0);
	signal wb_dat_o  : std_logic_vector(7 downto 0);
	signal wb_we_i   : std_logic;
	signal wb_stb_i  : std_logic;
	signal wb_ack_o  : std_logic;
	signal scl_wi    : std_logic;
	signal scl_wo    : std_logic;
	signal sda_wi    : std_logic;
	signal sda_wo    : std_logic;
	signal debug     : std_logic_vector(3 downto 0);
	signal sda_ro    : std_logic;
begin
	rst   <= transport '1', '0' after (4 * CLK_PERIOD);
	rst_n <= not rst;
	clock: process begin
		clk <= '1', '0' after CLK_PERIOD/2;
		wait for CLK_PERIOD;
	end process;
	wb_clk_i <= clk;
	wb_rst_i <= rst;


	beh_mst: process
	begin
		wb_dat_i <= x"00";
		wb_we_i <= '0';
		wb_adr_i <= x"6a08";
		wb_stb_i <= '0';
		wait for 20*CLK_PERIOD;
		wb_stb_i <= '1';
		wait until wb_ack_o = '1';
		wb_stb_i <= '0';
		wait;
	end process beh_mst;

	DUT_MST: i2c_wrapper
	port map (
		wb_clk_i  => wb_clk_i,
		wb_rst_i  => wb_rst_i,
		wb_adr_i  => wb_adr_i,
		wb_dat_i  => wb_dat_i,
		wb_dat_o  => wb_dat_o,
		wb_we_i   => wb_we_i,
		wb_stb_i  => wb_stb_i,
		wb_ack_o  => wb_ack_o,
		scl_i     => scl_wi,
		scl_o     => scl_wo,
		sda_i     => sda_wi,
		sda_o     => sda_wo
	);

	scl_wi <= scl_wo;
	sda_wi <=   '1'  when sda_ro = 'Z' else
	            '0'  when sda_ro = '0' else sda_wo;

	DUT: i2c_rom
	port map (
		clk    => wb_clk_i,
		rst_n  => rst_n,
		sda_i  => sda_wo,
		sda_o  => sda_ro,
		scl_i  => scl_wo
	);

end rtl;
