DDFS technique problem in generating a few clocks

A

Atif

Guest
Hello all,
I am generating the clock of frequency 548KHz from a clock of
73.728MHz. I am using the Direct digital frequency synthesis DDFS
technique in which a constant A
is placed on one port of an adder, and the other port of the adder is
fed back from a D-type latch whose input is connected to the output of
the adder. At every clock of the latch, an incremental phase is added
to the previous result. The most significant bit of the latch will
transition at a frequency determined by the equation
Fclock . A
Fout = ------------
2^k
In my module Fout=548KHz, Fclock=73.728MHz, k=48bits (48-bit adder
and latch)
then A=48'd2092126291740
But I am not getting the exact output waveform of frequenct 548K.

Using this technique to generate the clocks 2.048M, 544K, 38M works
really fine and accurate. But problems in clocks 548K, 4352K.
Can anyone please help me why this method of DDFS is not working for
few clocks and works for a few?

Thanks and Regards
Atif Nadeem
Research Associate
 
On 20 Oct 2003 05:39:57 -0700, atif@kics.edu.pk (Atif) wrote:

Hello all,
I am generating the clock of frequency 548KHz from a clock of
73.728MHz. I am using the Direct digital frequency synthesis DDFS
technique in which a constant A
is placed on one port of an adder, and the other port of the adder is
fed back from a D-type latch whose input is connected to the output of
the adder. At every clock of the latch, an incremental phase is added
to the previous result. The most significant bit of the latch will
transition at a frequency determined by the equation
Fclock . A
Fout = ------------
2^k
In my module Fout=548KHz, Fclock=73.728MHz, k=48bits (48-bit adder
and latch)
then A=48'd2092126291740

But I am not getting the exact output waveform of frequenct 548K.

Using this technique to generate the clocks 2.048M, 544K, 38M works
really fine and accurate. But problems in clocks 548K, 4352K.
Can anyone please help me why this method of DDFS is not working for
few clocks and works for a few?
73.728MHz / 548kHz = 18432 / 137

This can't ever be *exactly* represented by a ratio with a power of 2
in the denominator ... but you can get it arbitrarily close. You used
a 48 bit accumulator, which should give you accuracy adequate for any
practical application.

If it's "not working" then you probably have a bug somewhere, but we
can't suggest what it is unless you post your code and explain what
"not working" means.

BTW, a different architecture can give you the exact frequency you
want, using less than half that number of flip flops.
See:
http://fractional-divider.tripod.com/
for a free Verilog code generator written in Perl.

Regards,
Allan
 
"Atif" <atif@kics.edu.pk> wrote in message
news:6a0a3f23.0310200439.35848843@posting.google.com...

I am generating the clock of frequency 548KHz from a clock of
73.728MHz. I am using the Direct digital frequency synthesis DDFS
technique in which a constant A
is placed on one port of an adder, and the other port of the adder is
fed back from a D-type latch whose input is connected to the output of
the adder. At every clock of the latch, an incremental phase is added
to the previous result. The most significant bit of the latch will
transition at a frequency determined by the equation
Fclock . A
Fout = ------------
2^k
In my module Fout=548KHz, Fclock=73.728MHz, k=48bits (48-bit adder
and latch)
then A=48'd2092126291740
But I am not getting the exact output waveform of frequenct 548K.

Using this technique to generate the clocks 2.048M, 544K, 38M works
really fine and accurate.
You are fibbing. You can't get a 38MHz output from the MSB of
a phase accumulator clocked at 73.728MHz. The highest possible
frequency is obtained by toggling the MSB on every clock cycle;
that would give a frequency of 73.728MHz/2, or about 36.9MHz.

But problems in clocks 548K, 4352K.
Can anyone please help me why this method of DDFS is not working for
few clocks and works for a few?
There's no sensible reason.

Why do you need such a huge (48-bit) accumulator? It gives
you a frequency resolution of about 0.3 micro-hertz (!!).
I find it hard to believe that your 73.7MHz base clock is
anywhere near as precise as this. I'm guessing you need
these clock rates for some telecoms application, and surely
1ppm would be plenty accurate enough? So a 32-bit accumulator
would be more than enough for you. Even 28 bits would give
better than 1Hz frequency resolution.

