--------------------------------------------------------------------------------
-- 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;

library ieee_proposed;
use ieee_proposed.fixed_float_types.all;
use ieee_proposed.fixed_pkg.all;

library work;
use work.fixed_util_pkg.all;

ENTITY ddc IS
	Generic 
	(
		nbits_in			: integer := 18;
		nbits_in_frac		: integer := 16;
		nbits_out			: integer := 18;
		nbits_out_frac		: integer := 16;
		lo_nbits_phase		: integer := 20;
		lo_nbits_freq		: integer := 20;
		cic_nstages			: integer := 3;
		cic_max_ratio		: integer := 4096;
		cic_max_diff_delay	: integer := 2;
		cic_scale_nbits_min	: integer := 9;
		cic_scale_nbits_max	: integer := 32
	);
	PORT
	(
		rst					: in std_logic;
		clk					: in std_logic;
		lo_nco_rst			: in std_logic;
		lo_nco_en			: in std_logic;
		lo_freq_in			: in unsigned(lo_nbits_freq-1 downto 0);
		lo_phase_in			: in unsigned(lo_nbits_phase-1 downto 0);
		cic_ratio			: in natural range 1 to cic_max_ratio;
		cic_diff_delay		: in natural range 1 to cic_max_diff_delay;
		cic_shift_in		: in natural range 0 to cic_scale_nbits_max;
		din_i				: in  sfixed;
		din_q				: in  sfixed;
		dout_i				: out sfixed;
		dout_q				: out sfixed;
		din_vld				: in  std_logic;
		dout_vld			: out std_logic
	);
END ddc;

ARCHITECTURE behavior OF ddc IS 

	-- Component Declaration for the Unit Under Test (UUT)
	COMPONENT mix
	GENERIC
	(
		nbits_din		: integer;
		nbits_din_frac	: integer;
		nbits_dout		: integer;
		nbits_dout_frac	: integer;
		nbits_phase		: integer;
		nbits_freq		: integer
	);
	PORT
	(
		rst				: in std_logic;
		clk				: in std_logic;
		nco_rst			: in std_logic;
		nco_en			: in std_logic;
		freq_in			: in unsigned(nbits_freq-1 downto 0);
		phase_in		: in unsigned(nbits_phase-1 downto 0);
		din_i			: in  sfixed;
		din_q			: in  sfixed;
		dout_i			: out sfixed;
		dout_q			: out sfixed;
		din_vld			: in std_logic;
		dout_vld		: out std_logic
	);
	END COMPONENT;

	COMPONENT cic_decim_pipe
	GENERIC
	(
		nstages			: integer;
		ratio_max		: integer;
		scale_nbits_min	: integer;
		scale_nbits_max	: integer;
		max_diff_delay	: integer;
		in_width		: integer;
		in_width_frac	: integer;
		out_width		: integer;
		out_width_frac	: integer
	);
	PORT
	(
		clk				: in std_logic;
		rst				: in std_logic;
		vld_in			: in std_logic;
		ratio			: in natural range 1 to ratio_max;
		diff_delay		: in natural range 1 to max_diff_delay;
		shift_in		: in natural range 0 to scale_nbits_max;
		din				: in sfixed;
		dout			: out sfixed;
		vld_out 		: out std_logic
	);
	END COMPONENT;

	constant lo_nbits_in		: integer := nbits_in;
	constant lo_nbits_in_frac	: integer := nbits_in_frac;
	constant lo_nbits_out		: integer := nbits_in;
	constant lo_nbits_out_frac	: integer := nbits_in_frac;
	
	constant cic_nbits_in		: integer := lo_nbits_out;
	constant cic_nbits_in_frac	: integer := lo_nbits_out_frac;
	constant cic_nbits_out		: integer := nbits_out;
	constant cic_nbits_out_frac	: integer := nbits_out_frac;

	SIGNAL mix_dout_i			: sfixed(shi(lo_nbits_out, lo_nbits_out_frac) downto slo(lo_nbits_out, lo_nbits_out_frac));
	SIGNAL mix_dout_q			: sfixed(shi(lo_nbits_out, lo_nbits_out_frac) downto slo(lo_nbits_out, lo_nbits_out_frac));
	SIGNAL mix_dout_vld			: std_logic;

	SIGNAL dec_dout_i			: sfixed(shi(cic_nbits_out, cic_nbits_out_frac) downto slo(cic_nbits_out, cic_nbits_out_frac));
	SIGNAL dec_dout_q			: sfixed(shi(cic_nbits_out, cic_nbits_out_frac) downto slo(cic_nbits_out, cic_nbits_out_frac));
	SIGNAL dec_dout_vld_i		: std_logic;
	SIGNAL dec_dout_vld_q		: std_logic;

