--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:    12:16:14 10/02/05
-- Design Name:    
-- Module Name:    cordic_stage - Behavioral
-- Project Name:   
-- Target Device:  
-- Tool versions:  
-- Description:
--
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
--------------------------------------------------------------------------------
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;
use work.cordic_pkg.all;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity mix is
Generic
(
	nbits_din		: integer := 18;
	nbits_din_frac	: integer := 16;
	nbits_dout		: integer := 18;
	nbits_dout_frac	: integer := 16;
	nbits_phase		: integer := 16;
	nbits_freq		: integer := 16
);
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 mix;

architecture Behavioral of mix is

	COMPONENT cordic_pipe_top
	GENERIC 
	(
		cordic_mode			: cordic_mode_t;
		z_range				: real;
		gain_corr_mode		: gain_corr_mode_t;
		nstages				: integer;
		nbits_x_in			: integer;
		nbits_y_in			: integer;
		nbits_z_in			: integer;
		nbits_frac_x_in		: integer;
		nbits_frac_y_in		: integer;
		nbits_frac_z_in		: integer;
		nbits_x_out			: integer;
		nbits_y_out			: integer;
		nbits_z_out			: integer;
		nbits_frac_x_out	: integer;
		nbits_frac_y_out	: integer;
		nbits_frac_z_out	: integer
	);
	PORT
	(
		rst					: in std_logic;
		clk					: in std_logic;
		vld_in				: in std_logic;
		xin					: in sfixed;
		yin					: in sfixed;
		zin					: in sfixed;
		xout				: out sfixed;
		yout				: out sfixed;
		zout				: out sfixed;
		vld_out				: out std_logic
	);
	END COMPONENT;

-------------------------------------------------------------------------------
	constant nbits_phase_frac : integer := nbits_phase;

-------------------------------------------------------------------------------
	signal phase : signed(nbits_phase-1 downto 0);
	signal xin, yin : sfixed(shi(nbits_din, nbits_din_frac) downto slo(nbits_din, nbits_din_frac));
	signal xout, yout : sfixed(shi(nbits_dout, nbits_dout_frac) downto slo(nbits_dout, nbits_dout_frac));
	
	signal dout_valid : std_logic;

	signal zin : sfixed(shi(nbits_phase, nbits_phase_frac) downto slo(nbits_phase, nbits_phase_frac));
	signal zout : sfixed(shi(nbits_phase, nbits_phase_frac) downto slo(nbits_phase, nbits_phase_frac));
	
-------------------------------------------------------------------------------
begin

	dout_i		<= xout;
	dout_q		<= yout;
	xin			<= din_i;
	yin			<= din_q;
	
	dout_vld	<= dout_valid;

------------------------------------------------------------
	proc_phase_accu: process(clk)
	variable phase_accu : signed(nbits_phase-1 downto 0);

	begin
		if rising_edge(clk) then 
			if rst = '1' or nco_rst = '1' then
				phase_accu	:= (others => '0');
			elsif nco_en = '1' then
				phase		<= phase_accu + signed(phase_in);
				phase_accu	:= phase_accu + signed(freq_in);
			end if;	
		end if;
		zin	<= sfixed(phase);
	end process;

------------------------------------------------------------
	inst_cordic: cordic_pipe_top
	GENERIC MAP
	(
		cordic_mode 		=> cordic_mode_rotate,
		z_range				=> 1.0,
		gain_corr_mode		=> gain_mode_disabled,
		nstages				=> nbits_phase,
		nbits_x_in			=> nbits_din,
		nbits_frac_x_in		=> nbits_din_frac,
		nbits_y_in			=> nbits_din,
		nbits_frac_y_in		=> nbits_din_frac,
		nbits_z_in			=> nbits_phase,
		nbits_frac_z_in		=> nbits_phase_frac,
		nbits_x_out			=> nbits_dout,
		nbits_frac_x_out	=> nbits_dout_frac,
		nbits_y_out			=> nbits_dout,
		nbits_frac_y_out	=> nbits_dout_frac,
		nbits_z_out			=> nbits_phase,
		nbits_frac_z_out	=> nbits_phase_frac
	)
	PORT MAP
	(
		rst					=> rst,
		clk					=> clk,
		vld_in				=> din_vld,
		xin					=> xin,
		yin					=> yin,
		zin					=> zin,
		xout				=> xout,
		yout				=> yout,
		zout				=> zout,
		vld_out				=> dout_valid
	);

------------------------------------------------------------
end Behavioral;
