--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:   17:16:42 13.05.2007
-- Design Name:   tb_fir_stage
-- Module Name:   tb_fir_stage.vhd
-- Project Name:  fir_stage
-- 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.filter_pkg.all;
use work.fir_pkg.all;

use work.PCK_FIO.all;

ENTITY tb_fir_iterative IS
	Generic (
		ntaps				: integer := 11;
		nbits_in			: integer := 16;
		nbits_in_frac		: integer := 15;
		nbits_stages		: integer := 16;
		nbits_stages_frac	: integer := 15;
		nbits_out			: integer := 16;
		nbits_out_frac		: integer := 15;
		fir_mode			: fir_iterative_mode_t := symmetric;
		rounding			: boolean := true;
		saturating			: boolean := true
	        );
END tb_fir_iterative;

ARCHITECTURE behavior OF tb_fir_iterative IS 

	-- Component Declaration for the Unit Under Test (UUT)
	COMPONENT fir_iterative
	GENERIC
	(
		ntaps				: integer;
		nbits_in			: integer;
		nbits_in_frac		: integer;
		nbits_stages		: integer;
		nbits_stages_frac	: integer;
		nbits_out			: integer;
		nbits_out_frac		: integer;
		fir_mode			: fir_iterative_mode_t;
		rounding			: boolean;
		saturating			: boolean
	);
	PORT
	(
		srst			: in std_logic;
		clk				: in std_logic;
		h_din			: in sfixed;
		h_addr_out		: out natural;
		ready			: out std_logic;
		x_valid			: in std_logic;
		x_din			: in sfixed;
		y_dout_valid	: out std_logic;
		y_dout			: out sfixed
	);
	END COMPONENT;

	-------------------------------------------------------------------------------
	--Constants
	constant nsamples : integer := 32;
	
	constant PERIOD : time := 10 ns;
	constant zero_in : sfixed := to_sfixed(0, nbits_in, nbits_in_frac);

	--Inputs
	SIGNAL clk         : std_logic := '0';
	SIGNAL srst        : std_logic := '1';
	SIGNAL x_valid    : std_logic := '0';
	SIGNAL h_din        : sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
	SIGNAL x_din        : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac));

	--Outputs
	SIGNAL y_dout       : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac));
	SIGNAL y_valid   : std_logic;
	SIGNAL ready   : std_logic;

	SIGNAL fileout_enable   : std_logic := '1';
	
	-- Test coefficients
	SIGNAL coeffs : real_array_t(0 to ntaps_addr(ntaps, fir_mode)-1) := FilterCoef_Delta(ntaps, (ntaps-1)/2, 1.0)(0 to ntaps_addr(ntaps, fir_mode)-1);
--	SIGNAL coeffs : real_array_t(0 to ntaps_addr(ntaps, fir_mode)-1) := FilterCoef_Bandpass(ntaps, 0.25, 0.125, 1.0)(0 to ntaps_addr(ntaps, fir_mode)-1);
--	SIGNAL coeffs : real_array_t(0 to ntaps-1) := FilterTestCoef(ntaps);
	signal x_input : real_array_t(0 to nsamples-1) :=
	(
		0.01,	
		0.02,		
		0.03,		
		0.04,		
		0.05,		
		0.06,		
		0.07,		
		0.08,		
		0.09,		
		0.10,		
		0.11,		
		0.12,		
		0.13,		
		0.14,		
		0.15,		
		0.9999,
		-0.9999,
		-0.15,	
		-0.14,		
		-0.13,		
		-0.12,		
		-0.11,		
		-0.10,		
		-0.09,		
		-0.08,		
		-0.07,		
		-0.06,		
		-0.05,		
		-0.04,		
		-0.03,		
		-0.02,		
		-0.01	
		
	);
	type ymem_t is array (0 to nsamples-1) of sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac));
	signal ymem : ymem_t;
	
	signal y_cnt : integer ;
	SIGNAL xi, yo : real := 0.0;
	SIGNAL h_addr : natural;
	
	-- file I/O
	subtype sample_t is integer range -32768 to 32767;
	type file_t is file of sample_t;
	
	-------------------------------------------------------------------------------
BEGIN

	xi <= to_real(x_din);
	yo <= to_real(y_dout);
	
	----------------------------------------
	-- Instantiate the Unit Under Test (UUT)
	----------------------------------------
		uut_fir_iterative: fir_iterative
		GENERIC MAP
		(
			ntaps				=> ntaps,
			nbits_in			=> nbits_in,
			nbits_in_frac		=> nbits_in_frac,
			nbits_out			=> nbits_out,
			nbits_out_frac		=> nbits_out_frac,
			nbits_stages		=> nbits_stages,
			nbits_stages_frac	=> nbits_stages_frac,
			fir_mode			=> fir_mode,
			rounding			=> rounding,
			saturating			=> saturating
		)
		PORT MAP
		(
			srst			=> srst,
			clk				=> clk,
			h_din			=> h_din,
			h_addr_out		=> h_addr,
			ready			=> ready,
			x_valid			=> x_valid,
			x_din			=> x_din,
			y_dout_valid	=> y_valid,
			y_dout			=> y_dout
		);

	----------------------------------------
	-- Finished instantiation
	----------------------------------------
	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;
		
		for i in 0 to nsamples-1 loop
			if i = nsamples/2 then
				wait for 43*PERIOD;
			end if;					
			------------------------------------------
			wait until rising_edge(clk) and ready = '1';
			x_din <= to_sfixed(x_input(i), x_din);
			x_valid <= '1';
			------------------------------------------
			wait until rising_edge(clk);
			x_valid <= '0';
		end loop;

		assert false report "Test finished" severity error;
		wait; 
	END PROCESS;
	
	process(srst, clk, y_valid)
	begin
		if rising_edge(clk) then
			h_din <= to_sfixed(coeffs(h_addr), h_din);
			if srst = '1' then
				y_cnt <= 0;
				
			elsif y_valid = '1' then
				ymem(y_cnt) <= y_dout;
				y_cnt <= y_cnt + 1;
			end if;
		end if;	
	end process;	

END;
