IFUTestUtils.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Curry, October 24, 1986 3:09:23 pm PDT
Don Curry October 27, 1986 12:01:04 pm PST
DIRECTORY Atom, Cluster2, Convert, Core, CoreFlat, CoreName, Dragon, EU2, EU2Utils, HandCodingUtil, IFU2, IFUPLAInstrDecode, IFUPLAMainPipeControl, IFUTest, IO, REFBit, Rope, Rosemary, RoseTV, TerminalIO;
IFUTestUtils: CEDAR PROGRAM
IMPORTS Atom, Cluster2, Convert, CoreFlat, CoreName, HandCodingUtil, IO, REFBit, Rope, Rosemary, RoseTV, TerminalIO
EXPORTS IFUTest =
BEGIN
← &v ← ViewerOps.FindViewer["Interp: World:Local"]
← ViewerOps.DestroyViewer[&v]
Interpreter
← &v ← ViewerOps.FindViewer["Interp: World:Local"]
← &out ← ViewerIO.CreateViewerStreams["Stuffin", &v].out
← IO.PutRope[&out, "&sgf[IFUTestUtils]"]
Debugging Notes
RemoveButton SIFU
RemoveButton SC2
RemoveButton TSet
RemoveButton TSet
RemoveButton RB
RemoveButton TDay
CreateButton cHsty Interpreter; RCompile IFUTestUtils; Run IFUTestUtils; ← &v ← ViewerOps.FindViewer["Interp: World:Local"]; ← &out ← ViewerIO.CreateViewerStreams["Stuffin", &v].out; ← IO.PutRope[&out, "&sgf[IFUTestUtils]"]
CreateButton cHsty Interpreter; RCompile IFUTestUtils; Run IFUTestUtils; ← &v ← ViewerOps.FindViewer["Interp: World:Local"]; ← &out ← ViewerIO.CreateViewerStreams["Stuffin", &v].out; ← IO.PutRope[&out, "&sgf[IFUTestUtils]"]
CreateButton Hsty ← IFUTestUtils.ShowCluster2[]
&sgf[IFUTestUtils]
UpdateProc:   TYPE = IFUTest.UpdateProc;
RTVal:    TYPE = RoseTV.RTVal;
ROPE:     TYPE = Rope.ROPE;
II:      TYPE = IFU2.II;
NextMacro:   TYPE = IFUPLAInstrDecode.NextMacro;
CondEffect:   TYPE = IFUPLAMainPipeControl.CondEffect;
CondSelects:   TYPE = Dragon.CondSelects;
ALULeftSources:  TYPE = Dragon.ALULeftSources;
ALURightSources: TYPE = Dragon.ALURightSources;
Store2ASources:  TYPE = Dragon.Store2ASources;
ALUOps:    TYPE = Dragon.ALUOps;
PBusFaults:   TYPE = Dragon.PBusFaults;
AluOpRp: ARRAY ALUOps OF ROPE = ["Or", "And", "VAd2", "BChk", "SAdd", "SSub", "LAdd", "LSub", "Xor", "?9", "FOP", "?11", "VAdd", "VSub", "UAdd", "USub"];
LtSrcRp: ARRAY ALULeftSources OF ROPE = ["a", "r", "c", "?"];
RtSrcRp: ARRAY ALURightSources OF ROPE = ["b", "r", "c", "k", "f", "?", "?", "?"];
StSrcRp: ARRAY Store2ASources  OF ROPE = ["b", "r", "c", "?"];
PhRp:   ARRAY Dragon.Phase OF ROPE = ["A", "B"];
BoolRp:   ARRAY BOOL OF ROPE = [FALSE: "F", TRUE: "T"];
NextMacroRp: ARRAY NextMacro OF ROPE =
["Get", "--?", "-?-", "Jmp", "?--", "Hld", "??-", "???"];
NextMacroRp: ARRAY [0..8) OF ROPE =["Get", "--?", "-?-", "Jmp", "?--", "Hld", "??-", "???"];
CondEffectRp: ARRAY CondEffect OF ROPE = ["macroT", "macroJ", "microJ", "bubble"]; -- %6g
CondSelectRp: ARRAY CondSelects OF ROPE = [ -- %3g
"--", "EZ", "LZ", "LE",  "?4", "NE",  "GE", "GZ",
"Ovf", "BC", "IL", "?11", "?12", "nBC", "nIL", "MFt"];
OpCodeRpRef: HandCodingUtil.NameArray ← HandCodingUtil.GetInstArray[];
OpCodeRp: PROC[op: [0..256)] RETURNS [ROPE] = {RETURN[OpCodeRpRef[LOOPHOLE[op]]]};
DPFaultRp: ARRAY [0..16) OF ROPE = [ -- %3g
"non", "?1","?2","?3","?4","?5","?6","?7", "mem", "io", "pg", "wt", "au", "?13", "?14", "?15"];
CondRope: PROC[rope: ROPE, cond: BOOL] =
{IF cond THEN TerminalIO.WriteRope[rope] ELSE WriteSpace[rope.Length[]] };
WriteSpace: PROC[size: INT] = {THROUGH [0..size) DO TerminalIO.WriteChar[IO.SP] ENDLOOP};
Signal: SIGNAL = CODE;
ShowCluster2: PUBLIC PROC = {
tos: IO.STREAM ← TerminalIO.TOS[];
TerminalIO.WriteF["%L\n", IO.char['f]];
TerminalIO.WriteRope["TOP\n"];
ShowClusterStates[Cluster2.lastKs.stateTop];
TerminalIO.WriteRope["FULL\n"];
ShowClusterStates[Cluster2.lastKs.stateFull]};
ShowClusterStates: PROC[states: ARRAY [0..Cluster2.historySize) OF Cluster2.ClusterState] ={};
DisplayType: TYPE =
{eu, cjump,    fetch, xbus, pipe, stack, instr, test};
DisplayTypeRp: ARRAY DisplayType OF ROPE
["EU", "CJump", "Fetch", "Xbus", "Pipe", "Stack", "Instr", "Test"];
ShowAll: PUBLIC PROC = {
FOR type: DisplayType IN [eu..cjump]  DO ShowTop[type] ENDLOOP;
FOR type: DisplayType IN [fetch..test]  DO Show[type]  ENDLOOP};
ShowLast: PUBLIC PROC = {
FOR type: DisplayType IN [eu..cjump]  DO
ShowStates[top, last, type] ENDLOOP;
FOR type: DisplayType IN [fetch..test]  DO
ShowStates[top, last, type];
ShowStates[full, last, type] ENDLOOP};
ShowTop: PUBLIC PROC[type: DisplayType] = {
TerminalIO.WriteF["\n%g\n", IO.rope[DisplayTypeRp[type]]];
TerminalIO.WriteRope[" TOP\n"];
ShowStates[top, all, type]};
Show: PUBLIC PROC[type: DisplayType] = {
TerminalIO.WriteF["%g\n", IO.rope[DisplayTypeRp[type]]];
TerminalIO.WriteRope[" TOP\n"];
ShowStates[top, all, type];
TerminalIO.WriteRope[" FULL\n"];
ShowStates[full, all, type]};
ShowStates: PROC[which: {top, full}, range: {last, all}, type: DisplayType] = {
states: ARRAY [0..Cluster2.historySize) OF Cluster2.ClusterState ← IF which=top
THEN Cluster2.lastKs.stateTop
ELSE Cluster2.lastKs.stateFull;
end: INTIF range=last THEN 1 ELSE Cluster2.historySize-1;
tos: IO.STREAM ← TerminalIO.TOS[];
tf:  ROPEIF which=top THEN "T" ELSE "F";
FOR i: INT DECREASING IN [0..end) DO -- state0=state1
ia: IFU2.IFUState  ← NARROW[states[i+1 ].data[ifu]];
ib: IFU2.IFUState ← NARROW[states[i  ].data[ifu]];
ea: EU2.EU2State  ← NARROW[states[i+1 ].data[eu]];
eb: EU2.EU2State ← NARROW[states[i  ].data[eu]];
xbus: IFU2.RegAddrRec ← LOOPHOLE[ib.XBus];
IF states[i].refPh^=a     THEN LOOP;
IF states[i+1].refPh^#a    THEN LOOP;
IF states[i].refPh^#b     THEN LOOP;
IF states[i].refCy^#states[i+1].refCy^ THEN LOOP;
IF states[i].refCy^#ia.cycle   THEN Signal[];
tos.PutF["%3g ", IO.int[ia.cycle] ];
tos.PutF["%g%g %3g ",
IO.char[DisplayTypeRp[type].Fetch[]], IO.rope[tf], IO.int[states[i].refCy^] ];
SELECT type FROM
test => {
tos.PutF["A:%02x ",  IO.int[ ia.aPipe [1][a] ] ];
tos.PutF["%02x ",  IO.int[ ib.aPipe [1][b] ] ];
tos.PutF["B:%02x ",  IO.int[ ia.bPipe [1][a] ] ];
tos.PutF["%02x ",  IO.int[ ib.bPipe [1][b] ] ];
tos.PutF["C:%02x ",  IO.int[ ia.cPipe [1][a] ] ];
tos.PutF["%02x ",  IO.int[ ib.cPipe [1][b] ] ];
tos.PutF["%02x ",  IO.int[ ia.cPipe [2][a] ] ];
tos.PutF["%02x ",  IO.int[ ib.cPipe [2][b] ] ];
tos.PutF["%02x ",  IO.int[ ia.cPipe [3][a] ] ];
tos.PutF["%02x ",  IO.int[ ib.cPipe [3][b] ] ];
tos.PutF["%4g ",   IO.rope[ AluOpRp[  ib.ctlPipe1AB.aluOp ] ] ];
tos.PutF["%4g ",   IO.rope[ AluOpRp[  ib.ctlPipe1BA.aluOp ] ] ];
tos.PutF["%4g ",   IO.rope[ AluOpRp[  ib.ctlPipe2AB.aluOp ] ] ];
};
pipe => {
CondRope[ "Ld1A ",  ia.LoadStage1Ac   ];
CondRope[ "Ld1B ",   ib.LoadStage1Bc   ];
CondRope[ "Ld2A ",  ia.LoadStage2Ac   ];
CondRope[ "(bub) ",  ia.Stage2ABubbleBA];
CondRope[ "Abrt2B ",  ib.Stage2BAbortAB  ];
CondRope[ "Ld3A ",  ia.LoadStage3Ac   ];
CondRope[ "(abrt) ",  ia.Stage3AAbortBA  ];
};
stack => {
tos.PutF["%02x ",    IO.int[ ib.TosBA    ] ];
tos.PutF["%02x ",    IO.int[ ib.BosBA    ] ];
};
instr => {
CondRope[ "* ",        ia.ResetBA    ];
tos.PutF["%2x ",     IO.int[ ia.StateAB    ] ];
CondRope[ "Rdy ",       ia.InstReadyAB   ];
tos.PutF["%5g ", IO.rope[ OpCodeRp[  ia.OpAB     ] ] ];
tos.PutF["%2x ",     IO.int[ ia.AlphaAB    ] ];
tos.PutF["%2x ",     IO.int[ ia.BetaAB     ] ];
tos.PutF["%2x ",     IO.int[ ia.GammaAB    ] ];
tos.PutF["%2x ",     IO.int[ ia.DeltaAB     ] ];
tos.PutF["%g ", IO.rope[ NextMacroRp[ ib.NextMacroBA.ORD ] ] ];
CondRope[ "Rd0 ",       ib.DPCmndIsRd0BA  ];
CondRope[ "Rd2 ",       ib.DPCmndIsRd2BA  ];
CondRope[ "ILck ",       ib.Stage1BHoldBA  ];
tos.PutF["L:%02x ",    IO.int[ ib.LBA     ] ];
tos.PutF["S:%02x ",    IO.int[ ib.SBA     ] ];
};
fetch => {
CondRope[ "Ftch ",    ia.NewFetchBA   ];
tos.PutF["a:%08x ", IO.card[ ia.fetchAddrBA   ] ];
CondRope[ "Rjt ",    ib.IPRejectBA   ];
CondRope[ "Flt ",    ib.IPFaultingBA   ];
CondRope[ "FA ",    ia.FetchingAB   ]; -- Fix these
CondRope[ "FB ",    ib.FetchingBA   ]; -- Fix these
tos.PutF["%02x ", IO.card[ ib.FetchWtAB   ] ];
tos.PutF["%02x ", IO.card[ ib.FetchRdBA   ] ];
tos.PutF["%02x ", IO.card[ ib.FetchBytesM1AB  ] ];
tos.PutF["%x ", IO.card[  ib.wtAB     ] ];
tos.PutF["%x ", IO.card[  ib.rdAB     ] ];
CondRope[ "IRdy ",    ia.InstReadyAB   ];
tos.PutF["d:%08x ", IO.card[ ib.IPData   ] ];
};
xbus => {
tos.PutF["Xa:%08x ", IO.card[ ia.XBus ] ];
tos.PutF["Xb:%08x ", IO.card[ ib.XBus ] ];
tos.PutF["X:%02x ",  IO.int[ xbus.aAddr ] ];
tos.PutF["%02x ",  IO.int[ xbus.bAddr ] ];
tos.PutF["%02x ",  IO.int[ xbus.cAddr ] ];
tos.PutF["l:%g ",   IO.rope[ LtSrcRp[ xbus.aluLeftSrc ] ] ];
tos.PutF["r:%g ",  IO.rope[ RtSrcRp[ xbus.aluRightSrc ] ] ];
tos.PutF["s:%g ",  IO.rope[ StSrcRp[ xbus.storeSrc ] ] ];
CondRope[ "S3C",  xbus.st3AisC  ];
};
cjump => {
tos.PutF["CE2:%6g ", IO.rope[ CondEffectRp[ ia.CondEffect2AB ] ] ];
tos.PutF["CS2:%3g ", IO.rope[ CondSelectRp[ ia.ctlPipe2AB.condSel ] ] ];
CondRope[ "Cond ",         ia.EUCondition2BA  ];
};
eu => {
tos.PutF["%4g ",  IO.rope[ AluOpRp[  ib.ctlPipe2AB.aluOp ] ] ];
tos.PutF["2:%3g ", IO.rope[ CondSelectRp[ ib.ctlPipe2AB.condSel ] ] ];
CondRope[ "Cnd ",        ib.EUCondition2BA  ];
tos.PutF["3:%3g ", IO.rope[ CondSelectRp[ ib.ctlPipe3AB.condSel ] ] ];
CondRope[ "Rd",         ib.ctlPipe3AB.rdFromPBus  ];
CondRope[ "Wt",        ib.ctlPipe3AB.writeToPBus  ];
tos.PutF["%08x ", IO.card[ ea.simRegs[EU2Utils.left]]];
tos.PutF["%08x ", IO.card[ ea.simRegs[EU2Utils.right]]];
tos.PutF["%08x ", IO.card[ eb.simRegs[EU2Utils.r2B]]];
CondRope[ "CAB ",     ea.carryAB  ];
CondRope[ "CBA ",     eb.carryBA  ];
CondRope[ "Rjt ",     ib.DPRejectBA ];
tos.PutF["%3g ",  IO.rope[ DPFaultRp[ ib.DPFaultBA.ORD ] ] ];
};
ENDCASE => ERROR;
TerminalIO.WriteLn[] ENDLOOP};
Strip: PROC[path: ROPENIL] RETURNS[ROPE] = {
start: INT;
WHILE (start←path.Find["("]) # -1 DO
path ← Rope.Cat[path.Substr[0,start], path.Substr[path.Index[0, ")"]]] ENDLOOP;
RETURN[path]};
Cell: PROC[a,b: ROPENIL] RETURNS[cell: Core.CellType] = {
RETURN[IF a.Length[]=0
THEN Cluster2.lastKs.ifuSimulation.cellType
ELSE CoreFlat.ResolveFlatCellType
[Cluster2.lastKs.ifuSimulation.cellType, FlatCellRec[a,b]].cellType]};
State: PROC[a,b: ROPENIL] RETURNS[ref: REF] = {
ref ← Rosemary.GetState
[Cluster2.lastKs.ifuSimulation, NEW[CoreFlat.FlatCellTypeRec ← FlatCellRec[a,b]]]};
FlatCellRec: PROC[a,b: ROPENIL] RETURNS[flatCell: CoreFlat.FlatCellTypeRec] = {
flatCell ←
CoreFlat.ParseCellTypePath[Cluster2.lastKs.ifuSimulation.cellType, Rope.Cat[a,b]]};
PrintWire: PROC[wire: Core.Wire] = {
FinishOld: PROC = {nxtOld.idx ← 0; TerminalIO.WriteF["..%g)\n", IO.int[nxtIdx]]};
delayd: BOOLFALSE;
nxtOld: CoreName.SigRec;
nxtIdx: INT ← 0;
FOR i: INT IN [0..wire.size) DO
name: ROPE ← CoreName.WireNm[wire[i]].n;
IF delayd THEN {
test: CoreName.SigRec ← CoreName.NameSig[name];
nxtOld.idx ← test.idx;
IF nxtOld=test THEN {
IF nxtIdx#test.idx
THEN TerminalIO.WriteF["..%g) [%g", IO.int[nxtIdx], IO.int[test.idx]];
nxtIdx ← test.idx+1; LOOP};
FinishOld[]};
TerminalIO.WriteF[" %g", IO.rope[name]];
nxtOld ← CoreName.NameSig[name];
IF nxtOld.idx#-1
THEN {delayd ← TRUE; nxtIdx←nxtOld.idx+1}
ELSE {delayd ← FALSE; TerminalIO.WriteF["\n"]};
ENDLOOP;
IF delayd THEN FinishOld[]};
InitStates: PUBLIC PROC[sim: Rosemary.Simulation, size: CARDINAL]
RETURNS[states: IFUTest.StateSeq] = {
states ← NEW[IFUTest.StateSeqRec[size]];
FOR i: NAT IN [0..states.size) DO
states[i] ← NEW[IFU2.IFUStateRec];
ENDLOOP};
UpdateStates: PUBLIC PROC[
sim: Rosemary.Simulation,
states: IFUTest.StateSeq,
pass: INT,
qph: IFU2.QPh ] = {
temp: IFU2.IFUState ← states[states.size-1];
FOR i: NAT DECREASING IN [1..states.size) DO states[i] ← states[i-1] ENDLOOP;
states[0] ← temp;
UpdateState[sim, states[0], pass, qph]};
heart, lcc, left, dcm, right, rcc: ROPE;
fetchIndex, fetchControl, ltDrPadIO, stackControl, mainPipeBdy, mainPipeInDr, mainPipeOutDr, interlock, interlockBdy, stackIndex: ROPE;
fetch, fetchBuf, xaForm, pcTop, pcBot, stackBuf, lsForm, abForm, cpipe: ROPE;
instrDecode, rtDrPadIO, idInDr, idOutDr: ROPE;
idBdy0, idBdy1, idBdy2, idBdy3, idBdy4, idBdy5, idBdy6: ROPE;
cachedXFers: LIST OF RTVal ← NIL;
GetXFers: PROC RETURNS[xfers: LIST OF RTVal] = {
IF cachedXFers#NIL THEN RETURN[cachedXFers];
heart ← IF Cluster2.quickIFU THEN "/0" ELSE      "/0/2/1/1/1";
lcc ← IF Cluster2.quickIFU THEN "/9" ELSE Rope.Cat[heart, "/0/1"];
left ← IF Cluster2.quickIFU THEN ""  ELSE Rope.Cat[heart, "/1"];
dcm ← IF Cluster2.quickIFU THEN ""  ELSE Rope.Cat[heart, "/2/1/1"];
right ← IF Cluster2.quickIFU THEN ""  ELSE Rope.Cat[heart, "/3"];
rcc ← IF Cluster2.quickIFU THEN "/10" ELSE Rope.Cat[heart, "/4/1"];
fetchIndex  ← Rope.Cat[lcc, "/8"];
fetchControl  ← Rope.Cat[lcc, "/6"];
ltDrPadIO   ← Rope.Cat[lcc, "/5"];
stackControl  ← Rope.Cat[lcc, "/4"];
mainPipeBdy  ← Rope.Cat[lcc, "/3/1/1/0"];
mainPipeInDr ← Rope.Cat[lcc, "/3/1/0/1"];
mainPipeOutDr ← Rope.Cat[lcc, "/3/1/1/1"];
interlock   ← Rope.Cat[lcc, "/2"];
interlockBdy  ← Rope.Cat[lcc, "/2/1/1/0"];
stackIndex  ← Rope.Cat[lcc, "/0"];
fetch    ← Rope.Cat[dcm, "/8"];
fetchBuf   ← Rope.Cat[dcm, "/7"];
xaForm   ← Rope.Cat[dcm, "/6"];
pcTop    ← Rope.Cat[dcm, "/5"];
pcBot    ← Rope.Cat[dcm, "/4"];
stackBuf   ← Rope.Cat[dcm, "/3"];
lsForm   ← Rope.Cat[dcm, "/2"];
abForm   ← Rope.Cat[dcm, "/1"];
cpipe    ← Rope.Cat[dcm, "/0"];
instrDecode  ← Rope.Cat[rcc,    "/2"];
rtDrPadIO  ← Rope.Cat[rcc,    "/1"];
idInDr   ← Rope.Cat[instrDecode, "/1/1/1"];
idOutDr   ← Rope.Cat[instrDecode, "/1/0"];
idBdy0   ← Rope.Cat[idOutDr,  "/0/0"];
idBdy1   ← Rope.Cat[idOutDr,  "/1/0"];
idBdy2   ← Rope.Cat[idOutDr,  "/2/0"];
idBdy3   ← Rope.Cat[idOutDr,  "/3/0"];
idBdy4   ← Rope.Cat[idOutDr,  "/4/0"];
idBdy5   ← Rope.Cat[idOutDr,  "/5/0"];
idBdy6   ← Rope.Cat[idOutDr,  "/6/0"];
cachedXFers ← xfers ← LIST[ 
RoseTV.New[right,  "StateAB",     StateAB,     FALSE, FBN],
RoseTV.New[right,  "InstReadyAB",    InstReadyAB,   FALSE, FBN],
RoseTV.New[right,  "OpAB",      OpAB,     FALSE, FBN],
RoseTV.New[xaForm, "AlphaAB",     AlphaAB,    FALSE, FBN],
RoseTV.New[xaForm, "BetaAB",     BetaAB,     FALSE, FBN],
RoseTV.New[xaForm, "GammaAB",     GammaAB,    FALSE, FBN],
RoseTV.New[xaForm, "DeltaAB",     DeltaAB,     FALSE, FBN],
RoseTV.New[heart,  "TosBA",      TosBA,     FALSE, FBN],
RoseTV.New[heart,  "BosBA",      BosBA,     FALSE, FBN],
RoseTV.New[lsForm, "LBA",      LBA,      FALSE, FBN],
RoseTV.New[lsForm, "SBA",      SBA,      FALSE, FBN],
RoseTV.New[right,  "NextMacroBA",    NextMacroBA,   FALSE, FBN],
RoseTV.New[right,  "DPCmndIsRd0BA",   DPCmndIsRd0BA,  FALSE, FBN],
RoseTV.New[left,  "DPCmndIsRd2BA",   DPCmndIsRd2BA,  FALSE, FBN],
RoseTV.New[left,  "Stage1BHoldBA",   Stage1BHoldBA,   FALSE, FBN],
RoseTV.New[left,  "LoadStage1Ac",    LoadStage1Ac,   FALSE, FBN],
RoseTV.New[left,  "LoadStage1Bc",    LoadStage1Bc,   FALSE, FBN],
RoseTV.New[left,  "LoadStage2Ac",    LoadStage2Ac,   FALSE, FBN],
RoseTV.New[left,  "Stage2BAbortAB",   Stage2BAbortAB,  FALSE, FBN],
RoseTV.New[left,  "LoadStage3Ac",    LoadStage3Ac,   FALSE, FBN],
RoseTV.New[left,  "Stage3AAbortBA",   Stage3AAbortBA,  FALSE, FBN],
RoseTV.New[left,  "CondEffect2BA",   CondEffect2BA,   FALSE, FBN],
RoseTV.New[left,  "NewFetchBA",    NewFetchBA,   FALSE, FBN],
RoseTV.New[fetch,  "FetchAddrBA",    FetchAddrBA,   FALSE, FBN],
RoseTV.New[heart,  "IPData",      IPData,     FALSE, FBN],
RoseTV.New[left,  "FetchWtAB",    FetchWtAB,    FALSE, FBN],
RoseTV.New[left,  "FetchRdBA",    FetchRdBA,    FALSE, FBN],
RoseTV.New[left,  "FetchBytesM1AB",   FetchBytesM1AB,  FALSE, FBN],
RoseTV.New[dcm,  "XBus",      XBus,      FALSE, FBN],
RoseTV.New[right,  "DPFaultBA",    DPFaultBA,    FALSE, FBN],
RoseTV.New[right,  "DPRejectBA",    DPRejectBA,    FALSE, FBN],
RoseTV.New[left,  "IPRejectBA",    IPRejectBA,    FALSE, FBN],
RoseTV.New[left,  "IPFaultingBA",    IPFaultingBA,   FALSE, FBN],
RoseTV.New[left,  "FetchingBA",    FetchingBA,    FALSE, FBN],
RoseTV.New[cpipe,  "EUAluOp1AB",    AluOp1AB,    FALSE, FBN],
RoseTV.New[cpipe,  "EUAluOp1BA",    AluOp1BA,    FALSE, FBN],
RoseTV.New[cpipe,  "EUAluOp2AB",    AluOp2AB,    FALSE, FBN],
RoseTV.New[abForm, "A1AB",      A1AB,     FALSE, FBN],
RoseTV.New[abForm, "A1BA",      A1BA,     FALSE, FBN],
RoseTV.New[abForm, "B1AB",      B1AB,     FALSE, FBN],
RoseTV.New[abForm, "B1BA",      B1BA,     FALSE, FBN],
RoseTV.New[lsForm, "C1AB",      C1AB,     FALSE, FBN],
RoseTV.New[lsForm, "C1BA",      C1BA,     FALSE, FBN],
RoseTV.New[lsForm, "C2AB",      C2AB,     FALSE, FBN],
RoseTV.New[lsForm, "C2BA",      C2BA,     FALSE, FBN],
RoseTV.New[lsForm, "C3AB",      C3AB,     FALSE, FBN],
RoseTV.New[lsForm, "C3BA",      C3BA,     FALSE, FBN],
RoseTV.New[left,  "ResetBA",     ResetBA,     FALSE, FBN]]};
IFU2.IFUState
UpdateState: PUBLIC UpdateProc = {
RoseTV.XFerList[sim, GetXFers[]];
state.cycle    ← pass;
state.ph     ← qph;
state.StateAB    ← StateAB^;
state.InstReadyAB  ← InstReadyAB^;
state.OpAB    ← OpAB^;
state.AlphaAB   ← AlphaAB^;
state.BetaAB    ← BetaAB^;
state.GammaAB   ← GammaAB^;
state.DeltaAB    ← DeltaAB^;
state.TosBA    ← TosBA^;
state.BosBA    ← BosBA^;
state.LBA     ← LBA^;
state.SBA     ← SBA^;
state.NextMacroBA  ← NextMacroBA^;
state.DPCmndIsRd0BA ← DPCmndIsRd0BA^;
state.DPCmndIsRd2BA ← DPCmndIsRd2BA^;
state.Stage1BHoldBA  ← Stage1BHoldBA^;
state.LoadStage1Ac  ← LoadStage1Ac^;
state.LoadStage1Bc  ← LoadStage1Bc^;
state.LoadStage2Ac  ← LoadStage2Ac^;
state.Stage2BAbortAB ← Stage2BAbortAB^;
state.LoadStage3Ac  ← LoadStage3Ac^;
state.Stage3AAbortBA ← Stage3AAbortBA^;
state.CondEffect2BA  ← CondEffect2BA^;
state.NewFetchBA  ← NewFetchBA^;
state.fetchAddrBA  ← FetchAddrBA^;
state.IPData    ← IPData^;
state.FetchWtAB   ← FetchWtAB^;
state.FetchRdBA   ← FetchRdBA^;
state.FetchBytesM1AB ← FetchBytesM1AB^;
state.XBus    ← XBus^;
state.DPFaultBA   ← DPFaultBA^;
state.DPRejectBA  ← DPRejectBA^;
state.IPRejectBA   ← IPRejectBA^;
state.IPFaultingBA  ← IPFaultingBA^;
state.FetchingBA  ← FetchingBA^;
state.ctlPipe1AB.aluOp ← AluOp1AB^;
state.ctlPipe1BA.aluOp ← AluOp1BA^;
state.ctlPipe2AB.aluOp ← AluOp2AB^;
state.aPipe[1][a]   ← A1AB^;
state.aPipe[1][b]   ← A1BA^;
state.bPipe[1][a]   ← B1AB^;
state.bPipe[1][b]   ← B1BA^;
state.cPipe[1][a]   ← C1AB^;
state.cPipe[1][b]   ← C1BA^;
state.cPipe[2][a]   ← C2AB^;
state.cPipe[2][b]   ← C2BA^;
state.cPipe[3][a]   ← C3AB^;
state.cPipe[3][b]   ← C3BA^;
state.ResetBA    ← ResetBA^;
IF state.ph = B THEN ShowLast[]};
StateAB:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
InstReadyAB:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
OpAB:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
AlphaAB:    REF Dragon.HexByte ← NEW[Dragon.HexByte];
BetaAB:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
GammaAB:    REF Dragon.HexByte ← NEW[Dragon.HexByte];
DeltaAB:    REF Dragon.HexByte ← NEW[Dragon.HexByte];
TosBA:     REF [0..32)    ← NEW[[0..32)];
BosBA:     REF [0..32)    ← NEW[[0..32)];
LBA:      REF Dragon.HexByte ← NEW[Dragon.HexByte];
SBA:      REF Dragon.HexByte ← NEW[Dragon.HexByte];
NextMacroBA:   REF NextMacro   ← NEW[NextMacro];
DPCmndIsRd0BA:  REF RoseTV.Bool  ← NEW[RoseTV.Bool];
DPCmndIsRd2BA:  REF RoseTV.Bool  ← NEW[RoseTV.Bool];
Stage1BHoldBA:  REF RoseTV.Bool  ← NEW[RoseTV.Bool];
LoadStage1Ac:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
LoadStage1Bc:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
LoadStage2Ac:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
Stage2BAbortAB:  REF RoseTV.Bool  ← NEW[RoseTV.Bool];
LoadStage3Ac:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
Stage3AAbortBA:  REF RoseTV.Bool  ← NEW[RoseTV.Bool];
CondEffect2BA:  REF CondEffect   ← NEW[CondEffect];
NewFetchBA:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
FetchAddrBA:   REF RoseTV.LongCard ← NEW[RoseTV.LongCard];
IPData:     REF RoseTV.LongCard ← NEW[RoseTV.LongCard];
FetchWtAB:   REF [0..4)     ← NEW[[0..4)];
FetchRdBA:   REF [0..16)    ← NEW[[0..16)];
FetchBytesM1AB: REF [0..32)    ← NEW[[0..32)];
XBus:     REF RoseTV.LongCard ← NEW[RoseTV.LongCard];
DPFaultBA:   REF PBusFaults   ← NEW[PBusFaults];
DPRejectBA:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
IPRejectBA:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
IPFaultingBA:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
FetchingBA:   REF RoseTV.Bool  ← NEW[RoseTV.Bool];
AluOp1AB:    REF ALUOps    ← NEW[ALUOps];
AluOp1BA:    REF ALUOps    ← NEW[ALUOps];
AluOp2AB:    REF ALUOps    ← NEW[ALUOps];
A1AB:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
A1BA:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
B1AB:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
B1BA:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
C1AB:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
C1BA:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
C2AB:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
C2BA:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
C3AB:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
C3BA:     REF Dragon.HexByte ← NEW[Dragon.HexByte];
ResetBA:    REF RoseTV.Bool  ← NEW[RoseTV.Bool];
FBN, FieldBitName: RoseTV.FldBitNmProc = { -- only called for multibit unstructured fields
PROC[rtv: RTVal, index: INT] RETURNS[fieldBitNm: ROPE]
SELECT rtv.wwrSize FROM
1    => RETURN[rtv.field];
32    => RETURN[IO.PutFR["%g.%02b", IO.rope[rtv.field], IO.int[index]] ];
ENDCASE  => {
bf:   REFBit.Format ← REFBit.Desc[rtv.ref].bitForm;
sigRec: CoreName.SigRec ← CoreName.NameSig[rtv.field];
name:  ROPE ← bf[index].name;
IF name.Length[]=0
THEN {name ← bf[index].nameInv; rtv[index].inverted ← NOT rtv[index].inverted};
name   ← CoreName.BitRopeToSigRope[name];
sigRec.root ← sigRec.root.Cat[CoreName.RootExt[name].root];
IF CoreName.RootExt[name].ext.Length[]#0 THEN {
int: INT ← Convert.IntFromRope[CoreName.RootExt[name].ext.Substr[1]];
IF int#index THEN Signal[];
sigRec.idx ← int};
RETURN[CoreName.SigName[sigRec]]} };
CapChar: PROC[sm: CHAR] RETURNS[big: CHAR] =
{RETURN[IF sm IN ['a..'z] THEN sm + LOOPHOLE['A - 'a] ELSE sm]};
CapNth: PROC[rope: ROPE, n: INT] RETURNS[ROPE] =
{RETURN[IO.PutFR["%g%g%g",
IO.rope[rope.Substr[0, n]],
IO.char[CapChar[rope.Fetch[n]]],
IO.rope[rope.Substr[n+1]]] ]};
ifuUpdateProc: PUBLIC ATOM ← $IFUUpdateProc;
Atom.PutProp[ifuUpdateProc, ifuUpdateProc, NEW[UpdateProc ← UpdateState]];
TerminalIO.WriteF["%L\n%g\n", IO.char['f], IO.time[]];
END.