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

Subversion Repositories p9813_rgb_led_string_driver

[/] [p9813_rgb_led_string_driver/] [trunk/] [rtl/] [VHDL/] [dds_pack.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jclaytons
--------------------------------------------------------------------------
2
-- Package of Direct Digital Synthesizer (DDS) components
3
--
4
-- NOTE: These components are for producing digital pulse outputs at
5
--       desired frequencies and/or duty cycles.  In other words, there
6
--       are no modules here which include sinewave lookup tables.  For
7
--       that type of module, please refer to "dds_sine_pack.vhd"
8
--
9
 
10
library ieee;
11
use ieee.std_logic_1164.all;
12
use ieee.numeric_std.all;
13
 
14
package dds_pack is
15
 
16
-- Component declarations not provided any more.
17
-- With VHDL '93 and newer, component declarations are allowed,
18
-- but not required.
19
--
20
-- Please to try direct instantiation instead, for example:
21
--
22
--   instance_name : entity work.entity_name(beh)
23
--
24
 
25
end dds_pack;
26
 
27
package body dds_pack is
28
end dds_pack;
29
 
30
-------------------------------------------------------------------------------
31
-- Direct Digital Synthesizer Constant Squarewave module
32
-------------------------------------------------------------------------------
33
--
34
-- Author: John Clayton
35
-- Update: Sep.  5, 2002 copied this file from "auto_baud_pack.vhd"
36
--                       Added tracking functions, and debugged them.
37
--
38
-- Description
39
-------------------------------------------------------------------------------
40
-- This is a simple direct digital synthesizer module.  It includes a phase
41
-- accumulator which increments in order to produce the desired output
42
-- frequency in its most significant bit, which is the squarewave output.
43
--
44
-- In addition to the squarewave output there is a pulse output which is
45
-- high for one sys_clk period, during the sys_clk period immediately
46
-- preceding the rising edge of the squarewave output.
47
--
48
-- NOTES:
49
--   The accumulator increment word is:
50
--        increment = Fout*2^N/Fsys_clk
51
--
52
--   Where N is the number of bits in the phase accumulator.
53
--
54
--   There will always be jitter with this type of clock source, but the
55
--   long time average frequency can be made arbitrarily close to whatever
56
--   value is desired, simply by increasing N.
57
--
58
--   To reduce jitter, use a higher underlying system clock frequency, and
59
--   for goodness sakes, try to keep the desired output frequency much lower
60
--   than the system clock frequency.  The closer it gets to Fsys_clk/2, the
61
--   closer it is to the Nyquist limit, and the output jitter is much more
62
--   significant at that point.
63
--
64
--
65
 
66
 
67
library IEEE;
68
use IEEE.STD_LOGIC_1164.ALL;
69
use IEEE.NUMERIC_STD.ALL;
70
use IEEE.MATH_REAL.ALL;
71
 
72
  entity dds_constant_squarewave is
73
    generic (
74
      OUTPUT_FREQ  : real := 8000.0;     -- Desired output frequency
75
      SYS_CLK_RATE : real := 48000000.0; -- underlying clock rate
76
      ACC_BITS     : integer := 16       -- Bit width of DDS phase accumulator
77
    );
78
    port (
79
 
80
      sys_rst_n    : in  std_logic;
81
      sys_clk      : in  std_logic;
82
      sys_clk_en   : in  std_logic;
83
 
84
      -- Output
85
      pulse_o      : out std_logic;
86
      squarewave_o : out std_logic
87
    );
88
  end dds_constant_squarewave;
89
 
90
architecture beh of dds_constant_squarewave is
91
 
92
-- Constants
93
constant DDS_INCREMENT : integer := integer(OUTPUT_FREQ*(2**real(ACC_BITS))/SYS_CLK_RATE);
94
 
95
-- Signals
96
signal dds_phase      : unsigned(ACC_BITS-1 downto 0); -- phase accumulator register
97
signal dds_phase_next : unsigned(ACC_BITS-1 downto 0);
98
 
99
-----------------------------------------------------------------------------
100
begin
101
 
102
  dds_proc: Process(sys_rst_n,sys_clk)
103
  begin
104
    if (sys_rst_n = '0') then
105
      dds_phase <= (others=>'0');
106
    elsif (sys_clk'event and sys_clk='1') then
107
      if (sys_clk_en='1') then
108
        dds_phase <= dds_phase_next;
109
      end if;
110
    end if; -- sys_clk
111
  end process dds_proc;
112
  dds_phase_next <= dds_phase + DDS_INCREMENT;
113
  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';
114
  squarewave_o <= dds_phase(dds_phase'length-1);
115
 
116
end beh;
117
 
118
 
119
-------------------------------------------------------------------------------
120
-- Direct Digital Synthesizer Variable Frequency Squarewave module
121
-------------------------------------------------------------------------------
122
--
123
-- Author: John Clayton
124
-- Update: Jan. 31, 2013 copied code from dds_constant_squarewave, and
125
--                       modified it to accept a frequency setting input.
126
--
127
-- Description
128
-------------------------------------------------------------------------------
129
-- This is a simple direct digital synthesizer module.  It includes a phase
130
-- accumulator which increments in order to produce the desired output
131
-- frequency in its most significant bit, which is the squarewave output.
132
--
133
-- In addition to the squarewave output there is a pulse output which is
134
-- high for one sys_clk period, during the sys_clk period immediately
135
-- preceding the rising edge of the squarewave output.
136
--
137
-- NOTES:
138
--   The accumulator increment word is:
139
--        increment = Fout*2^N/Fsys_clk
140
--
141
--   Where N is the number of bits in the phase accumulator.
142
--
143
--   There will always be jitter with this type of clock source, but the
144
--   long time average frequency can be made arbitrarily close to whatever
145
--   value is desired, simply by increasing N.
146
--
147
--   To reduce jitter, use a higher underlying system clock frequency, and
148
--   for goodness sakes, try to keep the desired output frequency much lower
149
--   than the system clock frequency.  The closer it gets to Fsys_clk/2, the
150
--   closer it is to the Nyquist limit, and the output jitter is much more
151
--   significant as compared to the output period at that point.
152
--
153
--
154
 
155
 
156
library IEEE;
157
use IEEE.STD_LOGIC_1164.ALL;
158
use IEEE.NUMERIC_STD.ALL;
159
use IEEE.MATH_REAL.ALL;
160
 
161
  entity dds_squarewave is
162
    generic (
163
      ACC_BITS     : integer := 16       -- Bit width of DDS phase accumulator
164
    );
165
    port (
166
 
167
      sys_rst_n    : in  std_logic;
168
      sys_clk      : in  std_logic;
169
      sys_clk_en   : in  std_logic;
170
 
171
      -- Frequency setting
172
      freq_i       : in  unsigned(ACC_BITS-1 downto 0);
173
 
174
      -- Output
175
      pulse_o      : out std_logic;
176
      squarewave_o : out std_logic
177
    );
178
  end dds_squarewave;
179
 
180
architecture beh of dds_squarewave is
181
 
182
-- Signals
183
signal dds_phase      : unsigned(ACC_BITS-1 downto 0); -- phase accumulator register
184
signal dds_phase_next : unsigned(ACC_BITS-1 downto 0);
185
 
186
-----------------------------------------------------------------------------
187
begin
188
 
189
  dds_proc: Process(sys_rst_n,sys_clk)
190
  begin
191
    if (sys_rst_n = '0') then
192
      dds_phase <= (others=>'0');
193
    elsif (sys_clk'event and sys_clk='1') then
194
      if (sys_clk_en='1') then
195
        dds_phase <= dds_phase_next;
196
      end if;
197
    end if; -- sys_clk
198
  end process dds_proc;
199
  dds_phase_next <= dds_phase + freq_i;
200
  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';
201
  squarewave_o <= dds_phase(dds_phase'length-1);
202
 
203
end beh;
204
 
205
 
206
-------------------------------------------------------------------------------
207
-- Direct Digital Synthesizer Variable Frequency Squarewave module,
208
--   with synchronous phase load
209
-------------------------------------------------------------------------------
210
--
211
-- Author: John Clayton
212
-- Update: Aug.  1, 2013 copied code from dds_squarewave, and
213
--                       modified it to accept a synchronous load input.
214
--
215
-- Description
216
-------------------------------------------------------------------------------
217
-- This is a simple direct digital synthesizer module.  It includes a phase
218
-- accumulator which increments in order to produce the desired output
219
-- frequency in its most significant bit, which is the squarewave output.
220
--
221
-- In addition to the squarewave output there is a pulse output which is
222
-- high for one sys_clk period, during the sys_clk period immediately
223
-- preceding the rising edge of the squarewave output.
224
--
225
-- A synchronous load input allows the synthesizer to be adjusted to any
226
-- desired initial phase condition.  This is useful when using it for
227
-- timing and synchronization.
228
--
229
-- NOTES:
230
--   The accumulator increment word is:
231
--        increment = Fout*2^N/Fsys_clk
232
--
233
--   Where N is the number of bits in the phase accumulator.
234
--
235
--   There will always be jitter with this type of clock source, but the
236
--   long time average frequency can be made arbitrarily close to whatever
237
--   value is desired, simply by increasing N.
238
--
239
--   To reduce jitter, use a higher underlying system clock frequency, and
240
--   for goodness sakes, try to keep the desired output frequency much lower
241
--   than the system clock frequency.  The closer it gets to Fsys_clk/2, the
242
--   closer it is to the Nyquist limit, and the output jitter is much more
243
--   significant as compared to the output period at that point.
244
--
245
--
246
 
247
 
248
library IEEE;
249
use IEEE.STD_LOGIC_1164.ALL;
250
use IEEE.NUMERIC_STD.ALL;
251
use IEEE.MATH_REAL.ALL;
252
 
253
  entity dds_squarewave_phase_load is
254
    generic (
255
      ACC_BITS     : integer := 16       -- Bit width of DDS phase accumulator
256
    );
257
    port (
258
 
259
      sys_rst_n    : in  std_logic;
260
      sys_clk      : in  std_logic;
261
      sys_clk_en   : in  std_logic;
262
 
263
      -- Frequency setting
264
      freq_i       : in  unsigned(ACC_BITS-1 downto 0);
265
 
266
      -- Synchronous load
267
      phase_i      : in  unsigned(ACC_BITS-1 downto 0);
268
      phase_ld_i   : in  std_logic;
269
 
270
      -- Output
271
      pulse_o      : out std_logic;
272
      squarewave_o : out std_logic
273
    );
274
  end dds_squarewave_phase_load;
275
 
276
architecture beh of dds_squarewave_phase_load is
277
 
278
-- Signals
279
signal dds_phase      : unsigned(ACC_BITS-1 downto 0); -- phase accumulator register
280
signal dds_phase_next : unsigned(ACC_BITS-1 downto 0);
281
 
282
-----------------------------------------------------------------------------
283
begin
284
 
285
  dds_proc: Process(sys_rst_n,sys_clk)
286
  begin
287
    if (sys_rst_n = '0') then
288
      dds_phase <= (others=>'0');
289
    elsif (sys_clk'event and sys_clk='1') then
290
      if (sys_clk_en='1') then
291
        dds_phase <= dds_phase_next;
292
      end if;
293
      if (phase_ld_i='1') then
294
        dds_phase <= phase_i;
295
      end if;
296
    end if; -- sys_clk
297
  end process dds_proc;
298
  dds_phase_next <= dds_phase + freq_i;
299
  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';
300
  squarewave_o <= dds_phase(dds_phase'length-1);
301
 
302
end beh;
303
 
304
 
305
-------------------------------------------------------------------------------
306
-- Direct Digital Synthesizer Clock Enable Generator, Constant output frequency
307
-------------------------------------------------------------------------------
308
--
309
-- Author: John Clayton
310
-- Update: Oct.  4, 2013 Copied code from dds_clk_en_gen, and modified it to
311
--                       create a clock enable output using generics to set
312
--                       the frequency.
313
--
314
-- Description
315
-------------------------------------------------------------------------------
316
-- This is a simple direct digital synthesizer module.  It includes a phase
317
-- accumulator which increments in order to produce the desired output
318
-- frequency in its most significant bit, which is a squarewave with
319
-- some unavoidable jitter.
320
--
321
-- In this module, the squarewave is not provided as an output, because
322
-- this module's purpose is to generate a clock enable signal.
323
--
324
-- The clock enable output is a pulsed output which, for frequencies below
325
-- the Nyquist frequency is high for one sys_clk period, during the sys_clk
326
-- period immediately preceding the rising edge of the squarewave output.
327
--
328
-- A special "trick" is performed inside this module, which is to invert the
329
-- pulse output for frequencies above the Nyquist frequency.  Since the pulse
330
-- train is a perfect 50% duty cycle squarewave at the Nyquist frequency, the
331
-- pulse train and its inverse are equivalent at that point...  But for
332
-- higher frequencies, the squarewave reduces in frequency back down towards
333
-- zero Hz.  However, since the pulse train is inverted for frequencies above
334
-- the Nyquist frequency (Fsys_clk/2), then the output pulse train is high for
335
-- a larger and larger fraction of time... essentially forming a nice clock
336
-- enable which can be varied from 0% duty cycle, all the way up to N% duty
337
-- cycle, where K is given by:
338
--
339
--   K = max_duty_cycle = 100 * (1-2**(-N)) percent
340
--
341
--   Where N is the number of bits in the phase accumulator (ACC_BITS)
342
--
343
--
344
-- NOTES:
345
--   The accumulator increment word is set by generics:
346
--        increment = OUTPUT_FREQ*2^ACC_BITS/SYS_CLK_RATE
347
--
348
--   Where N is the number of bits in the phase accumulator (ACC_BITS)
349
--
350
--   There will always be jitter with this type of clock source, but the
351
--   clock enable output duty cycle can be adjusted in increments as fine
352
--   as may be desired, simply by increasing N.
353
--
354
--
355
 
356
 
357
library IEEE;
358
use IEEE.STD_LOGIC_1164.ALL;
359
use IEEE.NUMERIC_STD.ALL;
360
use IEEE.MATH_REAL.ALL;
361
 
362
  entity dds_constant_clk_en_gen is
363
    generic (
364
      OUTPUT_FREQ  : real := 32000000.0;   -- Desired output frequency
365
      SYS_CLK_RATE : real := 50000000.0;   -- underlying clock rate
366
      ACC_BITS     : integer := 30 -- Bit width of DDS phase accumulator
367
    );
368
    port (
369
 
370
      sys_rst_n    : in  std_logic;
371
      sys_clk      : in  std_logic;
372
      sys_clk_en   : in  std_logic;
373
 
374
      -- Output
375
      clk_en_o     : out std_logic
376
    );
377
  end dds_constant_clk_en_gen;
378
 
379
architecture beh of dds_constant_clk_en_gen is
380
 
381
-- Constants
382
constant DDS_INCREMENT : integer := integer(OUTPUT_FREQ*(2**real(ACC_BITS))/SYS_CLK_RATE);
383
constant HALFWAY       : integer := integer(2**real(ACC_BITS-1));
384
 
385
-- Signals
386
signal dds_phase      : unsigned(ACC_BITS-1 downto 0); -- phase accumulator register
387
signal dds_phase_next : unsigned(ACC_BITS-1 downto 0);
388
signal pulse_l        : std_logic;
389
 
390
-----------------------------------------------------------------------------
391
begin
392
 
393
  dds_proc: Process(sys_rst_n,sys_clk)
394
  begin
395
    if (sys_rst_n = '0') then
396
      dds_phase <= (others=>'0');
397
    elsif (sys_clk'event and sys_clk='1') then
398
      if (sys_clk_en='1') then
399
        dds_phase <= dds_phase_next;
400
      end if;
401
    end if; -- sys_clk
402
  end process dds_proc;
403
  dds_phase_next <= dds_phase + DDS_INCREMENT;
404
  pulse_l <= '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';
405
  clk_en_o <= pulse_l when (DDS_INCREMENT<HALFWAY) else not pulse_l;
406
 
407
end beh;
408
 
409
 
410
-------------------------------------------------------------------------------
411
-- Direct Digital Synthesizer Clock Enable Generator
412
-------------------------------------------------------------------------------
413
--
414
-- Author: John Clayton
415
-- Update: Oct.  4, 2013 Copied code from dds_squarewave, and modified it to
416
--                       create a clock enable output which essentially has
417
--                       a duty cycle that varies from zero up to 100%.  This
418
--                       is similar in some ways to a first order sigma-delta
419
--                       modulator, my friend!  It can be used as a DAC, if
420
--                       the sys_clk_en is high.  See dds_pwm_dac for a
421
--                       similar unit that allows slowing down the output
422
--                       waveform according to the period between sys_clk_en
423
--                       pulses.
424
--
425
-- Description
426
-------------------------------------------------------------------------------
427
-- This is a simple direct digital synthesizer module.  It includes a phase
428
-- accumulator which increments in order to produce the desired output
429
-- frequency in its most significant bit, which is a squarewave with
430
-- some unavoidable jitter.
431
--
432
-- In this module, the squarewave is not provided as an output, because
433
-- this module's purpose is to generate a clock enable signal.
434
--
435
-- The clock enable output is a pulsed output which, for frequencies below
436
-- the Nyquist frequency is high for one sys_clk period, during the sys_clk
437
-- period immediately preceding the rising edge of the squarewave output.
438
--
439
-- A special "trick" is performed inside this module, which is to invert the
440
-- pulse output for frequencies above the Nyquist frequency.  Since the pulse
441
-- train is a perfect 50% duty cycle squarewave at the Nyquist frequency, the
442
-- pulse train and its inverse are equivalent at that point...  But for
443
-- higher frequencies, the squarewave reduces in frequency back down towards
444
-- zero Hz.  However, since the pulse train is inverted for frequencies above
445
-- the Nyquist frequency (Fsys_clk/2), then the output pulse train is high for
446
-- a larger and larger fraction of time... essentially forming a nice clock
447
-- enable which can be varied from 0% duty cycle, all the way up to N% duty
448
-- cycle, where K is given by:
449
--
450
--   K = max_duty_cycle = 100 * (1-2**(-N)) percent
451
--
452
--   Where N is the number of bits in the phase accumulator (ACC_BITS)
453
--
454
-- This can perhaps operate as a form of PWM also... although the fundamental
455
-- frequency is not constant, as it is in true PWM.
456
--
457
--
458
-- NOTES:
459
--   The accumulator increment word is:
460
--        increment = Fout*2^N/Fsys_clk
461
--
462
--   Where N is the number of bits in the phase accumulator (ACC_BITS)
463
--
464
--   There will always be jitter with this type of clock source, but the
465
--   clock enable output duty cycle can be adjusted in increments as fine
466
--   as may be desired, simply by increasing N.
467
--
468
--
469
 
470
 
471
library IEEE;
472
use IEEE.STD_LOGIC_1164.ALL;
473
use IEEE.NUMERIC_STD.ALL;
474
use IEEE.MATH_REAL.ALL;
475
 
476
  entity dds_clk_en_gen is
477
    generic (
478
      ACC_BITS     : integer := 16       -- Bit width of DDS phase accumulator
479
    );
480
    port (
481
 
482
      sys_rst_n    : in  std_logic;
483
      sys_clk      : in  std_logic;
484
      sys_clk_en   : in  std_logic;
485
 
486
      -- Frequency setting
487
      freq_i       : in  unsigned(ACC_BITS-1 downto 0);
488
 
489
      -- Output
490
      clk_en_o     : out std_logic
491
    );
492
  end dds_clk_en_gen;
493
 
494
architecture beh of dds_clk_en_gen is
495
 
496
-- Signals
497
signal dds_phase      : unsigned(ACC_BITS-1 downto 0); -- phase accumulator register
498
signal dds_phase_next : unsigned(ACC_BITS-1 downto 0);
499
signal pulse_l        : std_logic;
500
 
501
-----------------------------------------------------------------------------
502
begin
503
 
504
  dds_proc: Process(sys_rst_n,sys_clk)
505
  begin
506
    if (sys_rst_n = '0') then
507
      dds_phase <= (others=>'0');
508
    elsif (sys_clk'event and sys_clk='1') then
509
      if (sys_clk_en='1') then
510
        dds_phase <= dds_phase_next;
511
      end if;
512
    end if; -- sys_clk
513
  end process dds_proc;
514
  dds_phase_next <= dds_phase + freq_i;
515
  pulse_l <= '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';
516
  clk_en_o <= pulse_l when freq_i(freq_i'length-1)='0' else not pulse_l;
517
 
518
end beh;
519
 
520
 
521
-------------------------------------------------------------------------------
522
-- Calibrated Direct Digital Synthesizer Clock Enable Generator
523
-------------------------------------------------------------------------------
524
--
525
-- Author: John Clayton
526
-- Update: Nov. 11, 2013 Copied code from dds_clk_en_gen, and modified it.
527
--
528
-- Description
529
-------------------------------------------------------------------------------
530
-- This is two DDS units tied together.  The first unit produces a calibration
531
-- clock enable, at a frequency which is very close to a power of two Hz.
532
-- It uses the highest power of two which can be achieved using the given
533
-- system clock frequency.
534
--
535
-- The second DDS unit then uses the calibration clock enable for its
536
-- clock enable input.  This effectively "calibrates" the second unit
537
-- so that its input frequency is in Hz.
538
--
539
-- The input frequency to this module was fixed at 32 bits, but the
540
-- most significant bits may be ignored.
541
--
542
 
543
 
544
library IEEE;
545
use IEEE.STD_LOGIC_1164.ALL;
546
use IEEE.NUMERIC_STD.ALL;
547
use IEEE.MATH_REAL.ALL;
548
 
549
library work;
550
use work.dds_pack.all;
551
use work.function_pack.all;
552
 
553
  entity calibrated_clk_en_gen is
554
    generic (
555
      SYS_CLK_RATE : real := 50000000.0 -- underlying clock rate
556
    );
557
    port (
558
 
559
      sys_rst_n    : in  std_logic;
560
      sys_clk      : in  std_logic;
561
      sys_clk_en   : in  std_logic;
562
 
563
      -- Frequency setting
564
      freq_i       : in  unsigned(31 downto 0);
565
 
566
      -- Output
567
      clk_en_o     : out std_logic
568
    );
569
  end calibrated_clk_en_gen;
570
 
571
architecture beh of calibrated_clk_en_gen is
572
 
573
-- Constants
574
constant LOG2_CAL_BITS : natural := bit_width(SYS_CLK_RATE)-1;
575
 
576
-- Signals
577
signal cal_clk_en      : std_logic;
578
 
579
 
580
 
581
-----------------------------------------------------------------------------
582
begin
583
 
584
  -- Calibration clock enable
585
  cal_clk_gen : entity work.dds_constant_clk_en_gen(beh)
586
    generic map(
587
      OUTPUT_FREQ  => real(2**LOG2_CAL_BITS),
588
      SYS_CLK_RATE => SYS_CLK_RATE,
589
      ACC_BITS     => 30
590
    )
591
    port map(
592
 
593
      sys_rst_n  => sys_rst_n,
594
      sys_clk    => sys_clk,
595
      sys_clk_en => sys_clk_en,
596
 
597
      -- Output
598
      clk_en_o     => cal_clk_en
599
    );
600
 
601
  clk_en_gen : entity work.dds_clk_en_gen(beh)
602
    generic map(
603
      ACC_BITS     => LOG2_CAL_BITS
604
    )
605
    port map(
606
 
607
      sys_rst_n  => sys_rst_n,
608
      sys_clk    => sys_clk,
609
      sys_clk_en => cal_clk_en,
610
 
611
      -- Frequency setting
612
      freq_i     => freq_i(LOG2_CAL_BITS-1 downto 0),
613
 
614
      -- Output
615
      clk_en_o   => clk_en_o
616
    );
617
 
618
end beh;
619
 
620
 
621
-------------------------------------------------------------------------------
622
-- Direct Digital Synthesizer PWM DAC
623
-------------------------------------------------------------------------------
624
--
625
-- Author: John Clayton
626
-- Update:
627
--         Jan. 23, 2015 Copied code from clk_en_gen, and brought pulse_l
628
--                       logic inside the sys_clk_en enabled process, so 
629
--                       that the pulses are widened according to sys_clk_en.
630
--
631
-- Description
632
-------------------------------------------------------------------------------
633
-- This is exactly the same as dds_clk_en_gen, except that it brings the pulse_l
634
-- logic inside the clocked process, so that output pulses are no longer 1
635
-- sys_clk wide, but are instead lengthened according to sys_clk_en.  This makes
636
-- the unit useful for generating a PWM output signal, with the smallest pulse
637
-- being the period between sys_clk_en pulses.
638
--
639
-- This is a simple direct digital synthesizer module.  It includes a phase
640
-- accumulator which increments in order to produce the desired output
641
-- frequency in its most significant bit, which is a squarewave with
642
-- some unavoidable jitter.
643
--
644
-- In this module, the squarewave is not provided as an output, because
645
-- this module's purpose is to generate a clock enable signal.
646
--
647
-- The clock enable output is a pulsed output which, for frequencies below
648
-- the Nyquist frequency is high for one sys_clk period, during the sys_clk
649
-- period immediately preceding the rising edge of the squarewave output.
650
--
651
-- A special "trick" is performed inside this module, which is to invert the
652
-- pulse output for frequencies above the Nyquist frequency.  Since the pulse
653
-- train is a perfect 50% duty cycle squarewave at the Nyquist frequency, the
654
-- pulse train and its inverse are equivalent at that point...  But for
655
-- higher frequencies, the squarewave reduces in frequency back down towards
656
-- zero Hz.  However, since the pulse train is inverted for frequencies above
657
-- the Nyquist frequency (Fsys_clk/2), then the output pulse train is high for
658
-- a larger and larger fraction of time... essentially forming a nice clock
659
-- enable which can be varied from 0% duty cycle, all the way up to N% duty
660
-- cycle, where K is given by:
661
--
662
--   K = max_duty_cycle = 100 * (1-2**(-N)) percent
663
--
664
--   Where N is the number of bits in the phase accumulator (ACC_BITS)
665
--
666
-- This can perhaps operate as a form of PWM also... although the fundamental
667
-- frequency is not constant, as it is in true PWM.
668
--
669
--
670
-- NOTES:
671
--   The accumulator increment word is:
672
--        increment = Fout*2^N/Fsys_clk
673
--
674
--   Where N is the number of bits in the phase accumulator (ACC_BITS)
675
--
676
--   There will always be jitter with this type of clock source, but the
677
--   clock enable output duty cycle can be adjusted in increments as fine
678
--   as may be desired, simply by increasing N.
679
--
680
--
681
 
682
 
683
library IEEE;
684
use IEEE.STD_LOGIC_1164.ALL;
685
use IEEE.NUMERIC_STD.ALL;
686
use IEEE.MATH_REAL.ALL;
687
 
688
  entity dds_pwm_dac is
689
    generic (
690
      ACC_BITS     : integer := 16       -- Bit width of DDS phase accumulator
691
    );
692
    port (
693
 
694
      sys_rst_n    : in  std_logic;
695
      sys_clk      : in  std_logic;
696
      sys_clk_en   : in  std_logic;
697
 
698
      -- Frequency setting
699
      freq_i       : in  unsigned(ACC_BITS-1 downto 0);
700
 
701
      -- Output
702
      clk_en_o     : out std_logic
703
    );
704
  end dds_pwm_dac;
705
 
706
architecture beh of dds_pwm_dac is
707
 
708
-- Signals
709
signal dds_phase      : unsigned(ACC_BITS-1 downto 0); -- phase accumulator register
710
signal dds_phase_next : unsigned(ACC_BITS-1 downto 0);
711
signal pulse_l        : std_logic;
712
 
713
-----------------------------------------------------------------------------
714
begin
715
 
716
  dds_proc: Process(sys_rst_n,sys_clk)
717
  begin
718
    if (sys_rst_n = '0') then
719
      dds_phase <= (others=>'0');
720
      pulse_l <= '0';
721
    elsif (sys_clk'event and sys_clk='1') then
722
      if (sys_clk_en='1') then
723
        dds_phase <= dds_phase_next;
724
        if (dds_phase(dds_phase'length-1)='0' and dds_phase_next(dds_phase_next'length-1)='1') then
725
          pulse_l <= '1';
726
        else
727
          pulse_l <= '0';
728
        end if;
729
      end if;
730
    end if; -- sys_clk
731
  end process dds_proc;
732
  dds_phase_next <= dds_phase + freq_i;
733
  clk_en_o <= pulse_l when freq_i(freq_i'length-1)='0' else not pulse_l;
734
 
735
end beh;
736
 
737
-------------------------------------------------------------------------------
738
-- Direct Digital Synthesizer PWM DAC - Synchronously Resettable Version
739
-------------------------------------------------------------------------------
740
--
741
-- Author: John Clayton
742
-- Update:
743
--         Jan. 23, 2015 Copied code from dds_pwm_dac, and added synchronous
744
--                       phase load input and phase value inputs
745
--
746
-- Description
747
-------------------------------------------------------------------------------
748
-- This is exactly the same as dds_pwm_dac, except that a synchronous phase
749
-- load is provided.  This was needed when using the DAC to "throttle" pixel
750
-- counters driving a display.  By resetting the DAC's phase accumulator
751
-- during each retrace interval, visible "jitter" was reduced, and made
752
-- identical for each line of display pixels.
753
--
754
-- NOTES:
755
--   The accumulator increment word is:
756
--        increment = Fout*2^N/Fsys_clk
757
--
758
--   Where N is the number of bits in the phase accumulator (ACC_BITS)
759
--
760
--   There will always be jitter with this type of clock source, but the
761
--   clock enable output duty cycle can be adjusted in increments as fine
762
--   as may be desired, simply by increasing N.
763
--
764
--
765
 
766
 
767
library IEEE;
768
use IEEE.STD_LOGIC_1164.ALL;
769
use IEEE.NUMERIC_STD.ALL;
770
use IEEE.MATH_REAL.ALL;
771
 
772
  entity dds_pwm_dac_srv is
773
    generic (
774
      ACC_BITS     : integer := 16   -- Bit width of DDS phase accumulator
775
    );
776
    port (
777
 
778
      sys_rst_n    : in  std_logic;
779
      sys_clk      : in  std_logic;
780
      sys_clk_en   : in  std_logic;
781
 
782
      -- Frequency/Phase settings
783
      phase_load_i : in  std_logic;
784
      phase_val_i  : in  unsigned(ACC_BITS-1 downto 0);
785
      freq_i       : in  unsigned(ACC_BITS-1 downto 0);
786
 
787
      -- Output
788
      clk_en_o     : out std_logic
789
    );
790
  end dds_pwm_dac_srv;
791
 
792
architecture beh of dds_pwm_dac_srv is
793
 
794
-- Signals
795
signal dds_phase      : unsigned(ACC_BITS-1 downto 0); -- phase accumulator register
796
signal dds_phase_next : unsigned(ACC_BITS-1 downto 0);
797
signal pulse_l        : std_logic;
798
 
799
-----------------------------------------------------------------------------
800
begin
801
 
802
  dds_proc: Process(sys_rst_n,sys_clk)
803
  begin
804
    if (sys_rst_n = '0') then
805
      dds_phase <= (others=>'0');
806
      pulse_l <= '0';
807
    elsif (sys_clk'event and sys_clk='1') then
808
      if (sys_clk_en='1') then
809
        if (phase_load_i='1') then
810
          dds_phase <= phase_val_i;
811
          pulse_l <= '0';
812
        else
813
          dds_phase <= dds_phase_next;
814
          if (dds_phase(dds_phase'length-1)='0' and dds_phase_next(dds_phase_next'length-1)='1') then
815
            pulse_l <= '1';
816
          else
817
            pulse_l <= '0';
818
          end if;
819
        end if; -- phase_zero_i
820
      end if; -- sys_clk_en
821
    end if; -- sys_clk
822
  end process dds_proc;
823
  dds_phase_next <= dds_phase + freq_i;
824
  clk_en_o <= pulse_l when freq_i(freq_i'length-1)='0' else not pulse_l;
825
 
826
end beh;
827
 
828
 

powered by: WebSVN 2.1.0

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