# Odd number frequency divider

Important note: You are not helping me do my homework. This is for a competition for engineering students, that encourages you to "use your network" ;)

I've got this pattern for a frequency divider that divides the clock by 5. It's supposed to have one major problem, but I can't seem to figure out exactly what it is. The options I have to fix this problem is:

• X==(000|001|100), Y==(001)
• X==(000|001|010|011), Y==(010|011)
• X==(001|010|011), Y==(000)
• Both a) and c) are correct!

I've taken the time to map out the signals in the original design and in option number 3, as I thought that was the answer. I've shifted the clock one half clock cycle, whoops. Shouldn't change anything though. The rest is done by hand.

Does anyone here have any good suggestions?

## 3 Answers

It's supposed to have one major problem

The one possible problem that jumps out at me is glitch prevention. Your output is a clock signal, so it would be very sensitive to extra edges. But it is a combinational output, so it can be prone to glitches.

Just as an example, let's say you had this naive implementation of a full carry generator (at least 2 inputs of 3 are true), namely

Y = ABC + AB(!C) + A(!B)C + (!A)BC


If your ABC signals switch from 111 to 011, there is a chance, depending on propagation delays, that the output Y, which should be a 1 the entire time, gives you a short glitch of 0. What's basically going on is that the output's trueness has to shift from one term to another: ABC -> (!A)BC in this case. If the (!A)BC term has a longer propagation delay than the ABC term for the 1 -> 0 transition on A, then both terms ABC and (!A)BC can be 0 for a short period of time, and you get a 0 as an output.

A proper implementation is one where a single input bit change produces no glitches in the output: the output's level is shared by two terms as it transitions. In the case of a full-carry generator, this works:

Y = AB + BC + CA


In your case, there are two possible causes of glitches.

One is that X and Z change at nearly the same time -- but in your case, according to your timing diagrams, this shouldn't happen.

The other is that the combinational logic that produces X is glitch-prone. We don't know how it's implemented, so that's hard to say.

The simplest solution in either case is to stick a flip-flop on the output, with the same clock input as your other flip-flops. Modern flip-flops have sample/hold specs such that any propagation delay >= 0 and < (clock period - setup time) will produce stable, glitch-free outputs, so unless your clock period is really fast, any glitch on the input of the flip-flop will settle out by the start of its setup time window on the next clock edge.

If you can't tolerate the delay of putting a flip-flop on the output, you need to guarantee that all combinational logic directly producing the output is glitch-free.

• I had missed that it was a clock output. Glitches are almost certainly the "major issue". I was thinking that one of the answers had a more optimal logic solution (fewer gates). – W5VO May 12 '11 at 15:58

I'd suggest starting with a divide-by-five counter, one of whose bits is high for two counts and low for three. For example:

Q0 := !Q1 & !Q2;
Q1 := Q0;
Q2 := Q1;


This counter will go through the sequence: 000 001 011 110 100 (a value of 101 will reach a valid state after two clocks; 010 or 111 will reach a valid state after one clock). Any bit of it may be used as a two-hot output.

Take the output of this counter and feed it into a latch which is triggered by the opposite clock edge. The "OR" of this counter output with the first one would yield the desired waveform.

No need to make it that complex. I have made for divide by 3, You can generalize it or hardcode it for divide by 5 just changing the value of c1 and sensitivity elements . Below is the code :

module clk ();
reg clk,clkout;
initial clk =0;
initial clkout = 0;
int c1,c2,c3;
always #5 clk = ~clk;
always@(posedge clk or negedge clk)
begin
c1 <= c1 +1;

if (c1 == 5)
begin
c1 <= 0;
end

//
end

always@(posedge clk or negedge clk)
begin
if(c1==0 || c1 == 3)
begin
clkout = ~clkout;
end
end

endmodule

• You should format your code, this is very hard to read – pipe May 25 '18 at 6:09
• Select the text and press the {} code button on the editor toolbar. Note that you seem to have provided a program for something without saying what that something is. Also note that the question is about logic, not programming. Finally, see that the OP accepted an answer seven years ago. – Transistor May 25 '18 at 6:23
• @DHANESH: nidhin has added the code tags but you need to indent the code properly and explain how this answers the question. – Transistor May 25 '18 at 17:06