Hardware‎ > ‎Writeups‎ > ‎

4-bit Synchronous Counter

I started thinking about how the program counter will work in the CPU.  The following requirements apply:
  • The counter must be 16 bits wide
  • It must count (obviously)
  • It must be presettable (so jump instructions can load new values)
Looking around, the 74HC161 4-bit synchronous counter seems to solve the problem.  Well, 1/4 of the problem, but four of them will solve the whole problem.  I decided to wire up some toy circuits to help me understand how the counter works -- how to make it increment, how to cascade them, and how to load new values.  I did this by wiring up two circuits: a simple counter with one 4-bit '161, and a 8-bit counter with two '161s.  The latter circuit also demonstrates resetting and presetting.  I didn't gather timing information.

NOTE: Vendors apparently disagree as to the pin names.  That is, the names on the TI '161 datasheet linked above disagree with those on NXP's version of the same chip, which differ from those on the Eagle version (which is actually a renamed CMOS 4161).  This writeup will use the 4161 pin names.  The pin numbers are the same between the various vendors.

Simple 4-bit counter

The counter is driven by a 555 timer, which generates a 4.8Hz square wave.  Slow enough that I can watch the counter, but not so slow that I fall asleep.  There's no video, which is unfortunate, but the circuit pretty much does what one might expect -- it counts 0000-1111 on the LEDs, forever.

Things to note:
  • TE and PE (TI's ENP and ENT) must be high for the counter to count.  I haven't the faintest idea what T and P stand for, but PE/ENP is always driven high, even when we cascade.  We'll think of this one as chip enable.  We can think of TE/ENT as carry-in.  In short, when the clock goes high, the chip adds TE to the current value in the counter.  If TE is always high, we'll always add one.  If it's only high periodically (as will be the case when we cascade), the counter will only increment when it's high.  Understanding the role of TE and PE is key to understanding the operation of the '161 counter.
  • The preset pins (P1-P4) are disconnected because this circuit doesn't support presetting (/LOAD is always high).
  • CO is disconnected because we're not cascading.
  • /CLEAR is driven high since this circuit doesn't support resetting.

Cascaded 8-bit counter

The CPU's program counter will be 16 bits wide, but we can learn everything we need to learn (aside from timing) with two 4-bit counters cascaded together to form an 8-bit counter.  Here's the circuit:


The 4-bit circuit was about as bare-bones as it could be.  This one, on the other hand, has all the trimmings, including:
  • A Reset button, connected to /CLEAR on both counters.
  • A Load button, connected to /LOAD on both counters.  When Load is pressed, the value hard-coded to the P1-P4 pins on both chips will be loaded into the counters.  I could've added 8 switches and thus made the loaded value dynamic, but that wouldn't have added to my understanding of the '161, and would've left me very cramped for board space.  With the setup shown, I'm able to leave everything nicely spread out (and easy to label).
The highlight of this circuit is the cascading between the two counters, accomplished by a wire which goes from CO on the first counter to TE on the second.  CO goes high on the first counter when Q1-Q4 are all high.  The second counter sees this on the next clock (when the first counter goes back to 0000), and the second counter increments.  Here's what the oscilloscope sees:
The blue trace is the clock, generated by the 555 timer circuit.  Note that the steady high voltage is at 3.94, rather than the 5V I had expected.  Apparently there is much I need to learn about the 555.  Regardless, 3.94 is within the triggering range for the '161, so the circuit works.

The red trace is the CO output from the first counter (CO0 in the schematic), which leads to TE on the second counter.  It goes high when Q1-Q4 go high, and goes low, as we can see here, when the clock goes high to make Q1-Q4 yield 0000.  This would be much clearer if I had a logic analyzer.