cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
788 Views
Registered: ‎10-09-2019

Low Frequency Clocks

Jump to solution

Dear Sir:

      I came across this webpage about low frequency clock design and I found it to be of interest:

https://www.edaboard.com/showthread.php?322910-low-frequency-clocks-generation-in-xilinx-clock-wizard

     The moderator of the discussion submits a snippet of code to generate a low frequency clock that I will set forth below (one must first read the webpage to understand the snippet of code that I have posted below) :

always @ (posedge clk_15m) begin // uses the same 15 MHz clock that generates the counters and enables
if (enb_1m5) begin
// code that runs at 1.5 MHz
end

      The moderator utilizes a method that I will term, the "enable method".

      I would like a detailed understanding of this method.    Can anyone provide me with a summary of how to implement this method to obtain a synchronous, low jitter, low frequency, clock?

 

       

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Scholar
Scholar
486 Views
Registered: ‎05-21-2015

Re: Low Frequency Clocks

Jump to solution

@goer001,


      If you have a solution in mind ("enable method") can you please show a post with a block diagram of your remedy?

I'll provide my "remedy" in Verilog, if you don't mind.  It's easier to do and much more flexible than any block design methodology.  First, let's create a 15MHz clock from a 150MHz clock.

initial counter_15mhz = 0;
always @(posedge i_clk_150mhz)
if (counter_15mhz >= 9)
begin
  counter_15mhz <= 0;
  ce_15mhz <= 1;
end else begin
  counter_15mhz <= counter_15mhz + 1;
  ce_15mhz <= 0;
end

Then, from this, you can create a 5MHz enable signal,

always @(posedge i_clk_150mhz)
if (ce_15mhz)
begin
// Logic *only* transitions when ce_15mhz is true
// With the exception of ce_5mhz that is cleared unless ce_15mhz && counter_5mhz==0
ce_5mhz <= 0; if (counter_5mhz == 0) begin counter_5mhz <= 2; ce_5mhz <= 1; end else begin counter_5mhz <= counter_5mhz - 1; end
end else
ce_5mhz <= 0;

Note that the first counter counted up and this one counts down.  I've done this for illustration.  Both methods are equivalent in their functionality, and which you choose to use is entirely up to you.

You can do the same to create a 1.5MHz clock enable signals as well.  Here again is an down-counter.

initial counter_1m5mhz = 0;
initial ce_1m5mhz = 0;
always @(posedge i_clk_150mhz)
if (ce_15mhz)
begin
  ce_1m5mhz <= 0;
  if (counter_1m5mhz == 0)
  begin
    counter_1m5mhz <= 9;
    ce_1m5mhz <= 1;
  end else
    counter_1m5mhz <= counter_1m5mhz - 1;
end else // Always make certain the CE signal is cleared if it isn't explicitly set
  ce_1m5mhz <= 0;

The same would apply to any 1MHz clock enable signal you might wish to create.  All that would need to change are the constants and (possibly) the bitwidths.  Now that you have these "ce*" signals, all you need to do is to use them to gate your logic,

always @(posedge i_clk_150mhz)
if (ce_1m5mhz)
begin
  // Your 1.5MHz logic would go here
end

As with anything, the devil lies in the details--particularly when crossing from enabled clock to another.  While such crossings are now synchronous, sparing you a lot of headache elsewhere in your design, it is still possible that a 1.5MHz enabled logic would miss something from the 5MHz domain, or that something in the 5MHz domain would see repeated versions of a signal from the 1.5MHz domain.  Likewise, I've started with a 150MHz clock.  You might find this challenging to work with, since all of your logic will need to take place at that speed--just enabled to operate at your favorite lower speed.  You might find it easier to start with a 45MHz clock and divide by 3, or even a 75MHz clock which you'd divide by 5, rather than working with the 150MHz clock that we divided by 10.

Other types of dividers are available as well.  For example, if you had a 100MHz clock to start from, and didn't want to use a PLL to create any of these other clocks, you could create an approximate 15MHz enable signal using a fractional divider.  In this case, your code might look like:

