--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:    12:16:14 10/02/05
-- Design Name:    
-- Module Name:    cordic_stage_pre - 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.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 cordic_pipe_pre is
Generic
(
	cordic_mode		: cordic_mode_t := cordic_mode_rotate;
	z_range			: real := pi;
	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_pre;

architecture Behavioral of cordic_pipe_pre is

constant pi_sfix 		: sfixed(shi(nbits_z, nbits_z_frac) downto slo(nbits_z, nbits_z_frac)) := to_sfixed(z_range, sproto(nbits_z, nbits_z_frac), fixed_wrap, fixed_truncate);
constant pi2_sfix 		: sfixed(shi(nbits_z, nbits_z_frac) downto slo(nbits_z, nbits_z_frac)) := to_sfixed(z_range/2.0, sproto(nbits_z, nbits_z_frac), fixed_wrap, fixed_truncate);

------------------------------------------------------------
begin

------------------------------------------------------------
cordic_proc_pre_stage: 
	process(clk)
	variable xi, xo			: sfixed(shi(nbits_x, nbits_x_frac) downto slo(nbits_x, nbits_x_frac));
	variable yi, 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;

				xo := xi;
				yo := yi;
				zo := zi;

				if (zi < -pi2_sfix) then
					xo := resize(-xi, xo, fixed_wrap, fixed_truncate);
					yo := resize(-yi, yo, fixed_wrap, fixed_truncate);
					zo := resize(zi + pi_sfix, zo, fixed_wrap, fixed_truncate);
				elsif (zi > pi2_sfix) then
					xo := resize(-xi, xo, fixed_wrap, fixed_truncate);
					yo := resize(-yi, yo, fixed_wrap, fixed_truncate);
					zo := resize(zi - pi_sfix, zo, fixed_wrap, fixed_truncate);
				end if;
				
				xout	<= xo after tpd;
				yout	<= yo after tpd;
				zout	<= zo after tpd;
			end if;	
		end if;
	end process;

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

-- if (y < 0) then
-- 	x' = -y
-- 	y' =  x
-- 	z' = z + pi/2;
-- else
-- 	x' =  y
-- 	y' = -x
-- 	z' = z - pi/2;
-- end if;
-- 
-- if (x < 0) then
-- 	x' = -x;
-- 	y' = -y;
-- 	z' = z - pi
-- else
-- 	x' = x;
-- 	y' = y;
-- 	z' = z
-- end if;
