--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:   17:16:42 13.05.2007
-- Design Name:   tb_mix_cpx
-- Module Name:   tb_mix_cpx.vhd
-- Project Name:  mix_cpx
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
--------------------------------------------------------------------------------
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 ieee_proposed;
use ieee_proposed.fixed_float_types.all;
use ieee_proposed.fixed_pkg.all;

library work;
use work.fixed_util_pkg.all;
use work.PCK_FIO.all;

ENTITY tb_mix_real IS
	Generic (
		nbits_in		: integer := 24;
		nbits_in_frac	: integer := 24;
		nbits_out		: integer := 24;
		nbits_out_frac	: integer := 24;
		nbits_scale_z	: integer := 0;
		has_in_reg		: boolean := true;
		has_pipe_reg	: boolean := true;
		has_out_reg		: boolean := true;
		rounding		: fixed_round_style_type := fixed_round;
		saturating		: fixed_overflow_style_type := fixed_saturate
	        );
END tb_mix_real;

ARCHITECTURE behavior OF tb_mix_real IS 

	-- Component Declaration for the Unit Under Test (UUT)
	COMPONENT mix_real
	GENERIC
	(
		nbits_in		: integer;
		nbits_in_frac	: integer;
		nbits_out		: integer;
		nbits_out_frac	: integer;
		nbits_scale_z	: integer;
		has_in_reg		: boolean;
		has_pipe_reg	: boolean;
		has_out_reg		: boolean;
		rounding		: fixed_round_style_type;
		saturating		: fixed_overflow_style_type
	);
	PORT
	(
		srst		: in std_logic;
		clk			: in std_logic;
		in_valid	: in std_logic;
		x_re_din		: in sfixed;
		y_re_din		: in sfixed;
		y_im_din		: in sfixed;
		out_valid	: out std_logic;
		z_re_dout	: out sfixed;
		z_im_dout	: out sfixed
	);
	END COMPONENT;

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

	--Inputs
	SIGNAL clk         : std_logic := '0';
	SIGNAL srst        : std_logic := '1';
	SIGNAL in_valid    : std_logic := '0';
	SIGNAL x_re_din     : sfixed(sproto(nbits_in, nbits_in_frac)'high downto sproto(nbits_in, nbits_in_frac)'low);
	SIGNAL y_re_din     : sfixed(sproto(nbits_in, nbits_in_frac)'high downto sproto(nbits_in, nbits_in_frac)'low);
	SIGNAL y_im_din     : sfixed(sproto(nbits_in, nbits_in_frac)'high downto sproto(nbits_in, nbits_in_frac)'low);

	--Outputs
	SIGNAL z_re_dout    : sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
	SIGNAL z_im_dout    : sfixed(sproto(nbits_out, nbits_out_frac)'high downto sproto(nbits_out, nbits_out_frac)'low);
	SIGNAL out_valid   : std_logic;
	
	SIGNAL fileout_enable   : std_logic := '0';
	SIGNAL x_re    : real := 0.0;
	SIGNAL y_re    : real := 0.0;
	SIGNAL y_im    : real := 0.0;
	SIGNAL z_re    : real := 0.0;
	SIGNAL z_im    : real := 0.0;

BEGIN

	-- Instantiate the Unit Under Test (UUT)
	uut: mix_real 
	GENERIC MAP
	(
		nbits_in		=> nbits_in,
		nbits_in_frac	=> nbits_in_frac,
		nbits_out		=> nbits_out,
		nbits_out_frac	=> nbits_out_frac,
		nbits_scale_z	=> nbits_scale_z,
		has_in_reg		=> has_in_reg,
		has_pipe_reg	=> has_pipe_reg,
		has_out_reg		=> has_out_reg,
		rounding		=> rounding,
		saturating		=> saturating
	)
	PORT MAP
	(
		srst		=> srst,
		clk			=> clk,
		in_valid	=> in_valid,
		x_re_din		=> x_re_din,
		y_re_din		=> y_re_din,
		y_im_din		=> y_im_din,
		out_valid	=> out_valid,
		z_re_dout	=> z_re_dout,
		z_im_dout	=> z_im_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 4*PERIOD;
		srst <= '0';
		------------------------------------------
		wait for 2*PERIOD;
		wait until rising_edge(clk);
		x_re_din <= to_sfixed(0.5, x_re_din);
		y_re_din <= to_sfixed(0.5, y_re_din);
		y_im_din <= to_sfixed(0.5, y_im_din);
		in_valid <= '1';
		wait until rising_edge(clk);
		in_valid <= '0';
		wait for 5*PERIOD;
		------------------------------------------
		wait until rising_edge(clk);
		x_re_din <= to_sfixed(0.125, x_re_din);
		y_re_din <= to_sfixed(0.25, y_re_din);
		y_im_din <= to_sfixed(0.125, y_im_din);
		in_valid <= '1';
		wait until rising_edge(clk);
		in_valid <= '0';
		wait for 5*PERIOD;
		------------------------------------------
		wait until rising_edge(clk);
		x_re_din <= to_sfixed(0.125, x_re_din);
		y_re_din <= to_sfixed(0.25, y_re_din);
		y_im_din <= to_sfixed(0.125, y_im_din);
		in_valid <= '1';
		------------------------------------------
		wait until rising_edge(clk);
		x_re_din <= to_sfixed(0.125, x_re_din);
		y_re_din <= to_sfixed(0.25, y_re_din);
		y_im_din <= to_sfixed(0.125, y_im_din);
		in_valid <= '1';
		------------------------------------------
		wait until rising_edge(clk);
		x_re_din <= to_sfixed(0.3, x_re_din);
		y_re_din <= to_sfixed(-0.5, y_re_din);
		y_im_din <= to_sfixed(0.5, y_im_din);
		in_valid <= '1';
		------------------------------------------
		wait until rising_edge(clk);
		x_re_din <= to_sfixed(0.0, x_re_din);
		y_re_din <= to_sfixed(0.0, y_re_din);
		y_im_din <= to_sfixed(-0.7071, y_im_din);
		in_valid <= '1';
		------------------------------------------
		wait until rising_edge(clk);
		in_valid <= '0';

		wait for 20*PERIOD;

		assert false report "Test finished" severity error;
		wait; 
	END PROCESS;
	
	x_re <= to_real(x_re_din);
	y_re <= to_real(y_re_din);
	y_im <= to_real(y_im_din);
	z_re <= to_real(z_re_dout);
	z_im <= to_real(z_im_dout);
	
END;
