--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:   17:16:42 13.05.2007
-- Design Name:   tb_nco
-- Module Name:   tb_nco.vhd
-- Project Name:  nco
-- 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 work;
use work.fixed_pkg.all;
use work.nco_pkg.all;
--use work.PCK_FIO.all;

ENTITY tb_syn_nco IS
	Generic (
		nbits_wave		: integer := 12;
		nbits_phase		: integer := 16; 
		nbits_lut_depth	: integer := 12; 
		nbits_dither	: integer := 5; 
		has_pipe_reg	: boolean := true;
		has_out_reg		: boolean := true
	        );
END tb_syn_nco;

ARCHITECTURE behavior OF tb_syn_nco IS 

	-- Component Declaration for the Unit Under Test (UUT)
	COMPONENT syn_nco
	GENERIC (
		nbits_wave		: integer;
		nbits_phase		: integer;
		nbits_lut_depth	: integer;
		nbits_dither	: integer;
		has_pipe_reg	: boolean;
		has_out_reg		: boolean
		);
	PORT(
		sys_rst		: in std_logic;
		sys_clk			: in std_logic;
		sys_pacc_clr	: in std_logic;
		sys_pacc_inc	: in std_logic;
		sys_freq_in		: in unsigned(nbits_phase-1 downto 0);
		sys_freq_load	: in std_logic;
		sys_phase_in	: in unsigned(nbits_phase-1 downto 0);
		sys_phase_load	: in std_logic;
		sys_phase_out	: out unsigned(nbits_phase-1 downto 0);
		sys_wave_out_i	: out signed(nbits_wave-1 downto 0);
		sys_wave_out_q	: out signed(nbits_wave-1 downto 0);
		sys_out_valid	: out std_logic
	);
	END COMPONENT;

	--Constants
	constant f : REAL := 10.2E6;
	constant df : REAL := 10.0E3;
	constant fa : REAL := 100.0E6;
	constant PERIOD : time := 10 ns;
	constant nbits_wave_frac : integer := nbits_wave;
	
	SIGNAL freq_word : integer := integer(f/fa*2.0**nbits_phase);
	SIGNAL dfreq_word : integer := integer(df/fa*2.0**nbits_phase);

	--Inputs
	SIGNAL clk         : std_logic := '0';
	SIGNAL srst        : std_logic := '1';
	SIGNAL pacc_clr   : std_logic := '0';
	SIGNAL pacc_inc   : std_logic := '0';
	SIGNAL phase_load  : std_logic := '0';
	SIGNAL freq_load   : std_logic := '0';
	SIGNAL freq_in     : unsigned(nbits_phase-1 downto 0);
	SIGNAL phase_in    : unsigned(nbits_phase-1 downto 0);

	--Outputs
	SIGNAL wave_out_i  : signed(nbits_wave-1 downto 0);
	SIGNAL wave_out_q  : signed(nbits_wave-1 downto 0);
	SIGNAL out_valid   : std_logic;
	SIGNAL phase_out   : unsigned(nbits_phase-1 downto 0);
	
	SIGNAL fileout_enable   : std_logic := '0';

