-------------------------------------------------------------------------------- -- 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 wavelut is Generic ( nbits_wave : integer := 12; nbits_wave_frac : integer := 12; nbits_lut_depth : integer := 12; q_phase : phase_relation_t := phase_90deg; has_out_reg : boolean := false ); Port ( rst : in std_logic; clk : in std_logic; addr_valid : in std_logic; addr : in unsigned(nbits_lut_depth-1 downto 0); wave_i_out : out sfixed; wave_q_out : out sfixed; valid_out : out std_logic ); end wavelut; architecture Behavioral of wavelut is COMPONENT waverom_dual Generic ( nbits_wave : integer; nbits_wave_frac : integer; nbits_rom_depth : integer ); 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 COMPONENT; ------------------------------------------------------------------------------- constant nbits_rom_depth : integer := nbits_lut_depth-2; ------------------------------------------------------------------------------- signal wave_i : sfixed(sproto(nbits_wave, nbits_wave_frac)'high downto sproto(nbits_wave, nbits_wave_frac)'low); signal wave_q : sfixed(sproto(nbits_wave, nbits_wave_frac)'high downto sproto(nbits_wave, nbits_wave_frac)'low); signal inv_i : std_logic; signal inv_q : std_logic; signal addr_i : unsigned(nbits_rom_depth-1 downto 0); signal addr_q : unsigned(nbits_rom_depth-1 downto 0); signal zero_i : std_logic; signal zero_q : std_logic; ------------------------------------------------------------------------------- begin inst_waverom_dual: waverom_dual GENERIC MAP ( nbits_wave => nbits_wave, nbits_wave_frac => nbits_wave_frac, nbits_rom_depth => nbits_rom_depth ) PORT MAP ( clk => clk, addr_i => addr_i, addr_q => addr_q, wave_i_out => wave_i, wave_q_out => wave_q ); ------------------------------------------------------------ proc_valid: process(clk) variable v : unsigned(0 to 1); begin if rising_edge(clk) then if rst = '1' then v := (others => '0'); valid_out <= '0'; else valid_out <= v(1); v(1) := v(0); v(0) := addr_valid; end if; end if; end process; ------------------------------------------------------------ proc_tbl_addr_i: process(clk, addr) variable index : unsigned(addr'left downto addr'right); variable n2 : integer; constant N_2 : integer := 2**(nbits_lut_depth-1); constant N_4 : integer := 2**(nbits_lut_depth-2); begin n2 := to_integer(addr(addr'left-1 downto addr'right)); if n2 > N_4 then index := to_unsigned(N_2 - n2, index'length); else index := to_unsigned(n2, index'length); end if; if rising_edge(clk) then if rst = '1' then addr_i <= (others => '0'); zero_i <= '0'; inv_i <= '0'; elsif addr_valid = '1' then addr_i <= index(addr'left-2 downto addr'right); zero_i <= index(addr'left-1); inv_i <= addr(addr'left) xor addr(addr'left-1); end if; end if; end process; ------------------------------------------------------------------------------- proc_tbl_addr_q: process(clk, addr) variable index : unsigned(addr'left downto addr'right); variable n2 : integer; constant N_4 : integer := 2**(nbits_lut_depth-2); begin n2 := to_integer(addr(addr'left-1 downto addr'right)); if n2 > N_4 then index := to_unsigned(n2 - N_4, index'length); else index := to_unsigned(N_4 - n2, index'length); end if; if rising_edge(clk) then if rst = '1' then addr_q <= (others => '0'); zero_q <= '0'; inv_q <= '0'; elsif addr_valid = '1' then addr_q <= index(addr'left-2 downto addr'right); zero_q <= index(addr'left-1); if q_phase = phase_90deg then inv_q <= addr(addr'left); elsif q_phase = phase_270deg then inv_q <= not addr(addr'left); end if; end if; end if; end process; ------------------------------------------------------------ proc_out_i: process(clk, wave_i, inv_i, zero_i) variable w : sfixed(sproto(nbits_wave, nbits_wave_frac)'high downto sproto(nbits_wave, nbits_wave_frac)'low); variable z, inv : std_logic; begin w := to_sfixed(0.0, w); if z = '0' then w := wave_i; if inv = '1' then w := resize(-wave_i, w, fixed_wrap, fixed_truncate); end if; end if; if has_out_reg = true then if rising_edge(clk) then wave_i_out <= w; end if; else wave_i_out <= w; end if; if rising_edge(clk) then z := zero_i; inv := inv_i; end if; end process; ------------------------------------------------------------ proc_out_q: process(clk, wave_q, inv_q, zero_q) variable w : sfixed(sproto(nbits_wave, nbits_wave_frac)'high downto sproto(nbits_wave, nbits_wave_frac)'low); variable z, inv : std_logic; begin w := to_sfixed(0.0, w); if z = '0' then w := wave_q; if inv = '1' then w := resize(-wave_q, w, fixed_wrap, fixed_truncate); end if; end if; if has_out_reg = true then if rising_edge(clk) then wave_q_out <= w; end if; else wave_q_out <= w; end if; if rising_edge(clk) then z := zero_q; inv := inv_q; end if; end process; ------------------------------------------------------------ end Behavioral;