// The step is given by the desired rate (15MHz) divided by the initial
// clock rate (100MHz in this case) times 2^32 (watch out for overflow!)
parameter [31:0] FRACTIONAL_STEP = 32'h266_6666;
reg [31:0] fractional_counter_15mhz;

initial fractional_counter_15mhz = 0;
always @(posedge i_clk_100mhz)
  { ce_15mhz, fractional_counter_15mhz }
<= fractional_counter_15mhz + FRACTIONAL_STEP;

Do be aware, though, that if you choose to use this method the ce_15mhz will appear to jump around a bit between once every six clocks and once every seven clocks as it tries to approximate 15MHz.

Dan

View solution in original post

0 Kudos
12 Replies
Highlighted
Teacher
Teacher
769 Views
Registered: ‎07-09-2009

Re: Low Frequency Clocks

Jump to solution
you can either cascade counters by taking an output from one counter to clock the next, or have one common clock and generate an enables of one clock width out of the first counter to enable the second,
The first one, is more ASIC like, where they have multiple clocks, but the second counter is now time delayed from the first,
The second option, all the counters run at the same clock, so the number of clocks is reduced, great for FPGAs , and the counters are time alligned, also good for designs,
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Adventurer
Adventurer
703 Views
Registered: ‎10-09-2019

Re: Low Frequency Clocks

Jump to solution

Dear Dr. Smith;

        I would like to thank you for your reply.    I will use the name "moderator" with regard to the person posing the solution to the problem posed in the webpage that I had referenced via the web link.   

        Let me summarize the remedy that the moderator of the discussion posed to create a "synchronous" clocking system.  

        There are 2 target frequencies:   1.0 MHz and 1.5 MHz

        The moderator proposes a common clock set at 15 MHz to achieve the 1.0 MHz and the 1.5 MHz target frequencies.

        The moderator's solution is utilize counter circuits to achieve both these target frequencies:

1) 15 MHz divide by 10 = 1.5 MHz

2) 15 MHz divide by 15 = 1.0 MHz

         After this point the moderator's explanation is not clear.   His code snippet solution appears to reference each clock separately.   In other words, for each clock there will exist that code snippet applied to each clock and these code snippets will operate independently of each other.   

         Your interpretation of his solution appears to utilize an "enable" remedy whereby the 2 clocks do not operate independently after division but are locked in phase (however, it appears one clock may be phase shifted from the other).     Can you please go into detail about your interpretation of the "enable" remedy, perhaps, provide a block diagram in context to a code snippet?   

 

 

 

         

       

        

0 Kudos
Highlighted
Teacher
Teacher
689 Views
Registered: ‎07-09-2009

Re: Low Frequency Clocks

Jump to solution
to be honest to tutor that level is beyond the bandwidth of the forums.
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Highlighted
Adventurer
Adventurer
682 Views
Registered: ‎10-09-2019

Re: Low Frequency Clocks

Jump to solution

I found the webpage to be of interest.  

Your solution appears to be different from the moderator's solution.    If your solution is a standard, conventional, approach a textbook reference would be of interest.  

Maybe, someone else at this forum can offer a definitive interpretation of what the moderator is proposing on the webpage I had uploaded.

0 Kudos
Highlighted
Scholar
Scholar
627 Views
Registered: ‎05-21-2015

Re: Low Frequency Clocks

Jump to solution

@goer001,

This "enable method" as you call it is common practice.

Let's back up for a moment and clarify what is meant by a "clock", since "clock" by itself can be ambiguous.  The clock we are talking about is one you would transition on the positive edge of, as in always @(posedge clk).  Other "clock"s exist, such as you might create from one of these posedge-capable clocks, which are sent to outputs of the chip or treated as logic.  These are often called clocks, but not what the moderator or I am referring to.

