OpenCores
URL https://opencores.org/ocsvn/lpd8806/lpd8806/trunk

Subversion Repositories lpd8806

[/] [lpd8806/] [trunk/] [dds_pack.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 jclaytons
--------------------------------------------------------------------------
2
-- Package of dds components
3
--
4
--
5
 
6
library ieee;
7
use ieee.std_logic_1164.all;
8
use ieee.numeric_std.all;
9
 
10
library work;
11
use work.sine_lut_pkg.all;
12
 
13
package dds_pack is
14
 
15
  component dds_constant_squarewave
16
    generic (
17
      OUTPUT_FREQ  : real;   -- Desired output frequency
18
      SYS_CLK_RATE : real;   -- underlying clock rate
19
      ACC_BITS     : integer -- Bit width of DDS phase accumulator
20
    );
21
    port (
22
 
23
      sys_rst_n    : in  std_logic;
24
      sys_clk      : in  std_logic;
25
      sys_clk_en   : in  std_logic;
26
 
27
      -- Output
28
      pulse_o      : out std_logic;
29
      squarewave_o : out std_logic
30
    );
31
  end component;
32
 
33
  component dds_squarewave
34
    generic (
35
      ACC_BITS     : integer -- Bit width of DDS phase accumulator
36
    );
37
    port (
38
 
39
      sys_rst_n    : in  std_logic;
40
      sys_clk      : in  std_logic;
41
      sys_clk_en   : in  std_logic;
42
 
43
      -- Frequency setting
44
      freq_i       : in  unsigned(ACC_BITS-1 downto 0);
45
 
46
      -- Output
47
      pulse_o      : out std_logic;
48
      squarewave_o : out std_logic
49
    );
50
  end component;
51
 
52
  component dds_sine_non_power_of_two
53
    generic(
54
      PHI_WIDTH : integer  -- Bits in phase accumulator.  Must hold numbers greater than full sinewave lut length...
55
      );
56
    port(
57
      clk_i     : in  std_logic;
58
      rst_n_i   : in  std_logic;
59
      clk_en_i  : in  std_logic;
60
      ftw_i     : in  unsigned(PHI_WIDTH-1 downto 0);
61
      accum_o   : out unsigned(PHI_WIDTH-1 downto 0);
62
      sine_o    : out signed(AMPL_WIDTH-1 downto 0)
63
      );
64
  end component;
65
 
66
end dds_pack;
67
 
68
package body dds_pack is
69
end dds_pack;
70
 
71
-------------------------------------------------------------------------------
72
-- Direct Digital Synthesizer Constant Squarewave module
73
-------------------------------------------------------------------------------
74
--
75
-- Author: John Clayton
76
-- Update: Sep.  5, 2002 copied this file from "auto_baud_pack.vhd"
77
--                       Added tracking functions, and debugged them.
78
--
79
-- Description
80
-------------------------------------------------------------------------------
81
-- This is a simple direct digital synthesizer module.  It includes a phase
82
-- accumulator which increments in order to produce the desired output
83
-- frequency in its most significant bit, which is the squarewave output.
84
--
85
-- In addition to the squarewave output there is a pulse output which is
86
-- high for one sys_clk period, during the sys_clk period immediately
87
-- preceding the rising edge of the squarewave output.
88
--
89
-- NOTES:
90
--   The accumulator increment word is:
91
--        increment = Fout*2^N/Fsys_clk
92
--
93
--   Where N is the number of bits in the phase accumulator.
94
--
95
--   There will always be jitter with this type of clock source, but the
96
--   long time average frequency can be made arbitrarily close to whatever
97
--   value is desired, simply by increasing N.
98
--
99
--   To reduce jitter, use a higher underlying system clock frequency, and
100
--   for goodness sakes, try to keep the desired output frequency much lower
101
--   than the system clock frequency.  The closer it gets to Fsys_clk/2, the
102
--   closer it is to the Nyquist limit, and the output jitter is much more
103
--   significant at that point.
104
--
105
--
106
 
107
 
108
library IEEE;
109
use IEEE.STD_LOGIC_1164.ALL;
110
use IEEE.NUMERIC_STD.ALL;
111
use IEEE.MATH_REAL.ALL;
112
 
113
  entity dds_constant_squarewave is
114
    generic (
115
      OUTPUT_FREQ  : real := 8000.0;     -- Desired output frequency
116
      SYS_CLK_RATE : real := 48000000.0; -- underlying clock rate
117
      ACC_BITS     : integer := 16       -- Bit width of DDS phase accumulator
118
    );
119
    port (
120
 
121
      sys_rst_n    : in  std_logic;
122
      sys_clk      : in  std_logic;
123
      sys_clk_en   : in  std_logic;
124
 
125
      -- Output
126
      pulse_o      : out std_logic;
127
      squarewave_o : out std_logic
128
    );
129
  end dds_constant_squarewave;
130
 
131
architecture beh of dds_constant_squarewave is
132
 
133
-- Constants
134
constant DDS_INCREMENT : integer := integer(OUTPUT_FREQ*(2**real(ACC_BITS))/SYS_CLK_RATE);
135
 
136
signal dds_phase      : unsigned(ACC_BITS-1 downto 0); -- phase accumulator register
137
signal dds_phase_next : unsigned(ACC_BITS-1 downto 0);
138
 
139
-----------------------------------------------------------------------------
140
begin
141
 
142
  dds_proc: Process(sys_rst_n,sys_clk)
143
  begin
144
    if (sys_rst_n = '0') then
145
      dds_phase <= (others=>'0');
146
    elsif (sys_clk'event and sys_clk='1') then
147
      if (sys_clk_en='1') then
148
        dds_phase <= dds_phase_next;
149
      end if;
150
    end if; -- sys_clk
151
  end process dds_proc;
152
  dds_phase_next <= dds_phase + DDS_INCREMENT;
153
  pulse_o <= '1' when sys_clk_en='1' and dds_phase(dds_phase'length-1)='0' and dds_phase_next(dds_phase_next'length-1)='1' else '0';
154
  squarewave_o <= dds_phase(dds_phase'length-1);
155
 
156
end beh;
157
 
158
 
159
-------------------------------------------------------------------------------
160
-- Direct Digital Synthesizer Constant Squarewave module
161
-------------------------------------------------------------------------------
162
--
163
-- Author: John Clayton
164
-- Update: Jan. 31, 2013 copied code from dds_constant_squarewave, and
165
--                       modified it to accept a frequency setting input.
166
--
167
-- Description
168
-------------------------------------------------------------------------------
169
-- This is a simple direct digital synthesizer module.  It includes a phase
170
-- accumulator which increments in order to produce the desired output
171
-- frequency in its most significant bit, which is the squarewave output.
172
--
173
-- In addition to the squarewave output there is a pulse output which is
174
-- high for one sys_clk period, during the sys_clk period immediately
175
-- preceding the rising edge of the squarewave output.
176
--
177
-- NOTES:
178
--   The accumulator increment word is:
179
--        increment = Fout*2^N/Fsys_clk
180
--
181
--   Where N is the number of bits in the phase accumulator.
182
--
183
--   There will always be jitter with this type of clock source, but the
184
--   long time average frequency can be made arbitrarily close to whatever
185
--   value is desired, simply by increasing N.
186
--
187
--   To reduce jitter, use a higher underlying system clock frequency, and
188
--   for goodness sakes, try to keep the desired output frequency much lower
189
--   than the system clock frequency.  The closer it gets to Fsys_clk/2, the
190
--   closer it is to the Nyquist limit, and the output jitter is much more
191
--   significant at that point.
192
--
193
--
194
 
195
 
196
library IEEE;
197
use IEEE.STD_LOGIC_1164.ALL;
198
use IEEE.NUMERIC_STD.ALL;
199
use IEEE.MATH_REAL.ALL;
200
 
201
  entity dds_squarewave is
202
    generic (
203
      ACC_BITS     : integer := 16       -- Bit width of DDS phase accumulator
204
    );
205
    port (
206
 
207
      sys_rst_n    : in  std_logic;
208
      sys_clk      : in  std_logic;
209
      sys_clk_en   : in  std_logic;
210
 
211
      -- Frequency setting
212
      freq_i       : in  unsigned(ACC_BITS-1 downto 0);
213
 
214
      -- Output
215
      pulse_o      : out std_logic;
216
      squarewave_o : out std_logic
217
    );
218
  end dds_squarewave;
219
 
220
architecture beh of dds_squarewave is
221
 
222
-- Constants
223
signal dds_phase      : unsigned(ACC_BITS-1 downto 0); -- phase accumulator register
224
signal dds_phase_next : unsigned(ACC_BITS-1 downto 0);
225
 
226
-----------------------------------------------------------------------------
227
begin
228
 
229
  dds_proc: Process(sys_rst_n,sys_clk)
230
  begin
231
    if (sys_rst_n = '0') then
232
      dds_phase <= (others=>'0');
233
    elsif (sys_clk'event and sys_clk='1') then
234
      if (sys_clk_en='1') then
235
        dds_phase <= dds_phase_next;
236
      end if;
237
    end if; -- sys_clk
238
  end process dds_proc;
239
  dds_phase_next <= dds_phase + freq_i;
240
  pulse_o <= '1' when sys_clk_en='1' and dds_phase(dds_phase'length-1)='0' and dds_phase_next(dds_phase_next'length-1)='1' else '0';
241
  squarewave_o <= dds_phase(dds_phase'length-1);
242
 
243
end beh;
244
 
245
 
246
-------------------------------------------------------------------------------
247
-- Direct Digital Synthesizer Arbitrary Length Sinewave Look Up Table module
248
-------------------------------------------------------------------------------
249
--
250
-- Author: John Clayton
251
-- Update: Jan. 24, 2013 Modified Matlab script "sine_arbitrary_length_lut_gen"
252
--                       to produce VHDL output which uses the "unsigned" type
253
--                       from ieee.numeric_std library.
254
--         Jan. 26, 2013 Rewrote accumulator folding logic.  Added saturation
255
--                       check to avoid indices beyond the end of the lookup
256
--                       table.
257
--
258
-- Description
259
-------------------------------------------------------------------------------
260
-- This is a direct digital synthesizer module, which uses a 1/4 wave lookup
261
-- to produce sinewave samples.  A Matlab script generates the samples to the
262
-- desired number of bits, number of samples and amplitude.
263
--
264
-- The generated file is the "sine_lut_pkg", although the filename may well
265
-- be different, such as "sine_lut_5000_x_16.vhd"
266
--
267
-- The generated file contains definitions for:
268
--   constant AMPL_WIDTH : integer
269
--   constant PHASE_LENGTH : integer
270
--   constant PHASE_WIDTH  : integer
271
--
272
 
273
library ieee;
274
use ieee.std_logic_1164.all;
275
use ieee.numeric_std.all;
276
 
277
library work;
278
use work.sine_lut_pkg.all;
279
use work.convert_pack.all;
280
 
281
entity dds_sine_non_power_of_two is
282
  generic(
283
    PHI_WIDTH : integer  -- Bits in phase accumulator.  Must hold numbers greater than full sinewave lut length...
284
    );
285
  port(
286
    clk_i    : in  std_logic;
287
    rst_n_i  : in  std_logic;
288
    clk_en_i : in  std_logic;
289
    ftw_i    : in  unsigned(PHI_WIDTH-1 downto 0);
290
    accum_o  : out unsigned(PHI_WIDTH-1 downto 0);
291
    sine_o   : out signed(AMPL_WIDTH-1 downto 0)
292
    );
293
end dds_sine_non_power_of_two;
294
 
295
architecture dds_arch of dds_sine_non_power_of_two is
296
 
297
  constant FRAC_BITS     : natural := PHI_WIDTH - PHASE_WIDTH;
298
  constant Q_PHASE_WIDTH : integer := PHASE_WIDTH-2;  -- Quarter phase takes two bits less to represent
299
  constant Q_LENGTH      : unsigned(Q_PHASE_WIDTH-1 downto 0) := to_unsigned(PHASE_LENGTH/4,Q_PHASE_WIDTH); -- Quadrant Length
300
  constant Q_THRESH      : unsigned(PHI_WIDTH-1 downto 0) := to_unsigned(2**FRAC_BITS*PHASE_LENGTH/4,PHI_WIDTH); -- Quadrant Length
301
 
302
  signal accum        : unsigned(PHI_WIDTH-1 downto 0);
303
  signal q_accum      : unsigned(PHI_WIDTH-1 downto 0);
304
  signal q_accum_next : unsigned(PHI_WIDTH-1 downto 0);
305
  signal accum_incr   : unsigned(PHI_WIDTH-1 downto 0);
306
  signal accum_folded : unsigned(PHI_WIDTH-1 downto 0);
307
  signal lut_out      : unsigned(AMPL_WIDTH-1 downto 0);
308
  signal lut_out_neg  : unsigned(AMPL_WIDTH-1 downto 0);
309
 
310
  signal q_phase      : unsigned(Q_PHASE_WIDTH-1 downto 0);
311
  signal q_phase_sat  : unsigned(Q_PHASE_WIDTH-1 downto 0);
312
  signal q_count      : unsigned(1 downto 0);
313
  signal q_count_r1   : unsigned(1 downto 0);
314
 
315
begin
316
 
317
  accum_incr   <= unsigned(ftw_i);
318
  q_accum_next   <= q_accum + accum_incr;
319
  accum_folded <=            q_accum when q_count(0)='0' else
320
                  Q_THRESH - q_accum;
321
  q_phase      <= u_resize(u_resize_l(accum_folded,PHASE_WIDTH),q_phase'length); -- Discard the fractional portion
322
  lut_out      <= sine_lut(to_integer(q_phase_sat));
323
  lut_out_neg  <= (not lut_out) + 1;
324
  sine_o       <= signed(lut_out_neg) when q_count_r1(1) = '1' else signed(lut_out);
325
  accum_o      <= accum+q_accum;
326
 
327
  process (clk_i, rst_n_i)
328
  begin
329
    if (rst_n_i = '0') then
330
      accum       <= (others=>'0');
331
      q_accum     <= (others=>'0');
332
      q_count     <= (others=>'0');
333
      q_count_r1  <= (others=>'0');
334
      q_phase_sat <= (others=>'0');
335
    elsif (clk_i'event and clk_i = '1') then
336
      if (clk_en_i = '1') then
337
        if (q_accum_next > Q_THRESH) then
338
          q_accum <= q_accum_next - Q_THRESH;
339
          q_count <= q_count+1;
340
          if (q_count="11") then
341
            accum <= (others=>'0');
342
          else
343
            accum   <= accum + Q_THRESH;
344
          end if;
345
        else
346
          q_accum <= q_accum_next;
347
        end if;
348
 
349
        -- Delayed q_count, to match delayed q_phase
350
        q_count_r1 <= q_count;
351
        -- Saturate the quarter phase signal, to avoid overflows when looking up sine values
352
        if (q_phase>=(PHASE_LENGTH/4)) then
353
          q_phase_sat <= to_unsigned(PHASE_LENGTH/4-1,q_phase_sat'length);
354
        else
355
          q_phase_sat <= q_phase;
356
        end if;
357
      end if;
358
    end if;
359
  end process;
360
 
361
end dds_arch;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.