IPipe.rose
Copyright © 1984 by Xerox Corporation. All rights reserved.
Uses MicroInstructionBA and microinstruction history to set up EUControl
It interfaces with the IDecoder above and the IStack below
May raise DelayACycleAB
Last edited by: McCreight, April 13, 1984 5:46:06 pm PST
Last edited by: Curry, August 23, 1984 1:59:55 pm PDT
IPipe:
CELL [
Decoder
XBus =INT[32],
Lev0PA <INT[32],
Lev0LA <INT[8],
Lev0SA <INT[8],
Lev0AaddrBA <INT[8],
Lev0BaddrBA <INT[8],
Lev0CaddrA <INT[8],
Lev0AluRtIsKBA <BOOL,
Lev0AluOpBA <EnumType["Dragon.ALUOps"],
Lev0CondSelBA <EnumType["Dragon.CondSelects"],
Lev0CondEffectBA <EnumType["DragonMicroPLA.CondEffect"],
Lev0IStackPostEffectBA <EnumType["DragonMicroPLA.IStackPostEffect"],
Lev0ITrapPostEffectBA <EnumType["DragonMicroPLA.ITrapPostEffect"],
Lev0EuPBusCmdBA <EnumType["Dragon.PBusCommands"],
Lev2CondSelBA >EnumType["Dragon.CondSelects"],
Lev3CaddrBA >INT[8],
XBSourceBA <EnumType["DragonMicroPLA.XBSource"],
Exceptions
DontBypassBA <BOOL,
KillPipeAB <BOOL,
PushPendingAB >BOOL,
PopPendingAB >BOOL,
ITrapEffectPendingAB >EnumType["DragonMicroPLA.ITrapPostEffect"],
Lev3ITrapEffectBA >EnumType["DragonMicroPLA.ITrapPostEffect"],
DelayACycleAB >BOOL,
Lev2CondEffectBA >EnumType["DragonMicroPLA.CondEffect"],
Stack
IStkPushBA >BOOL,
IStkPopBA >BOOL,
Lev3PBA >INT[32],
Lev3LBA >INT[8],
EU
KBus =INT[32], -- PhA bidirectional, PhB A,B,C to EU
EUAluLeftisR1BA >BOOL, -- Left Default is aRam 1B
EUAluLeftisR3BA >BOOL, -- Left Default is aRam 1B
EUAluRightisR1BA >BOOL, -- Right Default is bRam 1B
EUAluRightisR3BA >BOOL, -- Right Default is bRam 1B
EUAluRightisKBA >BOOL, -- Right Default is bRam 1B
EUS1isR1BA >BOOL, -- Default is bRam 1B
EUS1isR3BA >BOOL, -- Default is bRam 1B
EUAluOpAB >EnumType["Dragon.ALUOps"], -- 2A
EUCondSelAB >EnumType["Dragon.CondSelects"], -- 2A
EUR2isR3BA >BOOL, -- Default is R1 2B
EUS3isR3BA >BOOL, -- Default is S2 2B
EUTrapBA >BOOL, -- Trap on conditon 2B
EUHoldCarryBA >BOOL, -- Preserve carry
EUR3isR2AB >BOOL, -- Default is RData 3A
EUWriteToPBusAB >BOOL, -- Data direction 3A
EUCheckPParityAB >BOOL, -- Yes for non-FP Fetch 3A
FP
FPCSLoadBA >EnumType["DragonFP.CSLoad"],
FPCSUAluBA >EnumType["DragonFP.CSUnload"],
FPCSUMultBA >EnumType["DragonFP.CSUnload"],
euPBus PBus
EPCmdA >EnumType["Dragon.PBusCommands"],
EPRejectB <BOOL,
Serial debugging interface
ResetAB <BOOL,
DHoldAB <BOOL,
DShiftAB <BOOL,
DExecuteAB <BOOL,
DNSelectAB <BOOL,
DDataInAB <BOOL,
DDataOutAB =BOOL,
Timing and housekeeping interface
RescheduleAB <BOOL,
PhA <BOOL,
PhB <BOOL
]
State
delayed1: ARRAY Dragon.Phase OF DragonIFU.Level1,
level1: ARRAY Dragon.Phase OF DragonIFU.Level1,
level2: ARRAY Dragon.Phase OF DragonIFU.Level2,
level3: ARRAY Dragon.Phase OF DragonIFU.Level3,
lastCycleDelayedBA :BOOL,
level3RejectingBA :BOOL,
killPipeBA :BOOL,
dHoldBA :BOOL
EvalSimple
Bypass:
PROC[
next1: DragonIFU.Level1,
lev1: DragonIFU.Level1,
lev2: DragonIFU.Level2,
lev3: DragonIFU.Level3,
noBypassing:
BOOL]
RETURNS[interlock: BOOL, adjustedNext1: DragonIFU.Level1] = {
field :Dragon.HexByte ← DragonIFU.PRtoByte[euField];
read1 :BOOL ← DragonIFU.IsRdCmd [next1.euPBus];
read2 :BOOL ← DragonIFU.IsRdCmd [lev1.euPBus];
ac2 :BOOL ← next1.a = lev1.c;
ac3 :BOOL ← next1.a = lev2.c;
bc2 :BOOL ← next1.b = lev1.c;
bc3 :BOOL ← next1.b = lev2.c;
passRt :
BOOL ←
next1.aluOp=Or AND next1.a=(DragonIFU.PRtoByte[euConstant]+0) AND -- EU ALU nop
NOT DragonIFU.IsFPCmd[next1.euPBus]; -- can't bypass address
interlock ← read2 AND (ac2 OR (bc2 AND NOT (next1.aluRt=k OR passRt)));
interlock ← interlock
OR
next1.aluOp=FOP AND (lev1.c=field OR lev2.c=field OR lev3.c=field);
adjustedNext1 ← IF interlock THEN [] ELSE next1;
IF
NOT noBypassing
AND
NOT interlock
THEN {
OPEN adjustedNext1;
aluLt ← IF ac2 THEN r1 ELSE IF ac3 THEN r3 ELSE aluLt;
aluRt ←
IF next1.aluRt=k
THEN aluRt
ELSE
IF bc2
AND
NOT read2
THEN r1
ELSE IF bc3 THEN r3 ELSE aluRt;
store1 ←
IF next1.aluRt#k
THEN store1
-- Write to EU => =k
ELSE
IF bc2
AND
NOT read2
THEN r1
ELSE IF bc3 THEN r3 ELSE store1;
result2 ← IF bc2 AND passRt THEN r3 ELSE result2;
store3 ← IF bc2 THEN r3 ELSE store3;
result3 ← IF read1 THEN rdata ELSE result3;
} };
IF
PhA
AND
NOT dHoldBA
THEN {
pipeInterlock:BOOL ← FALSE;
input: DragonIFU.Level1 ← [
a : Lev0AaddrBA,
b : Lev0BaddrBA,
aluLt : aRam,
aluRt : IF Lev0AluRtIsKBA THEN k ELSE bRam,
store1 : bRam,
ka : Dragon.LFD[XBus],
aluOp : Lev0AluOpBA,
condSel : Lev0CondSelBA,
condOp : Lev0CondEffectBA,
result2 : r1,
store3 : s2,
euPBus : Lev0EuPBusCmdBA,
result3 : IF DragonIFU.IsRdCmd[Lev0EuPBusCmdBA] THEN rdata ELSE r2,
c : Lev0CaddrA,
iStackOp : Lev0IStackPostEffectBA,
iTrapOp : Lev0ITrapPostEffectBA,
p : Dragon.LFD[Lev0PA],
l : Lev0LA,
s : Lev0SA
];
IF killPipeBA
THEN {delayed1[a] ← level1[a] ← []; level2[a] ← []; level3[a] ← []}
ELSE
IF level3RejectingBA
THEN {
level1[a] ← level1[b];
level2[a] ← level2[b];
level3[a] ← level3[b];
IF lastCycleDelayedBA
THEN delayed1[a] ← delayed1[b]
ELSE delayed1[a] ← input }
ELSE {
IF lastCycleDelayedBA
THEN {
delayed1[a] ← delayed1[b];
[pipeInterlock , level1[a]]
← Bypass[delayed1[b], level1[b], level2[b], level3[b], DontBypassBA] }
ELSE {
delayed1[a] ← input;
[pipeInterlock , level1[a]]
← Bypass[input, level1[b], level2[b], level3[b], DontBypassBA] };
level2[a].ka ← level1[b].ka;
level2[a].aluOp ← level1[b].aluOp;
level2[a].condSel ← level1[b].condSel;
level2[a].condOp ← level1[b].condOp;
level2[a].result2 ← level1[b].result2;
level2[a].store3 ← level1[b].store3;
level2[a].euPBus ← level1[b].euPBus;
level2[a].result3 ← level1[b].result3;
level2[a].c ← level1[b].c;
level2[a].iStackOp ← level1[b].iStackOp;
level2[a].iTrapOp ← level1[b].iTrapOp;
level2[a].p ← level1[b].p;
level2[a].l ← level1[b].l;
level2[a].s ← level1[b].s;
level3[a].euPBus ← level2[b].euPBus;
level3[a].result3 ← level2[b].result3;
level3[a].c ← level2[b].c;
level3[a].iStackOp ← level2[b].iStackOp;
level3[a].iTrapOp ← level2[b].iTrapOp;
level3[a].p ← level2[b].p;
level3[a].l ← level2[b].l;
level3[a].s ← level2[b].s;
};
Send off EU PhA Control
PushPendingAB ← delayed1[a].iStackOp=push
OR
level1[a].iStackOp=push OR
level2[a].iStackOp=push OR
level3[a].iStackOp=push;
PopPendingAB ← delayed1[a].iStackOp=pop
OR
level1[a].iStackOp=pop OR
level2[a].iStackOp=pop OR
level3[a].iStackOp=pop;
ITrapEffectPendingAB ←
IF delayed1[a].iTrapOp#none
THEN delayed1[a].iTrapOp
ELSE
IF level1[a].iTrapOp#none
THEN level1[a].iTrapOp
ELSE
IF level2[a].iTrapOp#none
THEN level2[a].iTrapOp
ELSE level3[a].iTrapOp;
DelayACycleAB ← level3RejectingBA OR pipeInterlock;
EUAluOpAB ← level2[a].aluOp;
EUCondSelAB ← level2[a].condSel;
EPCmdA ← IF level3RejectingBA THEN NoOp ELSE level2[b].euPBus;
EUWriteToPBusAB ← DragonIFU.IsWtCmd[level3[a].euPBus];
EUCheckPParityAB ← EUWriteToPBusAB AND NOT DragonIFU.IsFPCmd[level3[a].euPBus];
EUR3isR2AB ← level3[a].result3=r2;
PhA KBus and XBus Control
Every microinstruction that causes the EU to drive the KBus must insure that following micros do not conflict.
IF DragonIFU.BytetoPR[Lev3CaddrBA]
IN [ifuXBus..ifuLast]
THEN XBus ← KBus
ELSE {
IF DragonIFU.BytetoPR[Lev0BaddrBA] = ifuLevel3LS
THEN XBus ← Dragon.LTD[level3[b].s*256 + level3[b].l];
IF level2[b].euPBus=StoreFP
THEN KBus ← Dragon.LTD[level2[b].ka]
ELSE KBus ← Dragon.LTD[level1[b].ka] } };
IF PhB THEN dHoldBA ← DHoldAB;
IF
PhB
AND
NOT DHoldAB
THEN {
PhB State changes
delayed1[b] ← IF KillPipeAB THEN [] ELSE delayed1[a];
level1[b] ← IF KillPipeAB THEN [] ELSE level1[a];
level2[b] ← IF KillPipeAB THEN [] ELSE level2[a];
level3[b] ←
IF KillPipeAB
-- p l s must be preserved for restart
THEN [p:level3[a].p, l:level3[a].l, s:level3[a].s] ELSE level3[a];
lastCycleDelayedBA ← DelayACycleAB;
level3RejectingBA ← EPRejectB;
killPipeBA ← KillPipeAB;
Send off PhB Exception Control to IDecoder:
Lev2CondEffectBA ← level2[b].condOp;
Lev2CondSelBA ← level2[b].condSel;
Lev3CaddrBA ← IF level3RejectingBA THEN DragonIFU.noStore ELSE level3[b].c;
Send off PhB IStack Control and Data:
IStkPushBA
← IF level3RejectingBA THEN FALSE ELSE level3[b].iStackOp=push;
IStkPopBA
← IF level3RejectingBA THEN FALSE ELSE level3[b].iStackOp=pop;
Lev3ITrapEffectBA
← IF level3RejectingBA THEN none ELSE level3[b].iTrapOp;
Lev3PBA ← Dragon.LTD[level3[b].p];
Lev3LBA ← level3[b].l;
FP Control
FPCSUAluBA ←
IF
NOT level3RejectingBA
AND level1[b].euPBus=FetchFPAlu
THEN unload ELSE dont;
FPCSUMultBA ←
IF
NOT level3RejectingBA
AND level1[b].euPBus=FetchFPMult
THEN unload ELSE dont;
FPCSLoadBA ←
IF
NOT level3RejectingBA
AND
level2[b].euPBus=StoreFP
May Need nop load to clock D regs
OR level1[b].euPBus=FetchFPAlu
OR level1[b].euPBus=FetchFPMult
THEN load ELSE dont;
Send off PhB EU Control and Data
KBus ← Dragon.
LTD
[(((level1[b].a*LONG[256]) + level1[b].b)*256 + level3[b].c)*256];
EUAluLeftisR1BA ← level1[b].aluLt=r1;
EUAluLeftisR3BA ← level1[b].aluLt=r3;
EUAluRightisR1BA ← level1[b].aluRt=r1;
EUAluRightisR3BA ← level1[b].aluRt=r3;
EUAluRightisKBA ← level1[b].aluRt=k;
EUS1isR1BA ← level1[b].store1=r1;
EUS1isR3BA ← level1[b].store1=r3;
EUR2isR3BA ← level2[b].result2=r3;
EUS3isR3BA ← level2[b].store3=r3;
EUTrapBA ← level2[b].condOp # microJump;
EUHoldCarryBA ← killPipeBA;
Check to see if XBus driven from IPipe during phB
IF XBSourceBA = pipe3PC THEN XBus ← Dragon.LTD[level3[b].p];
}