Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21335 Discussions

How to create a programmable clock in RTL(Verilog)

Altera_Forum
Honored Contributor II
5,711 Views

Hello, 

 

I'd like to be able to program a clock signal to be used internally for clocking other RTL blocks inside a Stratix FPGA. I have a 500 MHz system clock generated by an internal PLL and would like to use this clock to generate a slower clock based on the user-input value (32 bit). I have tried using an accumulator with the formula Fout = (Fsys x increment)/2^32. Fout = generated clock, Fsys = 500 MHz, increment = user-input data to generate Fout. The accumulator is 33 bits, the register to hold the increment data is 32 bits for high frequency step resolution.  

 

The math is accumulator[32:0] = acumulator[31:0] + increment[31:0]. Fout = accumulator[31]. 

 

My target Fout = xx Hz - 200 MHz. But as I tried to generate Fout around 100 MHz, the output waveform was no longer 50% duty cycle and the frequency step resolution got worse. Can someone provides some pointers on this or a new way of generating a programmable clock with high resolution on frequency step (1 Hz step would be great). 

 

 

Thank you, 

 

DN
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
4,340 Views

A more generic way would be to use two integers, a and b, with b > a. Then the algorithm would be (in pseudo code): 

 

on each clock cycle: 

 

if (accumulator > b-a) 

accumulator = accumulator + a - b 

generate a pulse on clock output 

else 

accumulator = accumulator + a 

end if 

 

This will generate a pulse with a frequency of Fsys * a / b 

If instead of a pulse you change the sign of the output, it will generate a rectangular signal with a duty cycle as close as 50% as you can get, with a frequency of Fsys * a / (2*b) 

 

Be careful if you plan to use this generated signal as a clock inside the FPGA itself, as you could have problems with glitches.
0 Kudos
Altera_Forum
Honored Contributor II
4,340 Views

This is simply impossible with a digital clock generator. 

 

Besides the 1 Hz frequency resolution, a jitter specification is necessary to decide about possible solutions. In general, the mentioned parameters demand for an analog PLL with low reference frrequency, not feasible with FPGA built-in PLLs.
0 Kudos
Altera_Forum
Honored Contributor II
4,340 Views

 

--- Quote Start ---  

This is simply impossible with a digital clock generator. 

 

Besides the 1 Hz frequency resolution, a jitter specification is necessary to decide about possible solutions. In general, the mentioned parameters demand for an analog PLL with low reference frrequency, not feasible with FPGA built-in PLLs. 

 

[...Thank you for your prompt response, 1 Hz frequency step is my wish. In my design, I really need the 500 MHz as the master clock and the slower generated clock (x Hz - 200 MHz) to be synchronous with the 500 MHz. The slower generated clock is the real clock that will be used to drive logics inside the Stratix III FPGA so clock jitter needs to be manageable. The frequency step can be in KHz (course) if necessary for trade off with better jitter and synchronous clock. I have also tried to use the Mega Wizard to PLL to output 1 clock at 500 MHz and the 2nd output at 200 MHz but these two don't sync up. Any help will be appreciate it....Thank you, DN ]
0 Kudos
Altera_Forum
Honored Contributor II
4,340 Views

 

--- Quote Start ---  

A more generic way would be to use two integers, a and b, with b > a. Then the algorithm would be (in pseudo code): 

 

on each clock cycle: 

 

if (accumulator > b-a) 

accumulator = accumulator + a - b 

generate a pulse on clock output 

else 

accumulator = accumulator + a 

end if 

 

This will generate a pulse with a frequency of Fsys * a / b 

If instead of a pulse you change the sign of the output, it will generate a rectangular signal with a duty cycle as close as 50% as you can get, with a frequency of Fsys * a / (2*b) 

 

Be careful if you plan to use this generated signal as a clock inside the FPGA itself, as you could have problems with glitches. 

 

[daven....I intended to use the generated clock as the real clock signal inside the FPGA! The frequency resolution does not have to be fine at 1 HZ ( can be in KHz) as along as the clock can be used to clock logics....Thanks again...daven]
0 Kudos
Altera_Forum
Honored Contributor II
4,340 Views

It really depends on what you mean by "manageable jitter". Except on frequencies that are a divisor of the original frequency (500MHz), you will have a jitter of about one original clock period (2ns). If you need a lower jitter, you must either use the FPGA's reconfigurable plls (but you will be more limited in the available frequencies) or use an external DDS. 

You can reduce the impact of glitches by adding a register stage on the output, clocked by the 500MHz clock. 

I am not sure but I think that on a Stratix you can connect a generated signal to the global clock network, either directly or through a clock control block. I just now this isn't possible on the Cyclone family.
0 Kudos
Altera_Forum
Honored Contributor II
4,340 Views

 

--- Quote Start ---  

It really depends on what you mean by "manageable jitter". Except on frequencies that are a divisor of the original frequency (500MHz), you will have a jitter of about one original clock period (2ns). If you need a lower jitter, you must either use the FPGA's reconfigurable plls (but you will be more limited in the available frequencies) or use an external DDS. 

You can reduce the impact of glitches by adding a register stage on the output, clocked by the 500MHz clock. 

I am not sure but I think that on a Stratix you can connect a generated signal to the global clock network, either directly or through a clock control block. I just now this isn't possible on the Cyclone family. 

--- Quote End ---  

 

 

A more generic way would be to use two integers, a and b, with b > a. Then the algorithm would be (in pseudo code): 

 

on each clock cycle: 

 

if (accumulator > b-a) 

accumulator = accumulator + a - b 

generate a pulse on clock output 

else 

accumulator = accumulator + a 

end if 

 

This will generate a pulse with a frequency of Fsys * a / b 

If instead of a pulse you change the sign of the output, it will generate a rectangular signal with a duty cycle as close as 50% as you can get, with a frequency of Fsys * a / (2*b) 

 

Be careful if you plan to use this generated signal as a clock inside the FPGA itself, as you could have problems with glitches.  

 

....Hello, 

1. There are two variables (a & b), what is the easy way to set up the parameters (a & b) to get the intended output frequency? Do I just keep one paramter constant and vary the other. Can you provide an example? 

2. When you say "generate a clock pulse on the output", can I just basically toggle the clock signal (example. If(accumulator > b-a) clock_out = ~clock_out;) 

3. "If instead of a pulse you change the sign of the output, it will generate a rectangular signal with a duty cycle as close as 50% as you can get, with a frequency of Fsys * a / (2*b)". I am not sure on this suggestion, can you explain more? 

 

Thank you so much 

 

daven
0 Kudos
Altera_Forum
Honored Contributor II
4,340 Views

What I meant was that the event "if (accumulator > b-a)" will happen with a frequency of Fsys * a / b. So if you toggle your clock signal inside this if, as you are suggesting in (2), then the generated clock will have a frequency of Fsys * a / (2*b). 

You will need both a and b to be variable if you need to fine tune your generated frequency. From the above formula you get a/b = 2*Foutput / FSys, so the problem of finding a and b is basically a fraction simplification problem, or you can just use a = 2*Foutput and b = FSys if you are lazy ;) 

 

