---------------------------------------------------- -- DDS : sinus ---------------------------------------------------- -- ESIEE -- creation : A. Exertier, 06/2009 -- modification : A. Exertier, 12/2011 ---------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; ----------------------------------------------------- -- GENERIC PARAMETER ----------------------------------------------------- -- N_data : output data number of bits -- M : phase accumulator precision -- amplitude : sinus amplitude -- should be < 2**N_data ----------------------------------------------------- -- INPUTS ----------------------------------------------------- -- clk : clock -- resetn : asynchronous reset (active low) -- incr_step : incrementation step (N_adr_ROM bits) -- => sinus frequency ----------------------------------------------------- -- OUTPUT ----------------------------------------------------- -- dds_out : output data (N_data bits) ----------------------------------------------------- entity dds_sinus is generic( N_data : positive := 16; M : positive := 12 ); port ( resetn : in std_logic; clk : in std_logic; en : in std_logic; dds_out : out std_logic_vector(N_data-1 downto 0) ); end dds_sinus; architecture RTL of dds_sinus is constant amplitude : positive :=2**(N_data-1)-1; constant incr_step : std_logic_vector(M-1 downto 0):= (0=>'1', others => '0'); constant N_adr_ROM : positive := M-2; constant middle : unsigned (N_data-1 downto 0) := to_unsigned(2**(dds_out'length-1),dds_out'length); --(N_data-1=>'1', others => '0'); signal counter : unsigned(N_adr_ROM+1 downto 0); signal address_sinus : std_logic_vector(N_adr_ROM-1 downto 0); signal data_sinus : std_logic_vector(N_data-2 downto 0); signal dds_out_int : std_logic_vector(dds_out'range); begin ------------------------------------ -- counter & output register ------------------------------------ process(resetn, clk) is begin if resetn = '0' then counter <= (others => '0'); dds_out <= (others => '0'); dds_out(dds_out'high) <= '1'; elsif rising_edge(clk) then if en = '1' then counter <= counter+unsigned(incr_step); dds_out <= dds_out_int; end if; end if; end process; ------------------------------------- -- address & signed output ------------------------------------- address_sinus <= std_logic_vector(counter(address_sinus'range)) when counter <2**(N_adr_ROM) or (counter >= 2**(N_adr_ROM+1) and counter <2**(N_adr_ROM)*3) else std_logic_vector(2**(N_adr_ROM)-1 - counter(address_sinus'range)) ; dds_out_int <= std_logic_vector(middle - unsigned(data_sinus)) when (counter >=(2**(N_adr_ROM+1)) + unsigned(incr_step)) or (counter N_data, N_adr_ROM => N_adr_ROM, amplitude => amplitude ) port map( address => address_sinus, clk => clk, data => data_sinus ); end architecture;