There are some(or most) instructions in a computer that simply cannot be executed in a single clock cycle. But there lies a problem. How does the program counter in the computer know when an instruction is completed, considering that one instruction might take 2 clock cycles vs another being 3 clock cycles. How do program counters(or more importantly, the machinery that detects that an instruction is complete) work?

  • \$\begingroup\$ AFAIK the PC is incremented when the instruction is fetched, before it has been decoded, executed and write back. \$\endgroup\$ – Marko Buršič Feb 24 at 21:43
  • \$\begingroup\$ A finite state machine controls instruction fetch and decode cycles. Charles Petztold’s book Code is a good first resource for this kind of question. \$\endgroup\$ – MarkU Feb 24 at 22:14
  • 2
    \$\begingroup\$ I strongly recommend watching entire series of videos (over 40 of them!) on Ben Eater's channel describing building 8-bit computer from scratch. He shows exactly how microcode is designed and executed. \$\endgroup\$ – Maple Feb 25 at 6:31
  • \$\begingroup\$ Okay, but watching 40 videos isn't something I can do in one day. I have school, so which video(or videos) do you think best answer my question? \$\endgroup\$ – Trevor Mershon Feb 26 at 17:06
  • \$\begingroup\$ @TrevorMershon this one: 8-bit CPU control logic, but it actually has 3 parts. Note that in his build Ben Eater uses fixed microcode length, but he mentions that one of the commands can be "reset microcode counter", which would allow each instruction to have its own length \$\endgroup\$ – Maple Feb 27 at 9:46

tl;dr version: instructions are expanded internally to multiple microcoded steps. The PC is held by microcode until the instruction sequence completes.

get-a-cuppa version:

A CPU has two types of code: instructions (opcodes + operands) that are fetched and executed from RAM, and the small steps that carry out that instruction, called microcode, that implement each sub-operation necessary for the instruction.

For example, an instruction that adds two numbers from memory and stores them back to memory would break down in steps like this:

  • fetch value A from RAM and load in register A
  • fetch value B from RAM and load in register B
  • add registers A and B, store in register C
  • store register C into RAM

So here we have four defined microinstructions (microcode sequence steps) to complete one opcode, expanded out from just one instruction fetched from RAM. These microinstructions are decoded, one by one, to steer the data from external memory or I/O, through the CPU, and finally back to memory or I/O.

Thus, there are two ‘program counters’: the system PC (Program Counter) that provides the external instruction address, and a microinstruction sequence count that selects the current microinstruction step. The PC advances on each instruction fetch, while the microinstruction sequence count advances faster, on each CPU clock. Greatly simplifying, the PC advances only when the microinstruction sequence is finished.

So in the above example, the PC is held for four clocks waiting for the microcode to complete, then advances to the next count and the next instruction is fetched. In reality, to save time the next fetch can be - and usually is - overlapped (pipelined) with the current instruction processing. This gets complicated with instructions that can lead to a branch, that is, a jump that isn't to the next code address. Anyway, instruction prefetch is a rabbit hole for another time.

What does it all mean?

Clock cycle count per instruction is a huge deal. It is a subject of hot debate and a long-standing competitive rivalry. Why? Without getting into too much detail, the two main approaches to computer architecture these days are:

  • CISC, for Complex Instruction Set Computer and
  • RISC, for Reduced Instruction Set Computer

Broadly speaking, CISC machines (like x86) have many complex, powerful instructions that are code-dense, but take many microcode cycles to execute. RISC machines (like ARM) have simpler (and fewer) instructions that take fewer cycles to complete, but are less code-dense (programs are bigger).

It's been nearly 40 years since RISC came about, and decades longer than that for microcoded CISC (going back to the late 1940s.) In those 40 years alongside each other as competitors for mind- and market share, there has been a lot of cross-pollination between RISC and CISC, hastened along as VLSI technology has become faster and more dense. So CISC hardware got more powerful and cycle-efficient, while RISC hardware increased in complexity while keeping to the small-is-beautiful idea of a simpler opcode set.

| improve this answer | |
  • \$\begingroup\$ From reading about the "SAP-1", I think the microcode counter is the ring counter. Is that true in modern computers? \$\endgroup\$ – Trevor Mershon Apr 13 at 14:29

There are many dozens of different ways in which this is done. And many computers have variable length instructions (multiple words or bytes, odd numbers of bytes, etc.), so the logic not only has to know when but how much to increment. Some computer (superscalar, etc.) fetch more than one instruction at a time, and retire variable numbers of instructions each clock, so that also adds to the logic required. In such cases, the ISA visible program counter may have little (or nothing?) to do with the actual physical instruction addresses being used fetch from various level(s) of the memory subsystem (due to speculation).

In the simplest form, part of the instruction informs a state machine; and, as the state machine sequences (one or more cycles), some of the state machine outputs freeze, increment, add an offset, load, or reset the program counter, as required by the particular state in the sequence. Or a microcoded CPU implementation does the same.

How do primitive microcode instructions and/or the state machine know what to do next? In some cases the next microcode address, ROM address, or state encoding is part of every microcode word and/or state machine output. Sometimes multiple levels of the above (MC68000 had 2 levels).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.