My best guess is that you have gone straight to an FPGA hardware
implementation instead of simulating first, and your 48-bit
adder chain is too slow for the 74MHz clock. If that is the case,
you would get erratic results that are strongly affected by the
chosen increment value - exactly as you describe.

Try a much narrower accumulator, so that the adder is much faster.

Here's my DDFS module - what's yours like?

module DDFS (clock, reset, demand, Q);
parameter W = 32; // bit width of phase accumulator
input clock, reset;
input [W-1:0] demand;
output Q;
reg [W-1:0] acc;
always @(posedge clock or posedge reset)
if (reset)
acc <= 0;
else
acc <= acc + demand;
assign Q = acc[W-1];
endmodule

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Dear Jonathan,
Thanks for your reply and sorry for the delayed responce as I was
away.
Here I go
Fclock . A
Fout = ------------
2^k
e-g Fout=548KHz, Fclock=73.728MHz, for k=48 bit A=2092126291740. But
I am not getting the exact output frequency using this technique as I
am getting the
frequency of 550K instead of 548K. For 2.048M this technique works
fine.
Here are the verilog codes for both:
*****************************************************************
//Verilog code for the clcok generation of 2.048M from an input clock
of 73.728M

module fulladd48(out,clock,reset);
output out;
input clock, reset;

reg [47:0] a;
reg [47:0] sum;

always @(posedge clock)
if(reset)
begin
sum <= 0;
a <= 48'd7818749353073;
end
else
sum <= sum+a;
assign out = sum[47];
endmodule //end of module fulladd48

module stimulus;
wire OUT;
reg CLOCK, RESET;

fulladd48 myfulladd48(OUT, CLOCK, RESET);

initial
begin
RESET=1'b1;
#10 RESET=1'b0;
end

initial
begin
CLOCK=1'b0;
forever #6.78 CLOCK=~CLOCK;
end

initial
begin
#100000 $finish;
end

endmodule //end of module stimulus
*******************************************************************

*****************************************************************
//Verilog code for the clcok generation of 548K from an input clock
of 73.728M

module fulladd48(out,clock,reset);
output out;
input clock, reset;

reg [47:0] a;
reg [47:0] sum;

always @(posedge clock)
if(reset)
begin
sum <= 0;
a <= 48'd2092126291740;
end
else
sum <= sum+a;
assign out = sum[47];
endmodule //end of module fulladd48

module stimulus;
wire OUT;
reg CLOCK, RESET;

fulladd48 myfulladd48(OUT, CLOCK, RESET);

initial
begin
RESET=1'b1;
#10 RESET=1'b0;
end

initial
begin
CLOCK=1'b0;
forever #6.78 CLOCK=~CLOCK;
end

initial
begin
#100000 $finish;
end

endmodule //end of module stimulus

********************************************************************

Please suggest me what to do?
Thanks and Regards

Atif nadeem
Research Associate

"Jonathan Bromley" <jonathan.bromley@doulos.com> wrote in message news:<bn2vvm$gcl$1$830fa7b3@news.demon.co.uk>...
"Atif" <atif@kics.edu.pk> wrote in message
news:6a0a3f23.0310200439.35848843@posting.google.com...

I am generating the clock of frequency 548KHz from a clock of
73.728MHz. I am using the Direct digital frequency synthesis DDFS
technique in which a constant A
is placed on one port of an adder, and the other port of the adder is
fed back from a D-type latch whose input is connected to the output of
the adder. At every clock of the latch, an incremental phase is added
to the previous result. The most significant bit of the latch will
transition at a frequency determined by the equation
Fclock . A
Fout = ------------
2^k
In my module Fout=548KHz, Fclock=73.728MHz, k=48bits (48-bit adder
and latch)
then A=48'd2092126291740
But I am not getting the exact output waveform of frequenct 548K.

Using this technique to generate the clocks 2.048M, 544K, 38M works
really fine and accurate.

You are fibbing. You can't get a 38MHz output from the MSB of
a phase accumulator clocked at 73.728MHz. The highest possible
frequency is obtained by toggling the MSB on every clock cycle;
that would give a frequency of 73.728MHz/2, or about 36.9MHz.

