|
constant
flag
Dest | Scr1 Src2
|<--------->| V |<--------->|<--------->|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| A | B | C | D | x | x | x | c | c | f | x | x | x | x | x | x |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|<-------------> |<----->|
opcode ^
|
cc = ALU opcode
00 = add
01 = subtract
10 = and
11 = not
or branch condition
00 = no branch
01 = branch if N = 1
10 = branch if Z = 1
11 = always branch
ABCD encodes the operation/instruction as follows:
A = 1 ---> LD instruction
B = 1 ---> ST instruction
C = 1 ---> Branch instruction (cc encode the branch condition)
D = 1 ---> SETHI instruction
ABC = 0000 ---> ALU instruction (cc encodes the operation)
Other combinations are not used (so decoding instruction is very easy)
|
Each type of instructions encode their constant differently and we must extract it differently, depending on the instruction type (you guess it, use MUXes...)
constant flag Dest | Scr1 Src2 |<--------->| V |<--------->|<--------->| +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | | | | | | | | 1 | | | | x | x | x | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Constant |
Dest |<--------->| +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | | 1 | | | | x | x | x | x | x | x | x | x | x | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Constant |
The SETHI instruction shifts the constant over by 3 bits and store the result in the Dest register.
So you should output this value when it is a SETHI instruction:
Forming the SETHI constant:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | 1 | | | | a | b | c | d | e | f | g | h | i |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Constant
Constant used in operation:
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| a | a | a | a | a | b | c | d | e | f | g | h | i | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
Don't use shifters to accomplish this. This can be done easily by "creative connection". Connect the input "shifted over" to a different multiplexer input - just like in a multiply circuit.
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | 1 | | x | x | x | x | x | x | x | x | x | x | x | x |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Constant offset
|
You must sign-extend the constant offset also.
|
You need this "constant extraction circuit" inside the ID stage
|
If Stall_IF = 1 then:
If Stall_ID = 1 then:
This is extremely important...
By default, all Dff (registers) are
written
at the
END of the clock:
+--------+
| |
| |
| |
+--------+ +
^
|
|
|
Update Dff (registers)
|
There are some registers that must be updated in the MIDDLE of the clock:
+--------+
| |
| |
| |
+--------+ +
^
|
|
|
Update Dff (registers)
|
I will indicate that explicitly in the design notes.
|
Define IF clk stall branch MemDataIn[15..0] branchAddr[15..0] |
MemRq Read PC[15..0] IF_Out[15..0];
.....
Endef;
|
The tri-state-buffers are on when: stall = 0
(that will take care of business, the memory will send the data to the input and IF stage will send it to the output)
|
Define ID clk IR_ID[15..0] PC[15..0] src1[15..0] src2[15..0] src3[15..0] |
src1_sel[0..3] src2_sel[0..3] src3_sel[0..3]
PC1[15..0] A[15..0] B[15..0] IR_Const[15..0] D[15..0];
.....
Endef;
|
The stalling will only affect the IR_ID register and it is handled by the "red dot" circuitry !
|
Define EX clk IR_ID[15..0] src1[15..0] src2[15..0] src3[15..0] |
N Z ALUout[15..0] DMAR[15..0] SMDR[15..0];
.....
Endef;
|
|
Define MEM clk IR_MEM[15..0] src1[15..0] src2[15..0] src3[15..0] |
bcc1 bcc0 MemRq Read ALUout[15..0] DMAR[15..0] SMDR[15..0];
.....
Endef;
|
The tri-state-buffers for MemAddrOut[15..0] are on when: instruction in MEM stage is LD or ST
The tri-state-buffers for MemDataOut[15..0] are on when: instruction in MEM stage is ST
|
Define WR clk IR_WR[15..0] src1[15..0] src2[15..0] |
C_Enable RegSel[0..2] CBus[15..0];
.....
Endef;
|
Define PSR clk N_in Z_in | N Z;
... 2 Dff's
Endef;
|
Define Registers clk CBus RegSel[2..0] DataIn[15..0] | Reg7[15..0] Reg6[15..0] Reg5[15..0] Reg4[15..0] Reg3[15..0] Reg2[15..0] Reg1[15..0] Reg0[15..0]; Endef; |
Define BranchDecision ccN ccZ N Z | branch ;
....
Endef;
|
ccN ccZ N Z | branch
---------------------------+----------
0 0 0 0 | 0
0 0 0 1 | 0
0 0 1 0 | 0
0 0 1 1 | 0
---------------------------+----------
0 1 0 0 | 0
0 1 0 1 | 1
0 1 1 0 | 0
0 1 1 1 | 1
---------------------------+----------
1 0 0 0 | 0
1 0 0 1 | 0
1 0 1 0 | 1
1 0 1 1 | 1
---------------------------+----------
1 1 0 0 | 1
1 1 0 1 | 1
1 1 1 0 | 1
1 1 1 1 | 1
|
Define Stall_IF ID_stall IR_ID[15..0] IR_EX[15..0] IR_MEM[15..0] | stall ;
....
Endef;
|
Define Stall_ID EX_stall IR_ID[15..0] IR_EX[15..0] IR_MEM[15..0] | stall ;
....
Endef;
|
Define Stall_EX MEM_stall IR_ID[15..0] IR_EX[15..0] IR_MEM[15..0] | stall ;
....
Endef;
|
Define Stall_MEM IR_ID[15..0] IR_EX[15..0] IR_MEM[15..0] | stall ;
....
Endef;
|
(I made it like this, so future extensions that require ID stage to be stalled, can be easily added)
|
Define BasicPipe clk reset DatabusIn[15..0] |
PC[15..0] N Z branch
MemRq Read AddrBusOut[15..0] DataBusOut[15..0]
Stall_IF Stall_ID Stall_EX Stall_MEM
IR_ID[15..0] IR_EX[15..0] IR_MEM[15..0] IR_WR[15..0]
Reg0[15..0] Reg1[15..0] Reg2[15..0] Reg3[15..0]
Reg4[15..0] Reg5[15..0] Reg6[15..0] Reg7[15..0]
IF_PC[15..0] IF_IF_Out[15..0]
ID_PC1[15..0] ID_A[15..0] ID_B[15..0] ID_Const[15..0] ID_D[15..0]
EX_Op1[15..0] EX_Op2[15..0]
EX_ALUout[15..0] EX_DMAR[15..0] EX_SMDR[15..0]
MEM_ALUout[15..0] MEM_LMDR[15..0]
WR_C_Enable WR_RegSel[2..0] WR_CBus[15..0]
Endef;
|