IFUData3.rose
Herrmann, September 17, 1985 1:46:03 pm PDT
Curry, September 5, 1985 11:21:50 pm PDT
McCreight, March 11, 1986 11:41:03 am PST
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by: Curry, January 15, 1985 11:47:59 am PST
Directory IFUPLAMainControl, DragOpsCross, IFUPLAInstrDecode;
TranslationNeeds Dragon, IFUPLAMainControl, IFUPLAInstrDecode;
Imports DragonRosemary, DragonRoseExtras, ClusterParams, LizardRosemary, Rope, IO;
CEDAR
defaultStatus: DragOpsCross.IFUStatusRec = [
userMode: FALSE,
trapsEnabled: FALSE,
reschedule: FALSE];
;
CELLTYPE "IFUStatus"
PORTS [
XBus      = INT[32],
RescheduleBA   < BOOL,
ClearTrapsEnbledBA < BOOL,
ClearUserModeBA  < BOOL,
RschWaiting2BA  > BOOL,
TrapsEnbled2BA   > BOOL,
UserMode0AB   > BOOL,
LoadStage1Ac   < BOOL,
LoadStage1Bc   < BOOL,
LoadStage2Ac   < BOOL,
LoadStage3Ac   < BOOL,
X2ASrcStatusBA   < BOOL,
X1ADstStatusBA   < BOOL,
PhA     < BOOL,
PhB     < BOOL
]
State
status: ARRAY Dragon.Phase OF DragOpsCross.IFUStatusRec,
rsPipe: ARRAY Dragon.Phase OF BOOL,
x2ASrcStatus: ARRAY Dragon.Phase OF BOOL,
statPipe: ARRAY Dragon.Phase OF DragOpsCross.IFUStatusRec
EvalSimple
IF PhA THEN {
newstatusRec: DragOpsCross.IFUStatusRec ← LOOPHOLE[XBus];
rsPipe[a] ← RescheduleBA;
status[a] ← [rescheduleKeep: TRUE];
status[a].reschedule ← (NOT X1ADstStatusBA AND status[b].reschedule)
OR (X1ADstStatusBA AND newstatusRec.rescheduleKeep AND status[b].reschedule)
OR (X1ADstStatusBA AND NOT newstatusRec.rescheduleKeep AND newstatusRec.reschedule)
OR (RescheduleBA AND NOT rsPipe[b]);
status[a].userMode ← (NOT ClearUserModeBA AND NOT X1ADstStatusBA AND status[b].userMode)
OR (NOT ClearUserModeBA AND X1ADstStatusBA AND newstatusRec.userModeKeep AND status[b].userMode)
OR (NOT ClearUserModeBA AND X1ADstStatusBA AND NOT newstatusRec.userModeKeep AND newstatusRec.userMode);
status[a].trapsEnabled ← (NOT ClearTrapsEnbledBA AND NOT X1ADstStatusBA AND status[b].trapsEnabled)
OR (NOT ClearTrapsEnbledBA AND X1ADstStatusBA AND newstatusRec.trapsEnabledKeep AND status[b].trapsEnabled)
OR (NOT ClearTrapsEnbledBA AND X1ADstStatusBA AND NOT newstatusRec.trapsEnabledKeep AND newstatusRec.trapsEnabled);
};
IF PhB THEN {
status[b] ← status[a];
rsPipe[b] ← rsPipe[a];
};
Pipe
IF LoadStage1Ac THEN {x2ASrcStatus[a] ← X2ASrcStatusBA; statPipe[a] ← status[b]};
IF LoadStage1Bc THEN {x2ASrcStatus[b] ← x2ASrcStatus[a]; statPipe[b] ← statPipe[a]};
IF PhA AND x2ASrcStatus[b] THEN {
drive[XBus] ← drive;
XBus ← LOOPHOLE[statPipe[b]];
}
ELSE drive[XBus] ← ignore;
UserMode0AB  ← status[a].userMode;
RschWaiting2BA ← status[b].reschedule AND NOT X1ADstStatusBA; -- just in case
TrapsEnbled2BA  ← status[b].trapsEnabled AND NOT ClearTrapsEnbledBA;
ENDCELLTYPE;
CELLTYPE "KBusPads"
PORTS [
KBus    = INT[32], -- External Signal
XBus    = INT[32],
KPadsIn3BA  < BOOL,
PhA    < BOOL,
PhB    < BOOL
]
EvalSimple
SELECT TRUE FROM
PhB =>
{drive[KBus] ← drive; drive[XBus] ← ignore; KBus ← XBus};
PhA AND NOT KPadsIn3BA =>
{drive[KBus] ← drive; drive[XBus] ← ignore; KBus ← XBus};
PhA -- AND KPadsIn3BA AND NOT PhB -- =>
{drive[KBus] ← ignore; drive[XBus] ← drive; XBus ← KBus};
ENDCASE -- NOT PhA AND NOT PhB -- =>
{drive[KBus] ← drive[XBus] ← ignore};
ENDCELLTYPE;
CELLTYPE "Misc"
PORTS [
ResetAB   < BOOL, -- External Signal
ResetBA   > BOOL,
RescheduleAB < BOOL, -- External Signal
RescheduleBA > BOOL,
DHoldAB   < BOOL, -- External Signal
DHold0BA  > BOOL,
DHold1AB  > BOOL,
DPRejectB  < BOOL, -- External signal
DPRejectedBA > BOOL,
PhA    < BOOL,
PhB    < BOOL
]
EvalSimple
IF PhA THEN {DHold1AB  ← DHold0BA};
IF PhB THEN {
DHold0BA ← DHoldAB;
ResetBA ← ResetAB;
RescheduleBA ← RescheduleAB;
DPRejectedBA ← DPRejectB;
};
ENDCELLTYPE;
CEDAR
MicroInstDisposition: TYPE = {unready, valid, interlocked, killed2b, killed3a, killed3b};
LogPipeState: TYPE = RECORD [
pc: Dragon.HexWord,
op: DragOpsCross.Inst ← x374B,
alpha, beta, gamma, delta: Dragon.HexByte ← 0,
microCyc: NAT ← 0,
disposition: MicroInstDisposition ← unready
];
;
IFULogger: LAMBDA [logRef: |REF IO.STREAM|, lizardSimRef: |REF LizardRosemary.Simulation| ] RETURN CELLTYPE AutoName
PORTS [
XBus     < INT[32],
DPRejectedBA  < BOOL,
OpAB     < INT[8],
AlphaAB    < INT[8],
BetaAB    < INT[8],
GammaAB   < INT[8],
DeltaAB    < INT[8],
OpLengthBA   < INT[3],
InstReadyAB   < BOOL,
ExceptionCodeAB < EnumType["IFUPLAMainControl.ExceptionCode"],
MicroCycleAB  < INT[8],
MicroCycleNextBA < EnumType["IFUPLAInstrDecode.MicroCycleNext"],
MacroJumpBA  < BOOL,
PCBusSrcB   < EnumType["IFUPLAInstrDecode.PCBusSrc"],
PCForLogAB   < INT[32],
LAB     < INT[8],
SAB     < INT[8],
AReg0BA    < INT[8],
BReg0BA    < INT[8],
CReg0BA    < INT[8],
P Interfaces for EU cache
DPCmnd3A    < EnumType["Dragon.PBusCommands"],
DPData     < INT[32],
DPRejectB    < BOOL,
DPFaultB     < EnumType["Dragon.PBusFaults"],
LoadStage1Ac  < BOOL, -- Pipe Controls
LoadStage1Bc  < BOOL,
LoadStage2Ac  < BOOL,
BubbleStage2A1BA  < BOOL,
NormalStage2A1BA  < BOOL,
AbortStage2B2AB  < BOOL,
NormalStage2B2AB  < BOOL,
LoadStage3Ac  < BOOL,
AbortStage3A2BA  < BOOL,
NormalStage3A2BA  < BOOL,
PhA     < BOOL,
PhB     < BOOL
]
State
opPipe: ARRAY [0..3] OF ARRAY Dragon.Phase OF LogPipeState,
last:       {a,ab,b,ba},
firstMicroOfMacro:  LogPipeState,
dpRejectedAB:   BOOL,
dpFaultedBA:   BOOL,
dpFaultedAB:   BOOL,
doTrap3BA:    BOOL,
xbusBCopy:    Dragon.HexWord,
logRegistersB:   BOOL,
interruptPending:  BOOL,
trapped:     BOOL
EvalSimple
NewDisposition: PROC [ pipeState: LogPipeState, disp: MicroInstDisposition ] RETURNS [ newPipeState: LogPipeState ] = {
newPipeState ← pipeState;
newPipeState.disposition ← disp;
};
log: IO.STREAM;
IF NOT PhB AND last=b THEN {
last ← ba;
IF logRegistersB AND (log ← logRef^) # IO.noWhereStream THEN {
log.PutF[" a:%02x", IO.card[AReg0BA]];
log.PutF[ " b:%02x", IO.card[BReg0BA]];
log.PutF[ " c:%02x", IO.card[CReg0BA]];
};
logRegistersB ← FALSE;
SELECT opPipe[3][b].microCyc FROM
117 => { -- Reset finished
ClusterParams.clusterPanel.instrCount ← -1;
trapped ← FALSE;
};
120 => { -- first cycle of trap
trapped ← TRUE;
};
0 => IF NOT DPRejectedBA AND (SELECT opPipe[3][b].disposition FROM
valid => TRUE,
killed3a, killed3b =>
(MicroCycleAB = 120 -- trap that will apply to the new instruction -- ),
ENDCASE => FALSE) THEN {
The first microinstruction of a new macroinstruction instrCount+1 is now committed to retire, either in victory or defeat (as in "trapped"). This means that all register stores for the macroinstruction instrCount are completed, and none for macroinstruction instrCount+1 have yet occurred.
ClusterParams.clusterPanel.instrCount ← ClusterParams.clusterPanel.instrCount+
LizardRosemary.CheckSynch[
lizardSimRef: lizardSimRef,
clusterInst: [ -- the completed instruction
cycle:    ClusterParams.clusterPanel.cycle,
instr:    ClusterParams.clusterPanel.instrCount,
trapped:   trapped,
trapPC:   IF trapped THEN opPipe[3][b].pc ELSE 0,
pc:    firstMicroOfMacro.pc,
op:    firstMicroOfMacro.op,
alpha:    firstMicroOfMacro.alpha,
beta:    firstMicroOfMacro.beta,
gamma:   firstMicroOfMacro.gamma,
delta:    firstMicroOfMacro.delta
]
].deltaInstrCount;
firstMicroOfMacro ← opPipe[3][b];
trapped ← FALSE;
};
ENDCASE => NULL;
};
IF PhA THEN {dpRejectedAB ← DPRejectedBA; dpFaultedAB ← dpFaultedBA};
Pipe
IF PhB THEN opPipe[0][b] ← [
pc: DragonRoseExtras.LFD[PCForLogAB],
op: LOOPHOLE[OpAB],
alpha: AlphaAB,
beta: BetaAB,
gamma: GammaAB,
delta: DeltaAB,
microCyc: MicroCycleAB,
disposition: IF InstReadyAB THEN valid ELSE unready
];
IF LoadStage1Ac THEN opPipe[1][a] ← opPipe[0][b];
IF LoadStage1Bc THEN opPipe[1][b] ← opPipe[1][a];
IF LoadStage2Ac THEN opPipe[2][a] ← (SELECT TRUE FROM
NormalStage2A1BA => opPipe[1][b],
BubbleStage2A1BA => NewDisposition[opPipe[1][b], interlocked],
ENDCASE => ERROR);
IF PhB THEN opPipe[2][b] ← (SELECT TRUE FROM
NormalStage2B2AB => opPipe[2][a],
AbortStage2B2AB => NewDisposition[opPipe[2][a], killed2b],
ENDCASE => ERROR);
IF LoadStage3Ac THEN opPipe[3][a] ← (SELECT TRUE FROM
NormalStage3A2BA => opPipe[2][b],
AbortStage3A2BA => NewDisposition[opPipe[2][b], killed3a],
ENDCASE => ERROR);
IF PhB THEN
{opPipe[3][b] ← opPipe[3][a]; IF dpFaultedAB THEN opPipe[3][b].disposition ← killed3b};
IF PhB THEN {
xbusBCopy ← DragonRoseExtras.LFD[XBus];
dpFaultedBA ← DPFaultB # none;
doTrap3BA ← SELECT ExceptionCodeAB FROM
none, cJump => FALSE,
ENDCASE => TRUE;
IF last#b THEN {
last ← b;
Log instruction at the beginning of Ph0B.
IF ((log ← logRef^) # IO.noWhereStream) AND (ExceptionCodeAB # reset) THEN {
IF (ExceptionCodeAB # none) OR InstReadyAB THEN {
log.PutF["\n%5g%5g", IO.int[ClusterParams.clusterPanel.cycle], IO.int[ClusterParams.clusterPanel.instrCount] ];
SELECT TRUE FROM
ExceptionCodeAB=reseting
=> log.PutF["**Reseting "];
ExceptionCodeAB=reset
=> log.PutF["**Reset "];
ExceptionCodeAB=dpFault
=> log.PutF["**DPFault "];
dpRejectedAB
=> log.PutF["**DPReject "];
ExceptionCodeAB=cTrap
=> log.PutF["**EUCC "];
ExceptionCodeAB=bubble
=> log.PutF["**Bubble "];
ExceptionCodeAB=cJump
=> log.PutF["**CJRestrt "];
ExceptionCodeAB=rschlWait
=> log.PutF["**Reschdl "];
ExceptionCodeAB=iStkOFlow
=> log.PutF["**IStkOver "];
ExceptionCodeAB=eStkOFlow
=> log.PutF["**EStkOver "];
ExceptionCodeAB=ipFault
=> log.PutF["**IPgFault "];
ExceptionCodeAB=none
=> log.PutRope[" "];
ENDCASE
=> log.PutF[" cy: %2g ", IO.card[ExceptionCodeAB.ORD]];
log.PutF["pc:%08x", IO.card[DragonRoseExtras.LFD[PCForLogAB]] ];
SELECT TRUE FROM
dpRejectedAB => log.PutF[" --EU reject delay..."];
NOT InstReadyAB => log.PutF[" --IFetch delay..."];
ENDCASE => {
opLength: [0..5] = DragonRosemary.OpLength[OpAB];
log.PutF[" %-7g", IO.rope[Rope.Cat[DragonRosemary.OpName[OpAB],
(IF MicroCycleAB=0 THEN "" ELSE IO.PutFR["-%g", IO.int[MicroCycleAB]])]]];
IF opLength > 1
THEN log.PutF[" %02x", IO.card[AlphaAB]] ELSE log.PutF[" "];
IF opLength > 2
THEN log.PutF["%02x", IO.card[BetaAB]] ELSE log.PutF[" "];
IF opLength > 3
THEN log.PutF["%02x%02x", IO.card[GammaAB], IO.card[DeltaAB]]
ELSE log.PutF[" "];
log.PutF[" l:%02x", IO.card[LAB]]; -- at beginning of instruction
log.PutF[ " s:%02x", IO.card[SAB]]; -- at beginning of instruction
logRegistersB ← TRUE;
};
};
};
IF ExceptionCodeAB=reset THEN
ClusterParams.clusterPanel.instrCount ← -1;
};
};
ENDCELLTYPE