-------------------------------------------------------------------------------- -- 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 nco is Generic ( nbits_wave : integer := 18; nbits_phase : integer := 16; nbits_lut_depth : integer := 12; nbits_dither : integer := 4; nbits_lfsr : integer := 12; q_phase : phase_relation_t := phase_90deg; has_pipe_reg : boolean := false; has_out_reg : boolean := false ); Port ( srst : in std_logic; clk : in std_logic; pacc_clr : in std_logic; pacc_inc : in std_logic; freq_in : in unsigned(nbits_phase-1 downto 0); freq_load : in std_logic; phase_in : in unsigned(nbits_phase-1 downto 0); phase_load : in std_logic; phase_out : out unsigned(nbits_phase-1 downto 0); wave_out_i : out sfixed; wave_out_q : out sfixed; out_valid : out std_logic; debug_out : out debug_out_t ); end nco; architecture Behavioral of nco is COMPONENT wavelut Generic ( nbits_wave : integer; nbits_wave_frac : integer; nbits_lut_depth : integer; q_phase : phase_relation_t; has_out_reg : boolean ); Port ( clk : in std_logic; rst : 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 COMPONENT; ------------------------------------------------------------------------------- constant nbits_wave_frac : integer := nbits_wave; ------------------------------------------------------------------------------- constant lfsr_gen_poly : unsigned(nbits_lfsr-1 downto 0) := to_unsigned(lfsr_poly(nbits_lfsr), nbits_lfsr); -- 24 signal phase : unsigned(nbits_phase-1 downto 0); signal freq_in_r : unsigned(nbits_phase-1 downto 0); signal phase_in_r : unsigned(nbits_phase-1 downto 0); signal lut_addr_ud : unsigned(nbits_lut_depth-1 downto 0); signal lut_addr_d : unsigned(nbits_lut_depth-1 downto 0); signal wave_i_d, wave_q_d : sfixed(sproto(nbits_wave, nbits_wave_frac)'high downto sproto(nbits_wave, nbits_wave_frac)'low); signal wave_i_ud, wave_q_ud : sfixed(sproto(nbits_wave, nbits_wave_frac)'high downto sproto(nbits_wave, nbits_wave_frac)'low); type lfsr_t is array (0 to 1) of unsigned(nbits_lfsr-1 downto 0); signal lfsr : lfsr_t; signal lfsr_out : unsigned(nbits_dither-1 downto 0); signal lut_addr_valid, lfsr_valid, wave_d_valid, wave_ud_valid : std_logic; ------------------------------------------------------------------------------- begin wave_out_i <= wave_i_d; wave_out_q <= wave_q_d; out_valid <= wave_d_valid; debug_out.lfsr <= (debug_out.lfsr'left downto (debug_out.lfsr'right+lfsr_out'left+1) => '0') & lfsr_out; debug_out.i_d <= to_real(wave_i_d); debug_out.q_d <= to_real(wave_q_d); debug_out.i_ud <= to_real(wave_i_ud); debug_out.q_ud <= to_real(wave_q_ud); ------------------------------------------------------------ proc_lfsr: process(srst, clk, lfsr, pacc_inc) variable lo : unsigned(nbits_dither-1 downto 0); begin if rising_edge(clk) then if srst = '1' then lfsr_valid <= '0'; lfsr_out <= (others => '0'); for i in lfsr'range loop lfsr(i) <= to_unsigned(2**i, nbits_lfsr); end loop; else lfsr_valid <= '0'; if pacc_inc ='1' then lfsr_valid <= '1'; lo := (others => '0'); for i in lfsr'range loop if lfsr(i)(lfsr(i)'left) = '1' then lfsr(i) <= (lfsr(i)(lfsr(i)'left-1 downto 0) & lfsr(i)(lfsr(i)'left)) xor lfsr_gen_poly; else lfsr(i) <= lfsr(i)(lfsr(i)'left-1 downto 0) & lfsr(i)(lfsr(i)'left); end if; end loop; for i in lfsr'range loop lo := lo + lfsr(i)(nbits_dither-1 downto 0); end loop; -- lo := lfsr(0)(nbits_dither downto 0); lfsr_out <= lo(nbits_dither-1 downto 0); end if; end if; end if; end process; ------------------------------------------------------------ proc_phase_accu: process(srst, clk, pacc_clr, pacc_inc, freq_in_r, phase_in_r) variable phase_accu : unsigned(nbits_phase-1 downto 0); begin if rising_edge(clk) then if srst = '1' then phase_accu := (others => '0'); else phase <= phase_accu + phase_in_r; if pacc_clr = '1' then phase_accu := (others => '0'); elsif pacc_inc = '1' then phase_accu := phase_accu + freq_in_r; end if; end if; end if; phase_out <= phase; end process; ------------------------------------------------------------ freq_in_reg: process(srst, clk, freq_load, freq_in) begin if rising_edge(clk) then if srst = '1' then freq_in_r <= (others => '0'); elsif freq_load = '1' then freq_in_r <= freq_in; end if; end if; end process; ------------------------------------------------------------ phase_in_reg: process(srst, clk, phase_load, phase_in) begin if rising_edge(clk) then if srst = '1' then phase_in_r <= (others => '0'); elsif phase_load = '1' then phase_in_r <= phase_in; end if; end if; end process; ------------------------------------------------------------ proc_pipe_reg: process(clk) variable lfsr_sum : unsigned(nbits_phase-1 downto 0); begin if rising_edge(clk) then lut_addr_valid <= '0'; if srst = '1' then lfsr_sum := (others => '0'); elsif lfsr_valid = '1' then lut_addr_valid <= '1'; lfsr_sum := lfsr_out + phase; end if; end if; lut_addr_d <= lfsr_sum(nbits_phase-1 downto nbits_phase-nbits_lut_depth); lut_addr_ud <= phase(nbits_phase-1 downto nbits_phase-nbits_lut_depth); end process; ------------------------------------------------------------ inst_wavelut_ud: wavelut GENERIC MAP ( nbits_wave => nbits_wave, nbits_wave_frac => nbits_wave_frac, nbits_lut_depth => nbits_lut_depth, q_phase => q_phase, has_out_reg => has_out_reg ) PORT MAP ( rst => srst, clk => clk, addr_valid => lut_addr_valid, addr => lut_addr_ud, wave_i_out => wave_i_ud, wave_q_out => wave_q_ud, valid_out => wave_ud_valid ); inst_wavelut_d: wavelut GENERIC MAP ( nbits_wave => nbits_wave, nbits_wave_frac => nbits_wave_frac, nbits_lut_depth => nbits_lut_depth, q_phase => q_phase, has_out_reg => has_out_reg ) PORT MAP ( rst => srst, clk => clk, addr_valid => lut_addr_valid, addr => lut_addr_d, wave_i_out => wave_i_d, wave_q_out => wave_q_d, valid_out => wave_d_valid ); ------------------------------------------------------------ end Behavioral;