As the "moderator" (your term) attempted to describe, logic takes time within a design.  It takes time for logic to go from inputs to a combinatorial expression to outputs somewhere else.  This amount of time is variable.  It depends upon where the LUTs and flip-flops of your design are placed within the chip, and so it will change from one build to the next.  If not managed properly, it can make strange and inexplicable things happen within your design.  For example, I managed to get an up-counter to count backwards.  While these effects are more common with faster clocks, slower clocks are not immune to the problem at all.  The digital designer is expected to know how to avoid these problems.

In a synchronous design, where everything transitions on the same edge of the same clock, the tools can verify that the time it takes from the output of all the flip-flops used in a calculation to the input of the next flip-flop is enough time for the logic to settle, and the output to reliably reflect the expression within your design.

However, in a design that uses multiple signals in the posedge block description, this is no longer the case.  To handle this, designs with multiple clock signals of this type are separated into "clock domains", and movement from one domain to another is carefully managed.  Going from one clock domain to another generally involves either 1) sending only a single signal, and using a 2-flip-flop synchronizer, or 2) using an Asynchronous FIFO.  These solutions are somewhat complex, and so they have consequences.  The most common consequence is that they slow down the logic within your design.  For this reason, alternatives are used.

One such alternative is the clock enable method the "moderator" proposed.  It's used all the time, and most definitely a recommended practice where usable.  The clock enable method makes it possible to operate on signals slower than the master clock rate, while avoiding all of the issues associated with clock domain crossings.

For further reference, I write a blog at zipcpu.com.  There you'll find articles discussing this enable method, clock domain crossings, asynchronous FIFOs and more.  Feel free to check it out.

Dan

Highlighted
Explorer
Explorer
616 Views
Registered: ‎04-19-2018

Re: Low Frequency Clocks

Jump to solution

 

Whenever I look for things on google and I found a solution in edaboard, I skip it. That's the result from my experience. Let's say it's a "low quality" place...

 

0 Kudos
Highlighted
Scholar
Scholar
592 Views
Registered: ‎05-21-2015

Re: Low Frequency Clocks

Jump to solution

@satguy,