BEGIN

	-- Instantiate the Unit Under Test (UUT)
	uut: syn_nco 
	GENERIC MAP (
		nbits_wave		=> nbits_wave,
		nbits_phase		=> nbits_phase,
		nbits_lut_depth	=> nbits_lut_depth,
		nbits_dither	=> nbits_dither,
		has_pipe_reg	=> has_pipe_reg,
		has_out_reg		=> has_out_reg
		)
	PORT MAP(
		sys_rst			=> srst,
		sys_clk			=> clk,
		sys_pacc_clr	=> pacc_clr,
		sys_pacc_inc	=> pacc_inc,
		sys_freq_in		=> freq_in,
		sys_freq_load	=> freq_load,
		sys_phase_in	=> phase_in,
		sys_phase_load	=> phase_load,
		sys_phase_out	=> phase_out,
		sys_wave_out_i	=> wave_out_i,
		sys_wave_out_q	=> wave_out_q,
		sys_out_valid	=> out_valid
	);

 	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;
		-------------------------------------------
		-- 1
		freq_in <= to_unsigned(0,nbits_phase);
		wait until rising_edge(clk);
		phase_load <= '1';
		wait until rising_edge(clk);
		phase_load <= '0';
		
		freq_in <= to_unsigned(1411,nbits_phase);
		wait until rising_edge(clk);
		freq_load <= '1';
		wait until rising_edge(clk);
		freq_load <= '0';

		wait for 2*PERIOD;
		pacc_inc <= '1';
		
		wait for 2*PERIOD;
		wait until rising_edge(clk);

		wait for 40*PERIOD;
		-------------------------------------------
		freq_in <= to_unsigned(643,nbits_phase);
		wait until rising_edge(clk);
		freq_load <= '1';
		wait until rising_edge(clk);
		freq_load <= '0';

		wait for 40*PERIOD;
		-------------------------------------------
		phase_in <= to_unsigned(800,nbits_phase);
		wait until rising_edge(clk);
		phase_load <= '1';
		wait until rising_edge(clk);
		phase_load <= '0';

		wait for 20*PERIOD;
		-------------------------------------------
		phase_in <= to_unsigned(45072,nbits_phase);
		wait until rising_edge(clk);
		phase_load <= '1';
		wait until rising_edge(clk);
		phase_load <= '0';

		wait for 20*PERIOD;
		-------------------------------------------
		phase_in <= to_unsigned(20593,nbits_phase);
		wait until rising_edge(clk);
		phase_load <= '1';
		wait until rising_edge(clk);
		phase_load <= '0';

		-------------------------------------------
		freq_in <= to_unsigned(freq_word,nbits_phase);
		wait until rising_edge(clk);
		freq_load <= '1';
		wait until rising_edge(clk);
		freq_load <= '0';
	
		wait for 20*PERIOD;
		fileout_enable <= '1';

		wait for 20000*PERIOD;
		fileout_enable <= '0';

		-------------------------------------------
		-- Sweep
		freq_word <= 100;
		for i in 1 to 200 loop
			wait for 20*PERIOD;
			freq_word <= freq_word + dfreq_word;
			
			freq_in <= to_unsigned(freq_word,nbits_phase);
			wait until rising_edge(clk);
			freq_load <= '1';
			wait until rising_edge(clk);
			freq_load <= '0';
	
		end loop;
		
		pacc_inc <= '0';
		wait for 20*PERIOD;
		fileout_enable <= '0';
		wait until rising_edge(clk);
		pacc_clr <= '1';
		wait until rising_edge(clk);
		pacc_clr <= '0';
		wait for 20*PERIOD;
		pacc_inc <= '1';
		wait for 20*PERIOD;
		wait until rising_edge(clk);
		pacc_clr <= '1';
		wait until rising_edge(clk);
		pacc_clr <= '0';
		wait for 20*PERIOD;
		pacc_inc <= '0';
		wait for 20*PERIOD;
		wait until rising_edge(clk);
		pacc_inc <= '1';
		wait until rising_edge(clk);
		pacc_inc <= '0';
		wait for 20*PERIOD;
		wait until rising_edge(clk);
		srst <= '1';
		wait until rising_edge(clk);
		srst <= '0';
		freq_in <= to_unsigned(freq_word,nbits_phase);
		wait until rising_edge(clk);
		freq_load <= '1';
		wait until rising_edge(clk);
		freq_load <= '0';
		
		wait for 20*PERIOD;
		pacc_inc <= '1';
		wait for 20*PERIOD;
		wait until rising_edge(clk);
		srst <= '1';
		wait until rising_edge(clk);
		srst <= '0';
		wait for 20*PERIOD;
		pacc_inc <= '0';

		wait for 20*PERIOD;

		assert false report "Test finished" severity error;
		wait; 
	END PROCESS;
	
--	tb_fo : PROCESS(clk, fileout_enable, out_valid)
--	file RESULT_I:      text open write_mode is "i_ud.txt"; 
--	file RESULT_Q:      text open write_mode is "q_ud.txt"; 
--	file RESULT_ID:      text open write_mode is "i_d.txt"; 
--	file RESULT_QD:      text open write_mode is "q_d.txt"; 
--	file RESULT_LFSR:   text open write_mode is "lfsr.txt"; 
---	variable L:         line;

--	BEGIN
--		if rising_edge(clk) and fileout_enable = '1' and out_valid = '1' then
--			fprint(RESULT_I, L,"%s\n", REAL'image(debug_out.i_ud));
--			fprint(RESULT_Q, L,"%s\n", REAL'image(debug_out.q_ud));
--			fprint(RESULT_ID, L,"%s\n", REAL'image(debug_out.i_d));
--			fprint(RESULT_QD, L,"%s\n", REAL'image(debug_out.q_d));
--			fprint(RESULT_LFSR, L,"%s\n", INTEGER'image(to_integer(debug_out.lfsr)));
--		end if;

--	END PROCESS;


END;
