Skip to content
digiwleeaTools
LearnGlossaryAboutCheat sheetHow a CPU worksBuild a CPUToolsOpen the lab →

Program counter circuit: count, jump and reset, live

A program counter (PC) is the register that holds the address of the next instruction. On each clock edge this 4-bit PC does one of four things: RST = 1 sets it to 0, JMP = 1 loads the jump target J3 to J0, INC = 1 adds 1, and otherwise it holds. Reset wins over jump, and jump wins over counting.

Every instruction a processor runs comes from the address in its program counter. Normally the PC just counts: after fetching the instruction at address 5, it moves on to 6. A jump or branch instruction breaks the sequence by loading a new address, which is how loops and if statements work, and reset sends the processor back to the start of its program. The circuit is a 4-bit register with three choices in front of each flip-flop. An incrementer adds 1 the way a synchronous counter does (each bit flips when INC is 1 and every lower bit is 1, so 1111 wraps to 0000); a 2-to-1 multiplexer picks the jump target instead when JMP is 1; and an AND with NOT RST forces 0 for a synchronous reset. With INC at 0 and JMP at 0 the incrementer passes the old value through, so the PC holds, which a CPU uses to wait while a slow instruction finishes. A conditional jump, like JZ in digiwleea's instruction set, is the same circuit with JMP driven by the zero flag. Flip-flops start in an unknown state, so the live circuit opens held in reset: turn RST off and the PC starts counting.

Big circuit: pinch, scroll or tap + to zoom in, then drag to move around.

Live circuit: click the inputs to toggle them and watch the outputs update. It runs the real simulator, right here on the page.

Open this circuit in the lab →

Embed or cite this circuit

Free to embed on a course page, blog or worksheet: paste this code. The circuit stays live, and the small digiwleea badge links back here.

To cite it: digiwleea, “4-bit program counter”, https://digiwleea.wleeaf.dev/tools/build/program-counter/

What you need

Step by step

  1. Place a clock CLK, inputs RST, INC, JMP and J3 to J0, four D flip-flops on CLK, and probes PC3 to PC0.
  2. Incrementer: carry into bit 0 is INC; each bit's sum is PC_k XOR carry_k, and the carry into the next bit is carry_k AND PC_k.
  3. Jump: for each bit, a 2-to-1 multiplexer chooses J_k when JMP is 1 and the incrementer's sum when JMP is 0.
  4. Reset: AND each multiplexer output with NOT RST and feed it to the flip-flop's D. Pulse RST, then let it count, hold with INC at 0, and jump by setting J and JMP.

Count, hold, jump and reset

Clock edgeRSTINCJMPJ3..J0ActionPC3..PC0PC
11000000reset00000
20101001count00011
30101001count00102
40101001count00113
50101001count01004
60101001count01015
70000111hold01015
80000111hold01015
90011100jump110012
100100000count110113
110100000count111014
120100000count111115
130100000count00000
140110011jump00113
150100000count01004
161100000reset00000

This is the exact run checked before the page is built, on all four PC bits after each of the 16 clocks: a reset, five counts, a two-cycle hold (the J inputs change but are ignored), a jump to 12, counting through 15 and wrapping to 0, a jump to 3 while INC is also 1 (the jump wins), one more count and a final reset. A processor core like this sits at the heart of both a microprocessor and a microcontroller; see microprocessor vs microcontroller.

You can also read the full theory in the lesson on the program counter. Prefer to build it yourself from scratch? Open the digiwleea lab and place the gates on the canvas, or start from the logic gate simulator.

More builds: Registers and counters

All 246 build guides, by topic

Each of these is one step from a transistor to a working CPU. Build every gate from CMOS transistors and work all the way up in the free digiwleea lab, with the free theory reference alongside.

Open the 4-bit program counter in the lab →

Frequently asked

What is a program counter?

The register in a CPU that holds the memory address of the next instruction to fetch. It normally counts up by one after each fetch, and jumps, branches and calls load it with a new address.

How is a program counter built?

From flip-flops, one per address bit, with logic in front of each: an incrementer that adds 1, a multiplexer that can load a jump address instead, and a reset that clears it. This 4-bit one uses 4 D flip-flops and 25 gates.

What happens to the program counter on a jump?

The jump target is loaded into it on the next clock edge instead of the incremented value, so the next instruction is fetched from the new address. A conditional jump loads it only when a condition, such as the zero flag, is true.

Why does the program counter wrap around?

A 4-bit counter can only hold 0 to 15, so adding 1 to 15 gives 10000, and the fifth bit is lost: the PC becomes 0. Real CPUs have wider program counters, 16, 32 or 64 bits, so programs rarely reach the end.

What is the difference between the program counter and the instruction register?

The program counter holds where the next instruction is (an address); the instruction register holds the instruction itself after it has been fetched from that address.