But problems in clocks 548K, 4352K.
Can anyone please help me why this method of DDFS is not working for
few clocks and works for a few?

There's no sensible reason.

Why do you need such a huge (48-bit) accumulator? It gives
you a frequency resolution of about 0.3 micro-hertz (!!).
I find it hard to believe that your 73.7MHz base clock is
anywhere near as precise as this. I'm guessing you need
these clock rates for some telecoms application, and surely
1ppm would be plenty accurate enough? So a 32-bit accumulator
would be more than enough for you. Even 28 bits would give
better than 1Hz frequency resolution.

My best guess is that you have gone straight to an FPGA hardware
implementation instead of simulating first, and your 48-bit
adder chain is too slow for the 74MHz clock. If that is the case,
you would get erratic results that are strongly affected by the
chosen increment value - exactly as you describe.

Try a much narrower accumulator, so that the adder is much faster.

Here's my DDFS module - what's yours like?

module DDFS (clock, reset, demand, Q);
parameter W = 32; // bit width of phase accumulator
input clock, reset;
input [W-1:0] demand;
output Q;
reg [W-1:0] acc;
always @(posedge clock or posedge reset)
if (reset)
acc <= 0;
else
acc <= acc + demand;
assign Q = acc[W-1];
endmodule

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
"Atif" <atif@kics.edu.pk> wrote in message
news:6a0a3f23.0310262334.42feb54f@posting.google.com...

Hi Atif,

Fclock . A
Fout = ------------
2^k
e-g Fout=548KHz, Fclock=73.728MHz, for k=48 bit A=2092126291740. But
I am not getting the exact output frequency using this technique as I
am getting the
frequency of 550K instead of 548K.
No, you're fibbing again :) Look more carefully.

First of all, make sure that you have a suitable directive

`timescale 1ns/1ps

at the beginning of your code, so that the simulator measures
time to a fine enough resolution.

Next, get the testbench to work out the frequency for you,
instead of messing around on the waveform viewer. Add this
piece of code to your test fixture:

always @(posedge OUT) begin : freqmeter
real t, period;
period = $realtime - t;
t = $realtime;
$display ("freq = %f Hz", 1000000000/period);
end

Now run the simulation and see what happens. Then go
back to my previous post and read again what I said about
jitter. Note that the period of 550kHz is 1817ns,
and the period of 546kHz is 1831ns. The difference
is 14ns. Spookily, this is just one cycle of your 73MHz
clock.

Finally, can I urge you to review how you've written the
DDFS? It's completely crazy to use a register for the
increment (a) and then assign a constant to that register
at reset. Either use a parameter that you can configure
instance-by-instance as a constant, or do as I did and
make the increment an input signal that you can change
on-the-fly.

Good luck
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Hi Jonathan,
Thanks for your valuable suggestions. Yes, you are right. Here is the
output of the 548K code.
******************************************************************************
Running...
929 929.134 t=0.000000
929.134period=929.134000
929.134t=929.134000
freq=1076271.022264 HZ
2747 2746.71 t=929.134000
2746.71period=1817.576000
2746.71t=2746.710000
freq=550183.321083 HZ
4578 4577.85 t=2746.710000
4577.85period=1831.140000
4577.85t=4577.850000
freq=546107.889075 HZ
Exiting VeriLogger Pro at simulation time 10000000
0 Errors, 0 Warnings
Compile time = 0.00000, Load time = 0.04700, Execution time = 0.04700

Normal exit
***********************************************************************

So can you please tell me why is this deviation from the required
frequency and how to remove it? Can you please suggest me another
accurate techinque to solve my problem? I want the accuracy of 20ppm
and the target device to be used is Xc2s50-5PQ208-I.

Thanks and Regards
Atif Nadeem
Research Associate
Al-Khawarizmi institute of Computer science,
University of Engineering and Technology,
Lahore, 54890, Pakistan
Phone#+92-42-6827626 Ext:810
URL: http://geocities.com/anadeemk/home


"Jonathan Bromley" <jonathan.bromley@doulos.com> wrote in message news:<bnj1lb$jaa$1$830fa79d@news.demon.co.uk>...
"Atif" <atif@kics.edu.pk> wrote in message
news:6a0a3f23.0310262334.42feb54f@posting.google.com...

Hi Atif,

Fclock . A
Fout = ------------
2^k
e-g Fout=548KHz, Fclock=73.728MHz, for k=48 bit A=2092126291740. But
I am not getting the exact output frequency using this technique as I
am getting the
frequency of 550K instead of 548K.

No, you're fibbing again :) Look more carefully.

First of all, make sure that you have a suitable directive

`timescale 1ns/1ps

