Controlling a computer like the CSC-2 is conceptually the same as the CSC-1 with the addition of needing to specify a 3-bit A address, a 3-bit B address and a 3-bit C address at all times. Since there are 8 registers, we need log28=3 bits in the addresses. In some cases, we may not want to store back a value into any register, such as when we store the value in the MBR into memory. In these cases, the scratch register TMP may be specified, or the pseudo-register +1, since it cannot be modified.
Let's go through ADD and STS using the CSC-2 configuration.
First, the instruction fetch stage will be similar for all CSC-2 instructions. We need to move the PC into the MAR and then request a memory read. This is done by setting the A decoder to 2, since PC is register number 2. The B decoder can be set to anything since the ALU function we will select is identity A, which copies only the A output to the shifter. The shifter is told to do nothing and the register is loaded. The C decoder is set to 6, which is the number of the MAR. Then MA is set to 1 and WR to 0 and the hardware waits for memory to fetch the value and copy it into the MBR. The MBR's mux is set to 1 in order to select the value coming from memory instead of the C bus.
Once the MBR has the instruction from memory, it must be copied into the IR register. This is done by setting A to 7, F to identity A, and C to 3. MA must be set to 0 to "turn off" the memory. Why is it necessary to actually have a separate IR register, you might ask why not just use the value in the MBR? Remember that the instruction must be decoded so that a specific instruction wire will get set to 1 in order to direct the rest of the control operations. Since the MBR will later be used to fetch the operand and store the result, that specific instruction wire must not change during these micro-operations. Hence, there needs to be a stable and safe place for the instruction to reside.
Next PC must be incremented. It would be possible to make PC be a "super register," one that has its own increment wire. But a more uniform, albeit slower, approach would be to add the +1 register to PC and store the value back into PC. This requires inputting 2 to the A decoder, 1 to the B decoder, selecting F=add, setting result-LD to 1 and then, after a suitable delay, selecting PC as the destination by putting 2 on the C decoder inputs.
Finally, we are ready to add. Recall that ADD is described by the RTL expression
A <- A + m[X]
The operand fetch stage is next. In the CSC-1, the operand value retrieved from memory was placed in the TMP register since that was the only other input to the ALU. But in the CSC-2, any two registers can be inputs to the ALU, including the MBR. Hence, once the value is fetched (by copying IR to MAR, setting MA=1, WR=0 and selecting the MBR-mux to get the value out of memory), we can directly use that value from the MBR, adding it to A and storing the result back into A. The TMP register is therefore freed for other tasks. Some operations like multiplication and division require several extra registers.
We call one complete movement of data from the registers, through the ALU and shifter, and back into one of the registers, one cycle of the main data path. The "machine instructions" of the CSC-1 would typically require several main data path cycles if the CSC-2 setup is used. Here is what would be needed for the ADD instruction:
MAR <- PC instruction fetch PC <- PC + 1 advancing program counter IR <- MBR saving the opcode MAR <- IR operand fetch A <- A + MBR main addition step, storeback
No fewer than 5 cycles are needed, which argues that the main data path be as short as possible and the adder as fast as possible. If the PC gets back its dedicated INCR wire, one complete cycle could be saved, making ADD faster.
Here's what the control point settings would look like for the CSC-2 doing an ADD instruction, based on the above five main data path cycles:
MAR <- PC A=2 F=0 SH=0 MA=1 WR=0 ; instruction fetch
RESULT-LD=1
C=6
PC <- PC + 1 A=2 B=1 F=5 SH=0 MA=0 ; increment PC
RESULT-LD=1
C=2
IR <- MBR A=7 F=0 SH=0 ; begin decoding
RESULT-LD=1
C=3
MAR <- IR A=3 F=0 SH=0 MA=1 WR=0 ; operand fetch
RESULT-LD=1
C=6
A <- A + MBR A=4 B=7 F=5 SH=0 MA=0 ; execute & storeback
RESULT-LD=1
C=4
Each of the values after A=, B= and C= encode a 3-bit binary number which is inputted to the appropriate 3x8 decoder that selects which register will be gated onto which bus. If A=2, then the value 0010 or 2 will be inputted to the A decoder, causing the contents of register 2, which is the PC register, to be copied onto the A bus. The F= value denotes the ALU function, according to the table on page 3, only expressed in decimal instead of binary. Thus F=5 means the F wires contain 101, which is an addition.
RISC computers try to make each cycle of the main data path be a machine instruction, so they usually disallow operand fetches from memory, instead using more registers. It is not uncommon for a RISC machine to have hundreds of registers.