From flip-flop to counter
A single D flip-flop wired to toggle its own output on every clock edge (Q feeds back into D through a NOT gate) divides the clock frequency by two — it counts 0,1,0,1... in a single bit. Chain several of these toggle stages together and you get a circuit that counts upward in binary, one count per clock pulse.
Ripple (asynchronous) counters
The simplest binary counter feeds the output of each flip-flop as the clock input of the next one. The first bit toggles every clock pulse, the second bit toggles every time the first bit falls, and so on — exactly like counting in binary by hand. This is called a ripple or asynchronous counter, because the change "ripples" through the chain one stage at a time rather than all stages updating simultaneously.
The downside: that ripple delay accumulates. In a 4-bit ripple counter, the most significant bit can update slightly after the clock edge, once the change has propagated through all 4 stages — which causes glitches if other logic reads the count mid-ripple.
Synchronous counters
A synchronous counter solves this by driving every flip-flop from the same clock signal directly, and using extra combinational logic (typically AND gates) to compute each bit's next value based on the current count. All bits update at exactly the same instant, eliminating ripple delay at the cost of slightly more gates.
Up/down and modulo-N counters
Adding a direction input lets a counter count down instead of up. Adding reset logic that triggers before the natural overflow point creates a modulo-N counter — for example, a counter that resets after reaching 9 instead of 15, useful for driving a decimal digit on a 7-segment display.
Try it yourself
Load a counter example in Boolflow, connect a CLOCK element, and watch the OUTPUT bits count upward in binary. Compare the timing against a truth table of the expected sequence to confirm the wiring is correct.