<> <> <> <> <<>> DIRECTORY Core, CoreClasses, CoreCreate, CoreFlat, CoreOps, Ports, Rosemary, RosemaryUser, Rope, SCLogic, SCParms; <<>> SCArrayImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreFlat, CoreOps, Ports, Rosemary, Rope, SCParms EXPORTS SCLogic ~ BEGIN OPEN SCLogic; <> ClockEvalEnabled: BOOL = TRUE; MySCName: ROPE = Rosemary.Register[roseClassName: "SCArray", init: Init, evalSimple: Simple, scheduleIfClockEval: ClockEvalEnabled]; NumMemLines: NAT = 2*SCParms.numMemLines; NumIOLines: NAT = 2*3; NumBytesPerWord: NAT = SCParms.numBytesPerWord; NumBitsPerByte: NAT = SCParms.numBitsPerByte; NumBitsPerWord: NAT = SCParms.numBitsPerWord; NumWordsPerLine: NAT = SCParms.numWordsPerLine; NumBitsPerLine: NAT = SCParms.numBitsPerLine; LogNumWordsPerLine: NAT = SCParms.logNumWordsPerLine; NumAddressBits: NAT = NumBitsPerWord+1; --Includes IO/Mem Bit-- NumPageBits: NAT = SCParms.numPageBits+1; --Includes IO/Mem Bit-- NumBlockBits: NAT = SCParms.numBlockBits; NumPageAndBlockBits: NAT = NumPageBits+NumBlockBits; NumDevIdBits: NAT = SCParms.numDevIdBits; 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 = ["111", "001", "001", "001", "001", "001"]; <> Match: TYPE = REF MatchRec; MatchRec: TYPE = RECORD [ ARRAY Index OF LevelSequence ]; IOMatch: TYPE = REF IOMatchRec; IOMatchRec: TYPE = RECORD [ ARRAY Index[LRM..GND] OF LevelSequence ]; Array: TYPE = REF ArrayRec; ArrayRec: TYPE = RECORD [ SEQUENCE size: NAT OF LevelSequence ]; Flags: TYPE = REF FlagsRec; FlagsRec: TYPE = RECORD [ SEQUENCE size: NAT OF ARRAY [0..2] OF Level ]; KindOfMatch: TYPE = {Virtual, Real}; Index: TYPE = {Victim, RamSel, LRM, 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[LRM..GND] OF ARRAY [0..NumIOLines) OF Level, csMuxSR: ARRAY [0..1] OF Level, -- two flops in CSMuxInterface rsCmdLatch : ARRAY[0..1] OF Level, -- latch in RSMuxInterface csOut, rsOut, iorsOut: Index, -- to implement csmux, rsmux, iorsmux bCycle: ARRAY [3..5] OF Level, -- delay stages in RML234 lduse: Level, -- ldUse in VictimInterface victimIndex: INT, -- line pointed to by victim use: LevelSequence _ NIL, -- use bits in array 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 ldSORdLatch: Level, -- input to SOInterface ramWtSR, ramRdSR: ARRAY [0..1] OF Level, -- 2 flops each in RamInterfaceCtl ramrd, ramwt: Level, -- 2 flops to generate ramClock ramRdLatch: LevelSequence _ NIL, -- ramRdLatch in RamInterface ram: Array _ NIL, -- ram bits ioRam: RECORD [cWSOld, cWSNew, aID, faultCode, intStatus, intMask, modes, lFCode1, lFCode3, lFCode5, lFCode7: LevelSequence _ NIL], -- ioram bits pRamClock, ramClock: Level, -- previous and current ramClocks wdAdrs: LevelSequence _ NIL, -- input to RamInterfaceCtl byteSel: LevelSequence _ NIL, -- input to RamInterfaceCtl wdSel: Level, -- input to RamInterfaceCtl vCamCSCmd1, rCamCSCmd1: Level, -- latches in RCam and VCam Interfaces rCam, vCam: Array _ 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: Flags _ NIL, -- flags array ioFlags: ARRAY [0..NumIOLines) OF ARRAY [0..2] OF Level, -- ioflags array rCamRdLatch, rCamWtReg, vCamRdLatch, vCamWtReg: LevelSequence, flagsRdLatch, flagsWtReg: ARRAY [0..2] OF Level, vCamPartMch, rCamPartMch: Level, -- flops to delay PartMch vCamRdSR, vCamWtSR, rCamRdSR, rCamWtSR: ARRAY [0..2] OF Level, -- flops in CamInterfaceCtl; odd indeces correspond to flops clocked by nClock, even to those clocked by Clock vCamSel: Index, -- source of input for vcam select line aVct: Level, -- arrayVictim deMapRply1: Level, -- flop in VCamInterface resetDone: BOOLEAN, -- used to suppress error due to X's before Reset has been done <> tmpRAdrsIn, tmpVAdrsInOut: LevelSequence _ NIL, tmpFlagsIn: ARRAY [0..2] OF Level, tmpxEnCamSel, tmpBCycle2, tmpxWtRam, tmpxRdRam, tmpxWtMchVCam, tmpxRdVCam, tmpxRdRCam, tmpVPValidIn, tmpRPValidIn, tmpxPartRMch, tmpPCtlPartVMch, tmpPWtInProg, tmpxDrRCamBL, tmpDeMapRply1, tmpxLdRCamWR: Level ]; <> Reset, PCtlDrABusVB, PCtlDrABusVP, PCtlPartVMch, xRdVCam, xWtMchVCam, DeMapRply1, VAdrsInOut, VPValidIn, PCtlDrABusRB, PCtlDrABusRP, xRdRCam, xPartRMch, xDrRCamBL, xLdRCamWR, xEnCamSelExt, BCycle2, RAdrsIn, RPValidIn, FlagsIn, nPMFlags, xEnCamSel, PCtlShftVictim4, PCtlFrzVictim, xCSCmd, nEnRS, xRSCmd, PWtInProg, BCtlSetOw, BCtlClrOw, SetSh, ClrSh, xRdRam, xWtRam, xSelWdData, xByteSel, xWdAdrs,WdWtData, BlkWtData, RAdrsOut, FlagsOut, BlkRdData, WdRdData, SetReschedule, ASh, AOw, ARM, AVM, Clock, nClock: NAT; <> SCArray: PUBLIC PROC [] RETURNS [ct: CellType] = BEGIN public: Wire _ CoreCreate.WireList[LIST[ "Reset", "PCtlDrABusVB", "PCtlDrABusVP", "PCtlPartVMch", "xRdVCam", "xWtMchVCam", "DeMapRply1", CoreCreate.Seq["VAdrsInOut", NumAddressBits], "VPValidIn", "PCtlDrABusRB", "PCtlDrABusRP", "xRdRCam", "xPartRMch", "xDrRCamBL", "xLdRCamWR", "xEnCamSelExt", "BCycle2", CoreCreate.Seq["RAdrsIn", NumAddressBits], "RPValidIn", CoreCreate.Seq["FlagsIn",3], CoreCreate.Seq["nPMFlags", 3], "xEnCamSel", "PCtlShftVictim4", "PCtlFrzVictim", CoreCreate.Seq["xCSCmd", 2], "nEnRS", CoreCreate.Seq["xRSCmd",2], "PWtInProg", "BCtlSetOw", "BCtlClrOw", "SetSh", "ClrSh", "xRdRam", "xWtRam", "xSelWdData", CoreCreate.Seq["xByteSel", NumBytesPerWord], CoreCreate.Seq["xWdAdrs", LogNumWordsPerLine], CoreCreate.Seq["WdWtData", NumBitsPerWord], CoreCreate.Seq["BlkWtData", NumBitsPerLine], CoreCreate.Seq["RAdrsOut", NumAddressBits], CoreCreate.Seq["FlagsOut", 3], CoreCreate.Seq["BlkRdData", NumBitsPerLine], CoreCreate.Seq["WdRdData", NumBitsPerWord], "SetReschedule", "ASh", "AOw", "ARM", "AVM", "Clock", "nClock"]]; ct _ CoreClasses.CreateUnspecified[public: public]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: MySCName]; [] _ 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, "FlagsIn"]; Ports.InitPorts[ct, ls, none, "nPMFlags"]; Ports.InitPorts[ct, ls, none, "xCSCmd"]; Ports.InitPorts[ct, ls, none, "xRSCmd"]; Ports.InitPorts[ct, ls, none, "xByteSel"]; Ports.InitPorts[ct, ls, none, "xWdAdrs"]; Ports.InitPorts[ct, ls, none, "WdWtData"]; Ports.InitPorts[ct, ls, none, "BlkWtData"]; [] _ Ports.InitPort[public[CoreOps.GetWireIndex[public, "FlagsOut"]], ls, separate, none, NEW [Ports.DriveSequenceRec[3]]]; Ports.InitPorts[ct, ls, drive, "BlkRdData"]; Ports.InitPorts[ct, ls, drive, "WdRdData"]; Ports.InitPorts[ct, l, none, "Reset", "PCtlDrABusVB", "PCtlDrABusVP", "PCtlPartVMch", "xRdVCam", "xWtMchVCam", "DeMapRply1"]; Ports.InitPorts[ct, l, none, "Clock", "nClock", "VPValidIn", "PCtlDrABusRB", "PCtlDrABusRP", "xRdRCam", "xPartRMch", "xDrRCamBL", "xLdRCamWR", "xEnCamSelExt", "BCycle2"]; Ports.InitPorts[ct, l, none, "xEnCamSel", "PCtlShftVictim4", "PCtlFrzVictim", "nEnRS"]; Ports.InitPorts[ct, l, none, "PWtInProg", "BCtlSetOw", "BCtlClrOw", "SetSh", "ClrSh", "xRdRam", "xWtRam", "xSelWdData", "RPValidIn"]; Ports.InitPorts[ct, l, drive, "SetReschedule", "ASh", "AOw", "ARM", "AVM"] END; <> Init: Rosemary.InitProc = BEGIN i, j: INT; k: Index; cs: CacheState; <> 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.sh _ NEW [LevelSequenceRec[NumMemLines]]; cs.ow _ NEW [LevelSequenceRec[NumMemLines]]; cs.ramRdLatch _ NEW [LevelSequenceRec[NumBitsPerLine]]; cs.ram _ NEW [ArrayRec[NumMemLines]]; FOR i: NAT IN [0..NumMemLines) DO cs.ram[i] _ NEW [LevelSequenceRec[NumBitsPerLine]]; ENDLOOP; cs.ioRam.cWSOld _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.cWSNew _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.aID _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.faultCode _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.intStatus _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.intMask _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.modes _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.lFCode1 _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.lFCode3 _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.lFCode5 _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.ioRam.lFCode7 _ NEW [LevelSequenceRec[NumBitsPerWord]]; cs.wdAdrs _ NEW [LevelSequenceRec[LogNumWordsPerLine]]; cs.byteSel _ NEW [LevelSequenceRec[NumBytesPerWord]]; cs.rCam _ NEW [ArrayRec[NumMemLines]]; FOR i: NAT IN [0..NumMemLines) DO cs.rCam[i] _ NEW [LevelSequenceRec[NumAddressBits]]; ENDLOOP; cs.vCam _ NEW [ArrayRec[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 [FlagsRec[NumMemLines]]; 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.tmpVAdrsInOut _ NEW [LevelSequenceRec[NumAddressBits]]; } ELSE cs _ NARROW[oldStateAny, CacheState]; cs.prevClk _ X; cs.lduse _ X; cs.vCamCSCmd1 _ X; cs.rCamCSCmd1 _ X; cs.aVct _ X; cs.vCamPartMch _ X; cs.rCamPartMch _ X; cs.wdSel _ X; cs.pRamClock _ X; cs.ramClock _ X; cs.ramrd _ X; cs.ramwt _ X; cs.pWtInProgB _ X; cs.ldSORdLatch _ X; cs.deMapRply1 _ 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..2] DO cs.flagsRdLatch[i] _ X; cs.flagsWtReg[i] _ X; ENDLOOP; FOR i IN [0..NumBitsPerLine) DO cs.ramRdLatch[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+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..2] DO cs.flags[i][j] _ X; ENDLOOP; FOR j IN [0..NumBitsPerLine) DO cs.ram[i][j] _ X; ENDLOOP; cs.use[i] _ X; cs.sh[i] _ X; cs.ow[i] _ X; FOR k IN [Victim..RML4] DO cs.match[k][i] _ X; ENDLOOP; cs.match[GND][i] _ L; ENDLOOP; cs.shBit _ X; cs.owBit _ X; FOR i IN [0..1] DO cs.csMuxSR[i] _ X; cs.rsCmdLatch[i] _ X; cs.ramWtSR[i] _ X; cs.ramRdSR[i] _ X; cs.soSR[i] _ X; ENDLOOP; FOR i IN [3..5] DO cs.bCycle[i] _ X; ENDLOOP; FOR i IN [0..NumBytesPerWord) DO cs.byteSel[i] _ X; ENDLOOP; FOR i IN [0..LogNumWordsPerLine) DO cs.wdAdrs[i] _ X; ENDLOOP; FOR i IN [0..2] DO cs.vCamRdSR[i] _ X; cs.vCamWtSR[i] _ X; cs.rCamRdSR[i] _ X; cs.rCamWtSR[i] _ X; ENDLOOP; cs.tmpxEnCamSel _ X; FOR i IN [0..NumAddressBits) DO cs.tmpRAdrsIn[i] _ X; cs.tmpVAdrsInOut[i] _ X; ENDLOOP; FOR i IN [0..2] DO cs.tmpFlagsIn[i] _ X; ENDLOOP; cs.tmpBCycle2 _ X; cs.tmpxWtRam _ X; cs.tmpxRdRam _ X; cs.tmpxWtMchVCam _ X; cs.tmpxRdVCam _ p[xRdVCam].l; cs.tmpxRdRCam _ X; cs.tmpVPValidIn _ X; cs.tmpRPValidIn _ X; cs.tmpxPartRMch _ X; cs.tmpPCtlPartVMch _ X; cs.tmpPWtInProg _ X; cs.tmpxDrRCamBL _ X; cs.tmpxLdRCamWR _ X; cs.tmpDeMapRply1 _ X; FOR i IN [0..NumIOLines) DO FOR j IN [NumPageAndBlockBits..NumPageAndBlockBits+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..2] 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..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 IN [LRM..RML4] DO cs.iomatch[k][i] _ X; ENDLOOP; cs.iomatch[GND][i] _ L; ENDLOOP; cs.resetDone _ FALSE; [Reset, PCtlDrABusVB, PCtlDrABusVP, PCtlPartVMch, xRdVCam, xWtMchVCam, DeMapRply1, VAdrsInOut, VPValidIn] _ Ports.PortIndexes[cellType.public, "Reset", "PCtlDrABusVB", "PCtlDrABusVP", "PCtlPartVMch", "xRdVCam", "xWtMchVCam", "DeMapRply1", "VAdrsInOut", "VPValidIn"]; [PCtlDrABusRB, PCtlDrABusRP, xRdRCam, xPartRMch, xDrRCamBL, xLdRCamWR, xEnCamSelExt, BCycle2, RAdrsIn, FlagsIn] _ Ports.PortIndexes[cellType.public, "PCtlDrABusRB", "PCtlDrABusRP", "xRdRCam", "xPartRMch", "xDrRCamBL", "xLdRCamWR", "xEnCamSelExt", "BCycle2", "RAdrsIn", "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, xSelWdData, xByteSel, xWdAdrs,WdWtData, BlkWtData, RAdrsOut] _ Ports.PortIndexes[cellType.public, "SetSh", "ClrSh", "xRdRam", "xWtRam", "xSelWdData", "xByteSel", "xWdAdrs", "WdWtData", "BlkWtData", "RAdrsOut"]; [FlagsOut, BlkRdData, WdRdData, SetReschedule, ASh, AOw] _ Ports.PortIndexes[cellType.public, "FlagsOut", "BlkRdData", "WdRdData", "SetReschedule", "ASh", "AOw"]; [ARM, AVM, Clock, nClock, RPValidIn] _ Ports.PortIndexes[cellType.public, "ARM", "AVM", "Clock", "nClock", "RPValidIn"]; stateAny _ cs; END; Simple: Rosemary.EvalProc = BEGIN cs: CacheState _ NARROW[stateAny]; IF p[Reset].l = H THEN cs.resetDone _ TRUE; IF ClockL[p, cs, clockEval] THEN Capture[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]; 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] }; Capture: PROC[p: Ports.Port, cs: CacheState] = BEGIN i: INT; cs.tmpxEnCamSel _ p[xEnCamSel].l; FOR i IN [0..NumAddressBits) DO cs.tmpRAdrsIn[i] _ p[RAdrsIn].ls[i]; cs.tmpVAdrsInOut[i] _ p[VAdrsInOut].ls[i]; ENDLOOP; FOR i IN [0..2] DO cs.tmpFlagsIn[i] _ p[FlagsIn].ls[i]; ENDLOOP; cs.tmpBCycle2 _ p[BCycle2].l; cs.tmpxWtRam _ p[xWtRam].l; cs.tmpxRdRam _ p[xRdRam].l; cs.tmpxWtMchVCam _ p[xWtMchVCam].l; cs.tmpxRdVCam _ p[xRdVCam].l; cs.tmpxRdRCam _ p[xRdRCam].l; cs.tmpVPValidIn _ p[VPValidIn].l; cs.tmpRPValidIn _ p[RPValidIn].l; cs.tmpxPartRMch _ p[xPartRMch].l; cs.tmpPCtlPartVMch _ p[PCtlPartVMch].l; cs.tmpPWtInProg _ p[PWtInProg].l; cs.tmpxDrRCamBL _ p[xDrRCamBL].l; cs.tmpxLdRCamWR _ p[xLdRCamWR].l; cs.tmpDeMapRply1 _ p[DeMapRply1].l; END; CSMux: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] = BEGIN i: INT; <> IF ClockLToH[p, cs, clockEval] THEN cs.csMuxSR[0] _ cs.tmpxEnCamSel; IF ClockHToL[p, cs, clockEval] THEN cs.csMuxSR[1] _ cs.csMuxSR[0]; <> IF cs.csMuxSR[1] = L THEN cs.csOut _ GND; IF cs.csMuxSR[1] = 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; <> IF p[nEnRS].l=H THEN { FOR i IN [0..1] DO cs.rsCmdLatch[i] _ p[xRSCmd].ls[i]; ENDLOOP; }; <> 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 <> IF ClockLToH[p, cs, clockEval] THEN { cs.bCycle[5] _ cs.bCycle[4]; cs.bCycle[4] _ cs.bCycle[3]; cs.bCycle[3] _ cs.tmpBCycle2; }; <> IF ClockL[p, cs, clockEval] THEN { IF cs.bCycle[3] = H THEN { cs.match[RML2] _ cs.match[LRM]; cs.iomatch[RML2] _ cs.iomatch[LRM]; }; IF cs.bCycle[4] = H THEN { cs.match[RML3] _ cs.match[RML2]; cs.iomatch[RML3] _ cs.iomatch[RML2]; }; IF cs.bCycle[5] = H THEN { cs.match[RML4] _ cs.match[RML3]; cs.iomatch[RML4] _ cs.iomatch[RML3]; }; }; END; Victim: PROC[p: Ports.Port, cs: CacheState, clockEval: BOOL] = BEGIN i: INT; DecMod: PROC[n: INT] RETURNS [INT] = BEGIN RETURN[IF n=0 THEN NumMemLines-1 ELSE n-1] END; <> IF ClockLToH[p, cs, clockEval] THEN { IF p[PCtlFrzVictim].l = H THEN cs.use[cs.victimIndex] _ L; IF p[PCtlShftVictim4].l = H THEN { IF cs.use[cs.victimIndex] = H THEN { cs.match[Victim][cs.victimIndex] _ L; cs.victimIndex _ DecMod[cs.victimIndex]; cs.match[Victim][cs.victimIndex] _ H } ELSE cs.use[cs.victimIndex] _ H; } ELSE { IF cs.use[cs.victimIndex] = H THEN { cs.use[cs.victimIndex] _ L; cs.match[Victim][cs.victimIndex] _ L; cs.victimIndex _ DecMod[cs.victimIndex]; cs.match[Victim][cs.victimIndex] _ H; }; }; IF cs.lduse = H THEN { FOR i IN [0..NumMemLines) DO IF cs.match[LVM][i] = H THEN cs.use[i] _ H ; ENDLOOP; }; IF cs.tmpxEnCamSel = L AND cs.tmpxWtMchVCam = H AND cs.tmpPCtlPartVMch = L THEN cs.lduse _ H ELSE cs.lduse _ L; }; <> IF p[Reset].l = H THEN { FOR i IN [0..NumMemLines) DO cs.use[i] _ L; cs.match[Victim][i] _ L; ENDLOOP; cs.match[Victim][NumMemLines-1] _ H; cs.victimIndex _ 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) <> 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; <> 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; <> 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; <> 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; <> IF (numH > 1 OR numX > 0) AND cs.resetDone THEN ERROR; <> IF ClockLToH[p, cs, clockEval] THEN { cs.ramWtSR[0] _ cs.tmpxWtRam; cs.ramRdSR[0] _ cs.tmpxRdRam; }; <> IF ClockHToL[p, cs, clockEval] THEN { <> IF cs.ramRdSR[0] = H THEN { IF RamIndex >= 0 THEN FOR i IN [0..NumBitsPerLine) DO cs.ramRdLatch[i] _ cs.ram[RamIndex][i]; ENDLOOP ELSE IORam[p, cs, IORamIndex]; }; <> IF cs.ramWtSR[0] = H THEN { IF RamIndex >= 0 THEN { IF cs.wdSel = L THEN FOR i IN [0..NumBitsPerLine) DO cs.ram[RamIndex][i] _ p[BlkWtData].ls[i]; ENDLOOP ELSE { j _ DecodeAdrs[cs]; FOR i IN [0..NumBitsPerWord) DO k _ i/NumBitsPerByte; IF cs.byteSel[k] = H THEN cs.ram[RamIndex][j] _ p[WdWtData].ls[i]; j_ j+NumBitsPerWord; ENDLOOP; }; } ELSE IORam[p, cs, IORamIndex]; }; cs.ramWtSR[1] _ cs.ramWtSR[0]; cs.ramRdSR[1] _ cs.ramRdSR[0]; cs.ramrd _ cs.tmpxRdRam; cs.ramwt _ cs.tmpxWtRam; }; <> cs.pRamClock _ cs.ramClock; <<>> <> IF ((cs.ramrd=H AND cs.tmpxRdRam=H) OR (cs.ramwt=H AND cs.tmpxWtRam=H)) AND p[nEnRS].l=H THEN cs.ramClock _ H ELSE cs.ramClock _ L; <> IF cs.pRamClock = L AND cs.ramClock = H THEN { FOR i IN [0..NumBytesPerWord) DO cs.byteSel[i] _ p[xByteSel].ls[i]; ENDLOOP; FOR i IN [0..LogNumWordsPerLine) DO cs.wdAdrs[i] _ p[xWdAdrs].ls[i]; ENDLOOP; cs.wdSel _ p[xSelWdData].l }; <> Ports.CopyLS[cs.ramRdLatch, p[BlkRdData].ls]; IF cs.wdSel = H THEN { adrs: NAT _ DecodeAdrs[cs]; FOR i: NAT IN [0..NumBitsPerWord) DO p[WdRdData].ls[i] _ cs.ramRdLatch[adrs]; adrs _ adrs+NumBitsPerWord; ENDLOOP }; <> p[SetReschedule].l _ L; numX _ 0; FOR i IN [0..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; <> IF cs.ramWtSR[0] = H OR cs.ramWtSR[1] = H OR cs.ramRdSR[0] = H OR cs.ramRdSR[1] = H THEN cs.ldSORdLatch _ H ELSE cs.ldSORdLatch _ L; <> IF cs.ldSORdLatch = H THEN BEGIN <> 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; <> p[ASh].l _ cs.shBit; p[AOw].l _ cs.owBit; <> 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 _ DecodeAdrs[cs]; l _ j; <<>> <> IF cs.ramRdSR[0] = H THEN { FOR k IN [0..NumBitsPerLine) DO cs.ramRdLatch[k] _ H; -- Precharge value ENDLOOP; IF cs.wdSel = H THEN { IF ioRamIndex = 0 AND j = 1 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.cWSOld[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 0 AND j = 3 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.cWSNew[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 1 AND j = 1 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.aID[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 1 AND j = 3 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.faultCode[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 1 AND j = 5 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.intStatus[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 1 AND j = 7 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.intMask[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 4 AND j = 5 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.modes[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 5 AND j = 1 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.lFCode1[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 5 AND j = 3 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.lFCode3[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 5 AND j = 5 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.lFCode5[k]; j _ j+NumBitsPerWord; ENDLOOP ELSE IF ioRamIndex = 5 AND j = 7 THEN FOR k IN [0..NumBitsPerWord) DO cs.ramRdLatch[j] _ cs.ioRam.lFCode7[k]; j _ j+NumBitsPerWord; ENDLOOP; }; }; <<>> <> IF cs.ramWtSR[0] = H THEN { IF cs.wdSel = H THEN { IF ioRamIndex = 0 AND j = 1 THEN FOR k IN [0..NumBitsPerWord) DO l _ k/NumBitsPerByte; IF cs.byteSel[l] = H THEN cs.ioRam.cWSOld[k] _ p[WdWtData].ls[k]; ENDLOOP ELSE IF ioRamIndex = 0 AND j = 3 THEN FOR k IN [0..NumBitsPerWord) DO l _ k/NumBitsPerByte; IF cs.byteSel[l] = H THEN cs.ioRam.cWSNew[k] _ p[WdWtData].ls[k]; ENDLOOP ELSE IF ioRamIndex = 1 AND j = 1 THEN FOR k IN [0..NumBitsPerWord) DO l _ k/NumBitsPerByte; IF cs.byteSel[l] = H THEN cs.ioRam.aID[k] _ p[WdWtData].ls[k]; ENDLOOP ELSE IF ioRamIndex = 1 AND j = 3 THEN FOR k IN [0..NumBitsPerWord) DO l _ k/NumBitsPerByte; IF cs.byteSel[l] = H THEN cs.ioRam.faultCode[k] _ p[WdWtData].ls[k]; ENDLOOP ELSE IF ioRamIndex = 1 AND j = 5 THEN FOR k IN [0..NumBitsPerWord) DO l _ k/NumBitsPerByte; IF cs.byteSel[l] = H THEN cs.ioRam.intStatus[k] _ p[WdWtData].ls[k]; ENDLOOP ELSE IF ioRamIndex = 1 AND j = 7 THEN FOR k IN [0..NumBitsPerWord) DO l _ k/NumBitsPerByte; IF cs.byteSel[l] = H THEN cs.ioRam.intMask[k] _ p[WdWtData].ls[k]; ENDLOOP ELSE IF ioRamIndex = 4 AND j = 5 THEN FOR k IN [0..NumBitsPerWord) DO l _ k/NumBitsPerByte; IF cs.byteSel[l] = H THEN cs.ioRam.modes[k] _ p[WdWtData].ls[k]; ENDLOOP ELSE IF ioRamIndex = 2 AND j = 5 THEN FOR k IN[0..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..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; DecodeAdrs: PROC[cs: CacheState] RETURNS[i: INT] = BEGIN k: INT _ NumWordsPerLine; i _ 0; FOR j: INT IN [0..LogNumWordsPerLine) DO k _ k/2; IF cs.wdAdrs[j] = H THEN i _ i + k; ENDLOOP; 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) <> 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; <> 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; <> cs.vCamSel _ IF p[xEnCamSelExt].l = H THEN cs.csOut ELSE GND; <> 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 p[xEnCamSelExt].l = H AND cs.resetDone THEN ERROR; <> IF ClockHToL[p, cs, clockEval] THEN { cs.vCamRdSR[1] _ cs.vCamRdSR[0]; cs.rCamRdSR[1] _ cs.rCamRdSR[0]; }; <> IF cs.vCamRdSR[1] = H THEN cs.vCamCSCmd1 _ p[xCSCmd].ls[1]; IF cs.rCamRdSR[1] = H THEN cs.rCamCSCmd1 _ p[xCSCmd].ls[1]; <> IF ClockLToH[p, cs, clockEval] THEN { <> cs.vCamRdSR[2] _ cs.vCamRdSR[1]; cs.vCamRdSR[0] _ cs.tmpxRdVCam; cs.rCamRdSR[2] _ cs.rCamRdSR[1]; cs.rCamRdSR[0] _ cs.tmpxRdRCam; cs.deMapRply1 _ cs.tmpDeMapRply1; <> IF cs.vCamRdSR[0] = H AND cs.vCamRdSR[2] = H THEN FOR j IN [0..NumAddressBits) DO cs.vCamRdLatch[j] _ IF vCamIndex >= 0 THEN cs.vCam[vCamIndex][j] ELSE H; ENDLOOP; IF cs.rCamRdSR[0] = H AND cs.rCamRdSR[2] = 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..2] DO cs.flagsRdLatch[j] _ IF rCamIndex >= 0 THEN cs.flags[rCamIndex][j] ELSE H; ENDLOOP; }; <> cs.vCamWtSR[2] _ cs.vCamWtSR[0]; cs.rCamWtSR[2] _ cs.rCamWtSR[0]; cs.vCamWtSR[0] _ cs.tmpxWtMchVCam; cs.rCamWtSR[0] _ cs.tmpxDrRCamBL; <> IF cs.tmpxWtMchVCam = H THEN { FOR i IN [0..NumPageAndBlockBits) DO cs.vCamWtReg[i] _ cs.tmpVAdrsInOut[i]; ENDLOOP; cs.vCamWtReg[NumAddressBits-1] _ cs.tmpVPValidIn; FOR i IN [0..2] DO cs.flagsWtReg[i] _ cs.tmpFlagsIn[i]; ENDLOOP; }; IF cs.tmpxLdRCamWR = H THEN { FOR i IN [0..NumPageAndBlockBits) DO cs.rCamWtReg[i] _ cs.tmpRAdrsIn[i]; ENDLOOP; cs.rCamWtReg[NumAddressBits-1] _ cs.tmpRPValidIn; }; <<>> <> IF cs.vCamWtSR[2] = H THEN { IF cs.vCamRdSR[2] = H THEN { FOR j IN [0..NumPageAndBlockBits) DO cs.vCamRdLatch[j] _ cs.vCamWtReg[j]; ENDLOOP; cs.vCamRdLatch[NumAddressBits-1] _ cs.tmpVPValidIn; }; IF vCamIndex < 0 THEN ComputeMatch[p, cs, Virtual] ELSE { FOR j IN [1..NumPageAndBlockBits) DO cs.vCam[vCamIndex][j] _ cs.vCamWtReg[j]; ENDLOOP; cs.vCam[vCamIndex][NumAddressBits-1] _ cs.tmpVPValidIn; FOR j IN [0..2] DO IF p[nPMFlags].ls[j] = H THEN cs.flags[vCamIndex][j] _ cs.flagsWtReg[j] ELSE cs.flags[vCamIndex][j] _ L; ENDLOOP; }; }; IF cs.rCamWtSR[2] = H THEN { IF cs.rCamRdSR[2] = H THEN { FOR j IN [0..NumPageAndBlockBits) DO cs.rCamRdLatch[j] _ cs.rCamWtReg[j]; ENDLOOP; cs.rCamRdLatch[NumAddressBits-1] _ cs.tmpRPValidIn; }; IF rCamIndex < 0 THEN ComputeMatch[p, cs, Real] ELSE { FOR j IN [1..NumPageAndBlockBits) DO cs.rCam[rCamIndex][j] _ cs.rCamWtReg[j]; ENDLOOP; cs.rCam[rCamIndex][NumAddressBits-1] _ cs.tmpRPValidIn; }; }; cs.vCamPartMch _ cs.tmpPCtlPartVMch; cs.rCamPartMch _ cs.tmpxPartRMch; }; <> p[AVM].l _ cs.avm; p[ARM].l _ cs.arm; <> 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; } ELSE { FOR i IN [0..NumPageBits) DO p[VAdrsInOut].ds[i] _ none; ENDLOOP; FOR i IN [NumPageAndBlockBits..NumAddressBits-1) 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 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..2] 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..2] 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; <> IF cs.deMapRply1 = H OR p[DeMapRply1].l = H THEN { FOR i IN [0..NumMemLines) DO IF cs.match[LRM][i] = H THEN cs.vCam[i][NumAddressBits - 1] _ L; ENDLOOP; }; IF p[Reset].l = H THEN { FOR i IN [0..NumMemLines) DO cs.vCam[i][NumAddressBits-1] _ L; cs.rCam[i][NumAddressBits-1] _ L; cs.match[LVM][i] _ L; cs.match[LRM][i] _ L; ENDLOOP; FOR i IN [0..NumIOLines) DO cs.iomatch[LVM][i] _ L; cs.iomatch[LRM][i] _ L; ENDLOOP; cs.avm _ L; cs.arm _ L; }; END; ComputeMatch: PROC[p: Ports.Port, cs: CacheState, matchType: KindOfMatch] = 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 THEN { cs.avm _ L; IF cs.vCamPartMch = H 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.vCamPartMch = L AND cs.match[LVM][i] = H THEN { FOR j IN [0..2] 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.vCamPartMch = L AND cs.iomatch[LVM][i] = H THEN { FOR j IN [0..2] 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 cs.bCycle[3]=H THEN { cs.arm _ L; IF cs.rCamPartMch = H THEN finish _ NumPageBits-1 ELSE finish _ NumPageAndBlockBits-1; {FOR i IN [0..NumMemLines) DO cs.match[LRM][i] _ H; XCount _ 0; j _ 0; WHILE j <= finish AND cs.match[LRM][i] = H DO IF UnEqual[cs.rCamWtReg[j], cs.rCam[i][j]] THEN cs.match[LRM][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[LRM][i] _ L; IF cs.rCamWtReg[NumAddressBits-1] = X OR cs.rCam[i][NumAddressBits-1] = X THEN XCount _ XCount + 1; IF cs.match[LRM][i] = H AND XCount > 0 THEN cs.match[LRM][i] _ X; IF cs.match[LRM][i] = H THEN existsMatchH _ TRUE ELSE IF cs.match[LRM][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[LRM][i] _ L; ENDLOOP ELSE { FOR i IN [0..NumIOLines) DO cs.iomatch[LRM][i] _ H; XCount _ 0; j _ 0; WHILE j <= NumPageBits-NumDevIdBits-1 AND cs.iomatch[LRM][i] = H DO IF UnEqual[cs.rCamWtReg[j], cs.ioRCam[i][j]] THEN cs.iomatch[LRM][i] _ L; IF cs.rCamWtReg[j] = X OR cs.ioRCam[i][j] = X THEN XCount _ XCount + 1; j _ j + 1; ENDLOOP; IF cs.rCamPartMch = L THEN { j _ NumPageBits; WHILE j <= NumPageAndBlockBits-1 AND cs.iomatch[LRM][i] = H DO IF UnEqual[cs.rCamWtReg[j], cs.ioRCam[i][j]] THEN cs.iomatch[LRM][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[LRM][i] _ L; IF cs.rCamWtReg[NumAddressBits-1] = X OR cs.ioRCam[i][NumAddressBits-1] = X THEN XCount _ XCount + 1; IF cs.iomatch[LRM][i] = H AND XCount > 0 THEN cs.iomatch[LRM][i] _ X; IF cs.iomatch[LRM][i] = H THEN existsMatchH _ TRUE ELSE IF cs.iomatch[LRM][i] = L THEN existsMatchL _ TRUE ELSE existsMatchX _ TRUE; ENDLOOP; IF existsMatchH THEN cs.arm _ H ELSE IF existsMatchX THEN cs.arm _ X; }; }; }; END; END. <<>>