That's a shame.  The "moderator"s answer on EDA board wasn't that bad at all.  Indeed, I thought it was pretty good.  The biggest problem with it was that the OP either didn't  follow what he was recommending, or didn't realize it was a standard practice.  (I'm not sure which.)

Dan

0 Kudos
Highlighted
Adventurer
Adventurer
530 Views
Registered: ‎10-09-2019

Re: Low Frequency Clocks

Jump to solution

Dear Dan;

      Thank you for your reply.

      If you have a solution in mind ("enable method") can you please show a post with a block diagram of your remedy?

      Again, thank you for your reply.

 

0 Kudos
Highlighted
Scholar
Scholar
487 Views
Registered: ‎05-21-2015

Re: Low Frequency Clocks

Jump to solution

@goer001,


      If you have a solution in mind ("enable method") can you please show a post with a block diagram of your remedy?

I'll provide my "remedy" in Verilog, if you don't mind.  It's easier to do and much more flexible than any block design methodology.  First, let's create a 15MHz clock from a 150MHz clock.

initial counter_15mhz = 0;
always @(posedge i_clk_150mhz)
if (counter_15mhz >= 9)
begin
  counter_15mhz <= 0;
  ce_15mhz <= 1;
end else begin
  counter_15mhz <= counter_15mhz + 1;
  ce_15mhz <= 0;
end

Then, from this, you can create a 5MHz enable signal,

always @(posedge i_clk_150mhz)
if (ce_15mhz)
begin
// Logic *only* transitions when ce_15mhz is true
// With the exception of ce_5mhz that is cleared unless ce_15mhz && counter_5mhz==0
ce_5mhz <= 0; if (counter_5mhz == 0) begin counter_5mhz <= 2; ce_5mhz <= 1; end else begin counter_5mhz <= counter_5mhz - 1; end
end else
ce_5mhz <= 0;

Note that the first counter counted up and this one counts down.  I've done this for illustration.  Both methods are equivalent in their functionality, and which you choose to use is entirely up to you.

You can do the same to create a 1.5MHz clock enable signals as well.  Here again is an down-counter.

initial counter_1m5mhz = 0;
initial ce_1m5mhz = 0;
always @(posedge i_clk_150mhz)
if (ce_15mhz)
begin
  ce_1m5mhz <= 0;
  if (counter_1m5mhz == 0)
  begin
    counter_1m5mhz <= 9;
    ce_1m5mhz <= 1;
  end else
    counter_1m5mhz <= counter_1m5mhz - 1;
end else // Always make certain the CE signal is cleared if it isn't explicitly set
  ce_1m5mhz <= 0;

The same would apply to any 1MHz clock enable signal you might wish to create.  All that would need to change are the constants and (possibly) the bitwidths.  Now that you have these "ce*" signals, all you need to do is to use them to gate your logic,

always @(posedge i_clk_150mhz)
if (ce_1m5mhz)
begin
  // Your 1.5MHz logic would go here
end

As with anything, the devil lies in the details--particularly when crossing from enabled clock to another.  While such crossings are now synchronous, sparing you a lot of headache elsewhere in your design, it is still possible that a 1.5MHz enabled logic would miss something from the 5MHz domain, or that something in the 5MHz domain would see repeated versions of a signal from the 1.5MHz domain.  Likewise, I've started with a 150MHz clock.  You might find this challenging to work with, since all of your logic will need to take place at that speed--just enabled to operate at your favorite lower speed.  You might find it easier to start with a 45MHz clock and divide by 3, or even a 75MHz clock which you'd divide by 5, rather than working with the 150MHz clock that we divided by 10.

Other types of dividers are available as well.  For example, if you had a 100MHz clock to start from, and didn't want to use a PLL to create any of these other clocks, you could create an approximate 15MHz enable signal using a fractional divider.  In this case, your code might look like:

// The step is given by the desired rate (15MHz) divided by the initial
// clock rate (100MHz in this case) times 2^32 (watch out for overflow!)
parameter [31:0] FRACTIONAL_STEP = 32'h266_6666;
reg [31:0] fractional_counter_15mhz;

initial fractional_counter_15mhz = 0;
always @(posedge i_clk_100mhz)
  { ce_15mhz, fractional_counter_15mhz }
<= fractional_counter_15mhz + FRACTIONAL_STEP;

Do be aware, though, that if you choose to use this method the ce_15mhz will appear to jump around a bit between once every six clocks and once every seven clocks as it tries to approximate 15MHz.

Dan

View solution in original post

0 Kudos
Explorer
Explorer
480 Views
Registered: ‎04-19-2018

Re: Low Frequency Clocks

Jump to solution

 

I honestly think you are reinventing the wheel, to not to say the stone...

If I need a clock in an FPGA, I use an MMCM block.

If it's a ridiculously low frequency for today's FPGAs (< 10 MHz) and/ or I don't have MMCMs available, I use the binary counter with count limit and a threshold for SDR clocking.

for example: to divide a clock by 100, set it to count up to 99 (7 bits) and set the threshold to 99. It will pass 1 out of 100 clocks, not a 50% duty but it works for SDR processes. Don't use it as a clock but as enable.

Highlighted
Adventurer
Adventurer
457 Views
Registered: ‎10-09-2019

Re: Low Frequency Clocks

Jump to solution

Dear Dan;

        I would like to thank you for your detailed and most excellent reply.

        Your feedback was many steps above the typical response that I have read in the past.   Your reply was far and away much better than the responses that I have read from people in the past, even better, than the responses from people who earn a salary responding to these forum posts.    You are certainly one of a kind and a person whom I will remember.    

        Again, I would like to thank you for your most excellent post.  

        

0 Kudos
Highlighted
Adventurer
Adventurer
447 Views
Registered: ‎10-09-2019

Re: Low Frequency Clocks

Jump to solution

Thank you, Satguy, for your input.

0 Kudos