--------------------------------------------------------------------------------
-- 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_post is
Generic
(
	cordic_mode		: cordic_mode_t := cordic_mode_rotate;
	nstages			: 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_post;

architecture Behavioral of cordic_pipe_post is

constant gain_x	: sfixed := to_sfixed(gain_tbl(nstages), sproto(nbits_x, nbits_x_frac), fixed_wrap, fixed_round);
constant gain_y	: sfixed := to_sfixed(gain_tbl(nstages), sproto(nbits_y, nbits_y_frac), fixed_wrap, fixed_round);

------------------------------------------------------------
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 := resize(xin, xi, fixed_wrap, fixed_truncate);
				yi := resize(yin, yi, fixed_wrap, fixed_truncate);
				zi := resize(zin, zi, fixed_wrap, fixed_truncate);

				xo := resize(xi * gain_x, xo, cordic_saturate_mode, cordic_round_mode);
				yo := resize(yi * gain_y, yo, cordic_saturate_mode, cordic_round_mode);
				zo := zi;

				xout	<= xo after tpd;
				yout	<= yo after tpd;
				zout	<= zo after tpd;
			end if;	
		end if;
	end process;

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