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;
|