As we talked about previously in the edge sensitivity lab, we have a new tool in our toolbox. Flip flops, as opposed to latches, can be used to build counters. While these may seem trivial, counters are a versatile and flexible tool that we can use to do all sorts of fun things.
In this lab, we are going to use them to build two kinds of clock dividers — modulo counters and cascaded T-FF counters.
Why do we need clock dividers?
Generally, digital logic hardware will have only small numbers of actual hardware oscillators, that is some sort of hardware that generates a regular pulse train. On the Basys 3 board we use in this class, there is a single 100 MHz crystal oscillator.
100 MHz, or 100 million times a second, is really fast. I mean, in terms of modern computers that run at ~5 GHz, maybe not that fast, but it is way too fast for most of the things we do in our college labs. If we hooked up an LED to the output of the clock, it would just look like it was solidly on, as your persistence of vision would make it so you couldn’t see the individual on/off events.
So, what would we do if we wanted to turn on/off the LED once a second?
Answer 1: Technically Correct (Module Counters)
Let’s suppose a digital logic circuit that can count. Let’s say it has a button on it where every time it gets pressed, it counts up by 1. If we were to hook up the 100 MHz clock to that button, we would see that in 1 second, it had counted up to 100 million.
If we then had another digital circuit that could read that counter value and compare it to an arbitrary value, say 100 million, and toggle an output each time it reaches that value, we would have a circuit that outputs something like the following:
| Please note, when N = 100 million, as in our example here, we are dividing by 200 Million, leading to a 0.5 Hz signal. Why is this? In the modulo counter we toggle the output each time we reach our desired count. A single "Hz" is defined by a transition from high to low and back to high. That means we actually have to do two full counts to reach a single Hz. |
If we then also had that circuit reset our counter, we could have a digital circuit that takes our input 100 MHz clock and generates one that toggles once a second! This is known as a "modulo counter", one where it counts to a programmed level, then toggles and resets.
To implement this, we need an adder to compute N + 1, a set of D-FlipFlops to store the current count, and a comparison block to check the current count against the reset value. Practically the block diagram is this:
Each of the Cmp Reset lines are connected to the Comparator’s reset
output. For brevity I showed them connected like that.
|
How do we pick how many bits wide our adder/storage need to be? Thankfully, there’s a super easy eqation for this \$ceil(log2(Cval))\$, where Cval is the value we count to. In this example case, we have: \$ceil(log2(100,000,000))\$, which is: 27. We would a 27 bit wide adder and 27 bits of storage.
How does the reset/comparison work, then? Well, it is purely combinatorial logic
that sits on top of the Q outputs of our D-FlipFlops and checks that the output
value equals a certain number, and it then sets the next state of the output
D-FlipFlop to 1, and queues up a reset. It would check for the binary pattern of
101111101011110000100000000 (100 million in binary) on the output, and assert
the D line to the output flip flop as well as the reset line for all counters.
Answer 2: Close enough, probably, I hope (Ripple Counters)
The modulo counter, for reasons we will examine as we implement things in our lab, can be fairly expensive to implement. It requires an n-bit adder, and then a whole pile of circuitry to compare that count to a given value (could even be configurable! That’s even harder). So, what if we’re in a resource constrained environment and we don’t actually care what rate the LED toggles at? What if it only has to be about every once a second?
For this, we have the Ripple Counter. It is a signifcanly more simple, if more limited, way to implement clock dividers.
It is very simple in construction. If we have a single T-FlipFlop and we hook up the 100 MHz clock to it, we get something like this:
It divided the clock by 2! If we then feed that into another T-FlipFlop… It divides it by 2 again. We have now divided the 100 MHz signal to 25 MHz. If we keep going, we find out that chaining N T-FlipFlops divides our input clock by \$2^N\$. Notice, this cannot be any arbitrary value like could the modulo counter. The arrangement would look like this:
With a waveform like this:
The output of the ripple counter is just the Q of the final T-FlipFlop, however many you have.
Lab Procedure
To properly visualize this, we are going to implement a much… smaller divider. Using the center button as our "clock" signal, we will divide this by 12 (a count of 6) with a modulo divider and by 8 with a ripple counter.
For the ripple counter, use the T-FlipFlop module you implemented in previous labs. For the modulo divider, please use your existing full adder circuitry and D-FlipFlops from previous labs. The only behavioral verilog should be within the D-FlipFlop.
You will be responsible to implmement both the ripple counter and the modulo divider folowing the below IO table:
Signal |
Purpose |
Direction |
btnU |
Reset |
IN |
btnC |
Input Clock |
IN |
led[0] |
Ripple counter stage 1 |
OUT |
led[1] |
Ripple counter stage 2 |
OUT |
led[2] |
Ripple counter stage 3 |
OUT |
led[3] |
Modulo counter state bit 0 |
OUT |
led[4] |
Modulo counter state bit 1 |
OUT |
led[5] |
Modulo counter state bit 2 |
OUT |
led[6] |
Modulo counter output |
OUT |