What exactly is the purpose of this clock generation? If it is just to be able to slow down the system to spare energy or generate less heat, then I think that using a 200MHz and a clock enable signal that only enables the logic on n cycles per second will produce the same result, with a much simpler design and an easier job for the fitter and Timequest.
0 Kudos
Altera_Forum
Honored Contributor II
4,340 Views

 

--- Quote Start ---  

What I meant was that the event "if (accumulator > b-a)" will happen with a frequency of Fsys * a / b. So if you toggle your clock signal inside this if, as you are suggesting in (2), then the generated clock will have a frequency of Fsys * a / (2*b). 

You will need both a and b to be variable if you need to fine tune your generated frequency. From the above formula you get a/b = 2*Foutput / FSys, so the problem of finding a and b is basically a fraction simplification problem, or you can just use a = 2*Foutput and b = FSys if you are lazy ;) 

 

What exactly is the purpose of this clock generation? If it is just to be able to slow down the system to spare energy or generate less heat, then I think that using a 200MHz and a clock enable signal that only enables the logic on n cycles per second will produce the same result, with a much simpler design and an easier job for the fitter and Timequest. 

--- Quote End ---  

 

 

...Hello again. Thank you for the response, since I'm interested in your clock generator suggestion. Below is my Verilog code to generate the clock based on your formula. From the Verilog code, in order for me to generate a 200 MHz clk_out, I need to actually generate a 400 MHz clock and toggle it to get 200 MHz. And at high clock rates (~100 MHz and up), the output clock waveform is no longer displayed a consistent 50/50 or 60/40 duty cycle clock pattern (the clock periods varied dramatically) and the frequency step also becomes coarse! (BTW, it works great for low frequency range 0 - ~50 MHz with fine frequency step.)  

 

The purpose of this clock generator is I need to be able to generate a variable clock dynamically to support differerent data rate (15 KHz - 200 MHz) in our test equipment. This allows the user to generate clock & data from (15 KHz - 200 MHz) to test their UUT. 

 

// ================================================================= 

// verilog module for variable clock generation triggering logic 

// fout = fsys * a/b. a, b = integer (32-bit) 

// clk_in = 500 mhz, clk_out = variable output clock 

// ================================================================= 

module clockgen_x( 

input clk_in, // 500 MHz 

input reset_in, // Async reset 

output reg clk_out // variable output clock 

); 

 

 

integer a; 

integer b; 

integer accumulator; 

 

always @(posedge reset_in or posedge clk_in) 

begin 

if(reset_in) 

begin 

// fout = 500 mhz x (1000 / 2717) =~ 184 mhz 

// clk_out = fout / 2 =~ 92 mhz 

a <= 1000; 

b <= 2717; 

clk_out <= 1'b1; 

accumulator <= 32'h0000_0000; 

end 

else if(accumulator > (b-a)) 

begin 

accumulator <= accumulator + a-b; 

clk_out <= ~clk_out; 

end 

else 

accumulator <= accumulator + a; 

 

end 

 

endmodule 

 

 

Once again thank you for your assistance.
0 Kudos
Altera_Forum
Honored Contributor II
4,340 Views

I don't know what is going on with your messages on this forum but I only got now a notification that you replied. It's the second time in a row in this thread... really strange. 

Anyway your code seems correct and yes, with this solution your clock will get more and more irregular as you get close to FSys/2, it is inevitable. You could have a look at a reconfigurable PLL to smooth your signal but I never had a look at the megafunction and I don't know how flexible it would be. And the PLL would only filter some of the jitter out, it wouldn't remove it completely. 

If you need a better clock signal with such a wide range in frequencies your best solution is an external DDS. We have used the Analog Devices AD9912 DDS on several projects and are quite happy with the performance. It of course has some drawbacks compared to an FPGA only solution, mostly the space (it requires a big analog filter) and power consumption.
0 Kudos
Reply