SmallCacheArrayImpl.mesa
Created: Paraminder Sahai September 1, 1987 6:55:41 am PDT
Paraminder Sahai September 27, 1987 0:53:06 am PDT
Pradeep Sindhu May 15, 1988 10:32:16 pm PDT
DIRECTORY
Convert, Core, CoreClasses, CoreCreate, CoreFlat, CoreOps, IO, Ports, Rosemary, RosemaryUser, Rope, PWCoreHack, SmallCacheLogic, SCParms, Sisyph, TerminalIO;
SmallCacheArrayImpl: CEDAR PROGRAM
IMPORTS Convert, CoreClasses, CoreCreate, CoreFlat, CoreOps, Ports, PWCoreHack, Rosemary, Rope, SCParms, Sisyph, TerminalIO
EXPORTS SmallCacheLogic
~ BEGIN OPEN SmallCacheLogic;
Constants and Type Defs
ClockEvalEnabled: BOOL = TRUE;
MySmallCacheName: ROPE = Rosemary.Register[roseClassName: "SmallCacheArray", init: Init, evalSimple: Simple, scheduleIfClockEval: ClockEvalEnabled];
NumFlagsBits: NAT = 4;
NumIOLines: NAT = 2*3;
numMemLines: NAT ← 2*SCParms.numMemLines;
numAddressBits: NAT ← SCParms.numBitsPerWord+1;   --Includes IO/Mem Bit--
numPageBits: NAT ← SCParms.numPageBits+1;   --Includes IO/Mem Bit--
numPageAndBlockBits: NAT ← numPageBits+SCParms.numBlockBits;
IOVCamLine: ARRAY [0..NumIOLines) OF Rope.ROPE ← [
Rope.Cat[SCParms.vPagePattern, SCParms.vBlock0Pattern],
Rope.Cat[SCParms.vPagePattern, SCParms.vBlock1Pattern],
Rope.Cat[SCParms.vPagePattern, SCParms.vBlock2Pattern],
Rope.Cat[SCParms.vPagePattern, SCParms.vBlock3Pattern],
Rope.Cat[SCParms.vPagePattern, SCParms.vBlock4Pattern],
Rope.Cat[SCParms.vPagePattern, SCParms.vBlock5Pattern]
];
IORCamLine: ARRAY[0..NumIOLines) OF Rope.ROPE ← [
Rope.Cat[SCParms.rPagePattern, SCParms.rBlock0Pattern],
Rope.Cat[SCParms.rPagePattern, SCParms.rBlock1Pattern],
Rope.Cat[SCParms.rPagePattern, SCParms.rBlock2Pattern],
Rope.Cat[SCParms.rPagePattern, SCParms.rBlock3Pattern],
Rope.Cat[SCParms.rPagePattern, SCParms.rBlock4Pattern],
Rope.Cat[SCParms.rPagePattern, SCParms.rBlock5Pattern]
];
IOFlagsLine: ARRAY[0..NumIOLines) OF Rope.ROPE = ["1111", "0011", "0011", "0011", "0011", "0011"];
Two-D array containing Victim, RamSel, RML1, LVM, RML2, RML3, RML4, and GND
Match: TYPE = REF MatchRec;
MatchRec: TYPE = RECORD [
ARRAY Index OF LevelSequence
];
IOMatch: TYPE = REF IOMatchRec;
IOMatchRec: TYPE = RECORD [
ARRAY Index[RML1..GND] OF LevelSequence
];
TwoDArray: TYPE = REF TwoDArrayRec;
TwoDArrayRec: TYPE = RECORD [
SEQUENCE size: NAT OF LevelSequence
];
KindOfMatch: TYPE = {Virtual, Real};
Index: TYPE = {Victim, RamSel, RML1, LVM, RML2, RML3, RML4, GND};
CacheState: TYPE = REF CacheStateRec;
CacheStateRec: TYPE = RECORD [
prevClk: Level,
match: Match ← NIL,   -- contains mem array ctl bits (see def)
iomatch: ARRAY Index[RML1..GND] OF ARRAY [0..NumIOLines) OF Level,
csMuxSR: Level,   -- flop in CSMuxInterface
rsCmdLatch : ARRAY[0..1] OF Level,  -- latch in RSMuxInterface
csOut, rsOut, iorsOut: Index,  -- to implement csmux, rsmux, iorsmux
rBCycle: ARRAY [3..5] OF Level,   -- delay stages in RML234
enCamSelExtFF: Level,   -- delay stage for EnCamSelExt
victimIndex: INT,   -- line pointed to by victim
tmpVictimIndex: INT,   -- to implement victim Flops
use: LevelSequence ← NIL,  -- use bits in array
tmpUse: LevelSequence ← NIL,  -- to implement use Flops
soSR: ARRAY [0..1] OF Level,  -- delay stages in SOInterface
sh, ow: LevelSequence ← NIL,   -- sh ow bits in array
shBit, owBit: Level,   -- sh and ow bits in SORdLatch
pWtInProgB: Level,   -- output of SOInterface
ramWtSR, ramRdSR: ARRAY [0..1] OF Level, -- 2 flops each in RamInterfaceCtl
ramRdorWt: Level,   -- flop to generate Prech
ramRdLatch: LevelSequence ← NIL,  -- ramRdLatch in RamInterface
bar: LevelSequence ← NIL,  -- block assembly register
ram: TwoDArray ← NIL,   -- ram bits
ioRam: RECORD [cWSOld, cWSNew, aID, faultCode, intStatus, intMask, modes, lFCode1, lFCode3, lFCode5, lFCode7: LevelSequence ← NIL], -- ioram bits
vCamCSCmd1, rCamCSCmd1: Level,  -- latches in RCam and VCam Interfaces
rCam, vCam: TwoDArray ← NIL,  -- rcam and vcam bits
arm, avm: Level,   -- values of arm and avm
ioRCam, ioVCam: ARRAY [0..NumIOLines) OF LevelSequence, -- iorcam and iovcam bits
flags: TwoDArray ← NIL,   -- flags array
ioFlags: ARRAY [0..NumIOLines) OF ARRAY [0..NumFlagsBits) OF Level, -- ioflags array
rCamRdLatch, rCamWtReg, vCamRdLatch, vCamWtReg: LevelSequence,
flagsRdLatch, flagsWtReg: ARRAY [0..NumFlagsBits) OF Level,
vCamDrBLFF, rCamDrBLFF: Level,   -- flops for CamDrBL
vCamLdFF, rCamLdFF: Level,  -- flop for LdCamRL; note there is no flop for CCamPr because precharge is not modeled explicitly
vCamSel: Index,   -- source of input for vcam select line
aVct: Level,    -- arrayVictim
resetDone: BOOLEAN,   -- used to suppress error due to X's before Reset has been done
The following are used to capture input signals that go to flops
tmpRAdrsIn, tmpVAdrsInOut: LevelSequence ← NIL,
tmpCycleIn: LevelSequence ← NIL,
tmpBAREn: LevelSequence ← NIL,
tmpFlagsIn: ARRAY [0..NumFlagsBits) OF Level,
tmpxEnCamSel,
tmpxEnCamSelExt,
tmpRBCycle2,
tmpxWtRam,
tmpxRdRam,
tmpramRdorWt,
tmpxLdVCamWR,
tmpxDrVCamBL,
tmpxLdVCamRL,
tmpxLdRCamRL,
tmpVPValidIn,
tmpRPValidIn,
tmpPWtInProg,
tmpxDrRCamBL,
tmpxLdRCamWR,
tmpReset: Level,
numCyclesAfterReset: NAT
];
Signal Defs
enableDumpState: BOOLFALSE;
cacheStateRef: CacheState ← NIL;
cacheStateValueIn, cacheStateValueOut: ROPENIL;
Vdd, Gnd, Reset, xCVCamPr, xCRCamPr, LdVML, ClrVPV, PCtlClrAllVPV, PCtlResetVictim, Spare, RamClock, xLdUse, PCtlDrABusVB, PCtlDrABusVP, nPartVMch, xLdVCamRL, xLdVCamWR, xDrVCamBL, VAdrsInOut, VPValidIn, PCtlDrABusRB, PCtlDrABusRP, xLdRCamRL, nxPartRMch, xDrRCamBL, xLdRCamWR, xEnCamSelExt, RBCycle2, RAdrsIn, RPValidIn, FlagsIn, nPMFlags, xEnCamSel, PCtlShftVictim4, PCtlFrzVictim, xCSCmd, nEnRS, xRSCmd, PWtInProg, BCtlSetOw, BCtlClrOw, SetSh, ClrSh, xRdRam, xWtRam, nxSelWdData, nxByteSel, nxWdSel, WdWtData, CycleIn, BAREn, Modes, RAdrsOut, FlagsOut, BlkRdData, WdRdData, SetReschedule, ASh, AOw, ARM3, AVM, Clock: NAT;
Public Procs
Array: PUBLIC PROC [cts: CellTypeSpec, cx: Context] RETURNS [ct: CellType] = BEGIN
public: Wire ← CoreCreate.WireList[LIST["Vdd", "Gnd", "Reset", "xCVCamPr", "xCRCamPr", "LdVML", "ClrVPV", "PCtlClrAllVPV", "PCtlResetVictim", CoreCreate.Seq["Spare", SCParms.numBitsPerCycle], "RamClock", "xLdUse", "PCtlDrABusVB", "PCtlDrABusVP", "nPartVMch", "xLdVCamRL", "xLdVCamWR", "xDrVCamBL", CoreCreate.Seq["VAdrsInOut", numAddressBits], "VPValidIn", "PCtlDrABusRB", "PCtlDrABusRP", "xLdRCamRL", "nxPartRMch", "xDrRCamBL", "xLdRCamWR", "xEnCamSelExt", "RBCycle2", CoreCreate.Seq["RAdrsIn", numAddressBits], "RPValidIn", CoreCreate.Seq["FlagsIn", NumFlagsBits], CoreCreate.Seq["nPMFlags", NumFlagsBits], "xEnCamSel", "PCtlShftVictim4", "PCtlFrzVictim", CoreCreate.Seq["xCSCmd", 2], "nEnRS", CoreCreate.Seq["xRSCmd",2], "PWtInProg", "BCtlSetOw", "BCtlClrOw", "SetSh", "ClrSh", "xRdRam", "xWtRam", "nxSelWdData", CoreCreate.Seq["nxByteSel", SCParms.numBytesPerWord], CoreCreate.Seq["nxWdSel", SCParms.numWordsPerLine], CoreCreate.Seq["WdWtData", SCParms.numBitsPerWord], CoreCreate.Seq["CycleIn", SCParms.numBitsPerCycle], CoreCreate.Seq["BAREn", SCParms.numCyclesPerLine], CoreCreate.Seq["Modes", SCParms.numBitsPerWord], CoreCreate.Seq["RAdrsOut", numAddressBits], CoreCreate.Seq["FlagsOut", NumFlagsBits], CoreCreate.Seq["BlkRdData", SCParms.numBitsPerLine], CoreCreate.Seq["WdRdData", SCParms.numBitsPerWord], "SetReschedule", "ASh", "AOw", "ARM3", "AVM", "Clock"]];
SELECT cts FROM
Schematic => ct ← Sisyph.ES["SCacheArray.sch", cx];
Procedure => {
ct ← CoreClasses.CreateUnspecified[public: public];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: MySmallCacheName];
[] ← CoreFlat.CellTypeCutLabels[ct, "Logic"];
[] ← Ports.InitPort[public[CoreOps.GetWireIndex[public, "VAdrsInOut"]], ls, separate, none, NEW [Ports.DriveSequenceRec[numAddressBits]]];
Ports.InitPorts[ct, ls, none, "RAdrsIn"];
[] ← Ports.InitPort[public[CoreOps.GetWireIndex[public, "RAdrsOut"]], ls, separate, none, NEW [Ports.DriveSequenceRec[numAddressBits]]];
Ports.InitPorts[ct, ls, none, "Spare"];
Ports.InitPorts[ct, ls, none, "FlagsIn"];
Ports.InitPorts[ct, ls, none, "nPMFlags"];
Ports.InitPorts[ct, ls, none, "xCSCmd"];
Ports.InitPorts[ct, ls, none, "xRSCmd"];
Ports.InitPorts[ct, ls, none, "nxByteSel"];
Ports.InitPorts[ct, ls, none, "nxWdSel"];
Ports.InitPorts[ct, ls, none, "WdWtData"];
Ports.InitPorts[ct, ls, none, "CycleIn"];
Ports.InitPorts[ct, ls, none, "BAREn"];
[] ← Ports.InitPort[public[CoreOps.GetWireIndex[public, "FlagsOut"]], ls, separate, none, NEW [Ports.DriveSequenceRec[NumFlagsBits]]];
Ports.InitPorts[ct, ls, drive, "Modes"];
Ports.InitPorts[ct, ls, drive, "BlkRdData"];
Ports.InitPorts[ct, ls, drive, "WdRdData"];
Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "Reset", "xCVCamPr", "xCRCamPr", "LdVML", "ClrVPV", "PCtlClrAllVPV"];
Ports.InitPorts[ct, l, none, "PCtlResetVictim", "Spare", "xLdUse", "PCtlDrABusVB", "PCtlDrABusVP", "nPartVMch", "xLdVCamRL", "xLdVCamWR", "xDrVCamBL"];
Ports.InitPorts[ct, l, none, "Clock", "VPValidIn", "PCtlDrABusRB", "PCtlDrABusRP", "xLdRCamRL", "nxPartRMch", "xDrRCamBL", "xLdRCamWR", "xEnCamSelExt", "RBCycle2"];
Ports.InitPorts[ct, l, none, "xEnCamSel", "PCtlShftVictim4", "PCtlFrzVictim", "nEnRS"];
Ports.InitPorts[ct, l, none, "PWtInProg", "BCtlSetOw", "BCtlClrOw", "SetSh", "ClrSh", "xRdRam", "xWtRam", "nxSelWdData", "RPValidIn"];
Ports.InitPorts[ct, l, drive, "RamClock"];
Ports.InitPorts[ct, l, drive, "SetReschedule", "ASh", "AOw", "ARM3", "AVM"]
};
CoreFile => ct ← PWCoreHack.Retrieve["SCacheArray"];
ENDCASE => ERROR;
END;
Retrieves cacheStateValueOut
ArrayGetState: PUBLIC PROC[] RETURNS[csv: ROPE] = BEGIN
DumpState[];
csv ← cacheStateValueOut
END;
Sets cacheStateValueIn
ArrayPutState: PUBLIC PROC[csv: ROPE] = BEGIN
cacheStateValueIn ← csv;
END;
Internal Procs
Copies cache state from cacheStateValueIn to simulation
LoadState: PROC [] = BEGIN
cs: CacheState ← cacheStateRef;
fieldStart: NAT ← 0;
fieldStop: NAT ← 0;
RopeToL: PROC[value: ROPE] RETURNS[l: Level] = BEGIN
IF Rope.Length[value] # 1 THEN ERROR;
SELECT Rope.Fetch[value, 0] FROM
'1 => RETURN[H];
'0 => RETURN[L];
'X => RETURN[X];
ENDCASE => ERROR;
END;
LoadLS: PROC[ls: LevelSequence, value: ROPE] = BEGIN
ropeIx: NAT ← 0;
FOR i: NAT IN [0..ls.size) DO
ropeIx ← Rope.SkipTo[s: value, pos: ropeIx, skip: "01X"];
SELECT Rope.Fetch[value, ropeIx] FROM
'1 => ls[i] ← H;
'0 => ls[i] ← L;
'X => ls[i] ← X;
ENDCASE;
ropeIx ← ropeIx+1
ENDLOOP;
END;
LoadBlock: PROC[block: LevelSequence, value: ROPE] = BEGIN
ropeIx: NAT ← 0;
FOR wdIx: NAT IN [0..SCParms.numWordsPerLine) DO
FOR bitIx: NAT IN [0..SCParms.numBitsPerWord) DO
ropeIx ← Rope.SkipTo[s: value, pos: ropeIx, skip: "01X"];
SELECT Rope.Fetch[value, ropeIx] FROM
'1 => block[bitIx*SCParms.numWordsPerLine+wdIx] ← H;
'0 => block[bitIx*SCParms.numWordsPerLine+wdIx] ← L;
'X => block[bitIx*SCParms.numWordsPerLine+wdIx] ← X;
ENDCASE;
ropeIx ← ropeIx+1;
ENDLOOP;
ENDLOOP;
END;
GetInt: PROC[] RETURNS[i: INT] = BEGIN
fieldStart ← Rope.SkipTo[s: cacheStateValueIn, pos: fieldStart, skip: "0123456789"];
fieldStop ← Rope.SkipTo[s: cacheStateValueIn, pos: fieldStart, skip: ","];
i ← Convert.IntFromRope[Rope.Substr[cacheStateValueIn, fieldStart, fieldStop-fieldStart]];
fieldStart ← fieldStop+1;
END;
GetRope: PROC[] RETURNS[r: ROPE] = BEGIN
fieldStart ← Rope.SkipTo[s: cacheStateValueIn, pos: fieldStart, skip: "01X"];
fieldStop ← Rope.SkipTo[s: cacheStateValueIn, pos: fieldStart, skip: ","];
r ← Rope.Substr[cacheStateValueIn, fieldStart, fieldStop-fieldStart];
fieldStart ← fieldStop+1;
END;
IF cacheStateValueIn=NIL THEN RETURN;
cs.victimIndex ← cs.tmpVictimIndex ← GetInt[];
FOR i: NAT IN [0..numMemLines) DO
cs.match[Victim][i] ← L
ENDLOOP;
cs.match[Victim][cs.victimIndex] ← H;
THROUGH [0..numMemLines) DO
lineNum: NAT ← GetInt[];
LoadLS[cs.vCam[lineNum], GetRope[]];
LoadLS[cs.rCam[lineNum], GetRope[]];
LoadLS[cs.flags[lineNum], GetRope[]];
cs.sh[lineNum] ← RopeToL[GetRope[]];
cs.ow[lineNum] ← RopeToL[GetRope[]];
cs.use[lineNum] ← RopeToL[GetRope[]];
LoadBlock[cs.ram[lineNum], GetRope[]];
ENDLOOP;
END;
Copies cache state from simulation to cacheStateValueOut
DumpState: PROC[] = BEGIN
cs: CacheState ← cacheStateRef;
LToRope: PROC[l: Level] RETURNS [ROPE] = BEGIN
SELECT l FROM
L => RETURN["0"];
H => RETURN["1"];
X => RETURN["x"];
ENDCASE => ERROR;
END;
LSToRope: PROC[ls: LevelSequence] RETURNS [lsr: ROPENIL] = BEGIN
FOR i: NAT IN [0..ls.size) DO lsr ← Rope.Cat[lsr, LToRope[ls[i]]] ENDLOOP;
END;
AdrsToRope: PROC[adrs: LevelSequence] RETURNS [ar: ROPE] = BEGIN
ar ← Rope.Cat[LToRope[adrs[0]], " "];
FOR i: NAT IN [1..numPageBits) DO ar ← Rope.Cat[ar, LToRope[adrs[i]]] ENDLOOP;
ar ← Rope.Cat[ar, " "];
FOR i: NAT IN [numPageBits..numPageAndBlockBits) DO ar ← Rope.Cat[ar, LToRope[adrs[i]]] ENDLOOP;
ar ← Rope.Cat[ar, " "];
FOR i: NAT IN [numPageAndBlockBits..numAddressBits) DO ar ← Rope.Cat[ar, LToRope[adrs[i]]] ENDLOOP;
END;
BlockToRope: PROC[block: LevelSequence] RETURNS[br: ROPENIL] = BEGIN
FOR wdIx: NAT IN [0..SCParms.numWordsPerLine) DO
FOR bitIx: NAT IN [0..SCParms.numBitsPerWord) DO
br ← Rope.Cat[br, LToRope[block[bitIx*SCParms.numWordsPerLine+wdIx]]];
ENDLOOP;
IF wdIx<SCParms.numWordsPerLine-1 THEN br ← Rope.Cat[br, " "];
ENDLOOP;
END;
IF cs=NIL THEN RETURN;
cacheStateValueOut ← Rope.Cat["\n Victim: ", Convert.RopeFromInt[cs.victimIndex], ","];
FOR i: NAT IN [0..numMemLines) DO
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, "\nLine: ", Convert.RopeFromInt[i]];
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, ", VCam: ", AdrsToRope[cs.vCam[i]]];
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, ", RCam: ", AdrsToRope[cs.rCam[i]]];
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, ", Flags: ", LSToRope[cs.flags[i]]];
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, ", Sh: ", LToRope[cs.sh[i]]];
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, ", Ow: ", LToRope[cs.ow[i]]];
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, ", Use: ", LToRope[cs.use[i]]];
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, ", Ram: ", BlockToRope[cs.ram[i]]];
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, ", "];
ENDLOOP;
cacheStateValueOut ← Rope.Cat[cacheStateValueOut, "\n"];
END;
Init: Rosemary.InitProc = BEGIN
i, j: INT;
cs: CacheState;
Create the state if it doesn't already exist
IF oldStateAny=NIL
THEN {
cs ← NEW [CacheStateRec];
cs.match ← NEW[MatchRec];
FOR k: Index IN Index DO
cs.match[k] ← NEW [LevelSequenceRec[numMemLines]]
ENDLOOP;
cs.use ← NEW [LevelSequenceRec[numMemLines]];
cs.tmpUse ← NEW [LevelSequenceRec[numMemLines]];
cs.sh ← NEW [LevelSequenceRec[numMemLines]];
cs.ow ← NEW [LevelSequenceRec[numMemLines]];
cs.ramRdLatch ← NEW [LevelSequenceRec[SCParms.numBitsPerLine]];
cs.bar ← NEW [LevelSequenceRec[SCParms.numBitsPerLine]];
cs.ram ← NEW [TwoDArrayRec[numMemLines]];
FOR i: NAT IN [0..numMemLines) DO
cs.ram[i] ← NEW [LevelSequenceRec[SCParms.numBitsPerLine]];
ENDLOOP;
cs.ioRam.cWSOld ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.cWSNew ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.aID ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.faultCode ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.intStatus ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.intMask ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.modes ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.lFCode1 ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.lFCode3 ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.lFCode5 ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.ioRam.lFCode7 ← NEW [LevelSequenceRec[SCParms.numBitsPerWord]];
cs.rCam ← NEW [TwoDArrayRec[numMemLines]];
FOR i: NAT IN [0..numMemLines) DO
cs.rCam[i] ← NEW [LevelSequenceRec[numAddressBits]];
ENDLOOP;
cs.vCam ← NEW [TwoDArrayRec[numMemLines]];
FOR i: NAT IN [0..numMemLines) DO
cs.vCam[i] ← NEW [LevelSequenceRec[numAddressBits]];
ENDLOOP;
cs.arm ← X; cs.avm ← X;
FOR i: NAT IN [0..NumIOLines) DO
cs.ioRCam[i] ← NEW [LevelSequenceRec[numAddressBits]];
ENDLOOP;
FOR i: NAT IN [0..NumIOLines) DO
cs.ioVCam[i] ← NEW [LevelSequenceRec[numAddressBits]];
ENDLOOP;
cs.flags ← NEW [TwoDArrayRec[numMemLines]];
FOR i: NAT IN [0..numMemLines) DO
cs.flags[i] ← NEW [LevelSequenceRec[NumFlagsBits]];
ENDLOOP;
cs.rCamRdLatch ← NEW [LevelSequenceRec[numAddressBits]];
cs.rCamWtReg ← NEW [LevelSequenceRec[numAddressBits]];
cs.vCamRdLatch ← NEW [LevelSequenceRec[numAddressBits]];
cs.vCamWtReg ← NEW [LevelSequenceRec[numAddressBits]];
cs.tmpRAdrsIn ← NEW [LevelSequenceRec[numAddressBits]];
cs.tmpCycleIn ← NEW [LevelSequenceRec[SCParms.numBitsPerCycle]];
cs.tmpBAREn ← NEW [LevelSequenceRec[SCParms.numCyclesPerLine]];
cs.tmpVAdrsInOut ← NEW [LevelSequenceRec[numAddressBits]];
}
ELSE cs ← NARROW[oldStateAny, CacheState];
cs.prevClk ← X; cs.vCamCSCmd1 ← X; cs.rCamCSCmd1 ← X; cs.aVct ← X; cs.ramRdorWt ← X; cs.pWtInProgB ← X;
FOR i IN [0..numAddressBits) DO
cs.vCamRdLatch[i] ← X; cs.vCamWtReg[i] ← X; cs.rCamRdLatch[i] ← X; cs.rCamWtReg[i] ← X;
ENDLOOP;
FOR i IN [0..NumFlagsBits) DO
cs.flagsRdLatch[i] ← X; cs.flagsWtReg[i] ← X;
ENDLOOP;
FOR i IN [0..SCParms.numBitsPerLine) DO
cs.ramRdLatch[i] ← X;
cs.bar[i] ← X;
ENDLOOP;
FOR i IN [0..numMemLines) DO
cs.vCam[i][0] ← L; cs.vCam[i][numAddressBits-1] ← X;
cs.rCam[i][0] ← L; cs.rCam[i][numAddressBits-1] ← X;
FOR j IN [numPageAndBlockBits..numPageAndBlockBits+SCParms.logNumWordsPerLine-2] DO
cs.vCam[i][j] ← L; cs.rCam[i][j] ← L;
ENDLOOP;
FOR j IN [1..numPageAndBlockBits) DO
cs.vCam[i][j] ← X; cs.rCam[i][j] ← X;
ENDLOOP;
FOR j IN [0..NumFlagsBits) DO
cs.flags[i][j] ← X;
ENDLOOP;
FOR j IN [0..SCParms.numBitsPerLine) DO
cs.ram[i][j] ← X;
ENDLOOP;
cs.use[i] ← X; cs.tmpUse[i] ← X; cs.sh[i] ← X; cs.ow[i] ← X;
FOR k: Index IN [Victim..RML4] DO
cs.match[k][i] ← X;
ENDLOOP;
cs.match[GND][i] ← L;
ENDLOOP;
cs.shBit ← X; cs.owBit ← X;
cs.csMuxSR ← X;
FOR i IN [0..1] DO
cs.rsCmdLatch[i] ← X;
cs.ramWtSR[i] ← X;
cs.ramRdSR[i] ← X;
cs.soSR[i] ← X;
ENDLOOP;
FOR i IN [3..5] DO
cs.rBCycle[i] ← X;
ENDLOOP;
cs.vCamDrBLFF ← X; cs.rCamDrBLFF ← X;
cs.vCamLdFF ← X; cs.rCamLdFF ← X;
cs.tmpxEnCamSel ← X; cs.tmpxEnCamSelExt ← X;
FOR i IN [0..numAddressBits) DO
cs.tmpRAdrsIn[i] ← X; cs.tmpVAdrsInOut[i] ← X;
ENDLOOP;
FOR i IN [0..SCParms.numBitsPerCycle) DO
cs.tmpCycleIn[i] ← X;
ENDLOOP;
FOR i IN [0..SCParms.numCyclesPerLine) DO
cs.tmpBAREn[i] ← X;
ENDLOOP;
FOR i IN [0..NumFlagsBits) DO
cs.tmpFlagsIn[i] ← X;
ENDLOOP;
cs.tmpRBCycle2 ← X; cs.tmpxWtRam ← X; cs.tmpxRdRam ← X; cs.tmpramRdorWt ← X; cs.tmpxLdVCamWR ← X; cs.tmpxLdVCamRL ← p[xLdVCamRL].l; cs.tmpxLdRCamRL ← X; cs.tmpVPValidIn ← X; cs.tmpRPValidIn ← X; cs.tmpPWtInProg ← X; cs.tmpxDrRCamBL ← X; cs.tmpxLdRCamWR ← X; cs.tmpxDrVCamBL ← X; cs.tmpReset ← X; cs.numCyclesAfterReset ← LAST[NAT];
FOR i IN [0..NumIOLines) DO
FOR j IN [numPageAndBlockBits..numPageAndBlockBits+SCParms.logNumWordsPerLine-2] DO
cs.ioVCam[i][j] ← L; cs.ioRCam[i][j] ← L;
ENDLOOP;
cs.ioVCam[i][numAddressBits-1] ← H;
cs.ioRCam[i][numAddressBits-1] ← H;
ENDLOOP;
FOR i IN [0..NumIOLines) DO
FOR j IN [0..NumFlagsBits) DO
cs.ioFlags[i][j] ← IF Rope.Fetch[IOFlagsLine[i], j] = '1 THEN H ELSE L;
ENDLOOP;
FOR j IN [0..numPageAndBlockBits) DO
cs.ioVCam[i][j] ← IF Rope.Fetch[IOVCamLine[i], j] = '1 THEN H ELSE L;
cs.ioRCam[i][j] ← IF Rope.Fetch[IORCamLine[i], j] = '1 THEN H ELSE L;
ENDLOOP;
ENDLOOP;
FOR i IN [0..SCParms.numBitsPerWord) DO
cs.ioRam.cWSOld[i] ← X;
cs.ioRam.cWSNew[i] ← X;
cs.ioRam.aID[i] ← X;
cs.ioRam.faultCode[i] ← X;
cs.ioRam.intStatus[i] ← X;
cs.ioRam.intMask[i] ← X;
cs.ioRam.modes[i] ← X;
cs.ioRam.lFCode1[i] ← H;
cs.ioRam.lFCode3[i] ← H;
cs.ioRam.lFCode5[i] ← H;
cs.ioRam.lFCode7[i] ← H;
ENDLOOP;
FOR i IN [0..NumIOLines) DO
FOR k: Index IN [RML1..RML4] DO
cs.iomatch[k][i] ← X;
ENDLOOP;
cs.iomatch[GND][i] ← L;
ENDLOOP;
cs.resetDone ← FALSE;
[Vdd, Gnd, Reset, xCVCamPr, xCRCamPr, LdVML, ClrVPV, PCtlClrAllVPV] ← Ports.PortIndexes[cellType.public, "Vdd", "Gnd", "Reset", "xCVCamPr", "xCRCamPr", "LdVML", "ClrVPV", "PCtlClrAllVPV"];
[PCtlResetVictim, Spare, RamClock, xLdUse, PCtlDrABusVB, PCtlDrABusVP, nPartVMch, xLdVCamRL, xLdVCamWR, xDrVCamBL, VAdrsInOut, VPValidIn] ← Ports.PortIndexes[cellType.public, "PCtlResetVictim", "Spare", "RamClock", "xLdUse", "PCtlDrABusVB", "PCtlDrABusVP", "nPartVMch", "xLdVCamRL", "xLdVCamWR", "xDrVCamBL", "VAdrsInOut", "VPValidIn"];
[PCtlDrABusRB, PCtlDrABusRP, xLdRCamRL, nxPartRMch, xDrRCamBL, xLdRCamWR, xEnCamSelExt, RBCycle2, RAdrsIn, RPValidIn, FlagsIn] ← Ports.PortIndexes[cellType.public, "PCtlDrABusRB", "PCtlDrABusRP", "xLdRCamRL", "nxPartRMch", "xDrRCamBL", "xLdRCamWR", "xEnCamSelExt", "RBCycle2", "RAdrsIn", "RPValidIn", "FlagsIn"];
[nPMFlags, xEnCamSel, PCtlShftVictim4, PCtlFrzVictim, xCSCmd, nEnRS, xRSCmd, PWtInProg, BCtlSetOw, BCtlClrOw] ← Ports.PortIndexes[cellType.public, "nPMFlags", "xEnCamSel", "PCtlShftVictim4", "PCtlFrzVictim", "xCSCmd", "nEnRS", "xRSCmd", "PWtInProg", "BCtlSetOw", "BCtlClrOw"];
[SetSh, ClrSh, xRdRam, xWtRam, nxSelWdData, nxByteSel, nxWdSel, WdWtData, CycleIn, BAREn, Modes, RAdrsOut] ← Ports.PortIndexes[cellType.public, "SetSh", "ClrSh", "xRdRam", "xWtRam", "nxSelWdData", "nxByteSel", "nxWdSel", "WdWtData", "CycleIn", "BAREn", "Modes", "RAdrsOut"];
[FlagsOut, BlkRdData, WdRdData, SetReschedule, ASh, AOw] ← Ports.PortIndexes[cellType.public, "FlagsOut", "BlkRdData", "WdRdData", "SetReschedule", "ASh", "AOw"];
[ARM3, AVM, Clock] ← Ports.PortIndexes[cellType.public, "ARM3", "AVM", "Clock"];
stateAny ← cs;
END;
Simple: Rosemary.EvalProc = BEGIN
cs: CacheState ← NARROW[stateAny];
cacheStateRef ← cs;
IF p[Reset].l = H THEN cs.resetDone ← TRUE;
IF ClockL[p, cs, clockEval] THEN CaptureL[p, cs];
IF ClockH[p, cs, clockEval] THEN CaptureH[p, cs];
CSMux[p, cs, clockEval];
RSMux[p, cs];
RML234[p, cs, clockEval];
Victim[p, cs, clockEval];
VCamRCamAndFlags[p, cs, clockEval];
SOAndRam[p, cs, clockEval];
HandleState[p, cs, clockEval];
IF (NOT ClockEvalEnabled) OR (NOT clockEval) THEN cs.prevClk ← p[Clock].l;
END;
ClockLToH: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] RETURNS[BOOL] = {
IF ClockEvalEnabled
THEN RETURN[NOT clockEval AND cs.prevClk=L AND p[Clock].l=H]
ELSE RETURN[cs.prevClk=L AND p[Clock].l=H]
};
ClockHToL: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] RETURNS[BOOL] = {
IF ClockEvalEnabled
THEN RETURN[NOT clockEval AND cs.prevClk=H AND p[Clock].l=L]
ELSE RETURN[cs.prevClk=H AND p[Clock].l=L]
};
ClockL: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] RETURNS[BOOL] = {
IF ClockEvalEnabled
THEN RETURN[NOT clockEval AND p[Clock].l=L]
ELSE RETURN[p[Clock].l=L]
};
ClockH: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] RETURNS[BOOL] = {
IF ClockEvalEnabled
THEN RETURN[NOT clockEval AND p[Clock].l=H]
ELSE RETURN[p[Clock].l=H]
};
For signals going to flops triggered by Clock
CaptureL: PROC[p: Ports.Port, cs: CacheState] = BEGIN
FOR i: INT IN [0..numAddressBits) DO
cs.tmpRAdrsIn[i] ← p[RAdrsIn].ls[i]; cs.tmpVAdrsInOut[i] ← p[VAdrsInOut].ls[i];
ENDLOOP;
FOR i: INT IN [0..SCParms.numBitsPerCycle) DO
cs.tmpCycleIn[i] ← p[CycleIn].ls[i];
ENDLOOP;
FOR i: INT IN [0..SCParms.numCyclesPerLine) DO
cs.tmpBAREn[i] ← p[BAREn].ls[i];
ENDLOOP;
FOR i: INT IN [0..NumFlagsBits) DO
cs.tmpFlagsIn[i] ← p[FlagsIn].ls[i];
ENDLOOP;
cs.tmpRBCycle2 ← p[RBCycle2].l;
cs.tmpxWtRam ← p[xWtRam].l;
cs.tmpxRdRam ← p[xRdRam].l;
cs.tmpxLdVCamWR ← p[xLdVCamWR].l;
cs.tmpVPValidIn ← p[VPValidIn].l;
cs.tmpRPValidIn ← p[RPValidIn].l;
cs.tmpPWtInProg ← p[PWtInProg].l;
cs.tmpxDrRCamBL ← p[xDrRCamBL].l;
cs.tmpxLdRCamWR ← p[xLdRCamWR].l;
cs.tmpxDrVCamBL ← p[xDrVCamBL].l;
cs.tmpReset ← p[Reset].l
END;
For signals going to flops triggered by nClock
CaptureH: PROC[p: Ports.Port, cs: CacheState] = BEGIN
cs.tmpxEnCamSel ← p[xEnCamSel].l;
cs.tmpxEnCamSelExt ← p[xEnCamSelExt].l;
cs.tmpxLdVCamRL ← p[xLdVCamRL].l;
cs.tmpxLdRCamRL ← p[xLdRCamRL].l;
cs.tmpramRdorWt ← Ports.OrL[p[xRdRam].l, p[xWtRam].l];
END;
HandleState: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] = BEGIN
IF NOT ClockLToH[p, cs, clockEval] THEN RETURN;
SELECT cs.tmpReset FROM
H => cs.numCyclesAfterReset ← 0;
L => cs.numCyclesAfterReset ← cs.numCyclesAfterReset+1
ENDCASE;
Keep loading state 3 cycles after Reset L to prevent PCtlClrAllVPV from screwing us
IF cs.tmpReset=H OR (cs.tmpReset=L AND cs.numCyclesAfterReset <=3)
THEN LoadState[]
ELSE IF enableDumpState THEN {DumpState[]; TerminalIO.PutRope[cacheStateValueOut]}
END;
CSMux: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] = BEGIN
i: INT;
First the state changes
IF ClockHToL[p, cs, clockEval] THEN cs.csMuxSR ← cs.tmpxEnCamSel;
Then the combinatorial part
IF cs.csMuxSR = L THEN cs.csOut ← GND;
IF cs.csMuxSR = H THEN {
IF p[xCSCmd].ls[0] = H THEN i ← 2 ELSE i ← 0;
IF p[xCSCmd].ls[1] = H THEN i ← i + 1;
IF i = 0 THEN
cs.csOut ← GND
ELSE
IF i = 1 THEN
cs.csOut ← RML3
ELSE
IF i = 2 THEN
cs.csOut ← LVM
ELSE IF i = 3 THEN
cs.csOut ← Victim;
};
END;
RSMux: PROC[p: Ports.Port, cs: CacheState] = BEGIN
i: INT;
First the state change to the latch
IF p[nEnRS].l=H THEN {
FOR i IN [0..1] DO
cs.rsCmdLatch[i] ← p[xRSCmd].ls[i];
ENDLOOP;
};
Then the combinatorial part
IF cs.rsCmdLatch[0] = H THEN i ← 2 ELSE i ← 0;
IF cs.rsCmdLatch[1] = H THEN i ← i + 1;
IF i = 0 THEN {
cs.rsOut ← GND;
cs.iorsOut ← GND;
}
ELSE
IF i = 1 THEN {
cs.rsOut ← RML4;
cs.iorsOut ← RML4;
}
ELSE
IF i = 2 THEN {
cs.rsOut ← LVM;
cs.iorsOut ← LVM;
}
ELSE
IF i = 3 THEN {
cs.rsOut ← Victim;
cs.iorsOut ← GND;
};
END;
RML234: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] = BEGIN
On clock rising edge change the state for flops in the interface
IF ClockLToH[p, cs, clockEval] THEN {
cs.rBCycle[5] ← cs.rBCycle[4];
cs.rBCycle[4] ← cs.rBCycle[3];
cs.rBCycle[3] ← cs.tmpRBCycle2;
};
Note that the array latches are enabled only during half cycles where Clock is low
IF ClockL[p, cs, clockEval] THEN {
FOR i: NAT IN [0..numMemLines) DO
IF cs.rBCycle[5] = H THEN {
cs.match[RML4][i] ← cs.match[RML3][i];
};
IF cs.rBCycle[4] = H THEN {
cs.match[RML3][i] ← cs.match[RML2][i];
};
IF cs.rBCycle[3] = H THEN {
cs.match[RML2][i] ← cs.match[RML1][i];
};
ENDLOOP;
FOR i: NAT IN [0..NumIOLines) DO
IF cs.rBCycle[5] = H THEN {
cs.iomatch[RML4][i] ← cs.iomatch[RML3][i];
};
IF cs.rBCycle[4] = H THEN {
cs.iomatch[RML3][i] ← cs.iomatch[RML2][i];
};
IF cs.rBCycle[3] = H THEN {
cs.iomatch[RML2][i] ← cs.iomatch[RML1][i];
};
ENDLOOP;
};
END;
Victim: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] = BEGIN
DecMod: PROC[n: INT] RETURNS [INT] = BEGIN
RETURN[IF n=0 THEN numMemLines-1 ELSE n-1]
END;
On ClockLow, capture use and victim in tmp variables
IF ClockL[p, cs, clockEval] THEN {
FOR i: NAT IN [0..numMemLines) DO
cs.tmpUse[i] ← Ports.OrL[
Ports.AndL[Ports.AndL[Ports.NotL[cs.match[Victim][i]], cs.use[i]], Ports.NotL[p[Reset].l]],
Ports.OrL[
Ports.AndL[cs.match[LVM][i], p[xLdUse].l],
Ports.AndL[cs.match[Victim][i], p[PCtlShftVictim4].l]]
]
ENDLOOP;
IF p[PCtlFrzVictim].l = L THEN {
IF cs.use[cs.victimIndex] = H THEN cs.tmpVictimIndex ← DecMod[cs.victimIndex]
}
};
On Rising edge of clock change the state of the flops
IF ClockLToH[p, cs, clockEval] THEN {
cs.victimIndex ← cs.tmpVictimIndex;
FOR i: NAT IN [0..numMemLines) DO
cs.use[i] ← cs.tmpUse[i];
IF cs.tmpVictimIndex=i THEN cs.match[Victim][i] ← H ELSE cs.match[Victim][i] ← L
ENDLOOP;
};
On Reset we set victim to point to some location
IF p[Reset].l = H OR p[PCtlResetVictim].l = H THEN {
FOR i: NAT IN [0..numMemLines) DO
cs.match[Victim][i] ← L;
ENDLOOP;
cs.match[Victim][numMemLines-1] ← H;
cs.victimIndex ← cs.tmpVictimIndex ← numMemLines-1;
cs.aVct ← H;
};
END;
SOAndRam: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] = BEGIN
i, j, k,
RamIndex,  -- index of ramselect line that is high (if only one is high)
IORamIndex, -- index of ioramselect line that is high (if only one is high)
numH,  -- number of ramSelectOut lines high (total of ram and ioram)
numX: INT;  -- number of ramSelectOut lines that are x (total of ram and ioram)
prech: Level;
Do the computation for the PWtInProg path in SOInterface
IF ClockLToH[p, cs, clockEval] THEN cs.soSR[0] ← cs.tmpPWtInProg;
IF ClockHToL[p, cs, clockEval] THEN cs.soSR[1] ← cs.soSR[0];
IF cs.soSR[0] = H OR cs.soSR[1] = H THEN cs.pWtInProgB ← H ELSE cs.pWtInProgB ← L;
Load BAR if necessary
IF ClockLToH[p, cs, clockEval] THEN {
numEnablesHigh: NAT ← 0;
FOR c: NAT IN [0..SCParms.numCyclesPerLine) DO
IF cs.tmpBAREn[c] = H THEN {
IF (numEnablesHigh ← numEnablesHigh+1) > 1 THEN ERROR;
FOR i: NAT IN [0..SCParms.numBitsPerWord) DO
cs.bar[i*SCParms.numWordsPerLine+SCParms.numWordsPerCycle*c] ← cs.tmpCycleIn[i];
cs.bar[i*SCParms.numWordsPerLine+SCParms.numWordsPerCycle*c+1] ← cs.tmpCycleIn[SCParms.numBitsPerWord+i];
ENDLOOP;
}
ENDLOOP;
};
Compute the values of Sh and Ow bits in array (Ow computation is completed below)
FOR i IN [0..numMemLines) DO
IF cs.match[cs.rsOut][i]=H
THEN {
IF p[BCtlClrOw].l=H AND p[BCtlSetOw].l=H
THEN cs.ow[i] ← X
ELSE {
IF p[BCtlSetOw].l=H
THEN cs.ow[i] ← H
ELSE IF p[BCtlClrOw].l=H THEN cs.ow[i] ← L;
};
IF p[ClrSh].l=H AND p[SetSh].l=H
THEN cs.sh[i] ← X
ELSE {
IF p[SetSh].l=H
THEN cs.sh[i] ← H
ELSE IF p[ClrSh].l = H THEN cs.sh[i] ← L;
}
}
ELSE {
IF cs.match[cs.rsOut][i]=X THEN {
IF (p[BCtlSetOw].l=H AND cs.ow[i]#H) OR (p[BCtlClrOw].l=H AND cs.ow[i]#L) OR (p[BCtlClrOw].l=H AND p[BCtlSetOw].l=H)
THEN cs.ow[i] ← X;
IF (p[SetSh].l=H AND cs.sh[i]#H) OR (p[ClrSh].l=H AND cs.sh[i]#L) OR (p[ClrSh].l=H AND p[SetSh].l=H)
THEN cs.sh[i] ← X;
};
};
ENDLOOP;
Compute RamSelectOut, numH, numX and complete computation of Ow
numH ← 0; numX ← 0;
RamIndex ← -1; IORamIndex ← -1;
FOR i IN [0..numMemLines) DO
IF p[nEnRS].l=L AND ((cs.pWtInProgB=L) OR (cs.pWtInProgB=H AND cs.sh[i]=L))
THEN cs.match[RamSel][i] ← cs.match[cs.rsOut][i]
ELSE
IF p[nEnRS].l=L AND cs.pWtInProgB=H AND ((cs.match[cs.rsOut][i]=H AND cs.sh[i]=X) OR (cs.match[cs.rsOut][i]=X AND cs.sh[i]=X) OR (cs.match[cs.rsOut][i]=X AND cs.sh[i]=L))
THEN cs.match[RamSel][i] ← X
ELSE cs.match[RamSel][i] ← L;
IF cs.match[RamSel][i] = H
THEN {numH ← numH + 1; RamIndex ← i}
ELSE {IF cs.match[RamSel][i] = X THEN numX ← numX + 1};
IF p[nEnRS].l=L AND cs.pWtInProgB=H AND cs.match[cs.rsOut][i]=H
THEN {
IF cs.sh[i]=L
THEN {cs.ow[i] ← IF p[BCtlClrOw].l=L THEN H ELSE X}
ELSE
IF cs.sh[i]=X AND p[BCtlClrOw].l=H
THEN cs.ow[i] ← X
ELSE IF cs.sh[i]=X AND p[BCtlSetOw].l=L AND p[BCtlClrOw].l=L AND cs.ow[i]#H THEN cs.ow[i] ← X
}
ELSE {
IF p[nEnRS].l=L AND cs.pWtInProgB=H AND cs.match[cs.rsOut][i]=X THEN {
IF cs.sh[i]#H AND p[BCtlClrOw].l=H
THEN cs.ow[i] ← X
ELSE IF cs.sh[i]#H AND p[BCtlClrOw].l=L AND p[BCtlSetOw].l=L AND cs.ow[i]#H THEN cs.ow[i] ← X;
}
}
ENDLOOP;
Compute outputs of IOSharedOwnerCell's, and complete computation of numH and numX
IF p[nEnRS].l=H
THEN cs.iorsOut ← GND
ELSE FOR i IN [0..NumIOLines) DO
IF cs.iomatch[cs.iorsOut][i] = H
THEN {numH ← numH + 1; IORamIndex ← i}
ELSE {IF cs.iomatch[cs.iorsOut][i] = X THEN numX ← numX + 1};
ENDLOOP;
Sanity check on numH and numX
IF (numH > 1 OR numX > 0) AND cs.resetDone THEN ERROR;
Change the state of flops in RamInterfaceCtl triggered by Clock
IF ClockLToH[p, cs, clockEval] THEN {
cs.ramWtSR[0] ← cs.tmpxWtRam;
cs.ramRdSR[0] ← cs.tmpxRdRam;
};
Do a Ram Read/Write and change the state of flops in RamInterfaceCtl triggered by nClock
IF ClockHToL[p, cs, clockEval] THEN {
Handle reads
IF cs.ramRdSR[0] = H THEN {
IF RamIndex >= 0
THEN FOR i IN [0..SCParms.numBitsPerLine) DO
cs.ramRdLatch[i] ← cs.ram[RamIndex][i];
ENDLOOP
ELSE IORam[p, cs, IORamIndex];
};
Handle writes
IF cs.ramWtSR[0] = H THEN {
IF RamIndex >= 0
THEN {
IF p[nxSelWdData].l = H
THEN FOR i IN [0..SCParms.numBitsPerLine) DO
cs.ram[RamIndex][i] ← cs.bar[i];
ENDLOOP
ELSE {
j ← IndexOfSelectedWord[p];
FOR i IN [0..SCParms.numBitsPerWord) DO
k ← i/SCParms.numBitsPerByte;
IF p[nxByteSel].ls[k] = L THEN cs.ram[RamIndex][j] ← p[WdWtData].ls[i];
j← j+SCParms.numWordsPerLine;
ENDLOOP;
};
}
ELSE IORam[p, cs, IORamIndex];
};
cs.ramWtSR[1] ← cs.ramWtSR[0];
cs.ramRdSR[1] ← cs.ramRdSR[0];
cs.ramRdorWt ← cs.tmpramRdorWt
};
Assert the block and word values onto the ports from the RamRdLatch
Ports.CopyLS[cs.ramRdLatch, p[BlkRdData].ls];
IF p[nxSelWdData].l = L THEN {
adrs: NAT ← IndexOfSelectedWord[p];
FOR i: NAT IN [0..SCParms.numBitsPerWord) DO
p[WdRdData].ls[i] ← cs.ramRdLatch[adrs];
adrs ← adrs+SCParms.numWordsPerLine;
ENDLOOP
};
Compute SetReschedule
p[SetReschedule].l ← L;
numX ← 0;
FOR i IN [0..SCParms.numBitsPerWord) DO
IF cs.ioRam.intStatus[i]=H AND cs.ioRam.intMask[i]=H
THEN p[SetReschedule].l ← H
ELSE IF cs.ioRam.intStatus[i]#L AND cs.ioRam.intMask[i]#L THEN
numX ← numX+1;
ENDLOOP;
IF p[SetReschedule].l = L AND numX > 0 THEN p[SetReschedule].l ← X;
Compute composite values on lines going in to SOInterface from array and load SORdlatch
IF p[nEnRS].l = L THEN BEGIN
In numShAB, A is the value of the enable on the tristates, and B the value in storage
numShHH: INT ← 0;
numShHL: INT ← 0;
numShHX: INT ← 0;
numShXH: INT ← 0;
numShXL: INT ← 0;
numShXX: INT ← 0;
numOwHH: INT ← 0;
numOwHL: INT ← 0;
numOwHX: INT ← 0;
numOwXH: INT ← 0;
numOwXL: INT ← 0;
numOwXX: INT ← 0;
FOR i IN [0..numMemLines) DO
IF cs.match[cs.rsOut][i]=H
THEN {
IF cs.sh[i]=H
THEN numShHH ← numShHH+1
ELSE IF cs.sh[i] = L
THEN numShHL ← numShHL+1
ELSE numShHX ← numShHX+1;
IF cs.ow[i]=H
THEN numOwHH ← numOwHH + 1
ELSE IF cs.ow[i] = L
THEN numOwHL ← numOwHL+1
ELSE numOwHX ← numOwHX+1;
}
ELSE {
IF cs.match[cs.rsOut][i]=X
THEN {
IF cs.sh[i] = H
THEN numShXH ← numShXH+1
ELSE IF cs.sh[i]=L
THEN numShXL ← numShXL+1
ELSE numShXX ← numShXX+1;
IF cs.ow[i] = H
THEN numOwXH ← numOwXH+1
ELSE IF cs.ow[i] = L
THEN numOwXL ← numOwXL+1
ELSE numOwXX ← numOwXX+1;
}
}
ENDLOOP;
FOR i IN [0..NumIOLines) DO
IF cs.iomatch[cs.iorsOut][i] = H
THEN numOwHH ← numOwHH + 1
ELSE IF cs.iomatch[cs.iorsOut][i] = X THEN numOwXH ← numOwXH + 1;
ENDLOOP;
IF numShHH+numShHL+numShHX+numShXH+numShXL+numShXX = 0
THEN cs.shBit ← L
ELSE IF numShHH>0 AND numShHL+numShXL+numShXX+numShHX = 0
THEN cs.shBit ← H
ELSE IF numShHL>0 AND numShHH+numShHX+numShXX+numShXH = 0
THEN cs.shBit ← L
ELSE cs.shBit ← X;
IF numOwHH+numOwHL+numOwHX+numOwXH+numOwXL+numOwXX = 0
THEN cs.owBit ← L
ELSE IF numOwHH>0 AND numOwHL+numOwXL+numOwXX+numOwHX = 0
THEN cs.owBit ← H
ELSE IF numOwHL>0 AND numOwHH+numOwHX+numOwXX+numOwXH = 0
THEN cs.owBit ← L
ELSE cs.owBit ← X;
END;
Assert Modes onto its port
FOR i: NAT IN [0..SCParms.numBitsPerWord) DO p[Modes].ls[i] ← cs.ioRam.modes[i] ENDLOOP;
Assert shared and owner onto their ports
p[ASh].l ← cs.shBit; p[AOw].l ← cs.owBit;
Assert RamClock onto its port
prech ← Ports.AndL[cs.ramRdorWt, Ports.OrL[p[xRdRam].l, p[xWtRam].l]];
p[RamClock].l ← Ports.AndL[p[nEnRS].l, prech];
Clear shared and owner latches in interface
IF p[Reset].l = H THEN {cs.shBit ← L; cs.owBit ← L};
END;
IORam: PROC[p: Ports.Port, cs: CacheState, ioRamIndex: INT] = BEGIN
j, k, l: INT;
j ← IndexOfSelectedWord[p]; l ← j;
Handle Read
IF cs.ramRdSR[0] = H THEN {
FOR k IN [0..SCParms.numBitsPerLine) DO
cs.ramRdLatch[k] ← L;-- precharge value
ENDLOOP;
IF p[nxSelWdData].l = L THEN {
IF ioRamIndex = 0 AND j = 1 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.cWSOld[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 0 AND j = 3 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.cWSNew[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 1 AND j = 1 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.aID[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 1 AND j = 3 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.faultCode[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 1 AND j = 5 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.intStatus[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 1 AND j = 7 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.intMask[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 4 AND j = 5 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.modes[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 5 AND j = 1 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.lFCode1[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 5 AND j = 3 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.lFCode3[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 5 AND j = 5 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.lFCode5[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP
ELSE
IF ioRamIndex = 5 AND j = 7 THEN FOR k IN [0..SCParms.numBitsPerWord) DO
cs.ramRdLatch[j] ← cs.ioRam.lFCode7[k]; j ← j+SCParms.numWordsPerLine;
ENDLOOP;
};
};
Handle Write
IF cs.ramWtSR[0] = H THEN {
IF p[nxSelWdData].l = L THEN {
IF ioRamIndex = 0 AND j = 1 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
l ← k/SCParms.numBitsPerByte;
IF p[nxByteSel].ls[l] = L THEN
cs.ioRam.cWSOld[k] ← p[WdWtData].ls[k];
ENDLOOP
ELSE
IF ioRamIndex = 0 AND j = 3 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
l ← k/SCParms.numBitsPerByte;
IF p[nxByteSel].ls[l] = L THEN
cs.ioRam.cWSNew[k] ← p[WdWtData].ls[k];
ENDLOOP
ELSE
IF ioRamIndex = 1 AND j = 1 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
l ← k/SCParms.numBitsPerByte;
IF p[nxByteSel].ls[l] = L THEN
cs.ioRam.aID[k] ← p[WdWtData].ls[k];
ENDLOOP
ELSE
IF ioRamIndex = 1 AND j = 3 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
l ← k/SCParms.numBitsPerByte;
IF p[nxByteSel].ls[l] = L THEN
cs.ioRam.faultCode[k] ← p[WdWtData].ls[k];
ENDLOOP
ELSE
IF ioRamIndex = 1 AND j = 5 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
l ← k/SCParms.numBitsPerByte;
IF p[nxByteSel].ls[l] = L THEN
cs.ioRam.intStatus[k] ← p[WdWtData].ls[k];
ENDLOOP
ELSE
IF ioRamIndex = 1 AND j = 7 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
l ← k/SCParms.numBitsPerByte;
IF p[nxByteSel].ls[l] = L THEN
cs.ioRam.intMask[k] ← p[WdWtData].ls[k];
ENDLOOP
ELSE
IF ioRamIndex = 4 AND j = 5 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
l ← k/SCParms.numBitsPerByte;
IF p[nxByteSel].ls[l] = L THEN
cs.ioRam.modes[k] ← p[WdWtData].ls[k];
ENDLOOP
ELSE
IF ioRamIndex = 2 AND j = 5 THEN
FOR k IN[0..SCParms.numBitsPerWord) DO
IF p[WdWtData].ls[k] = H THEN
cs.ioRam.intStatus[k] ← L
ELSE
IF p[WdWtData].ls[k] = X AND cs.ioRam.intStatus[k] # L THEN
cs.ioRam.intStatus[k] ← X;
ENDLOOP
ELSE
IF ioRamIndex = 3 AND j = 5 THEN
FOR k IN [0..SCParms.numBitsPerWord) DO
IF p[WdWtData].ls[k] = H THEN
cs.ioRam.intStatus[k] ← H
ELSE
IF p[WdWtData].ls[k] = X AND cs.ioRam.intStatus[k] # H THEN
cs.ioRam.intStatus[k] ← X;
ENDLOOP;
};
};
END;
IndexOfSelectedWord: PROC[p: Ports.Port] RETURNS[INT] = BEGIN
FOR i: INT IN [0..SCParms.numWordsPerLine) DO
IF p[nxWdSel].ls[i] = L THEN RETURN [i]
ENDLOOP;
RETURN [0]
END;
VCamRCamAndFlags: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] = BEGIN
i, j,
vCamIndex,  -- index of vCamSelect line that is high (if only one)
rCamIndex,  -- index of rCamSelect line that is high (if only one)
numX, numH: INT; -- number of rCamSelect lines that are X (H)
Check if either set of tristates on VCamInterface are on
CRdVCam: PROC[p: Ports.Port, cs: CacheState ] RETURNS [ b: BOOLEAN] = BEGIN
IF (p[PCtlDrABusVB].l = H OR p[PCtlDrABusVP].l = H) AND ((cs.vCamCSCmd1 = H AND cs.aVct = H) OR (cs.vCamCSCmd1 = L AND cs.avm = H)) THEN
b ← TRUE ELSE b ← FALSE
END;
Check if either set of tristates on RCamInterface are on
CRdRCam: PROC[p: Ports.Port, cs: CacheState ] RETURNS [ b: BOOLEAN] = BEGIN
IF (p[PCtlDrABusRB].l = H OR p[PCtlDrABusRP].l = H) AND ((cs.rCamCSCmd1 = H AND cs.aVct = H) OR (cs.rCamCSCmd1 = L AND cs.avm = H)) THEN
b ← TRUE ELSE b ← FALSE;
END;
Change the state of flops clocked by nClock in CamInterfaceCtl's
IF ClockHToL[p, cs, clockEval] THEN {
cs.enCamSelExtFF ← cs.tmpxEnCamSelExt;
cs.vCamLdFF ← cs.tmpxLdVCamRL;
cs.rCamLdFF ← cs.tmpxLdRCamRL;
};
Handle the effect of xEnCamSelExt
cs.vCamSel ← IF cs.enCamSelExtFF = H THEN cs.csOut ELSE GND;
Compute vCamIndex, rCamIndex, numX, and numH
vCamIndex ← -1; rCamIndex ← -1;
numX ← 0; numH ← 0;
FOR i IN [0..numMemLines) DO
IF cs.match[cs.csOut][i] = H
THEN {numH ← numH + 1; rCamIndex ← i}
ELSE IF cs.match[cs.csOut][i] = X THEN numX ← numX+1;
IF cs.match[cs.vCamSel][i] = H THEN vCamIndex ← i;
ENDLOOP;
IF numX > 0 AND cs.resetDone THEN ERROR;
IF numH > 1 AND cs.enCamSelExtFF = H AND cs.resetDone THEN ERROR;
Handle latch that holds CSCmd1
IF cs.vCamLdFF = H THEN cs.vCamCSCmd1 ← p[xCSCmd].ls[1];
IF cs.rCamLdFF = H THEN cs.rCamCSCmd1 ← p[xCSCmd].ls[1];
If vcam load latch signal is high and exactly one select line is high then read else precharge
IF cs.vCamLdFF = H THEN FOR j IN [0..numAddressBits) DO
cs.vCamRdLatch[j] ← IF vCamIndex >= 0 THEN cs.vCam[vCamIndex][j] ELSE H;
ENDLOOP;
If rcam load latch signal is high and exactly one select line is high then read else precharge
IF cs.rCamLdFF = H THEN {
FOR j IN [0..numAddressBits) DO
cs.rCamRdLatch[j] ← IF rCamIndex >= 0 THEN cs.rCam[rCamIndex][j] ELSE H;
ENDLOOP;
FOR j IN [0..NumFlagsBits) DO
cs.flagsRdLatch[j] ← IF rCamIndex >= 0 THEN cs.flags[rCamIndex][j] ELSE H;
ENDLOOP;
};
On rising edge of clock:
IF ClockLToH[p, cs, clockEval] THEN {
Change state of write flops in CamInterfaceCtl's
cs.vCamDrBLFF ← cs.tmpxDrVCamBL;
cs.rCamDrBLFF ← cs.tmpxDrRCamBL;
First load the write registers for vcam and rcam; note that valid bits are always enabled
IF cs.tmpxLdVCamWR = H THEN {
FOR i IN [0..numPageAndBlockBits) DO
cs.vCamWtReg[i] ← cs.tmpVAdrsInOut[i];
ENDLOOP;
FOR i IN [0..NumFlagsBits) DO
cs.flagsWtReg[i] ← cs.tmpFlagsIn[i];
ENDLOOP;
};
cs.vCamWtReg[numAddressBits-1] ← cs.tmpVPValidIn;
IF cs.tmpxLdRCamWR = H THEN {
FOR i IN [0..numPageAndBlockBits) DO
cs.rCamWtReg[i] ← cs.tmpRAdrsIn[i];
ENDLOOP;
};
cs.rCamWtReg[numAddressBits-1] ← cs.tmpRPValidIn;
};
Drive the bit lines and do a write or match, as appropriate
IF cs.vCamDrBLFF = H THEN {
IF cs.vCamLdFF = H THEN {
FOR j IN [0..numPageAndBlockBits) DO
cs.vCamRdLatch[j] ← cs.vCamWtReg[j];
ENDLOOP;
cs.vCamRdLatch[numAddressBits-1] ← cs.vCamWtReg[numAddressBits-1];
};
IF vCamIndex < 0
THEN ComputeMatch[p, cs, Virtual, clockEval]
ELSE {
FOR j IN [1..numPageAndBlockBits) DO
cs.vCam[vCamIndex][j] ← cs.vCamWtReg[j];
ENDLOOP;
cs.vCam[vCamIndex][numAddressBits-1] ← cs.vCamWtReg[numAddressBits-1];
FOR j IN [0..NumFlagsBits) DO
IF p[nPMFlags].ls[j] = H
THEN cs.flags[vCamIndex][j] ← cs.flagsWtReg[j]
ELSE cs.flags[vCamIndex][j] ← X; -- both lines are driven low so result is X
ENDLOOP;
};
};
IF cs.rCamDrBLFF = H THEN {
IF cs.rCamLdFF = H THEN {
FOR j IN [0..numPageAndBlockBits) DO
cs.rCamRdLatch[j] ← cs.rCamWtReg[j];
ENDLOOP;
cs.rCamRdLatch[numAddressBits-1] ← cs.rCamWtReg[numAddressBits-1];
};
IF rCamIndex < 0
THEN ComputeMatch[p, cs, Real, clockEval]
ELSE {
FOR j IN [1..numPageAndBlockBits) DO
cs.rCam[rCamIndex][j] ← cs.rCamWtReg[j];
ENDLOOP;
cs.rCam[rCamIndex][numAddressBits-1] ← cs.rCamWtReg[numAddressBits-1];
};
};
Assert avm and arm values onto port
p[AVM].l ← cs.avm; p[ARM3].l ← cs.arm;
If either block or page part VCamInterface tristates are on then output the appropriate one(s)
IF CRdVCam[p, cs]
THEN {
IF p[PCtlDrABusVP].l = H
THEN {
FOR i IN [0..numPageBits) DO
p[VAdrsInOut].ds[i] ← drive;
p[VAdrsInOut].ls[i] ← cs.vCamRdLatch[i];
ENDLOOP;
FOR i IN [numPageAndBlockBits..numAddressBits-1) DO
p[VAdrsInOut].ds[i] ← drive;
p[VAdrsInOut].ls[i] ← L;
ENDLOOP;
p[VAdrsInOut].ds[numAddressBits-1] ← drive;
p[VAdrsInOut].ls[numAddressBits-1] ← cs.vCamRdLatch[numAddressBits-1];
}
ELSE {
FOR i IN [0..numPageBits) DO
p[VAdrsInOut].ds[i] ← none;
ENDLOOP;
FOR i IN [numPageAndBlockBits..numAddressBits) DO
p[VAdrsInOut].ds[i] ← none;
ENDLOOP;
};
IF p[PCtlDrABusVB].l = H
THEN FOR i IN [numPageBits..numPageAndBlockBits) DO
p[VAdrsInOut].ds[i] ← drive;
p[VAdrsInOut].ls[i] ← cs.vCamRdLatch[i] ;
ENDLOOP
ELSE FOR i IN [numPageBits..numPageAndBlockBits) DO
p[VAdrsInOut].ds[i] ← none;
ENDLOOP;
}
ELSE FOR i: NAT IN [0..numAddressBits) DO
p[VAdrsInOut].ds[i] ← none;
ENDLOOP;
If either block or page RCamInterface part tristates are on then output the appropriate one(s)
IF CRdRCam[p, cs]
THEN {
IF p[PCtlDrABusRP].l = H
THEN {
FOR i: NAT IN [0..numPageBits) DO
p[RAdrsOut].ds[i] ← drive;
p[RAdrsOut].ls[i] ← cs.rCamRdLatch[i];
ENDLOOP;
FOR i: NAT IN [0..NumFlagsBits) DO
p[FlagsOut].ds[i] ← drive;
p[FlagsOut].ls[i] ← cs.flagsRdLatch[i];
ENDLOOP;
}
ELSE {
FOR i: NAT IN [0..numPageBits) DO p[RAdrsOut].ds[i] ← none; ENDLOOP;
FOR i: NAT IN [0..NumFlagsBits) DO p[FlagsOut].ds[i] ← none; ENDLOOP;
};
IF p[PCtlDrABusRB].l = H
THEN {
FOR i: NAT IN [numPageBits..numAddressBits) DO
p[RAdrsOut].ds[i] ← drive;
p[RAdrsOut].ls[i] ← cs.rCamRdLatch[i];
ENDLOOP;
FOR i: NAT IN [numPageAndBlockBits..numAddressBits-1) DO
p[RAdrsOut].ds[i] ← drive;
p[RAdrsOut].ls[i] ← L;
ENDLOOP;
}
ELSE {
FOR i: NAT IN [numPageBits..numAddressBits) DO
p[RAdrsOut].ds[i] ← none;
ENDLOOP;
};
}
ELSE FOR i: NAT IN [0..numAddressBits) DO
p[RAdrsOut].ds[i] ← none;
ENDLOOP;
Handle ClrVPV
IF p[ClrVPV].l = H THEN {
FOR i IN [0..numMemLines) DO
IF cs.match[RML1][i] = H THEN cs.vCam[i][numAddressBits - 1] ← L;
ENDLOOP;
};
Handle PCtlClrAllVPV
IF p[PCtlClrAllVPV].l = H THEN {
FOR i IN [0..numMemLines) DO
cs.vCam[i][numAddressBits-1] ← L;
ENDLOOP;
};
Handle Reset
IF p[Reset].l = H THEN {
FOR i IN [0..numMemLines) DO
cs.rCam[i][numAddressBits-1] ← L;
cs.match[LVM][i] ← L;
cs.match[RML1][i] ← L;
ENDLOOP;
FOR i IN [0..NumIOLines) DO
cs.iomatch[LVM][i] ← L;
cs.iomatch[RML1][i] ← L;
ENDLOOP;
cs.avm ← L; cs.arm ← L;
};
END;

ComputeMatch: PROC[p: Ports.Port, cs: CacheState, matchType: KindOfMatch, clockEval: BOOL] = BEGIN
i, j,
XCount, -- number of bit positions in a line that compute X for their match contribution
finish: INT; -- gives index of bit position up to which a match is done (handles part match)
existsMatchL, existsMatchH, existsMatchX: BOOLEAN;
Equal: PROC[a, b: Level] RETURNS [c: BOOLEAN] = BEGIN
IF (a = H AND b = H) OR (a = L AND b = L) THEN c ← TRUE ELSE c ← FALSE;
END;
UnEqual: PROC[a, b: Level] RETURNS [c: BOOLEAN] = BEGIN
IF (a = H AND b = L) OR (a = L AND b = H) THEN c ← TRUE ELSE c ← FALSE;
END;
existsMatchX ← FALSE; existsMatchL ← FALSE; existsMatchH ← FALSE;
IF matchType=Virtual AND p[LdVML].l=H THEN {
cs.avm ← L;
IF p[nPartVMch].l = L
THEN finish ← numPageBits-1
ELSE finish ← numPageAndBlockBits-1;
{FOR i IN [0..numMemLines) DO
cs.match[LVM][i] ← H;
XCount ← 0;
j ← 0;
WHILE j <= finish AND cs.match[LVM][i] = H DO
IF UnEqual[cs.vCamWtReg[j], cs.vCam[i][j]] THEN cs.match[LVM][i] ← L;
IF cs.vCamWtReg[j] = X OR cs.vCam[i][j] = X THEN XCount ← XCount + 1;
j ← j + 1;
ENDLOOP;
IF Equal[cs.vCamWtReg[numAddressBits-1], cs.vCam[i][numAddressBits-1]] THEN
cs.match[LVM][i] ← L;
IF cs.vCamWtReg[numAddressBits-1] = X OR cs.vCam[i][numAddressBits-1] = X THEN
XCount ← XCount + 1;
IF cs.match[LVM][i] = H THEN {
FOR j IN [0..NumFlagsBits) DO
IF p[nPMFlags].ls[j] = H AND UnEqual[cs.flagsWtReg[j], cs.flags[i][j]] THEN
cs.match[LVM][i] ← L;
IF cs.flags[i][j] = X OR cs.flagsWtReg[j] = X THEN
XCount ← XCount + 1;
ENDLOOP;
};
IF cs.match[LVM][i] = H AND XCount > 0 THEN cs.match[LVM][i] ← X;
IF cs.match[LVM][i] = H
THEN existsMatchH ← TRUE
ELSE IF cs.match[LVM][i] = L
THEN existsMatchL ← TRUE
ELSE existsMatchX ← TRUE;
ENDLOOP;
IF existsMatchH
THEN cs.avm ← H
ELSE IF existsMatchX THEN cs.avm ← X;
IF cs.avm = H
THEN FOR i IN [0..NumIOLines) DO
cs.iomatch[LVM][i] ← L;
ENDLOOP
ELSE {
FOR i IN [0..NumIOLines) DO
cs.iomatch[LVM][i] ← H;
XCount ← 0;
j ← 0;
WHILE j <= finish AND cs.iomatch[LVM][i] = H DO
IF UnEqual[cs.vCamWtReg[j], cs.ioVCam[i][j]] THEN cs.iomatch[LVM][i] ← L;
IF cs.vCamWtReg[j] = X OR cs.ioVCam[i][j] = X THEN XCount ← XCount + 1; j ← j + 1;
ENDLOOP;
IF Equal[cs.vCamWtReg[numAddressBits-1], cs.ioVCam[i][numAddressBits-1]] THEN
cs.iomatch[LVM][i] ← L;
IF cs.vCamWtReg[numAddressBits-1] = X OR cs.ioVCam[i][numAddressBits-1] = X THEN
XCount ← XCount + 1;
IF cs.iomatch[LVM][i] = H THEN {
FOR j IN [0..NumFlagsBits) DO
IF p[nPMFlags].ls[j] = H AND UnEqual[cs.flagsWtReg[j], cs.ioFlags[i][j]] THEN
cs.iomatch[LVM][i] ← L;
IF cs.ioFlags[i][j] = X OR cs.flagsWtReg[j] = X THEN XCount ← XCount + 1;
ENDLOOP;
};
IF cs.iomatch[LVM][i] = H AND XCount > 0 THEN cs.iomatch[LVM][i] ← X;
IF cs.iomatch[LVM][i] = H
THEN existsMatchH ← TRUE
ELSE IF cs.iomatch[LVM][i] = L
THEN existsMatchL ← TRUE
ELSE existsMatchX ← TRUE;
ENDLOOP;
IF existsMatchH
THEN cs.avm ← H
ELSE IF existsMatchX THEN cs.avm ← X;
};
};
};
IF matchType=Real AND p[RBCycle2].l=H AND ClockL[p, cs, clockEval] THEN {
cs.arm ← L;
IF p[nxPartRMch].l = L
THEN finish ← numPageBits-1
ELSE finish ← numPageAndBlockBits-1;
{FOR i IN [0..numMemLines) DO
cs.match[RML1][i] ← H;
XCount ← 0;
j ← 0;
WHILE j <= finish AND cs.match[RML1][i] = H DO
IF UnEqual[cs.rCamWtReg[j], cs.rCam[i][j]] THEN cs.match[RML1][i] ← L;
IF cs.rCamWtReg[j] = X OR cs.rCam[i][j] = X THEN XCount ← XCount + 1; j ← j + 1;
ENDLOOP;
IF Equal[cs.rCamWtReg[numAddressBits-1], cs.rCam[i][numAddressBits-1]] THEN
cs.match[RML1][i] ← L;
IF cs.rCamWtReg[numAddressBits-1] = X OR cs.rCam[i][numAddressBits-1] = X THEN
XCount ← XCount + 1;
IF cs.match[RML1][i] = H AND XCount > 0 THEN cs.match[RML1][i] ← X;
IF cs.match[RML1][i] = H
THEN existsMatchH ← TRUE
ELSE IF cs.match[RML1][i] = L
THEN existsMatchL ← TRUE
ELSE existsMatchX ← TRUE;
ENDLOOP;
IF existsMatchH
THEN cs.arm ← H
ELSE IF existsMatchX THEN cs.arm ← X;
IF cs.arm = H
THEN FOR i IN [0..NumIOLines) DO
cs.iomatch[RML1][i] ← L;
ENDLOOP
ELSE {
FOR i IN [0..NumIOLines) DO
cs.iomatch[RML1][i] ← H;
XCount ← 0;
j ← 0;
WHILE j <= numPageBits-SCParms.numDevIdBits-1 AND cs.iomatch[RML1][i] = H DO
IF UnEqual[cs.rCamWtReg[j], cs.ioRCam[i][j]] THEN cs.iomatch[RML1][i] ← L;
IF cs.rCamWtReg[j] = X OR cs.ioRCam[i][j] = X THEN
XCount ← XCount + 1;
j ← j + 1;
ENDLOOP;
IF p[nxPartRMch].l = H THEN {
j ← numPageBits;
WHILE j <= numPageAndBlockBits-1 AND cs.iomatch[RML1][i] = H DO
IF UnEqual[cs.rCamWtReg[j], cs.ioRCam[i][j]] THEN cs.iomatch[RML1][i] ← L;
IF cs.rCamWtReg[j] = X OR cs.ioRCam[i][j] = X THEN
XCount ← XCount + 1;
j ← j + 1;
ENDLOOP;
};
IF Equal[cs.rCamWtReg[numAddressBits-1], cs.ioRCam[i][numAddressBits-1]] THEN
cs.iomatch[RML1][i] ← L;
IF cs.rCamWtReg[numAddressBits-1] = X OR cs.ioRCam[i][numAddressBits-1] = X THEN XCount ← XCount + 1;
IF cs.iomatch[RML1][i] = H AND XCount > 0 THEN cs.iomatch[RML1][i] ← X;
IF cs.iomatch[RML1][i] = H
THEN existsMatchH ← TRUE
ELSE IF cs.iomatch[RML1][i] = L
THEN existsMatchL ← TRUE
ELSE existsMatchX ← TRUE;
ENDLOOP;
IF existsMatchH
THEN cs.arm ← H
ELSE IF existsMatchX THEN cs.arm ← X;
};
};
};
END;
END.