--------------------------------------------------------------------------------
-- 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.nco_pkg.all;

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

entity waverom_dual is
Generic
(
	nbits_wave		: integer := 12;
	nbits_wave_frac	: integer := 12;
	nbits_rom_depth	: integer := 12
);
Port
(
	clk			: in std_logic;
	addr_i		: in unsigned(nbits_rom_depth-1 downto 0);
	addr_q		: in unsigned(nbits_rom_depth-1 downto 0);
	wave_i_out	: out sfixed;
	wave_q_out	: out sfixed
);
end waverom_dual;

architecture Behavioral of waverom_dual is

-------------------------------------------------------------------------------
constant rom_depth : integer := 2**nbits_rom_depth;
type wave_mem_t is array (0 to rom_depth-1) of sfixed(sproto(nbits_wave, nbits_wave_frac)'high downto sproto(nbits_wave, nbits_wave_frac)'low);

constant sfixed_proto : sfixed(sproto(nbits_wave, nbits_wave_frac)'high downto sproto(nbits_wave, nbits_wave_frac)'low) := (others => '0');

-------------------------------------------------------------------------------
function to_wave_mem(wave_real : real_array_t; len : integer; proto : sfixed) return wave_mem_t is
variable res : wave_mem_t;
begin
	for i in 0 to len-1 loop
		res(i) := to_sfixed(wave_real(i), proto, fixed_saturate, fixed_round);
	end loop;

	return res;
end to_wave_mem;	

-------------------------------------------------------------------------------
-- Create ROM
constant real_wave_tbl : real_array_t(0 to rom_depth-1) := cos_tbl(rom_depth, 0.25/real(rom_depth), 0.0);
constant wave_tbl : wave_mem_t := to_wave_mem(real_wave_tbl, rom_depth, sfixed_proto);

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

-------------------------------------------------------------------------------
proc_wave: process(clk)
	begin
		if rising_edge(clk) then
			wave_i_out <= wave_tbl(to_integer(addr_i));
			wave_q_out <= wave_tbl(to_integer(addr_q));
		end if;	
	end process;

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