--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:   17:16:42 10/02/2005
-- Design Name:   mac_top
-- Module Name:   tb_mac_top.vhd
-- Project Name:  mac
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: cordic_top
--
-- 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.MATH_REAL.ALL;
USE ieee.numeric_std.ALL;
use std.textio.all; --  Imports the standard textio package.

library work;
use work.fixed_ja.all;
use work.PCK_FIO.all;

ENTITY tb_mac_top IS
	Generic (
	        nbits_in		: integer := 8;
	        nbits_in_int	: integer := 1;
	        nbits_out		: integer := 16;
	        nbits_out_int	: integer := 1
	        );
END tb_mac_top;

ARCHITECTURE behavior OF tb_mac_top IS 

	-- Component Declaration for the Unit Under Test (UUT)
	COMPONENT mac_top
	GENERIC (
		nbits_in		: integer;
		nbits_in_int	: integer;
		nbits_out		: integer;
		nbits_out_int	: integer
		);
	PORT(
		rst			: in std_logic;
		clk			: in std_logic;
		ce			: in std_logic;
		xin			: in sfixed_t;
		yin			: in sfixed_t;
		dout		: out sfixed_t;
		ready		: out std_logic;
		valid_din	: in std_logic;
		valid_dout	: out std_logic
	);
	END COMPONENT;

	--Constants
	constant PERIOD : time := 10 ns;

	--Inputs
	SIGNAL clk			: std_logic := '0';
	SIGNAL rst			: std_logic := '1';
	SIGNAL ce			: std_logic := '0';
	SIGNAL valid_din	: std_logic := '0';
	SIGNAL xin, yin		: sfixed_t(sproto(nbits_in, nbits_in_int)'range) := to_sfixed(0, nbits_in, nbits_in_int);

	--Outputs
	SIGNAL dout			: sfixed_t(sproto(nbits_out, nbits_out_int)'range);
	SIGNAL valid_dout, ready : std_logic;
	

		
BEGIN

	-- Instantiate the Unit Under Test (UUT)
	uut: mac_top 
	GENERIC MAP (
		nbits_in		=> nbits_in,
		nbits_in_int	=> nbits_in_int,
		nbits_out		=> nbits_out,
		nbits_out_int	=> nbits_out_int
		)
	PORT MAP(
		clk  => clk,
		rst  => rst,
		ce   => ce,
		xin  => xin,
		yin  => yin,
		dout => dout,
		ready => ready,
		valid_din => valid_din,
		valid_dout => valid_dout
	);

 	tb_clk : PROCESS
	BEGIN
		clk <= not clk;
		wait for PERIOD/2;
	END PROCESS;

	tb : PROCESS
	BEGIN

		-- Wait 100 ns for global reset to finish
		wait for 1*PERIOD;
		rst <= '0';

		wait for 1*PERIOD;
		
		wait until rising_edge(clk);
		ce <= '0';
		valid_din <= '0';
		xin <= (others => '-');
		yin <= (others => '-');

		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '1';
		xin <= to_sfixed(0.5, nbits_in, nbits_in_int);
		yin <= to_sfixed(0.5, nbits_in, nbits_in_int);
		
		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '1';
		xin <= to_sfixed(-0.25, nbits_in, nbits_in_int);
		yin <= to_sfixed(0.25, nbits_in, nbits_in_int);

		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '1';
		xin <= to_sfixed(0.125, nbits_in, nbits_in_int);
		yin <= to_sfixed(-0.125, nbits_in, nbits_in_int);
		
		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '1';
		xin <= to_sfixed(1.0, nbits_in, nbits_in_int);
		yin <= to_sfixed(0.5, nbits_in, nbits_in_int);
		
		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '1';
		xin <= to_sfixed(0.333, nbits_in, nbits_in_int);
		yin <= to_sfixed(0.75, nbits_in, nbits_in_int);

		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '1';
		xin <= to_sfixed(0.7071, nbits_in, nbits_in_int);
		yin <= to_sfixed(-0.7071, nbits_in, nbits_in_int);

		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '0';
		xin <= (others => '-');
		yin <= (others => '-');

		wait for 2*PERIOD;

		wait until rising_edge(clk);
		ce <= '0';
		valid_din <= '0';
		xin <= (others => '-');
		yin <= (others => '-');

		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '1';
		xin <= to_sfixed(0.9, nbits_in, nbits_in_int);
		yin <= to_sfixed(0.333, nbits_in, nbits_in_int);

		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '0';
		xin <= (others => '-');
		yin <= (others => '-');

		wait for 2*PERIOD;

		wait until rising_edge(clk);
		ce <= '1';
		valid_din <= '0';
		xin <= (others => '-');
		yin <= (others => '-');

		wait until rising_edge(clk);
		ce <= '0';
		valid_din <= '0';
		xin <= (others => '-');
		yin <= (others => '-');
		
		wait for 20*PERIOD;
		assert false report "Test finished" severity error;
		wait; 
	END PROCESS;

END;