BEGIN

	dout_vld	<= dec_dout_vld_i and dec_dout_vld_q;
	dout_i		<= dec_dout_i;
	dout_q		<= dec_dout_q;
	
	-- Instantiate the Unit Under Test (UUT)
	inst_mixer: mix 
	GENERIC MAP
	(
		nbits_din			=> lo_nbits_in,
		nbits_din_frac		=> lo_nbits_in_frac,
		nbits_dout			=> lo_nbits_out,
		nbits_dout_frac		=> lo_nbits_out_frac,
		nbits_phase			=> lo_nbits_phase,
		nbits_freq			=> lo_nbits_freq
	)
	PORT MAP
	(
		rst					=> rst,
		clk					=> clk,
		nco_rst				=> lo_nco_rst,
		nco_en				=> lo_nco_en,
		freq_in				=> lo_freq_in,
		phase_in			=> lo_phase_in,
		din_i				=> din_i,
		din_q				=> din_q,
		dout_i				=> mix_dout_i,
		dout_q				=> mix_dout_q,
		din_vld				=> din_vld,
		dout_vld			=> mix_dout_vld
	);

	inst_cic_decim_pipe_I : cic_decim_pipe
	GENERIC MAP
	(
		nstages				=> cic_nstages,
		ratio_max			=> cic_max_ratio,
		scale_nbits_min		=> cic_scale_nbits_min,
		scale_nbits_max		=> cic_scale_nbits_max,
		max_diff_delay		=> cic_max_diff_delay,
		in_width			=> cic_nbits_in,
		in_width_frac		=> cic_nbits_in_frac,
		out_width			=> cic_nbits_out,
		out_width_frac		=> cic_nbits_out_frac
	)
	PORT MAP
	(
		clk					=> clk,
		rst					=> rst,
		vld_in				=> mix_dout_vld,
		ratio				=> cic_ratio,
		diff_delay			=> cic_diff_delay,
		shift_in			=> cic_shift_in,
		din					=> mix_dout_i,
		dout				=> dec_dout_i,
		vld_out				=> dec_dout_vld_i
	);

	inst_cic_decim_pipe_Q : cic_decim_pipe
	GENERIC MAP
	(
		nstages				=> cic_nstages,
		ratio_max			=> cic_max_ratio,
		scale_nbits_min		=> cic_scale_nbits_min,
		scale_nbits_max		=> cic_scale_nbits_max,
		max_diff_delay		=> cic_max_diff_delay,
		in_width			=> cic_nbits_in,
		in_width_frac		=> cic_nbits_in_frac,
		out_width			=> cic_nbits_out,
		out_width_frac		=> cic_nbits_out_frac
	)
	PORT MAP
	(
		clk					=> clk,
		rst					=> rst,
		vld_in				=> mix_dout_vld,
		ratio				=> cic_ratio,
		diff_delay			=> cic_diff_delay,
		shift_in			=> cic_shift_in,
		din					=> mix_dout_q,
		dout				=> dec_dout_q,
		vld_out				=> dec_dout_vld_q
	);

END;
