--------------------------------------------------------------------------------
-- 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.numeric_std.ALL;

library ieee_proposed;
use ieee_proposed.math_utility_pkg.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 cordic_pipe_stage is
Generic
(
	cordic_mode		: cordic_mode_t := cordic_mode_rotate;
	z_range			: real := pi;
	stage_num		: integer := 0;
	nbits_x			: integer := 8;
	nbits_x_frac	: integer := 6;
	nbits_y			: integer := 8;
	nbits_y_frac	: integer := 6;
	nbits_z			: integer := 8;
	nbits_z_frac	: integer := 8
);
Port
(
	clk			: in std_logic;
	rst			: 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 cordic_pipe_stage;

architecture Behavioral of cordic_pipe_stage is

constant coeff	: sfixed := to_sfixed(arctan_tbl(stage_num)*z_range, sproto(nbits_z, nbits_z_frac), fixed_wrap, fixed_round);

begin

------------------------------------------------------------
cordic_proc_stage: 
	process(clk)
	variable xi, xt, xo		: sfixed(shi(nbits_x, nbits_x_frac) downto slo(nbits_x, nbits_x_frac));
	variable yi, yt, yo		: sfixed(shi(nbits_y, nbits_y_frac) downto slo(nbits_y, nbits_y_frac));
	variable zi, zo			: sfixed(shi(nbits_z, nbits_z_frac) downto slo(nbits_z, nbits_z_frac));

	begin

		if rising_edge(clk) then
			vld_out <= '0';
			if rst = '1' then
				xout <= (shi(nbits_x, nbits_x_frac) downto slo(nbits_x, nbits_x_frac) => '0');
				yout <= (shi(nbits_y, nbits_y_frac) downto slo(nbits_y, nbits_y_frac) => '0');
				zout <= (shi(nbits_z, nbits_z_frac) downto slo(nbits_z, nbits_z_frac) => '0');
			elsif vld_in = '1' then

				vld_out <= '1';
				
				xi := xin;
				yi := yin;
				zi := zin;

				xt := xi sra stage_num;
				yt := yi sra stage_num;

				if zi(zi'high) = '1' then
					xo := resize(xi + yt, xo);
					yo := resize(yi - xt, yo);
					zo := resize(zi + coeff, zo);
				else
					xo := resize(xi - yt, xo);
					yo := resize(yi + xt, yo);
					zo := resize(zi - coeff, zo);
				end if;
				
				xout	<= xo after tpd;
				yout	<= yo after tpd;
				zout	<= zo after tpd;
			end if;	
		end if;
	end process;

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