In a CPU, how are LU inputs/outputs controlled and fed back to registers?

Basic problem: CPU instruction chooses which register to feed into a LU (such as an ALU), which then outputs a number somewhere and fed back into a register. But sometimes you want to feed the answer back into the same register. An example is Add RA and RB and store the answer in RA.

So trying to imagine that in my head just gets me stuck in an infinite feedback loop. So I searched around online for a relatively long time, but only got irrelevant stuff about what's inside an ALU.

I've done 4-bit and 8-bit adders before, even got the carry bit working. That's not what I'm looking for here. I'm looking for the architecture outside the LU that controls the inputs and outputs, and feeds it back to the registers. As far as I'm concerned, right now the LUs can be black boxes.

I decided to try to draw my own diagram and see how far I can get. (Click for higher resolution.)

In this example, I have four 4-bit registers, and four LUs. One of the LUs does only unary operations, so only takes one register as an input. The other three LUs do binary operations so they take two registers as inputs.

LU1 has one multiplexer guarding the input. 2 control bits choose which register to feed in. The other LUs have two multiplexers guarding their inputs. (Note that means you can "copy" one register into both inputs, so e.g., use Reg A and Reg A in LU2.)

The LU processes the inputs and generates an output. In fact, all LUs output their answer into another multiplexer, which has 2 control bits choosing which value to send to the final thing, which is a plus-shaped demultiplexer. 2 control bits choose which register to send that value to.

So finally we get to the problem. Storing the answer in Reg A, when Reg A was used as an input in the first place, is going to cause problems. Wildly varying states that might settle, might not. You could call this a racing condition.

Now I know "the obvious answer" is to use a clock to slow down the transmissions. But I don't know how to use it. Which parts need a clock? The MUXs? The LUs? The DEMUX? The Regs themselves? All of the above?

I also know there is a thing called the three-state buffer, but as far as I can tell it just uses impedance to "disconnect" a line, as if it's cut in half, so that the MUX or DEMUX is no longer driving (determining) the voltage state of the line.

I'm sorry this problem took many paragraphs to write out. I thought it was simpler to explain, but can't think of good ways to condense it. Hopefully someone can enlighten my architecture, or at least a link to a good diagram with control parts displayed and explained. I feel like I'm just missing one small critical piece that will make everything click.

• So your basic question is how synchronous logic (such as a CPU) updates a register value on a clock edge, without immediately affecting the output, even when the output feeds back to the input -- this is your underlying question, right? This can be greatly simplified to just examining how a D flip-flop works. D flip flop is a 1-bit register, longer registers can be built from the same technology. – MarkU Jun 15 at 0:40
• @MarkU I think that's an accurate summary, but don't really know a lot about clocks so can't be totally sure. If it can be simplified to a D flipflop then I would be very happy, i just need someone to show me where to insert the flipflop into my diagram. Can a clock signal be synonymous with such a flipflop in certain cases? – DrZ214 Jun 15 at 0:44
• The registers themselves in your diagram are the flip-flops. When the clock is stable, they output a value and ignore what is at their input. When the clock rises, they copy the data from the input to the output. And then everything is stable again until the next rising edge. – Tom Verbeure Jun 15 at 0:45

Registers are normally made from D flip-flops, which transfer and hold data on the rising (or falling) clock edge. Assuming the data hold time of the flip flops is less than the propagation delay through the LUs etc., these D flip flops are all you need to prevent a race condition. The rest can all be combinatorial logic that lets the signals flow through.

In operation you would set the MUXs so the output of the source register(s) is connected to the LU and then back into the registers. After waiting for a time long enough for the signals to propagate through the logic you then clock the destination register, which stores the 'answer'.

The clock forces the circuit to operate at a lower speed than it could do if you let everything happen as fast as possible, which sounds bad. But it greatly simplifies the design and improves reliability because the signals just have to be stable before the next clock, whereas with unclocked logic you would have to carefully adjust the propagation delays so the signals arrive at the correct times. Varying temperature and voltage could cause different parts of the CPU to work at varying speeds, upsetting the timing and making it misoperate.

Bottom line? You need a clock - not just for this circuit but other parts of the CPU as well. Some operations might have to be done in several steps with temporary registers holding intermediate results. To get the proper sequencing and account for delays you might need several consecutive clocks per machine cycle, which could be done by using both edges, having several synchronous clock inputs with skewed phases, or clocking a ring counter.