MakeCluster:
PUBLIC
PROC
RETURNS [ks: KitchenSink] = {
ifuRoseInst, euRoseInst, iCacheRoseInst, eCacheRoseInst: CoreClasses.CellInstance ← NIL;
tempInstances: CoreClasses.CellInstances ← NIL;
public: Core.Wire = CoreOps.CreateWire[
LIST[
IFUPublic.PortWire[TRUE, "ResetAB", 1, force],
IFUPublic.PortWire[TRUE, "RescheduleAB", 1, force],
IFUPublic.PortWire[TRUE, "Clk", 1, force],
IFUPublic.PortWire[TRUE, "PhAOut", 1],
IFUPublic.PortWire[TRUE, "PhBOut", 1],
IFUPublic.PortWire[TRUE, "PhA", 1, force],
IFUPublic.PortWire[TRUE, "PhB", 1, force],
IFUPublic.PortWire[TRUE, "NotPhA", 1, force], -- IFU no longer uses. Does EU?
IFUPublic.PortWire[TRUE, "NotPhB", 1, force], -- IFU no longer uses. Does EU?
IFUPublic.PortWire[TRUE, "Vdd", 1, infinite, H],
IFUPublic.PortWire[TRUE, "Gnd", 1, infinite, L],
IFUPublic.PortWire[TRUE, "PadVdd", 1, infinite, H],
IFUPublic.PortWire[TRUE, "PadGnd", 1, infinite, L],
IFUPublic.PortWire[TRUE, "IFUDShA", 1, force],
IFUPublic.PortWire[TRUE, "IFUDShB", 1, force],
IFUPublic.PortWire[TRUE, "IFUDShRd", 1, force],
IFUPublic.PortWire[TRUE, "IFUDShWt", 1, force],
IFUPublic.PortWire[TRUE, "IFUDShIn", 1, force],
IFUPublic.PortWire[TRUE, "IFUDShOut", 1],
IFUPublic.PortWire[TRUE, "EUDShA", 1, force],
IFUPublic.PortWire[TRUE, "EUDShB", 1, force],
IFUPublic.PortWire[TRUE, "EUDShRd", 1, force],
IFUPublic.PortWire[TRUE, "EUDShWt", 1, force],
IFUPublic.PortWire[TRUE, "EUDShIn", 1, force],
IFUPublic.PortWire[TRUE, "EUDShOut", 1],
IFUPublic.PortWire[TRUE, "DStAd", 4, force],
IFUPublic.PortWire[TRUE, "DHold", 1, force] ] ];
iOnly: Core.Wire = CoreCreate.WireList[
LIST[
"UserMode2BA",
"IPCmdFetchA",
"IPFaultingB",
CoreCreate.Seq[ "IPFaultingXB", 3],
CoreCreate.Seq[ "IPData", 32],
CoreCreate.Seq[ "DPCmdA", 8],
CoreCreate.Seq[ "DPFaultB", 4],
CoreCreate.Seq[ "DPData", 32],
CoreCreate.Seq[ "EUAluOp2AB", 4],
CoreCreate.Seq[ "EUCondSel2AB", 4],
CoreCreate.Seq[ "KBus", 32],
"EURdFromPBus3AB",
"EUWriteToPBus3AB",
"EUCondition2B",
"DPRejectB",
"IPRejectB",
"VbbGen" ] ];
ks ← lastKs ←
NEW[Cluster.KitchenSinkRec ← [
log: ViewerIO.CreateViewerStreams[
name: "Rosemary Cluster Simulation",
backingFile: "Cluster.log" ].out,
vm: CacheOps.NewVirtualMemory[] ]];
TypeScript.ChangeLooks[ViewerIO.GetViewerFromStream[ks.log], 'f];
ks.iCache ← CacheOps.NewCache[mem: ks.vm, nLines: nCacheLines];
ks.eCache ← CacheOps.NewCache[mem: ks.vm, nLines: nCacheLines];
ks.coreInsts[iCache] ← CoreCreate.InstanceList[
type: CoreFlat.
CellTypeCutLabels[
on: Cache.Create[vm: ks.iCache, skipRejects: skipIFURejects],
l1: "TopLevel"],
pas:
LIST[
["PUserMode", "Gnd"],
["PData", "IPData"],
["PCmdA[7]", "Gnd"],
["PCmdA[6]", "Gnd"],
["PCmdA[5]", "Gnd"],
["PCmdA[4]", "IPCmdFetchA"],
["PCmdA[3]", "IPCmdFetchA"],
["PCmdA[2]", "IPCmdFetchA"],
["PCmdA[1]", "IPCmdFetchA"],
["PCmdA[0]", "IPCmdFetchA"],
["PRejectB", "IPRejectB"],
["PFaultB[0]", "IPFaultingB"],
["PFaultB[1]", "IPFaultingXB[0]"],
["PFaultB[2]", "IPFaultingXB[1]"],
["PFaultB[3]", "IPFaultingXB[2]"] ] ];
ks.coreInsts[eCache] ← CoreCreate.InstanceList[
type: CoreFlat.
CellTypeCutLabels[
on: Cache.Create[vm: ks.eCache, skipRejects: skipEURejects],
l1: "TopLevel"],
pas:
LIST[
["PUserMode", "UserMode2BA"],
["PData", "DPData"],
["PCmdA", "DPCmdA"],
["PRejectB", "DPRejectB"],
["PFaultB", "DPFaultB"] ] ];
ks.coreInsts[ifu] ← CoreCreate.InstanceList[
type: CoreFlat.
CellTypeCutLabels[
on: IFUTop.CreateIFU[
NEW[IFUTop.IFUTypeData ←
[data: ks, getLog: GetLog, checkSynch: CheckSynch, getCycle: GetCycle ]],
fullIFU, quickIFU, rawIFU],
l1: "TopLevel" ],
pas:
LIST[
["KBus", "KBus"],
["EUAluOp", "EUAluOp2AB"],
["EUCondSel", "EUCondSel2AB"],
["EUCondition", "EUCondition2B"],
["EURdFromPBus", "EURdFromPBus3AB"],
["EUWriteToPBus", "EUWriteToPBus3AB"],
["UserMode", "UserMode2BA"],
["DPCmd", "DPCmdA"],
["DPReject", "DPRejectB"],
["DPFault", "DPFaultB"],
["IPCmdFetch", "IPCmdFetchA"],
["IPReject", "IPRejectB"],
["IPFaulting", "IPFaultingB"],
["IPData", "IPData"],
["Reset", "ResetAB"],
["Reschedule", "RescheduleAB"],
["DShA", "IFUDShA"],
["DShB", "IFUDShB"],
["DShRd", "IFUDShRd"],
["DShWt", "IFUDShWt"],
["DShIn", "IFUDShIn"],
["DShOut", "IFUDShOut"],
["Vbb", "Vdd"],
["VbbGen", "VbbGen"],
["Clk", "Clk"],
["PhAOut", "PhAOut"],
["PhBOut", "PhBOut"],
["PhA", "PhA"],
["PhB", "PhB"],
["Vdd", "Vdd"],
["Gnd", "Gnd"],
["PadVdd", "PadVdd"],
["PadGnd", "PadGnd"]
] ];
ks.coreInsts[eu] ← CoreCreate.InstanceList[
type: CoreFlat.CellTypeCutLabels[
on: EU.CreateEU[
typeData: NEW[EU.EUTypeData←[data: ks, storeNoted: FALSE, noteStore: NoteRegStore]],
fullEU: fullEU,
useCkPt: fullEU],
l1: "TopLevel" ],
pas:
LIST[
["DShA", "EUDShA"],
["DShB", "EUDShB"],
["DShRd", "EUDShRd"],
["DShWt", "EUDShWt"],
["DShIn", "EUDShIn"],
["DShOut", "EUDShOut"] ] ];
FOR inst: Instances
DECREASING
IN Instances
DO
tempInstances ← CONS[ks.coreInsts[inst], tempInstances] ENDLOOP;
IFUTop.MarkMemoryWires[iOnly[CoreOps.GetWireIndex[iOnly, "DPFaultB"]]];
IFUTop.MarkMemoryWires[iOnly[CoreOps.GetWireIndex[iOnly, "IPFaultingB"]]];
IFUTop.MarkMemoryWires[iOnly[CoreOps.GetWireIndex[iOnly, "IPFaultingXB"]]];
IFUTop.MarkMemoryWires[iOnly[CoreOps.GetWireIndex[iOnly, "DPRejectB"]]];
IFUTop.MarkMemoryWires[iOnly[CoreOps.GetWireIndex[iOnly, "IPRejectB"]]];
IFUTop.MarkMemoryWires[iOnly[CoreOps.GetWireIndex[iOnly, "IPData"]]];
IFUTop.MarkMemoryWires[iOnly[CoreOps.GetWireIndex[iOnly, "KBus"]]];
IF fullIFU THEN {
data: CoreClasses.RecordCellType ← NARROW[ks.coreInsts[ifu].type.data];
xbus: Core.Wire ← data.internal[CoreOps.GetWireIndex[data.internal, "XBus"]];
TerminalIO.PutRope["Marking XBus with Memory TRUE\n"];
IFUTop.MarkMemoryWires[xbus]};
ks.cluster ← CoreCreate.Cell[
public: public,
onlyInternal: iOnly,
instances: tempInstances,
name: "Cluster" ];
ks.clusterIOPort ← Ports.CreatePort[ks.cluster];
ks.rosemarySimulation ← Rosemary.Instantiate[
cellType: ks.cluster,
testPort: ks.clusterIOPort,
cutSet: CoreFlat.CreateCutSet[labels: LIST["TopLevel"] ] ];
FOR inst: Instances
IN Instances
DO
ks.flatCT[inst] ← NEW[CoreFlat.FlatCellTypeRec ← CoreFlat.ParseCellTypePath[ks.cluster, IO.PutFR["/%g", IO.int[Instances[inst].ORD]]]];
ks.stateTop[0].refCy ← NEW[INT ← 0];
ks.stateTop[0].refPh ← NEW[Dragon.Phase ← a];
ks.stateTop[0].data[inst] ← Rosemary.GetState[ks.rosemarySimulation, ks.flatCT[inst]];
ENDLOOP;
FOR i:
NAT
IN [1..Cluster.historySize)
DO
ks.stateTop[i].refCy ← NEW[INT ← 0];
ks.stateTop[i].refPh ← NEW[Dragon.Phase ← a];
ks.stateTop[i].data ← [
ifu: NEW[IFUTop.IFUStateRec],
eu: NEW[EU.EUStateRec],
iCache: NEW[Cache.CacheState],
eCache: NEW[Cache.CacheState]];
ENDLOOP;
FOR i:
NAT
IN [0..Cluster.historySize)
DO
ks.stateFull[i].refCy ← NEW[INT ← 0];
ks.stateFull[i].refPh ← NEW[Dragon.Phase ← a];
ks.stateFull[i].data ← [
ifu: NEW[IFUTop.IFUStateRec],
eu: NEW[EU.EUStateRec],
iCache: NEW[Cache.CacheState],
eCache: NEW[Cache.CacheState]];
ENDLOOP;
ks.euReject ← NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[ks.cluster, "DPRejectB"]];
ks.ifuSimulationTruthPort ← Ports.CreatePort[ks.coreInsts[ifu].type, TRUE];
IF fullIFU
THEN {
ifuCellType: Core.CellType ← ks.coreInsts[ifu].type;
TerminalIO.PutF["Make IFU Simulation %g\n", IO.time[]];
ks.ifuSimulationTestPort ← Ports.CreatePort[ifuCellType, TRUE];
ks.ifuSimulation ← Rosemary.Instantiate[
ifuCellType,
ks.ifuSimulationTestPort,
CoreFlat.CreateCutSet[labels: fullIFUCuts]];
ks.ifuDisplay ← RosemaryUser.DisplayViewer[ks.ifuSimulation, ifuCellType, "IFUTop", RosemaryUser.DisplayPortLeafWires[ifuCellType]];
Rosemary.Initialize[ks.ifuSimulation, FALSE];
RosemaryUser.InitializeDeltas[ks.ifuDisplay];
TerminalIO.PutF["IFU Instantiated %g\n", IO.time[]]};
ks.euSimulationTruthPort ← Ports.CreatePort[ks.coreInsts[eu].type, TRUE];
IF fullEU
THEN {
euCellType: Core.CellType ← ks.coreInsts[eu].type;
TerminalIO.PutF["Make EU Simulation %g\n", IO.time[]];
ks.euSimulationTestPort ← Ports.CreatePort[euCellType, TRUE];
ks.euSimulation ← Rosemary.Instantiate[
euCellType,
ks.euSimulationTestPort,
CoreFlat.CreateCutSet[labels: LIST["Logic"]]];
ks.euDisplay ← RosemaryUser.DisplayViewer[ks.euSimulation, euCellType, "EU", RosemaryUser.DisplayPortLeafWires[euCellType]];
Rosemary.Initialize[ks.euSimulation, FALSE];
RosemaryUser.InitializeDeltas[ks.euDisplay];
TerminalIO.PutF["EU Instantiated %g\n", IO.time[]]};
StartIFUScanPanel[ks];
StartPanel[ks]};
DoCluster:
PUBLIC
PROC [ks: KitchenSink, diagnostic: Core.
ROPE ←
NIL] = {
originalPriority: Process.Priority = Process.GetPriority[];
diagnosticName: Core.ROPE ← "unknown";
IF ks=NIL THEN ks ← MakeCluster[];
{
ENABLE
UNWIND => {
ks.log.PutF["\nSimulation of %g aborted\n\n", IO.rope[diagnosticName]];
ks.log.Flush[];
Process.SetPriority[ originalPriority ] };
time: INT ← -1;
DoEval:
PROC = {
inhibitExpects: BOOL ← ks.controlPanel.reset OR ks.protCyclesAfterReject>0;
time ← time+1;
ks.controlPanel.continueTestFromAbort ← FALSE;
IF GetPublicBool[ks, $PhA]
THEN {
SetPublicBool[ks, $RescheduleAB, ks.controlPanel.resched];
SetPublicBool[ks, $ResetAB, ks.controlPanel.reset] };
Rosemary.Settle[ ks.rosemarySimulation
! ABORTED => IF ks.controlPanel.continueTestFromAbort THEN CONTINUE ELSE REJECT];
CopyClusterArrayContents[ks.stateTop[0], ks.stateFull[0]];
Rosemary.SettleToTest[simulation: ks.rosemarySimulation, flatCell: ks.flatCT[ifu], test: ks.ifuSimulationTruthPort];
IF fullIFU
THEN {
Ports.CopyPortValue[from: ks.ifuSimulationTruthPort, to: ks.ifuSimulationTestPort];
IF ks.controlPanel.recordPlotData
THEN LogSettle[ks.ifuDisplay, time, ks.controlPanel.chrgdMemNodesOk
! Rosemary.Stop =>
IF reason # $BoolWireHasX
THEN
REJECT
ELSE
IF ks.controlPanel.reset
OR ks.protCyclesAfterReject>0
THEN
RESUME
ELSE {
TerminalIO.PutF["%g = X\n",
IO.rope[
CoreOps.GetShortWireName[NARROW[data, CoreFlat.FlatWire].wire]]];
RosemaryUser.UpdateDisplay[ks.ifuDisplay];
RESUME}]
ELSE Rosemary.Settle[ks.ifuSimulation,
NIL, ks.controlPanel.chrgdMemNodesOk
! Rosemary.Stop =>
IF reason # $BoolWireHasX
THEN
REJECT
ELSE
IF ks.controlPanel.reset
OR ks.protCyclesAfterReject>0
THEN
RESUME
ELSE {
TerminalIO.PutF["%g = X\n",
IO.rope[
CoreOps.GetShortWireName[NARROW[data, CoreFlat.FlatWire].wire]]];
RosemaryUser.UpdateDisplay[ks.ifuDisplay];
RESUME}];
IF ks.controlPanel.sampleFullIFU
AND GetPublicBool[ks, $PhA]
THEN UpdateIFUState
[ks.ifuSimulation, NARROW[ks.stateFull[0].data[ifu]], ks.controlPanel.cycle, A];
IF ks.controlPanel.sampleFullIFU
AND GetPublicBool[ks, $PhB]
THEN UpdateIFUState
[ks.ifuSimulation, NARROW[ks.stateFull[0].data[ifu]], ks.controlPanel.cycle, B];
RosemaryUser.UpdateDisplay[ks.ifuDisplay];
Ports.CheckPortValue[root: ks.coreInsts[ifu].type.public, truth: ks.ifuSimulationTruthPort, question: ks.ifuSimulationTestPort ! Ports.CheckError =>
IF
NOT (ks.controlPanel.proceedFromCheckPort
OR ks.protCyclesAfterReject>0)
THEN REJECT
ELSE {TerminalIO.PutF["%g\n", IO.rope[msg]]; RESUME}] };
Rosemary.SettleToTest[simulation: ks.rosemarySimulation, flatCell: ks.flatCT[eu], test: ks.euSimulationTruthPort];
IF fullEU
THEN {
Ports.CopyPortValue[from: ks.euSimulationTruthPort, to: ks.euSimulationTestPort];
RosemaryUser.LogSettle[ks.euDisplay, time
! Rosemary.Stop =>
IF ks.protCyclesAfterReject>0
AND reason = $BoolWireHasX
THEN RESUME ELSE {RosemaryUser.UpdateDisplay[ks.euDisplay]; REJECT}];
RosemaryUser.UpdateDisplay[ks.euDisplay];
Ports.CheckPortValue[root: ks.coreInsts[eu].type.public, truth: ks.euSimulationTruthPort, question: ks.euSimulationTestPort ! Ports.CheckError =>
IF
NOT ks.controlPanel.proceedFromCheckPort
THEN REJECT
ELSE {TerminalIO.PutF["%g\n", IO.rope[msg]]; RESUME}]};
IF ks.controlPanel.reset THEN ks.controlPanel.instrCount ← -1;
IF ks.ifuVectors#NIL THEN RosemaryVector.WriteVector[ks.ifuVectors, inhibitExpects];
IF ks.euVectors#NIL THEN RosemaryVector.WriteVector[ks.euVectors, inhibitExpects];
Process.Yield[];
ks.controlPanel.continueTestFromAbort ← FALSE};
LogSettle:
PROC [handle: RosemaryUser.RoseDisplay, time:
INT, memory:
BOOL ←
TRUE] = {
UpdateWire: Rosemary.UpdateProc = {
coreWire: CoreFlat.FlatWireRec;
RosemaryUser.RecordDelta[handle, roseWire, time];
IF NOT handle.traceChanges THEN RETURN;
RosemaryUser.UpdateDisplay[handle];
coreWire ← roseWire.wire;
wireKey^ ← coreWire;
IO.PutF[handle.tsout, "%g←%g ", IO.rope[CoreFlat.WirePathRope[handle.cellType, coreWire]], IO.rope[Ports.LevelSequenceToRope[Rosemary.WireValue[ handle.simulation, wireKey]]]]};
wireKey: CoreFlat.FlatWire ← NEW[CoreFlat.FlatWireRec];
Rosemary.Settle[handle.simulation, UpdateWire, memory];
RosemaryUser.DeltaFinished[handle, time];
IF handle.traceChanges
THEN
IO.PutRope[handle.tsout, "\n\n"]};
UpdateIFUState: IFUTest.UpdateProc = {
comp: IFUState ← NARROW[ks.stateTop[0].data[ifu]];
atom: ATOM ← $IFUUpdateProc; -- IFUTest.ifuUpdateProc
updateProc: REF IFUTest.UpdateProc ← NARROW[Atom.GetProp[atom, atom]];
IF updateProc=NIL OR rawIFU THEN RETURN;
updateProc^[sim, state, pass, qph];
comp.cycle ← state.cycle;
comp.ph ← state.ph;
IF state^#comp^
THEN
IF
ks.controlPanel.reset OR
ks.protCyclesAfterReject>0 OR
ks.controlPanel.proceedFromCompareTest
THEN TerminalIO.PutF["#\n"] ELSE Signal[]};
Signal: SIGNAL = CODE;
CopyClusterArrayContents:
PROC[fm, to: ClusterState] = {
to.refCy^ ← fm.refCy^;
to.refPh^ ← fm.refPh^;
NARROW[ to.data[ifu], IFUState]^ ← NARROW[ fm.data[ifu], IFUState]^;
NARROW[ to.data[eu], EUState]^ ← NARROW[ fm.data[eu], EUState]^;
NARROW[ to.data[iCache], CacheSt]^ ← NARROW[ fm.data[iCache], CacheSt]^;
NARROW[ to.data[eCache], CacheSt]^ ← NARROW[ fm.data[eCache], CacheSt]^};
Cycles:
PROC [ n:
INT ] =
{FOR i: INT IN [0..n) DO DoPh[a]; DoPh[b] ENDLOOP};
Remark:
PROC [explan: Core.
ROPE] = {
ks.controlPanel.msg ← explan;
ks.controlPanel.running ← FALSE;
DoEval[];
UNTIL ks.controlPanel.running DO Process.Pause[Process.MsecToTicks[1000]] ENDLOOP;
ks.controlPanel.msg ← runningMsg;
DoEval[];
};
DoDRd:
PROC = {
SetPublicBool[ks, $IFUDShRd, TRUE]; DoEval[];
SetPublicBool[ks, $IFUDShRd, FALSE]; DoEval[]};
DoDShift:
PROC[in, out: IFUPublic.ScanRef] = {
size: NAT ← REFBit.Size[in];
FOR i:
INT
IN [0..size)
DO
ks.controlPanel.ifuDebugScanLoc ← i;
IF
NOT ks.controlPanel.running
THEN Remark[
(
IF ks.controlPanel.msg = runningMsg
THEN "Simulation manually suspended..."
ELSE ks.controlPanel.msg)];
ks.controlPanel.msg ← runningMsg;
SetPublicBool[ks, $IFUDShIn, NOT IFUPublic.GetScanBit[in, size-1-i]];
SetPublicBool[ks, $IFUDShA, TRUE]; DoEval[];
SetPublicBool[ks, $IFUDShA, FALSE]; DoEval[];
SetPublicBool[ks, $IFUDShB, TRUE]; DoEval[];
SetPublicBool[ks, $IFUDShB, FALSE]; DoEval[];
IFUPublic.SetScanBit[out, size-1-i, NOT GetPublicBool[ks, $IFUDShOut]];
ENDLOOP};
DoDWt:
PROC = {
SetPublicBool[ks, $IFUDShWt, TRUE]; DoEval[];
SetPublicBool[ks, $IFUDShWt, FALSE]; DoEval[]};
DoPh:
PROC [ ph: Dragon.Phase ] = {
first: BOOL ← TRUE;
ks.controlPanel.phase ← ph;
WHILE first
OR ks.controlPanel.repeatPhase
DO
SetPublicBool[ks, $PhA, ph=a];
SetPublicBool[ks, $PhB, ph=b];
SetPublicBool[ks, $NotPhA, ph#a];
SetPublicBool[ks, $NotPhB, ph#b];
ks.stateTop[0].refPh^ ← ks.stateFull[0].refPh^ ← ks.controlPanel.phase;
ks.stateTop[0].refCy^ ← ks.stateFull[0].refCy^ ← ks.controlPanel.cycle;
IF ks.controlPanel.running
THEN {ks.controlPanel.msg ← runningMsg; DoEval[]}
ELSE Remark[(
IF ks.controlPanel.msg = runningMsg
THEN "Simulation manually suspended..." ELSE ks.controlPanel.msg)];
IF first
THEN {
OPEN cp: ks.controlPanel;
IF cp.stopInPh[ph]
AND
(cp.cycle >= cp.slowFromCycle OR
(cp.cycle >= 0
AND cp.instrCount >= cp.slowFromInstr))
THEN
Remark[
IO.PutFR["Doing cycle %g Ph%g...",
IO.int[cp.cycle], IO.char[IF ph=a THEN 'A ELSE 'B]]]}
ELSE Remark[
IO.PutFR["...repeating cycle %g Ph%g..",
IO.int[ks.controlPanel.cycle], IO.char[IF ph=a THEN 'A ELSE 'B]]];
IF first
THEN {
-- cycle history buffers [1..top)
lastTop: ClusterState ← ks.stateTop [Cluster.historySize-1];
lastFull: ClusterState ← ks.stateFull [Cluster.historySize-1];
FOR i:
NAT
DECREASING
IN (1..Cluster.historySize)
DO
ks.stateTop [i] ← ks.stateTop [i-1];
ks.stateFull [i] ← ks.stateFull [i-1] ENDLOOP;
ks.stateTop[1] ← lastTop;
ks.stateFull[1] ← lastFull;
CopyClusterArrayContents[ks.stateTop[0], ks.stateTop[1]];
CopyClusterArrayContents[ks.stateFull[0], ks.stateFull[1]];
first ← FALSE };
SetPublicBool[ks, $PhB, FALSE];
SetPublicBool[ks, $PhA, FALSE];
SetPublicBool[ks, $NotPhA, TRUE];
SetPublicBool[ks, $NotPhB, TRUE];
DoEval[];
ENDLOOP;
ks.protCyclesAfterReject ←
SELECT
TRUE
FROM
ks.controlPanel.reset => 3,
ph=a OR
Rosemary.WireValue[simulation: ks.rosemarySimulation, flatWire: ks.euReject][0]=H
=> ks.protCyclesAfterReject,
ks.protCyclesAfterReject>0 => ks.protCyclesAfterReject-1,
ENDCASE => 0};
Main body of Inner
Process.SetPriority[ Process.priorityBackground ];
ks.diagnostics ← IF diagnostic=NIL THEN "test end" ELSE diagnostic;
ks.controlPanel.diagnostic ← ks.diagnostics;
ks.controlPanel.running ← TRUE;
DO
-- over all diagnostics
Chop:
PROC
RETURNS [ first, rest: Rope.
ROPE ←
NIL ] = {
dStream: IO.STREAM = IO.RIS[ks.controlPanel.diagnostic];
first ← dStream.GetTokenRope[IO.IDProc ! IO.EndOfStream => CONTINUE].token;
rest ← ks.controlPanel.diagnostic.Substr[dStream.GetIndex]};
file, root: Core.ROPE;
diagnosticFileName: Core.ROPE ← diagnosticName ← Chop[].first;
IF ks.ifuVectors #
NIL
THEN
{RosemaryVector.CloseVectorFile[ks.ifuVectors]; ks.ifuVectors ← NIL};
IF ks.euVectors #
NIL
THEN
{RosemaryVector.CloseVectorFile[ks.euVectors]; ks.euVectors ← NIL};
ks.log.Flush[];
Main LOOP EXIT
IF Rope.Length[diagnosticFileName] = 0
OR
(Rope.Equal[s1: diagnosticFileName, s2: "END", case:
FALSE]
AND
ks.controlPanel.randomSeed=0) THEN EXIT;
file ← FileNames.GetShortName[diagnosticFileName];
root ← file.Substr[0, file.Index[0, "."]];
ks.controlPanel.reset ← TRUE;
WHILE ks.controlPanel.reset
DO
-- as often as RESET is asserted in the same diagnostic
IF ks.controlPanel.enaIFUVectorWt
AND ks.ifuVectors=
NIL
THEN ks.ifuVectors ← RosemaryVector.OpenVectorFile
[root.Cat[".ifuVectors"], ks.ifuSimulationTruthPort, FALSE];
IF ks.controlPanel.enaEUVectorWt
AND ks.euVectors=
NIL
THEN ks.euVectors ← RosemaryVector.OpenVectorFile
[root.Cat[".euVectors"], ks.euSimulationTruthPort, FALSE];
ks.controlPanel.stopInPh ← ALL[TRUE];
ks.controlPanel.repeatPhase ← ks.controlPanel.resched ← FALSE;
ks.controlPanel.cycle ← -1;
ks.controlPanel.instrCount ← -1;
{
public: Core.Wire ← ks.cluster.public;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "DHold"]].b ← FALSE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "DStAd"]].c ← 0;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "Clk"]].b ← TRUE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "IFUDShA"]].b ← TRUE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "IFUDShB"]].b ← TRUE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "IFUDShRd"]].b ← FALSE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "IFUDShWt"]].b ← FALSE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "IFUDShIn"]].b ← FALSE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "EUDShA"]].b ← TRUE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "EUDShB"]].b ← TRUE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "EUDShRd"]].b ← FALSE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "EUDShWt"]].b ← FALSE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "EUDShIn"]].b ← FALSE;
};
FOR j:
NAT
IN [0..8)
DO
DoPh[a !
DragonRosemary.AssertionFailed => RESUME;
Rosemary.Stop => IF reason = $FailedAssertion OR reason = $BoolWireHasX THEN RESUME ELSE REJECT;
IFUTop.IFUInconsistent => CONTINUE ];
DoPh[b !
DragonRosemary.AssertionFailed => RESUME;
Rosemary.Stop => IF reason = $FailedAssertion OR reason = $BoolWireHasX THEN RESUME ELSE REJECT;
IFUTop.IFUInconsistent => CONTINUE ];
ENDLOOP;
{
public: Core.Wire ← ks.cluster.public;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "IFUDShA"]].b ← FALSE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "IFUDShB"]].b ← FALSE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "EUDShA"]].b ← FALSE;
ks.clusterIOPort[CoreOps.GetWireIndex[public, "EUDShB"]].b ← FALSE;
};
Cycles[2];
SELECT TRUE FROM
diagnosticFileName #
NIL => {
fullName: Core.
ROPE ← FileNames.FileWithSearchRules
[diagnosticFileName, NIL, FALSE, TRUE, NIL].fullPath;
CacheOps.VirtualMemoryFromFile[ks.vm, fullName ];
ks.lizardSimulation ← (IF ks.controlPanel.lizardToo THEN StartNewLizard[ks.vm] ELSE NIL)};
ks.controlPanel.randomSeed#0 => {
diagnosticName ← IO.PutFR["random code (seed = %d)", IO.int[ks.controlPanel.randomSeed]];
InsertRandomProgramInVM[ks];
ks.lizardSimulation ← (IF ks.controlPanel.lizardToo THEN StartNewLizard[ks.vm] ELSE NIL)};
ks.controlPanel.reset ← FALSE;
DoPh[a];
IF ks.controlPanel.reset THEN LOOP; -- restart this diagnostic
DoPh[b];
IF ks.controlPanel.reset THEN LOOP; -- restart this diagnostic
IF ks.controlPanel.slowFromCycle<=0 THEN Remark["Processor has been reset..."];
ks.controlPanel.cycle ← 0;
ks.rosemaryStores ← NIL;
ks.log.PutF["\n\n\n%g Dragon Rosemary simulation of %g beginning...\n\n",
IO.time[],
IO.rope[diagnosticName]];
WHILE ks.controlPanel.randomSeed=0
OR ks.controlPanel.cycle<=ks.controlPanel.randomCycleLimit
DO
ENABLE {
Breakpoint => {
ks.log.PutF["\n%g Breakpoint XOP in %g at instruction %d, cycle %d.\n\n",
IO.time[],
IO.rope[diagnosticName],
IO.int[ks.controlPanel.instrCount],
IO.int[ks.controlPanel.cycle]];
SELECT
TRUE
FROM
ks.controlPanel.emulateBreakpoint => RESUME;
diagnosticFileName # NIL => REJECT;
ENDCASE => EXIT } };
IF ks.controlPanel.ifuDebugScanOut
THEN {
DoDRd[];
DoDShift[ks.ifuScanBuffer, ks.ifuScanBuffer];
ks.controlPanel.ifuDebugScanOut ← FALSE};
DoPh[a];
IF ks.controlPanel.reset THEN EXIT; -- restart this diagnostic
DoPh[b];
IF GetSuccessHalt[]
THEN {
ks.log.PutF["\n%g Success XOP in %g at instruction %d, cycle %d.\n\n",
IO.time[],
IO.rope[diagnosticName],
IO.int[ks.controlPanel.instrCount],
IO.int[ks.controlPanel.cycle]];
SetSuccessHalt[FALSE];
EXIT};
IF ks.controlPanel.reset
THEN
EXIT;
-- restart this diagnostic
ks.controlPanel.cycle ← ks.controlPanel.cycle+1;
IF
NOT ks.controlPanel.enaIFUVectorWt
AND (ks.ifuVectors #
NIL)
THEN
{RosemaryVector.CloseVectorFile[ks.ifuVectors]; ks.ifuVectors ← NIL};
IF
NOT ks.controlPanel.enaEUVectorWt
AND (ks.euVectors #
NIL)
THEN
{RosemaryVector.CloseVectorFile[ks.euVectors]; ks.euVectors ← NIL};
ENDLOOP; -- on ks.controlPanel.cycle
ENDLOOP; -- on a single diagnostic
SELECT
TRUE
FROM
diagnosticFileName #
NIL => {
first, rest: Rope.ROPE;
[first, rest] ← Chop[];
IF first.Equal[diagnosticFileName]
THEN
ks.controlPanel.diagnostic ← Rope.Cat[rest, " ",first]};
ks.controlPanel.randomSeed # 0 =>
ks.controlPanel.randomSeed ← ks.controlPanel.randomSeed+1;
ENDCASE => NULL;
ENDLOOP; -- on ks.diagnostic or ks.controlPanel.randomSeed
}; -- for catching UNWIND
Process.SetPriority[ originalPriority ]};
runningMsg: Core.ROPE ← "Running...";