-------------------------------------------------------------------------------- -- 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; use work.fixed_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 := 12; nbits_phase : integer := 16; nbits_lut_depth : integer := 12; nbits_dither : integer := 4; nbits_lfsr : integer := 12; 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 ); end nco; architecture Behavioral of nco is COMPONENT wavelut Generic ( nbits_wave : integer; nbits_wave_frac : integer; nbits_lut_depth : integer; has_out_reg : boolean ); Port ( 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 ); 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 valid : std_logic_vector(3 downto 0); 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 lsfr_sum : unsigned(nbits_phase-1 downto 0); signal lut_addr : unsigned(nbits_lut_depth-1 downto 0); signal wave_i, wave_q : 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 _ std_logic; ------------------------------------------------------------------------------- begin wave_out_i <= wave_i; wave_out_q <= wave_q; ------------------------------------------------------------ proc_ctrl: process(srst, clk, pacc_inc, pacc_clr) begin if rising_edge(clk) then if srst = '1' then valid <= (others => '0'); else valid <= valid(valid'left-1 downto valid'right) & (pacc_inc or pacc_clr); end if; end if; end process; ------------------------------------------------------------ proc_lfsr: process(srst, clk, lfsr, pacc_inc) variable lo : unsigned(nbits_dither downto 0); begin if rising_edge(clk) then if srst = '1' then for i in lfsr'range loop lfsr(i) <= to_unsigned(1234+2**i, nbits_lfsr); end loop; elsif pacc_inc ='1' then 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 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; 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) begin if rising_edge(clk) then lsfr_sum <= lfsr_out + phase; lut_addr <= lsfr_sum(nbits_phase-1 downto nbits_phase-nbits_lut_depth); end if; end process; ------------------------------------------------------------ proc_out_reg: process(clk, phase) begin if has_out_reg = true then if rising_edge(clk) then phase_out <= phase; end if; else phase_out <= phase; end if; end process; ------------------------------------------------------------ proc_valid_reg: process(clk, valid) begin out_valid <= valid(valid'right+1); if has_out_reg = true then out_valid <= valid(valid'right+2); if has_pipe_reg = true then out_valid <= valid(valid'right+3); end if; elsif has_pipe_reg = true then out_valid <= valid(valid'right+2); end if; end process; ------------------------------------------------------------ inst_wavelut_d: wavelut GENERIC MAP ( nbits_wave => nbits_wave, nbits_wave_frac => nbits_wave_frac, nbits_lut_depth => nbits_lut_depth, has_out_reg => has_out_reg ) PORT MAP ( clk => clk, addr => lut_addr, addr_valid => lut_addr_valid, wave_i_out => wave_i, wave_q_out => wave_q ); ------------------------------------------------------------ end Behavioral;