5

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.

enter image description here

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.

http://imgur.com/dD30q

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?

feetwet
  • 2,322
  • 9
  • 31
  • 55
LasseValentini
  • 153
  • 1
  • 4

3 Answers3

6

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.

Jason S
  • 13,950
  • 3
  • 41
  • 68
  • 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
0

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.

supercat
  • 45,939
  • 2
  • 84
  • 143
0

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
nidhin
  • 8,197
  • 3
  • 28
  • 46
  • 1
    You should format your code, this is very hard to read – pipe May 25 '18 at 06:09
  • 2
    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 06: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