----------------------------------------------
-- MSS copyright 1999-2005
-- Filename: SIGNED_SIN_COS_TBL2.VHD
-- Author: Alain Zarembowitch / MSS
-- Inheritance: SIGNED_SIN_COS_TBL
-- Edit date: 4-27-05
-- Revision: 1
--
-- Description: ROM table for sine and cosine. 
-- 
-- Implementation: uses a single RAMB16 spanning 0-90 deg for sine. 
-- Use quadrant symmetry for full 0-360 deg sine/cosine lookup. 
-- Use A/B sides for simultaneous sine and cosine.
-- Able to operate at the maximum speed of one sin/cos pair every system clock.
--	Latency between input and output is 2 CLK.
----------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Library UNISIM;
use UNISIM.vcomponents.all;

entity SIGNED_SIN_COS_TBL2 is
	port (
		CLK: in std_logic;
			-- system clock
		PHASE: in std_logic_vector(11 downto 0);
			-- angle: [0 to 360 degree[. No 360 representation.
			-- 0x00 -> 0.0 deg, 0xff -> 359.912 deg.
			-- Steps: 0.088 deg.
		SIN_OUT: out std_logic_vector(17 downto 0);
		COS_OUT: out std_logic_vector(17 downto 0)
			-- sine or cosine value. range -1 to +1. 
			-- 18-bit signed (2's complement)
			-- Latency is 2 CLK  
	);
end entity;

architecture BEHAVIOR of SIGNED_SIN_COS_TBL2 is

-----------------------------------------------------------------
-- COMPONENTS
-----------------------------------------------------------------
-- RAMB16_S18_S18SIN (simulation only). 
component RAMB16_S18_S18SIN
	generic (
		INIT_00: bit_vector(255 downto 0);
		INIT_01: bit_vector(255 downto 0);
		INIT_02: bit_vector(255 downto 0);
		INIT_03: bit_vector(255 downto 0);
		INIT_04: bit_vector(255 downto 0);
		INIT_05: bit_vector(255 downto 0);
		INIT_06: bit_vector(255 downto 0);
		INIT_07: bit_vector(255 downto 0);
		INIT_08: bit_vector(255 downto 0);
		INIT_09: bit_vector(255 downto 0);
		INIT_0A: bit_vector(255 downto 0);
		INIT_0B: bit_vector(255 downto 0);
		INIT_0C: bit_vector(255 downto 0);
		INIT_0D: bit_vector(255 downto 0);
		INIT_0E: bit_vector(255 downto 0);
		INIT_0F: bit_vector(255 downto 0);
		INIT_10: bit_vector(255 downto 0);
		INIT_11: bit_vector(255 downto 0);
		INIT_12: bit_vector(255 downto 0);
		INIT_13: bit_vector(255 downto 0);
		INIT_14: bit_vector(255 downto 0);
		INIT_15: bit_vector(255 downto 0);
		INIT_16: bit_vector(255 downto 0);
		INIT_17: bit_vector(255 downto 0);
		INIT_18: bit_vector(255 downto 0);
		INIT_19: bit_vector(255 downto 0);
		INIT_1A: bit_vector(255 downto 0);
		INIT_1B: bit_vector(255 downto 0);
		INIT_1C: bit_vector(255 downto 0);
		INIT_1D: bit_vector(255 downto 0);
		INIT_1E: bit_vector(255 downto 0);
		INIT_1F: bit_vector(255 downto 0);
		INIT_20: bit_vector(255 downto 0);
		INIT_21: bit_vector(255 downto 0);
		INIT_22: bit_vector(255 downto 0);
		INIT_23: bit_vector(255 downto 0);
		INIT_24: bit_vector(255 downto 0);
		INIT_25: bit_vector(255 downto 0);
		INIT_26: bit_vector(255 downto 0);
		INIT_27: bit_vector(255 downto 0);
		INIT_28: bit_vector(255 downto 0);
		INIT_29: bit_vector(255 downto 0);
		INIT_2A: bit_vector(255 downto 0);
		INIT_2B: bit_vector(255 downto 0);
		INIT_2C: bit_vector(255 downto 0);
		INIT_2D: bit_vector(255 downto 0);
		INIT_2E: bit_vector(255 downto 0);
		INIT_2F: bit_vector(255 downto 0);
		INIT_30: bit_vector(255 downto 0);
		INIT_31: bit_vector(255 downto 0);
		INIT_32: bit_vector(255 downto 0);
		INIT_33: bit_vector(255 downto 0);
		INIT_34: bit_vector(255 downto 0);
		INIT_35: bit_vector(255 downto 0);
		INIT_36: bit_vector(255 downto 0);
		INIT_37: bit_vector(255 downto 0);
		INIT_38: bit_vector(255 downto 0);
		INIT_39: bit_vector(255 downto 0);
		INIT_3A: bit_vector(255 downto 0);
		INIT_3B: bit_vector(255 downto 0);
		INIT_3C: bit_vector(255 downto 0);
		INIT_3D: bit_vector(255 downto 0);
		INIT_3E: bit_vector(255 downto 0);
		INIT_3F: bit_vector(255 downto 0);
		INITP_00: bit_vector(255 downto 0);
		INITP_01: bit_vector(255 downto 0);
		INITP_02: bit_vector(255 downto 0);
		INITP_03: bit_vector(255 downto 0);
		INITP_04: bit_vector(255 downto 0);
		INITP_05: bit_vector(255 downto 0);
		INITP_06: bit_vector(255 downto 0);						   	
		INITP_07: bit_vector(255 downto 0)
	);
   port (
			DOA : out std_logic_vector (15 downto 0);
         DOPA : out std_logic_vector (1 downto 0);
         ADDRA : in std_logic_vector (9 downto 0);
         CLKA : in std_logic;
         DIA : in std_logic_vector (15 downto 0);
         DIPA : in std_logic_vector (1 downto 0);
         ENA : in std_logic;
         SSRA : in std_logic;
         WEA : in std_logic;
			DOB : out std_logic_vector (15 downto 0);
         DOPB : out std_logic_vector (1 downto 0);
         ADDRB : in std_logic_vector (9 downto 0);
         CLKB : in std_logic;
         DIB : in std_logic_vector (15 downto 0);
         DIPB : in std_logic_vector (1 downto 0);
         ENB : in std_logic;
         SSRB : in std_logic;
         WEB : in std_logic);
end component; 
------------------------------------------------------
--			ATTRIBUTES
------------------------------------------------------  
--attribute INIT_00: string;
--attribute INIT_01: string;
--attribute INIT_02: string;
--attribute INIT_03: string;
--attribute INIT_04: string;
--attribute INIT_05: string;
--attribute INIT_06: string;
--attribute INIT_07: string;
--attribute INIT_08: string;
--attribute INIT_09: string;
--attribute INIT_0A: string;
--attribute INIT_0B: string;
--attribute INIT_0C: string;
--attribute INIT_0D: string;
--attribute INIT_0E: string;
--attribute INIT_0F: string;
--attribute INIT_10: string;
--attribute INIT_11: string;
--attribute INIT_12: string;
--attribute INIT_13: string;
--attribute INIT_14: string;
--attribute INIT_15: string;
--attribute INIT_16: string;
--attribute INIT_17: string;
--attribute INIT_18: string;
--attribute INIT_19: string;
--attribute INIT_1A: string;
--attribute INIT_1B: string;
--attribute INIT_1C: string;
--attribute INIT_1D: string;
--attribute INIT_1E: string;
--attribute INIT_1F: string;
--attribute INIT_20: string;
--attribute INIT_21: string;
--attribute INIT_22: string;
--attribute INIT_23: string;
--attribute INIT_24: string;
--attribute INIT_25: string;
--attribute INIT_26: string;
--attribute INIT_27: string;
--attribute INIT_28: string;
--attribute INIT_29: string;
--attribute INIT_2A: string;
--attribute INIT_2B: string;
--attribute INIT_2C: string;
--attribute INIT_2D: string;
--attribute INIT_2E: string;
--attribute INIT_2F: string;
--attribute INIT_30: string;
--attribute INIT_31: string;
--attribute INIT_32: string;
--attribute INIT_33: string;
--attribute INIT_34: string;
--attribute INIT_35: string;
--attribute INIT_36: string;
--attribute INIT_37: string;
--attribute INIT_38: string;
--attribute INIT_39: string;
--attribute INIT_3A: string;
--attribute INIT_3B: string;
--attribute INIT_3C: string;
--attribute INIT_3D: string;
--attribute INIT_3E: string;
--attribute INIT_3F: string;
--attribute INITP_00: string;
--attribute INITP_01: string;
--attribute INITP_02: string;
--attribute INITP_03: string;
--attribute INITP_04: string;
--attribute INITP_05: string;
--attribute INITP_06: string;
--attribute INITP_07: string;
--
--attribute INIT_00 of SIN_COS_TABLE_001 : label is "0bc80aff0a36096d08a407db07110648057f04b603ed0324025b019200c90000";
--attribute INIT_01 of SIN_COS_TABLE_001 : label is "1857178e16c515fc1533146a13a112d8120f1147107e0fb50eec0e230d5a0c91";
--attribute INIT_02 of SIN_COS_TABLE_001 : label is "24e224192351228821bf20f7202e1f651e9d1dd41d0b1c431b7a1ab119e8191f";
--attribute INIT_03 of SIN_COS_TABLE_001 : label is "3167309f2fd72f0f2e462d7e2cb62bee2b252a5d299528cc2804273b267325aa";
--attribute INIT_04 of SIN_COS_TABLE_001 : label is "3de53d1d3c563b8e3ac639ff3937386f37a736df3617354f348733bf32f7322f";
--attribute INIT_05 of SIN_COS_TABLE_001 : label is "4a59499248cb4804473d467645af44e844214359429241cb4103403c3f743ead";
--attribute INIT_06 of SIN_COS_TABLE_001 : label is "56c255fc5536546f53a952e3521c5156508f4fc94f024e3b4d754cae4be74b20";
--attribute INIT_07 of SIN_COS_TABLE_001 : label is "631e6258619360ce60085f435e7d5db75cf25c2c5b665aa059da5914584e5788";
--attribute INIT_08 of SIN_COS_TABLE_001 : label is "6f6a6ea66de16d1d6c586b946acf6a0b6946688167bc66f76632656d64a863e3";
--attribute INIT_09 of SIN_COS_TABLE_001 : label is "7ba57ae27a1e795b789877d47711764d758a74c67402733e727a71b670f2702e";
--attribute INIT_0A of SIN_COS_TABLE_001 : label is "87cd870b8649858784c584028340827e81bb80f980367f737eb17dee7d2b7c68";
--attribute INIT_0B of SIN_COS_TABLE_001 : label is "93e0931f925f919e90dd901c8f5b8e9a8dd98d188c568b958ad48a128950888f";
--attribute INIT_0C of SIN_COS_TABLE_001 : label is "9fdc9f1d9e5e9d9e9cdf9c209b609aa199e19921986197a196e19621956194a0";
--attribute INIT_0D of SIN_COS_TABLE_001 : label is "abbfab02aa44a987a8c9a80ba74da68fa5d1a513a454a396a2d7a219a15aa09b";
--attribute INIT_0E of SIN_COS_TABLE_001 : label is "b789b6cdb611b555b499b3ddb320b264b1a7b0ebb02eaf71aeb4adf7ad3aac7d";
--attribute INIT_0F of SIN_COS_TABLE_001 : label is "c335c27bc1c1c107c04dbf92bed8be1dbd63bca8bbedbb32ba76b9bbb900b844";
--attribute INIT_10 of SIN_COS_TABLE_001 : label is "cec4ce0ccd54cc9ccbe3cb2bca72c9b9c900c847c78ec6d5c61cc562c4a9c3ef";
--attribute INIT_11 of SIN_COS_TABLE_001 : label is "da33d97dd8c7d810d75ad6a4d5edd536d47fd3c8d311d25ad1a3d0ebd034cf7c";
--attribute INIT_12 of SIN_COS_TABLE_001 : label is "e580e4cce418e364e2b0e1fbe147e092dfdedf29de74ddbedd09dc54db9edae9";
--attribute INIT_13 of SIN_COS_TABLE_001 : label is "f0aaeff8ef46ee94ede3ed30ec7eebcceb19ea67e9b4e901e84ee79ae6e7e633";
--attribute INIT_14 of SIN_COS_TABLE_001 : label is "fbaefafffa50f9a0f8f1f841f791f6e1f631f580f4d0f41ff36ef2bdf20cf15b";
--attribute INIT_15 of SIN_COS_TABLE_001 : label is "068c05df0532048503d8032b027d01d001220074ffc6ff18fe69fdbbfd0cfc5d";
--attribute INIT_16 of SIN_COS_TABLE_001 : label is "114110970fed0f420e980ded0d420c970bec0b400a9509e9093d089107e50738";
--attribute INIT_17 of SIN_COS_TABLE_001 : label is "1bcc1b251a7d19d6192e188617dd1735168c15e3153a149113e8133f129511eb";
--attribute INIT_18 of SIN_COS_TABLE_001 : label is "262c258724e2243d239822f3224d21a82102205c1fb51f0f1e681dc21d1b1c74";
--attribute INIT_19 of SIN_COS_TABLE_001 : label is "305e2fbc2f1a2e782dd62d332c912bee2b4b2aa72a04296028bd2819277526d0";
--attribute INIT_1A of SIN_COS_TABLE_001 : label is "3a6139c23923388437e5374536a53606356534c53425338432e3324231a130ff";
--attribute INIT_1B of SIN_COS_TABLE_001 : label is "4434439842fc426041c44127408a3fee3f513eb33e163d783cda3c3c3b9e3b00";
--attribute INIT_1C of SIN_COS_TABLE_001 : label is "4dd44d3c4ca34c0a4b714ad84a3e49a4490a487047d6473b46a14606456b44cf";
--attribute INIT_1D of SIN_COS_TABLE_001 : label is "574156ac5617558154eb545553bf5328529151fb516350cc50354f9d4f054e6d";
--attribute INIT_1E of SIN_COS_TABLE_001 : label is "607a5fe85f565ec35e315d9e5d0b5c785be45b515abd5a2959955900586b57d7";
--attribute INIT_1F of SIN_COS_TABLE_001 : label is "697c68ed685e67cf674066b1662165926502647163e1635062bf622e619d610b";
--attribute INIT_20 of SIN_COS_TABLE_001 : label is "724671bb713070a470196f8d6f016e746de86d5b6cce6c416bb36b266a986a0a";
--attribute INIT_21 of SIN_COS_TABLE_001 : label is "7ad77a4f79c8794078b8783077a7771e7696760c758374f9746f73e5735b72d1";
--attribute INIT_22 of SIN_COS_TABLE_001 : label is "832d82aa822681a2811d809980147f8f7f0a7e847dfe7d787cf27c6c7be57b5e";
--attribute INIT_23 of SIN_COS_TABLE_001 : label is "8b488ac88a4889c8894788c6884587c4874286c1863f85bc853a84b7843483b1";
--attribute INIT_24 of SIN_COS_TABLE_001 : label is "932692aa922e91b1913590b8903a8fbd8f3f8ec18e438dc48d468cc78c478bc8";
--attribute INIT_25 of SIN_COS_TABLE_001 : label is "9ac69a4e99d6995d98e4986b97f2977896fe9684960a958f95149499941e93a2";
--attribute INIT_26 of SIN_COS_TABLE_001 : label is "a227a1b2a13ea0c9a0549fdf9f6a9ef49e7e9e089d929d1b9ca49c2d9bb69b3e";
--attribute INIT_27 of SIN_COS_TABLE_001 : label is "a947a8d6a866a7f6a785a714a6a2a631a5bfa54da4daa468a3f5a382a30ea29a";
--attribute INIT_28 of SIN_COS_TABLE_001 : label is "b025afb9af4daee0ae74ae07ad99ad2cacbeac50abe2ab73ab04aa95aa26a9b6";
--attribute INIT_29 of SIN_COS_TABLE_001 : label is "b6c1b659b5f1b589b520b4b7b44eb3e5b37bb311b2a7b23db1d2b167b0fcb091";
--attribute INIT_2A of SIN_COS_TABLE_001 : label is "bd19bcb5bc52bbedbb89bb25bac0ba5bb9f5b990b92ab8c4b85db7f6b78fb728";
--attribute INIT_2B of SIN_COS_TABLE_001 : label is "c32cc2cdc26ec20ec1aec14ec0edc08cc02bbfcabf68bf06bea4be42bddfbd7c";
--attribute INIT_2C of SIN_COS_TABLE_001 : label is "c8fac89fc844c7e9c78dc731c6d5c679c61cc5bfc562c504c4a6c448c3eac38b";
--attribute INIT_2D of SIN_COS_TABLE_001 : label is "ce82ce2bcdd5cd7ecd26cccfcc77cc1fcbc7cb6ecb15cabcca63ca09c9afc955";
--attribute INIT_2E of SIN_COS_TABLE_001 : label is "d3c2d370d31ed2cbd278d225d1d2d17ed12bd0d6d082d02dcfd8cf83cf2eced8";
--attribute INIT_2F of SIN_COS_TABLE_001 : label is "d8bad86cd81fd7d1d782d734d6e5d696d647d5f7d5a7d557d506d4b6d465d413";
--attribute INIT_30 of SIN_COS_TABLE_001 : label is "dd69dd20dcd7dc8ddc44dbfadbb0db65db1adacfda84da38d9ecd9a0d954d907";
--attribute INIT_31 of SIN_COS_TABLE_001 : label is "e1cee18ae146e101e0bce076e031dfebdfa5df5edf17ded0de89de41ddf9ddb1";
--attribute INIT_32 of SIN_COS_TABLE_001 : label is "e5e9e5aae56ae52ae4eae4a9e468e427e3e5e3a3e361e31fe2dce299e256e212";
--attribute INIT_33 of SIN_COS_TABLE_001 : label is "e9bae97fe944e908e8cde891e854e818e7dbe79ee760e722e6e4e6a6e667e629";
--attribute INIT_34 of SIN_COS_TABLE_001 : label is "ed3eed08ecd2ec9bec64ec2debf5ebbeeb85eb4deb14eadbeaa2ea68ea2ee9f4";
--attribute INIT_35 of SIN_COS_TABLE_001 : label is "f077f046f014efe2efb0ef7def4bef18eee4eeb0ee7cee48ee14eddfedaaed74";
--attribute INIT_36 of SIN_COS_TABLE_001 : label is "f363f337f30af2ddf2aff281f253f225f1f7f1c8f198f169f139f109f0d9f0a8";
--attribute INIT_37 of SIN_COS_TABLE_001 : label is "f602f5daf5b2f58af562f539f510f4e6f4bcf492f468f43df412f3e7f3bbf38f";
--attribute INIT_38 of SIN_COS_TABLE_001 : label is "f854f831f80ef7eaf7c7f7a3f77ef75af735f70ff6eaf6c4f69ef677f651f629";
--attribute INIT_39 of SIN_COS_TABLE_001 : label is "fa58fa3afa1bf9fdf9def9bff99ff980f95ff93ff91ef8fdf8dcf8baf899f876";
--attribute INIT_3A of SIN_COS_TABLE_001 : label is "fc0efbf4fbdbfbc1fba7fb8dfb72fb58fb3cfb21fb05fae9faccfab0fa93fa75";
--attribute INIT_3B of SIN_COS_TABLE_001 : label is "fd75fd61fd4cfd38fd22fd0dfcf7fce1fccbfcb4fc9efc86fc6ffc57fc3ffc26";
--attribute INIT_3C of SIN_COS_TABLE_001 : label is "fe8efe7ffe6ffe5ffe4ffe3ffe2efe1dfe0bfdfafde8fdd5fdc3fdb0fd9cfd89";
--attribute INIT_3D of SIN_COS_TABLE_001 : label is "ff58ff4eff43ff38ff2dff21ff16ff09fefdfef0fee3fed6fec8febafeabfe9d";
--attribute INIT_3E of SIN_COS_TABLE_001 : label is "ffd3ffceffc8ffc2ffbcffb5ffaeffa7ffa0ff98ff90ff87ff7eff75ff6cff62";
--attribute INIT_3F of SIN_COS_TABLE_001 : label is "fffffffffffffffefffcfffafff8fff6fff4fff1ffedffeaffe6ffe2ffddffd9";
--
---- The 2-bit INITP_XX stores the 2 MSbs of the 18-bit filter coefficients.
--attribute INITP_00 of SIN_COS_TABLE_001 : label is "0000000000000000000000000000000000000000000000000000000000000000";
--attribute INITP_01 of SIN_COS_TABLE_001 : label is "0000000000000000000000000000000000000000000000000000000000000000";
--attribute INITP_02 of SIN_COS_TABLE_001 : label is "5555555555555555555550000000000000000000000000000000000000000000";
--attribute INITP_03 of SIN_COS_TABLE_001 : label is "5555555555555555555555555555555555555555555555555555555555555555";
--attribute INITP_04 of SIN_COS_TABLE_001 : label is "5555555555555555555555555555555555555555555555555555555555555555";
--attribute INITP_05 of SIN_COS_TABLE_001 : label is "5555555555555555555555555555555555555555555555555555555555555555";
--attribute INITP_06 of SIN_COS_TABLE_001 : label is "5555555555555555555555555555555555555555555555555555555555555555";
--attribute INITP_07 of SIN_COS_TABLE_001 : label is "5555555555555555555555555555555555555555555555555555555555555555";
-----------------------------------------------------------------
-- SIGNALS
-----------------------------------------------------------------
signal ZERO: std_logic;
signal ONE: std_logic;
signal ZERO16: std_logic_vector(15 downto 0);
signal ADDRA: std_logic_vector(9 downto 0);
signal ADDRB: std_logic_vector(9 downto 0);
signal SIN0: std_logic_vector(17 downto 0);
signal COS0: std_logic_vector(17 downto 0);
signal PHASE_MSB_D: std_logic_vector(1 downto 0);
-----------------------------------------------------------------
-- IMPLEMENTATION
-----------------------------------------------------------------
begin   
ZERO <= '0';
ONE <= '1';
ZERO16 <= (others => '0');

-- The SINE table spans 0 - 90 deg. Use symmetry to reconstruct full 0 - 360 SINE/COSINE table.
SYMMETRY_IN: process(PHASE)
begin
	case(PHASE(11 downto 10)) is
		when "00" => 								-- 0 -> 90 deg
			ADDRA <= PHASE(9 downto 0); 		-- rising magnitude
			ADDRB <= not PHASE(9 downto 0);	-- falling magnitude
		when "01" => 								-- 90 -> 180 deg
			ADDRA <= not PHASE(9 downto 0);	-- falling magnitude
			ADDRB <= PHASE(9 downto 0);		-- rising magnitude
		when "10" => 							  	-- 180 -> 270 deg
			ADDRA <= PHASE(9 downto 0);		-- rising magnitude
			ADDRB <= not PHASE(9 downto 0);	-- falling magnitude
		when others => 						   -- 270 -> 0 deg
			ADDRA <= not PHASE(9 downto 0);	-- falling magnitude
			ADDRB <= PHASE(9 downto 0);		-- rising magnitude
	end case;	
end process;

-- delay the input PHASE two most significant bits to align with the block ram output.
RECLOCK_001: process(CLK)
begin
	if rising_edge(CLK) then
		PHASE_MSB_D <= PHASE(11 downto 10);
	end if;
end process;

-- Swap comment lines during simulation
--SIN_COS_TABLE_001: RAMB16_S18_S18SIN -- for simulation purposes
SIN_COS_TABLE_001: RAMB16_S18_S18
generic map(
	INIT_00=> x"0bc80aff0a36096d08a407db07110648057f04b603ed0324025b019200c90000",
	INIT_01=> x"1857178e16c515fc1533146a13a112d8120f1147107e0fb50eec0e230d5a0c91",
	INIT_02=> x"24e224192351228821bf20f7202e1f651e9d1dd41d0b1c431b7a1ab119e8191f",
	INIT_03=> x"3167309f2fd72f0f2e462d7e2cb62bee2b252a5d299528cc2804273b267325aa",
	INIT_04=> x"3de53d1d3c563b8e3ac639ff3937386f37a736df3617354f348733bf32f7322f",
	INIT_05=> x"4a59499248cb4804473d467645af44e844214359429241cb4103403c3f743ead",
	INIT_06=> x"56c255fc5536546f53a952e3521c5156508f4fc94f024e3b4d754cae4be74b20",
	INIT_07=> x"631e6258619360ce60085f435e7d5db75cf25c2c5b665aa059da5914584e5788",
	INIT_08=> x"6f6a6ea66de16d1d6c586b946acf6a0b6946688167bc66f76632656d64a863e3",
	INIT_09=> x"7ba57ae27a1e795b789877d47711764d758a74c67402733e727a71b670f2702e",
	INIT_0A=> x"87cd870b8649858784c584028340827e81bb80f980367f737eb17dee7d2b7c68",
	INIT_0B=> x"93e0931f925f919e90dd901c8f5b8e9a8dd98d188c568b958ad48a128950888f",
	INIT_0C=> x"9fdc9f1d9e5e9d9e9cdf9c209b609aa199e19921986197a196e19621956194a0",
	INIT_0D=> x"abbfab02aa44a987a8c9a80ba74da68fa5d1a513a454a396a2d7a219a15aa09b",
	INIT_0E=> x"b789b6cdb611b555b499b3ddb320b264b1a7b0ebb02eaf71aeb4adf7ad3aac7d",
	INIT_0F=> x"c335c27bc1c1c107c04dbf92bed8be1dbd63bca8bbedbb32ba76b9bbb900b844",
	INIT_10=> x"cec4ce0ccd54cc9ccbe3cb2bca72c9b9c900c847c78ec6d5c61cc562c4a9c3ef",
	INIT_11=> x"da33d97dd8c7d810d75ad6a4d5edd536d47fd3c8d311d25ad1a3d0ebd034cf7c",
	INIT_12=> x"e580e4cce418e364e2b0e1fbe147e092dfdedf29de74ddbedd09dc54db9edae9",
	INIT_13=> x"f0aaeff8ef46ee94ede3ed30ec7eebcceb19ea67e9b4e901e84ee79ae6e7e633",
	INIT_14=> x"fbaefafffa50f9a0f8f1f841f791f6e1f631f580f4d0f41ff36ef2bdf20cf15b",
	INIT_15=> x"068c05df0532048503d8032b027d01d001220074ffc6ff18fe69fdbbfd0cfc5d",
	INIT_16=> x"114110970fed0f420e980ded0d420c970bec0b400a9509e9093d089107e50738",
	INIT_17=> x"1bcc1b251a7d19d6192e188617dd1735168c15e3153a149113e8133f129511eb",
	INIT_18=> x"262c258724e2243d239822f3224d21a82102205c1fb51f0f1e681dc21d1b1c74",
	INIT_19=> x"305e2fbc2f1a2e782dd62d332c912bee2b4b2aa72a04296028bd2819277526d0",
	INIT_1A=> x"3a6139c23923388437e5374536a53606356534c53425338432e3324231a130ff",
	INIT_1B=> x"4434439842fc426041c44127408a3fee3f513eb33e163d783cda3c3c3b9e3b00",
	INIT_1C=> x"4dd44d3c4ca34c0a4b714ad84a3e49a4490a487047d6473b46a14606456b44cf",
	INIT_1D=> x"574156ac5617558154eb545553bf5328529151fb516350cc50354f9d4f054e6d",
	INIT_1E=> x"607a5fe85f565ec35e315d9e5d0b5c785be45b515abd5a2959955900586b57d7",
	INIT_1F=> x"697c68ed685e67cf674066b1662165926502647163e1635062bf622e619d610b",
	INIT_20=> x"724671bb713070a470196f8d6f016e746de86d5b6cce6c416bb36b266a986a0a",
	INIT_21=> x"7ad77a4f79c8794078b8783077a7771e7696760c758374f9746f73e5735b72d1",
	INIT_22=> x"832d82aa822681a2811d809980147f8f7f0a7e847dfe7d787cf27c6c7be57b5e",
	INIT_23=> x"8b488ac88a4889c8894788c6884587c4874286c1863f85bc853a84b7843483b1",
	INIT_24=> x"932692aa922e91b1913590b8903a8fbd8f3f8ec18e438dc48d468cc78c478bc8",
	INIT_25=> x"9ac69a4e99d6995d98e4986b97f2977896fe9684960a958f95149499941e93a2",
	INIT_26=> x"a227a1b2a13ea0c9a0549fdf9f6a9ef49e7e9e089d929d1b9ca49c2d9bb69b3e",
	INIT_27=> x"a947a8d6a866a7f6a785a714a6a2a631a5bfa54da4daa468a3f5a382a30ea29a",
	INIT_28=> x"b025afb9af4daee0ae74ae07ad99ad2cacbeac50abe2ab73ab04aa95aa26a9b6",
	INIT_29=> x"b6c1b659b5f1b589b520b4b7b44eb3e5b37bb311b2a7b23db1d2b167b0fcb091",
	INIT_2A=> x"bd19bcb5bc52bbedbb89bb25bac0ba5bb9f5b990b92ab8c4b85db7f6b78fb728",
	INIT_2B=> x"c32cc2cdc26ec20ec1aec14ec0edc08cc02bbfcabf68bf06bea4be42bddfbd7c",
	INIT_2C=> x"c8fac89fc844c7e9c78dc731c6d5c679c61cc5bfc562c504c4a6c448c3eac38b",
	INIT_2D=> x"ce82ce2bcdd5cd7ecd26cccfcc77cc1fcbc7cb6ecb15cabcca63ca09c9afc955",
	INIT_2E=> x"d3c2d370d31ed2cbd278d225d1d2d17ed12bd0d6d082d02dcfd8cf83cf2eced8",
	INIT_2F=> x"d8bad86cd81fd7d1d782d734d6e5d696d647d5f7d5a7d557d506d4b6d465d413",
	INIT_30=> x"dd69dd20dcd7dc8ddc44dbfadbb0db65db1adacfda84da38d9ecd9a0d954d907",
	INIT_31=> x"e1cee18ae146e101e0bce076e031dfebdfa5df5edf17ded0de89de41ddf9ddb1",
	INIT_32=> x"e5e9e5aae56ae52ae4eae4a9e468e427e3e5e3a3e361e31fe2dce299e256e212",
	INIT_33=> x"e9bae97fe944e908e8cde891e854e818e7dbe79ee760e722e6e4e6a6e667e629",
	INIT_34=> x"ed3eed08ecd2ec9bec64ec2debf5ebbeeb85eb4deb14eadbeaa2ea68ea2ee9f4",
	INIT_35=> x"f077f046f014efe2efb0ef7def4bef18eee4eeb0ee7cee48ee14eddfedaaed74",
	INIT_36=> x"f363f337f30af2ddf2aff281f253f225f1f7f1c8f198f169f139f109f0d9f0a8",
	INIT_37=> x"f602f5daf5b2f58af562f539f510f4e6f4bcf492f468f43df412f3e7f3bbf38f",
	INIT_38=> x"f854f831f80ef7eaf7c7f7a3f77ef75af735f70ff6eaf6c4f69ef677f651f629",
	INIT_39=> x"fa58fa3afa1bf9fdf9def9bff99ff980f95ff93ff91ef8fdf8dcf8baf899f876",
	INIT_3A=> x"fc0efbf4fbdbfbc1fba7fb8dfb72fb58fb3cfb21fb05fae9faccfab0fa93fa75",
	INIT_3B=> x"fd75fd61fd4cfd38fd22fd0dfcf7fce1fccbfcb4fc9efc86fc6ffc57fc3ffc26",
	INIT_3C=> x"fe8efe7ffe6ffe5ffe4ffe3ffe2efe1dfe0bfdfafde8fdd5fdc3fdb0fd9cfd89",
	INIT_3D=> x"ff58ff4eff43ff38ff2dff21ff16ff09fefdfef0fee3fed6fec8febafeabfe9d",
	INIT_3E=> x"ffd3ffceffc8ffc2ffbcffb5ffaeffa7ffa0ff98ff90ff87ff7eff75ff6cff62",
	INIT_3F=> x"fffffffffffffffefffcfffafff8fff6fff4fff1ffedffeaffe6ffe2ffddffd9",

	-- The 2-bit INITP_XX stores the 2 MSbs of the 18-bit filter coefficients.
	INITP_00=> x"0000000000000000000000000000000000000000000000000000000000000000",
	INITP_01=> x"0000000000000000000000000000000000000000000000000000000000000000",
	INITP_02=> x"5555555555555555555550000000000000000000000000000000000000000000",
	INITP_03=> x"5555555555555555555555555555555555555555555555555555555555555555",
	INITP_04=> x"5555555555555555555555555555555555555555555555555555555555555555",
	INITP_05=> x"5555555555555555555555555555555555555555555555555555555555555555",
	INITP_06=> x"5555555555555555555555555555555555555555555555555555555555555555",
	INITP_07=> x"5555555555555555555555555555555555555555555555555555555555555555"
)
port map (
   DOA => SIN0(15 downto 0),    -- 16-bit Data Output
   DOPA => SIN0(17 downto 16), 	-- + 2 extra bits 
   ADDRA => ADDRA,  					-- 10-bit Address Input
   CLKA => CLK,    					-- Clock
   DIA => ZERO16,
   DIPA => ZERO16(1 downto 0), 
   ENA => ONE,      					-- RAM Enable Input
   SSRA => ZERO,    					-- Synchronous Set/Reset Input
   WEA => ZERO,						-- Write Enable Input
   DOB => COS0(15 downto 0),  	-- 16-bit Data Output
   DOPB => COS0(17 downto 16), 	-- + 2 extra bits 
   ADDRB => ADDRB,  					-- 10-bit Address Input
   CLKB => CLK,    					-- Clock
   DIB => ZERO16,
   DIPB => ZERO16(1 downto 0), 
   ENB => ONE,      					-- RAM Enable Input
   SSRB => ZERO,    					-- Synchronous Set/Reset Input
   WEB => ZERO      					-- Write Enable Input
);



SYMMETRY_OUT: process(CLK)
begin
	if rising_edge(CLK) then
		if(PHASE_MSB_D(1) = '0') then
			-- positive SINE
			SIN_OUT <= SIN0;
		else
			-- negative SINE
			SIN_OUT <= not(SIN0) + 1;
		end if;

		if(PHASE_MSB_D(1) = PHASE_MSB_D(0)) then
			-- positive COSINE
			COS_OUT <= COS0;
		else
			-- negative SINE
			COS_OUT <= not(COS0) + 1;
		end if;

	end if;

end process;

				
end BEHAVIOR;

		

