Additional
Control and Status Lines
So far we have, we have had the values on the asel and bsel control lines determine what values are taken from the registers. However, in the instruction Add r3, r1,r2, how does the asel control line know the have the value of 1? The same goes the bsel and the r3write control lines. How does the information get from the ir to the control lines? Additional control lines are needed to get this information. These lines are to be called
risel, rjsel and rksel.
risel is used when the ir contains information about which register should be written to. The risel control line is combined with bits from the ir (which give the register to write to) and the r0write, r1write, r2write and r3write control lines to produce the vr0write, vr1write, vr2write and vr3write control lines. If risel is on, one of the vrXwrite control lines is on based on a value in the instruction register. If risel is off, the vrXwrite control lines contain the values of the appropriate rXwrite control lines. The vrXwrite control lines would replace the appropriate rXwrite control lines connected to the register set. The information from the instruction register would be considered a new status line, called irri.
rjsel and rksel work in a similar manner to risel. The rjsel control line combines the asel control line with bits from the ir to produce the vasel control line. If rjsel is on, the vasel control line value is determined by a value in the instruction register. The vasel control line would replace the asel control line connected to the register set. The information from the instruction register would be considered a new status line, called irrj. The rksel control line combines the bsel control line with bits from the ir to produce the vbsel control line. If rksel is on, the vbsel control line value is determined by a value in the instruction register. The vbsel control line would replace the bsel control line connected to the register set. The information from the instruction register would be considered a new status line, called irrk.
The instruction Add r3, r1, r2 would have the following control lines set
These would be the same control lines for any add operation no matter which registers are being used.
New Control Lines
New Status lines
|
|
|
Control
Programs
A control program is section of code that will specify the control lines set inside of a control unit. The syntax of each line is a listing of the control lines being used and its value. Any control line not listed is assumed to have value of zero. If a control line can only have values of zero or one, listing the control line implies a value of one while not listing the control line implies a value of zero.
Let use create a tiny instruction set using the Mythsim architecture. We will have the following operations:
Name |
Operation |
Opcode |
No-op |
does nothing |
0 |
Add |
ri ← rj + rk |
1 |
Set Register |
ri ← const8 |
2 |
Branch if zero |
if (rj == 0) PC ← PC + const4 |
3 |
Move |
ri ← rj |
4 |
Store |
Mem[rj] ← rk |
5 |
Load |
ri ← Mem[rj] |
6 |
Subtraction |
ri ← rj - rk |
7 |
The first part of the control program will be to fetch the next instruction based on the current value of the program counter. We saw this before, but we wish to redo it efficiently. We use register 6 to hold a copy of the PC that we can increment. This allows a more efficient way of doing the operation.
Address |
Label |
Control
Lines |
0 |
fetch0 |
asel = 7, bsel = 7, alusel = AND, r6write, marsel = LOAD, goto fetch1; |
1 |
fetch1 |
asel = 6, alusel = ADDA, cin, r7write, read, ir0sel = LOAD, if wait then goto fetch1 else goto fetch2 endif; |
2 |
fetch2 |
asel = 7, bsel = 7, alusel = AND, r6write, marsel = LOAD, goto fetch 3; |
3 |
fetch3 |
asel = 6, alusel = ADDA, cin, r7write, read, ir1sel = LOAD, if wait then goto fetch3 else goto fetch4 endif; |
The next part of the control program will be to decode the opcode. This is done by using a special input to determine the next instruction. This uses the opcode bits from the instruction register. Thus iropcode would be another status line.
Address |
Label |
Control
Lines |
4 |
fetch4 |
goto opcode[iropcode]; |
Now we need to determine what to do for each opcode. We won't worry about the addess values until we combine everything together.
Opcode 0: No-op
This operation is to do nothing. This is often useful in synchronizing other operations.
The control line would be:
Address |
Label |
Control
Lines |
|
opcode[0] |
goto fetch0; |
Opcode 1: Add - ri ← rj + rk
As pointed out before, this operation relies on the values in the instruction register.
Address |
Label |
Control
Lines |
|
opcode[1] |
risel, rjsel, rksel, alusel = ADD, goto fetch0; |
Opcode 2: Set Register - ri ← const8
This instruction will fill in a register with the value from the last 8 bits of the instruction register.
Address |
Label |
Control
Lines |
|
opcode[2] |
risel, resultsel = CONST8, goto fetch0; |
Opcode 3: Branch if zero - if (rj == 0) then PC ← PC + const4
This instruction will check if a register value is zero. If so, it will add the 4 bit value from the instruction register to the PC. To check if a value is zero, we can use the decrement operation in the ALU (SUBA) and check the cout signal line. If cout is one, the value was not zero. If cout is zero, the value was zero.
Address |
Label |
Control
Lines |
|
opcode[3] |
rjsel, alusel = SUBA, r6write, resultsel = CONST4, if cout then goto fetch0 else goto branch endif; |
|
branch |
r7write, asel = 7, bsel = 6, alusel = ADD, goto fetch0; |
Opcode 4: Move - ri ← rj
This instruction is to move a value from one register to another. The use of the increment operation without setting the value of cin is used to move the value through the ALU unchanged.
Address |
Label |
Control
Lines |
|
opcode[4] |
risel, rjsel, alusel = ADDA, goto fetch0; |
Opcode 5: Store - Mem[rj] ← rk
This instruction is to place a value from a register into the computer's memory. The address will be specified in another register. The use of the label memwrite is used to allow for other write operations (not yet defined). Note the two control statements that are needed to access the value to be written.
Address |
Label |
Control
Lines |
|
opcode[5] |
rjsel, alusel = ADDA, marsel = LOAD, goto opcode5a; |
|
opcode5a |
asel = 5, bsel = 5, alusel = SUB, cin, r5write, goto opcode5b |
|
opcode5b |
rksel, asel = 5, alusel = OR, mdrsel = LOAD_ALU, goto memwrite; |
|
memwrite |
write, if wait then goto memwrite else goto fetch0 endif; |
Opcode 6: Load - ri ← Mem[rj]
This instruction will place a value from the computer's memory into a register. The address will be specified in another register.
Address |
Label |
Control
Lines |
|
opcode[6] |
rjsel, alusel = ADDA, marsel = LOAD, goto opcode6a; |
|
opcode6a |
read, mdrsel = LOAD_MEM, if wait then goto opcode6a else goto opcode6b endif; |
|
opcode6b |
resultsel = MDR, risel, goto fetch0; |
Opcode 7: Subtraction - ri ← rj - rk
This is similar to the addition operation, except with a different alu operation.
Address |
Label |
Control
Lines |
|
opcode[7] |
risel, rjsel, rksel, aulsel = SUB, cin, goto fetch0; |
Putting it all together we get the following. Note that the opcode[X] labels are all listed sequentially.
Address |
Label |
Control
Lines |
0 |
fetch0 |
asel = 7, bsel = 7, alusel = AND, r6write, marsel = LOAD, goto fetch1; |
1 |
fetch1 |
asel = 6, alusel = ADDA, cin, r7write, read, ir0sel = LOAD, if wait then goto fetch1 else goto fetch2 endif; |
2 |
fetch2 |
asel = 7, bsel = 7, alusel = AND, r6write, marsel = LOAD, goto fetch 3; |
3 |
fetch3 |
asel = 6, alusel = ADDA, cin, r7write, read, ir1sel = LOAD, if wait then goto fetch3 else goto fetch4 endif; |
4 |
fetch4 |
goto opcode[iropcode]; |
5 |
opcode[0] |
goto fetch0; |
6 |
opcode[1] |
risel, rjsel, rksel, alusel = ADD, goto fetch0; |
7 |
opcode[2] |
risel, resultsel = CONST8, goto fetch0; |
8 |
opcode[3] |
rjsel, alusel = SUBA, r6write, resultsel = CONST4, if cout then goto fetch0 else goto branch endif; |
9 |
opcode[4] |
risel, rjsel, alusel = ADDA, goto fetch0; |
10 |
opcode[5] |
rjsel, alusel = ADDA, marsel = LOAD, goto opcode5a; |
11 |
opcode[6] |
rjsel, alusel = ADDA, marsel = LOAD, goto opcode6a; |
12 |
opcode[7] |
risel, rjsel, rksel, aulsel = SUB, cin, goto fetch0; |
13 |
branch |
r7write, asel = 7, bsel = 6, alusel = ADD, goto fetch0; |
14 |
|
|
15 |
opcode5a |
asel = 5, bsel = 5, alusel = SUB, cin, r5write, goto opcode5b |
16 |
opcode5b |
rksel, asel = 5, alusel = OR, mdrsel = LOAD_ALU, goto memwrite; |
17 |
memwrite |
write, if wait then goto memwrite else goto fetch0 endif; |
18 |
opcode6a |
read, mdrsel = LOAD_MEM, if wait then goto opcode6a else goto opcode6b endif; |
19 |
opcode6b |
resultsel = MDR, risel, goto fetch0; |