h1

Real World Examples #5 – Clock Divider by 5

August 26, 2009

Here is a neat little circuit that was used in an actual project a long, long time ago (in a galaxy far, far away…).

The requirement was to build a divide by 5 circuit for the clock with 50% duty cycle. The initial (on reset) behavior was not important – i.e. the circuit could wake up in an undefined state, but should have settled after a given time. The engineer produced the circuit below:

divby5

Basically, the circuit is made out of a 3-bit counter, that counts from 000 to 100 and then resets. Signal ‘X’ goes high when the value of the counter is either 000, 001 or 010. Signal ‘Y’ goes high when the counter equals its ‘middle’ state 010. ‘Z’ is a sample on the falling edge of ‘Y’ in order to generate the 50% duty cycle.

So far so good. The general thinking was OK, but there was a major problem with the circuit, can you discover what it was? How would you fix it in RTL? and more important, how would you fix it in an ECO (as it was eventually done)?

No extra flops are allowed!

About these ads

22 comments

  1. Glitches on X. Insert posedge flops in X and Y.


  2. imagine there are no flops available for the ECO.
    anyways a flop in Y is NOT necessary


    • Prior to imagining a world with no ECO flops, inserting a flop on X and not Y would have created a half-cycle “glitch” after Z deasserted.
      Sans flops…
      Connect X to count[2] through inverter. OR in another compare to the Y condition when count==011. X becomes extended by one cycle, but so does Y (and Z) and X is glitch-free.


      • If flop is allowed, insert a flop on the final output.2 flops are not necessary.


    • Jumped the gun… You can avoid the inverter by changing the final AND to an OR (or NOR) and changing the sense of both inputs. Then you can avoid the extra comparator by connecting Y to count[1].


    • Sheesh, is it time to go home already?! :)
      Change the AND to OR and just remove the one input bubble. Or… leave it as AND, but add a bubble to X input – whichever is smaller/easier/possible.
      So… X=count[2], Y=count[1], clkout=X||Z or clkout=!X&&!Z.
      And if it changes after this… I give up!


    • Remove both the clouds that generate X and Y. Use bit 1 of the counter (00110) as X. Register X on the falling edge to generate Z. Then OR them to get the clock out.

      SCN


      • Take count[1] as X and Y.
        Place a Mux between X and Y for the output.
        Use count[2] as the select line.

        i.e output = Y when count[2]
        output = X when !count[2]


      • In My comment I did a mistake.. The Mux is between X and Z..


  3. How about to change the counter to a Johnson counter (000, 100, 110, 111, 011, 001)!
    If the counter is done to count from 000 to 011 we can test only the last bit (==0) to generate the X value and the second bit (==1)to generate the Y value.


    • I made some changes on my proposal, duty cycle was not 50% – 50%…

      Seems to work right now!!!


    • Johnson counters (which is a form of gray counting) is the way to go when doing clock dividers. (actually normal Gray counters should also be OK)
      ND


  4. In case the flop has an unused (asynchronous) reset input:
    X = 1
    Y <= Z or (=001)
    reset <= (MSB of count = 1)

    that might work since (MSB of count = 1) should be glitch-free
    and the sequence 100-000-001 is also free of potential glitches…

    cheers,
    Philip


  5. May be we can replace Z by
    Z(n)= Y + (X * Z(n-1)).
    Assuming than Z is zero initially (resetted),
    for 000,001 Z=0, thus making OUT=X=1.
    For 010, when Y goes to 1, Z will go to 1, thus making
    output 0.
    For 011, if X becomes 0 before the negedge, then output will be zero. If it is still 1 at negedge, Z(n-1) combined with X will still keep Z at 1, thus keeping out at 0.

    Rajeev


  6. Clock dividers by 3 and 5 lead to the following question: what’s the simplest circuit that divides a clock by any odd number with 50% duty cycle.


  7. Recycle counter as D0, D1, D2.

    always @(posedge clk)
    begin
    D0 <= ~(D1 | D2);
    D1 <= D0;
    D2 <= D1;
    end

    always @(negedge clk)
    begin
    D3 <= D2;
    end

    clk_out = ~(D3 | D2);


  8. Well, i have been move across your site, this was pretty awesome
    to see such a nice list. It definitely help out to million, i guess.


  9. Useful information. Fortunate me I discovered your site by accident, and I’m surprised why this twist of fate didn’t took place earlier! I bookmarked it.


  10. So which of these answers is the correct one:
    a) X==(000|001|100), Y==(001)
    b) X==(000|001|010|011), Y==(010|011)
    c) X==(001|010|011), Y==(000)
    d) Both a) and c) are correct!


  11. [...] [...]


  12. I am genuinely keen of reading posts concerning creating new web site, or even on the topic of Search engine marketing.


  13. Logically, I am not seeing any error in the above circuit.
    Can you pls point me out the error??

    How about generating x == ! (cnt[0] || cnt[1], and then connect x to the input of negedge triggered flop and output is finally (x or z);



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 106 other followers

%d bloggers like this: