summaryrefslogtreecommitdiff
path: root/FPGA/vhdl/dds_sinus.vhd
blob: d47f2905b49bd42cddb0ae63ffe28f3ca012aec8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
----------------------------------------------------
--         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;
    incr_step   : in  std_logic_vector(M-1      downto 0);
    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 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 <unsigned(incr_step))
	             else  std_logic_vector(middle + unsigned(data_sinus));

------------------------------------------------------
--        sinus : fonction tabulee du quart de sinus
------------------------------------------------------            
tab_sinus: entity work.rom_sinus 
  generic map (
    N_data     => N_data,
    N_adr_ROM  => N_adr_ROM,
    amplitude  => amplitude
  )  
  port map(		   
    address   => address_sinus,
    clk       => clk, 
    data      => data_sinus
  );
	 
end architecture;