
--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:   20:35:49 10/22/2005
-- Design Name:   ps2_core
-- Module Name:   tb_ps2_core.vhd
-- Project Name:  ps2if
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: ps2_core
--
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes: 
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test.  Xilinx recommends 
-- that these types always be used for the top-level I/O of a design in order 
-- to guarantee that the testbench will bind correctly to the post-implementation 
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;

ENTITY tb_ps2_core_vhd IS
END tb_ps2_core_vhd;

ARCHITECTURE behavior OF tb_ps2_core_vhd IS 

	-- Component Declaration for the Unit Under Test (UUT)
	COMPONENT ps2_core
	PORT(
		rst : IN std_logic;
		clk : IN std_logic;
		ce : IN std_logic;
		d_in : IN std_logic_vector(7 downto 0);
		write_en : IN std_logic;
		read_en : IN std_logic;
		ps2_clk_in : IN std_logic;
		ps2_data_in : IN std_logic;          
      ps2_clk_out : out std_logic;
      ps2_data_out : out std_logic;
		d_out : OUT std_logic_vector(7 downto 0);
		input_rdy : OUT std_logic;
		output_rdy : OUT std_logic
		);
	END COMPONENT;

	--Constants
	constant SYSPERIOD : time := 10 ns;
	constant PS2PERIOD : time := 100 us;

	--Inputs
	SIGNAL rst :  std_logic := '1';
	SIGNAL clk :  std_logic := '0';
	SIGNAL ce :  std_logic := '1';
	SIGNAL write_en :  std_logic := '0';
	SIGNAL read_en :  std_logic := '0';
	SIGNAL ps2_clk_in :  std_logic := '1';
	SIGNAL ps2_data_in :  std_logic := '1';
	SIGNAL d_in :  std_logic_vector(7 downto 0) := (others=>'0');

	--Outputs
	SIGNAL d_out :  std_logic_vector(7 downto 0);
	SIGNAL input_rdy :  std_logic;
	SIGNAL output_rdy :  std_logic;
	SIGNAL ps2_clk_i :  std_logic := '1';
	SIGNAL ps2_clk_j :  std_logic := '1';
	SIGNAL ps2_clk_out :  std_logic;
	SIGNAL ps2_data_out :  std_logic;
	SIGNAl tx_trig : std_logic := '0';

BEGIN

	-- Instantiate the Unit Under Test (UUT)
	uut: ps2_core PORT MAP(
		rst => rst,
		clk => clk,
		ce => ce,
		d_in => d_in,
		d_out => d_out,
		input_rdy => input_rdy,
		output_rdy => output_rdy,
		write_en => write_en,
		read_en => read_en,
		ps2_clk_in => ps2_clk_in,
		ps2_data_in => ps2_data_in,
		ps2_clk_out => ps2_clk_out,
		ps2_data_out => ps2_data_out
	);

	ps2_clk_j <= ps2_clk_i after PS2PERIOD/4;
 	tb_pswclk : PROCESS
	BEGIN
		wait until ps2_clk_j'event;  
		ps2_clk_in <= ps2_clk_j;

--		wait for SYSPERIOD;
--		ps2_clk_in <= not ps2_clk_j;
--		wait for SYSPERIOD;
--		ps2_clk_in <= ps2_clk_j;
--		wait for SYSPERIOD;
--		ps2_clk_in <= not ps2_clk_j;
--		wait for SYSPERIOD;
--		ps2_clk_in <= ps2_clk_j;
--		wait for SYSPERIOD;
--		ps2_clk_in <= not ps2_clk_j;
--		wait for SYSPERIOD;
--		ps2_clk_in <= ps2_clk_j;
--		wait for SYSPERIOD;
--		ps2_clk_in <= not ps2_clk_j;
--		wait for SYSPERIOD;
--		ps2_clk_in <= ps2_clk_j;
	END PROCESS;

 	tb_sysclk : PROCESS
	BEGIN
		clk <= not clk;
		wait for SYSPERIOD/2;
	END PROCESS;

 	tb_read : PROCESS
	BEGIN
		if output_rdy = '1' then
			wait for 10*SYSPERIOD;
			read_en <= '1';
		end if;
		wait for 2*SYSPERIOD;
		read_en <= '0';

	END PROCESS;

 	tb_write : PROCESS
	BEGIN
		wait until ps2_clk_out = '0';
		wait for PS2PERIOD;
		wait until ps2_data_out = '0';
		wait until ps2_clk_out = '1';
		wait for PS2PERIOD/2;
		tx_trig <= '1';

	END PROCESS;
	
	tb : PROCESS
	BEGIN

		wait for 20*SYSPERIOD;
		rst <= '0';

 	   for iter in 1 to 2 loop
--		wait for 2*PS2PERIOD;

		--Start bit
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in <= '0';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Data bit 0
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in	<= '1';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Data bit 1
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in	<= '1';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Data bit 2
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in <= '0';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Data bit 3
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in <= '1';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Data bit 4
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in <= '1';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Data bit 5
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in <= '0';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Data bit 6
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in <= '1';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Data bit 7
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in <= '1';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Parity
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in <= '1';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		--Stop
		wait for PS2PERIOD/2;
		ps2_clk_i  <= '0';
		ps2_data_in <= '1';
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;

		end loop;

		ps2_data_in <= '1';
		ps2_clk_i <= '1';

		wait for PS2PERIOD;
 		d_in     <= x"A5";
		write_en	<= '1';
		wait for SYSPERIOD;
		write_en	<= '0';

		wait until tx_trig = '1';
		wait for 2*PS2PERIOD;
		-- Start
		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;

 	   for iter in 1 to 8 loop
		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;
		end loop;

		-- Stop
		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;

		-- Parity
		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;
		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;

		ps2_data_in <= '0';
		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;

		ps2_clk_i <= not ps2_clk_i;
		wait for PS2PERIOD/2;
		ps2_data_in <= '1';
		ps2_clk_i <= '1';
		-- Place stimulus here

		wait; -- will wait forever
	END PROCESS;

END;