at the beginning of your code, so that the simulator measures
time to a fine enough resolution.

Next, get the testbench to work out the frequency for you,
instead of messing around on the waveform viewer. Add this
piece of code to your test fixture:

always @(posedge OUT) begin : freqmeter
real t, period;
period = $realtime - t;
t = $realtime;
$display ("freq = %f Hz", 1000000000/period);
end

Now run the simulation and see what happens. Then go
back to my previous post and read again what I said about
jitter. Note that the period of 550kHz is 1817ns,
and the period of 546kHz is 1831ns. The difference
is 14ns. Spookily, this is just one cycle of your 73MHz
clock.

Finally, can I urge you to review how you've written the
DDFS? It's completely crazy to use a register for the
increment (a) and then assign a constant to that register
at reset. Either use a parameter that you can configure
instance-by-instance as a constant, or do as I did and
make the increment an input signal that you can change
on-the-fly.

Good luck
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
"Atif" <atif@kics.edu.pk> wrote in message
news:6a0a3f23.0310292021.77fbe1a8@posting.google.com...

Yes, you are right. Here is the
output of the 548K code.
**************************************
Running...
929 929.134 t=0.000000
929.134period=929.134000
929.134t=929.134000
freq=1076271.022264 HZ
This first measurement is completely wrong because I didn't
do a thorough job on initialisation of the "freqmeter" code.
You can safely ignore it.

2747 2746.71 t=929.134000
2746.71period=1817.576000
This period is 134 cycles of your 73.728MHz clock...

2746.71t=2746.710000
freq=550183.321083 HZ
4578 4577.85 t=2746.710000
4577.85period=1831.140000
and this one is 135 cycles.

So can you please tell me why is this deviation from
the required frequency and how to remove it?
Surely this is obvious? Your DDFS output is synchronous with
the 73.7MHz clock; its output can change only when the clock
ticks. The frequency you requested, 528kHz, has a period that
is not an integral number of cycles of the clock. In fact it's
134.54 cycles. The DDFS places transitions of the output as
close to the correct time as it possibly can, within the
constraint that it can only create a transition at a clock
edge. Therefore, to a reasonably close approximation, it
will alternately create outputs with 134 and 135 cycles.
Just occasionally it will create two 135-cycle outputs
in a row, because 134.54 is not exactly halfway between
134 and 135. This is the well-known jitter problem of DDFS.

It has equally well-known workarounds that have been
discussed here many times before. The two that seem to
be most popular are:
(1) use Xilinx DCMs or something similar to create
several phase-shifted versions of the 73.7MHz clock,
and then use various cunning tricks to choose which
phase should be used to resynchronise each edge;
(2) use more bits the DDFS phase accumulator to drive
a sinewave lookup table and then a DAC, so that you
get an approximate sinewave output; low-pass filter
that sinewave to reduce the quantization rubbish,
and then pass it through an analogue comparator to
square it up.

Can you please suggest me another
accurate techinque to solve my problem?
I want the accuracy of 20ppm
and the target device to be used is Xc2s50-5PQ208-I.
Please be very focused about what you mean by "accuracy". The
cumulative long-term accuracy of a DDFS is excellent - far
better than the 20ppm you need (although I must ask: is
your original 73.7MHz as good as 20ppm?!!!). The problem
with DDFS is short-term jitter: every transition of the
output is locked to the base clock, and therefore can have
a timing error of +/- 0.5 periods of the base clock.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

Welcome to EDABoard.com

Sponsor

Back
Top