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; 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"]; 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 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 ]; enableDumpState: BOOL _ FALSE; cacheStateRef: CacheState _ NIL; cacheStateValueIn, cacheStateValueOut: ROPE _ NIL; 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; 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; ArrayGetState: PUBLIC PROC[] RETURNS[csv: ROPE] = BEGIN DumpState[]; csv _ cacheStateValueOut END; ArrayPutState: PUBLIC PROC[csv: ROPE] = BEGIN cacheStateValueIn _ csv; END; 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; 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: ROPE _ NIL] = 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: ROPE _ NIL] = 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; 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] }; 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; 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; 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; IF ClockHToL[p, cs, clockEval] THEN cs.csMuxSR _ cs.tmpxEnCamSel; 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; 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.rBCycle[5] _ cs.rBCycle[4]; cs.rBCycle[4] _ cs.rBCycle[3]; cs.rBCycle[3] _ cs.tmpRBCycle2; }; 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; 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] } }; 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; }; 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; 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; 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; }; 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..SCParms.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 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 }; 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 }; 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; IF p[nEnRS].l = L 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; FOR i: NAT IN [0..SCParms.numBitsPerWord) DO p[Modes].ls[i] _ cs.ioRam.modes[i] ENDLOOP; p[ASh].l _ cs.shBit; p[AOw].l _ cs.owBit; prech _ Ports.AndL[cs.ramRdorWt, Ports.OrL[p[xRdRam].l, p[xWtRam].l]]; p[RamClock].l _ Ports.AndL[p[nEnRS].l, prech]; 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; 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; }; }; 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) 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; IF ClockHToL[p, cs, clockEval] THEN { cs.enCamSelExtFF _ cs.tmpxEnCamSelExt; cs.vCamLdFF _ cs.tmpxLdVCamRL; cs.rCamLdFF _ cs.tmpxLdRCamRL; }; cs.vCamSel _ IF cs.enCamSelExtFF = 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 cs.enCamSelExtFF = H AND cs.resetDone THEN ERROR; IF cs.vCamLdFF = H THEN cs.vCamCSCmd1 _ p[xCSCmd].ls[1]; IF cs.rCamLdFF = H THEN cs.rCamCSCmd1 _ p[xCSCmd].ls[1]; 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 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; }; IF ClockLToH[p, cs, clockEval] THEN { cs.vCamDrBLFF _ cs.tmpxDrVCamBL; cs.rCamDrBLFF _ cs.tmpxDrRCamBL; 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; }; 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]; }; }; p[AVM].l _ cs.avm; p[ARM3].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; 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 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; 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; }; IF p[PCtlClrAllVPV].l = H THEN { FOR i IN [0..numMemLines) DO cs.vCam[i][numAddressBits-1] _ L; ENDLOOP; }; 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. ���<��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 Constants and Type Defs Two-D array containing Victim, RamSel, RML1, LVM, RML2, RML3, RML4, and GND The following are used to capture input signals that go to flops Signal Defs Public Procs Retrieves cacheStateValueOut Sets cacheStateValueIn Internal Procs Copies cache state from cacheStateValueIn to simulation Copies cache state from simulation to cacheStateValueOut Create the state if it doesn't already exist For signals going to flops triggered by Clock For signals going to flops triggered by nClock Keep loading state 3 cycles after Reset L to prevent PCtlClrAllVPV from screwing us First the state changes Then the combinatorial part First the state change to the latch Then the combinatorial part On clock rising edge change the state for flops in the interface Note that the array latches are enabled only during half cycles where Clock is low On ClockLow, capture use and victim in tmp variables On Rising edge of clock change the state of the flops On Reset we set victim to point to some location Do the computation for the PWtInProg path in SOInterface Load BAR if necessary Compute the values of Sh and Ow bits in array (Ow computation is completed below) Compute RamSelectOut, numH, numX and complete computation of Ow Compute outputs of IOSharedOwnerCell's, and complete computation of numH and numX Sanity check on numH and numX Change the state of flops in RamInterfaceCtl triggered by Clock Do a Ram Read/Write and change the state of flops in RamInterfaceCtl triggered by nClock Handle reads Handle writes Assert the block and word values onto the ports from the RamRdLatch Compute SetReschedule Compute composite values on lines going in to SOInterface from array and load SORdlatch In numShAB, A is the value of the enable on the tristates, and B the value in storage Assert Modes onto its port Assert shared and owner onto their ports Assert RamClock onto its port Clear shared and owner latches in interface Handle Read Handle Write Check if either set of tristates on VCamInterface are on Check if either set of tristates on RCamInterface are on Change the state of flops clocked by nClock in CamInterfaceCtl's Handle the effect of xEnCamSelExt Compute vCamIndex, rCamIndex, numX, and numH Handle latch that holds CSCmd1 If vcam load latch signal is high and exactly one select line is high then read else precharge If rcam load latch signal is high and exactly one select line is high then read else precharge On rising edge of clock: Change state of write flops in CamInterfaceCtl's First load the write registers for vcam and rcam; note that valid bits are always enabled Drive the bit lines and do a write or match, as appropriate Assert avm and arm values onto port If either block or page part VCamInterface tristates are on then output the appropriate one(s) If either block or page RCamInterface part tristates are on then output the appropriate one(s) Handle ClrVPV Handle PCtlClrAllVPV Handle Reset �Ê=1��˜�šœ™IcodešÏnœ3™:K™2K™+K™�—šÏk ˜ Kšœ˜—J™�KšÑblnœžœž˜"Kšžœt˜{Kšžœ˜Kšœžœžœ˜headšÏl™Kšœžœžœ˜Kšœžœ~˜”K˜�Kšœžœ˜Kšœžœ˜K˜�Kšœ žœ˜)KšœžœÏc˜IKšœ žœ¡˜CKšœžœ$˜<šœžœžœžœ˜2Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ6˜6Kšœ˜—šœžœžœžœ˜1Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ6˜6Kšœ˜—Kšœ žœžœžœ4˜bK˜�Kšœ'žœžœžœžœžœž™KKšœžœžœ ˜šœ žœžœ˜Kšžœžœ˜K˜—K˜�Kšœ žœžœ˜šœžœžœ˜Kšžœžœžœžœ˜'K˜—K˜�Kšœžœžœ˜#šœžœžœ˜Kšžœžœžœ˜#K˜—K˜�Kšœ žœ˜$Kšœžœžœžœžœžœžœžœ˜BKšœžœžœ˜%šœžœžœ˜Kšœ˜Kšœžœ¡(˜>Kš œ žœžœžœžœžœžœ˜BKšœ¡˜+Kšœ žœžœ ¡˜>Kšœ¡%˜DKšœ žœžœ ¡˜;Kšœ¡˜6Kšœ žœ¡˜0Kšœžœ¡˜3Kšœžœ¡˜/Kšœžœ¡˜7Kšœžœžœ ¡˜<Kšœžœ¡˜5Kšœ¡˜5Kšœ¡˜-Kšœžœžœ¡"˜KKšœ¡˜-Kšœžœ¡˜?Kšœžœ¡˜5Kšœžœ¡˜#Kšœžœqžœ¡ ˜‘Kšœ ¡&˜FKšœžœ¡˜3Kšœ¡˜+Kšœžœžœ¡˜QKšœžœ¡˜(Kš œ žœžœžœžœ¡˜TKšœ>˜>Kšœžœžœ ˜=Kšœ!¡˜5Kšœžœ ¡a˜}Kšœ¡'˜9Kšœ¡˜Kšœžœ¡?˜UK˜�Kšœ@™@Kšœ+žœ˜/Kšœžœ˜ Kšœžœ˜Kšœžœžœ˜-Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœž˜Kšœ˜—K˜�—š ™Kšœžœžœ˜Kšœžœ˜ Kšœ'žœžœ˜2Kšœêžœ˜ï—š ™š Ÿœžœžœ"žœž˜RKšœ#žœ¶ ˜Ý K˜�šžœž˜Kšœžœ˜3˜Kšœ4˜4KšœJ˜JKšœ-˜-K˜�Kšœ\žœ,˜‹Kšœ)˜)KšœZžœ,˜‰Kšœ'˜'Kšœ)˜)Kšœ*˜*Kšœ(˜(Kšœ(˜(Kšœ+˜+Kšœ)˜)Kšœ*˜*Kšœ)˜)Kšœ'˜'KšœZžœ*˜‡Kšœ(˜(Kšœ,˜,Kšœ+˜+K˜�Kšœq˜qKšœ—˜—Kšœ¤˜¤KšœW˜WKšœ†˜†Kšœ*˜*KšœK˜KK˜—Kšœ4˜4Kšžœžœ˜—Kšžœ˜—K™�K™šŸ œžœžœžœžœž˜7K˜K˜Kšžœ˜—K™�K™š Ÿ œžœžœžœž˜-K˜Kšžœ˜——š ™K™7šŸ œžœž˜Kšœ˜Kšœžœ˜Kšœžœ˜š œžœžœžœ ž˜4Kšžœžœžœ˜%šžœž˜ Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšžœžœ˜—Kšžœ˜—K˜�šœžœžœž˜4Kšœžœ˜šžœžœžœž˜Kšœ9˜9šžœž˜%Kšœ˜Kšœ˜Kšœ˜Kšžœ˜—K˜Kšžœ˜—Kšžœ˜—K˜�š œžœžœž˜:Jšœžœ˜šžœžœžœž˜0šžœžœžœž˜0Jšœ9˜9šžœž˜%Kšœ4˜4Kšœ4˜4Kšœ4˜4Kšžœ˜—K˜Jšžœ˜—Jšžœ˜—Kšžœ˜—K˜�š œžœžœžœž˜&JšœT˜TJšœJ˜JJšœZ˜ZJšœ˜Jšžœ˜J˜�—š œžœžœžœž˜(JšœM˜MJšœJ˜JJšžœA˜EJšœ˜Jšžœ˜—J˜�Jšžœžœžœžœ˜%Jšœ.˜.šžœžœžœž˜!J˜Jšžœ˜—Jšœ%˜%J˜�šžœž˜Jšœ žœ˜Kšœ$˜$Kšœ$˜$Kšœ%˜%Kšœ$˜$Kšœ$˜$Kšœ%˜%Kšœ&˜&Kšžœ˜—Kšžœ˜—K˜�K™8šŸ œžœž˜Kšœ˜K˜�š œžœžœžœž˜.šžœž˜ Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšžœžœ˜—Kšžœ˜—K˜�šœžœžœžœžœž˜CKš žœžœžœžœ%žœ˜JKšžœ˜—K˜�š œžœžœžœž˜@Jšœ%˜%Jš žœžœžœžœ%žœ˜NJšœ˜Jš žœžœžœ$žœ%žœ˜`Jšœ˜Jš žœžœžœ'žœ%žœ˜cKšžœ˜—K˜�šœžœžœžœžœž˜Gšžœžœžœž˜0šžœžœžœž˜0JšœF˜FJšžœ˜—Jšžœ žœ˜>Jšžœ˜—Kšžœ˜—K˜�Kšžœžœžœžœ˜KšœW˜Wšžœžœžœž˜!KšœV˜VKšœV˜VKšœV˜VKšœV˜VKšœO˜OKšœO˜OKšœQ˜QKšœU˜UK˜8Kšžœ˜—K˜8Kšžœ˜—K˜�šŸœž˜Kšœžœ˜ Kšœ˜K˜�K™,šžœ ž˜šžœ˜Kšœžœ˜Kšœžœ˜šžœ žœž˜Kšœžœ ˜1Kšžœ˜—Kšœ žœ!˜-Kšœžœ!˜0Kšœžœ!˜,Kšœžœ!˜,Kšœžœ,˜?Kšœ žœ,˜8Kšœ žœ˜)šžœžœžœž˜!Kšœžœ,˜;Kšžœ˜—Kšœžœ,˜AKšœžœ,˜AKšœžœ,˜>Kšœžœ,˜DKšœžœ,˜DKšœžœ,˜BKšœžœ,˜@Kšœžœ,˜BKšœžœ,˜BKšœžœ,˜BKšœžœ,˜BKšœ žœ˜*šžœžœžœž˜!Kšœ žœ$˜4Kšžœ˜—Kšœ žœ˜*šžœžœžœž˜!Kšœ žœ$˜4Kšžœ˜—K˜šžœžœžœž˜ Kšœžœ$˜6Kšžœ˜—šžœžœžœž˜ Kšœžœ$˜6Kšžœ˜—Kšœžœ˜+šžœžœžœž˜!Kšœžœ"˜3Kšžœ˜—Kšœžœ$˜8Kšœžœ$˜6Kšœžœ$˜8Kšœžœ$˜6K˜�Kšœžœ$˜7Kšœžœ-˜@Kšœžœ.˜?Kšœžœ$˜:K˜—Kšžœžœ˜*—K˜�Kšœg˜gK˜�šžœžœžœ˜ K˜WKšžœ˜—šžœžœžœ˜Kšœ-˜-Kšžœ˜—šžœžœžœ˜(Kšœ˜Kšœ˜Kšžœ˜—šžœžœž˜Kšœ4˜4Kšœ4˜4šžœžœIž˜SKšœ%˜%Kšžœ˜—šžœžœžœ˜%K˜%Kšžœ˜—šžœžœž˜K˜Kšžœ˜—šžœžœžœ˜(Kšœ˜Kšžœ˜—K˜<šžœ žœ žœžœ˜"K˜Kšžœ˜—Kšœ žœ ˜Kšžœ˜—K˜Kšœ˜šžœžœžœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœ˜—šžœžœžœ˜K˜Kšžœ˜—Kšœ%˜%Kšœ"˜"Kšœ,˜,šžœžœžœ˜ Kšœ/˜/Kšžœ˜ —šžœžœžœ˜)Kšœ˜Kšžœ˜ —šžœžœžœ˜*Kšœ˜Kšžœ˜ —šžœžœžœ˜Kšœ˜Kšžœ˜ —KšœÅžœžœ˜Ïšžœžœžœ˜šžœžœIž˜SK˜+Kšžœ˜—Kšœ$˜$Kšœ#˜#Kšžœ˜—šžœžœž˜šžœžœžœ˜Kšœžœ$žœžœ˜HKšžœ˜—šžœžœž˜$Kšœžœ#žœžœ˜FKšœžœ#žœžœ˜FKšžœ˜—Kšžœ˜—šžœžœžœ˜)Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœ˜—šžœžœž˜š žœ žœžœžœž˜K˜Kšžœ˜—Kšœžœ ˜Kšžœ˜—Kšœžœ˜K˜�Kšœ¼˜¼KšœÐ˜ÐKšœ¸˜¸K˜�Kšœ”˜”K˜�Kšœ’˜’K˜�Kšœ¢˜¢K˜�KšœP˜PK˜�K˜Kšžœ˜K˜�—K˜�šŸœž˜!Kšœžœ˜"K˜Kšžœžœžœ˜+Kšžœžœ˜1Kšžœžœ˜1Kšœ˜Kšœ ˜ Kšžœ˜Kšœ˜Kšœ#˜#Kšœ˜Kšœ˜Kš žœžœžœžœžœ˜JKšžœ˜—K˜�š œžœ+žœžœžœ˜Qšžœ˜Kš žœžœžœžœžœ˜<Kšžœžœžœ˜*—K˜—K˜�š œžœ+žœžœžœ˜Qšžœ˜Kš žœžœžœžœžœ˜<Kšžœžœžœ˜*—K˜—K˜�š œžœ+žœžœžœ˜Nšžœ˜Kšžœžœžœžœ˜+Kšžœžœ˜—K˜—K˜�š œžœ+žœžœžœ˜Nšžœ˜Kšžœžœžœžœ˜+Kšžœžœ˜—K˜—K˜�K˜�K™-šœžœ"ž˜5šžœžœžœžœ˜%KšœP˜PKšžœ˜ —šžœžœžœžœ˜.Kšœ%˜%Kšžœ˜ —šžœžœžœžœ˜/Kšœ!˜!Kšžœ˜ —šžœžœžœžœ˜$Kšœ%˜%Kšžœ˜ —Kšœ ˜ Kšœ˜Kšœ˜Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ˜Kšžœ˜—K˜�K™.šœžœ"ž˜5Kšœ!˜!Kšœ'˜'Kšœ!˜!Kšœ!˜!Kšœ7˜7Kšžœ˜—K˜�šœžœ+žœž˜IKšžœžœžœžœ˜/šžœ ž˜Kšœ ˜ Kšœ6˜6Kšžœ˜—K™Sšžœžœžœ˜BKšžœ˜Kšžœžœžœ6˜R—Kšžœ˜—K˜�šœžœ+žœž˜CKšœžœ˜K™Kšžœžœ˜AK˜�K™Kšžœžœžœ˜&šžœžœ˜Kšžœžœžœ˜-Kšžœžœ˜&šžœžœ˜Kšœž˜—šžœ˜šžœžœ˜Kšœž˜—šžœ˜šžœžœ˜Kšœž˜—šžœžœžœ˜Kšœ˜———Kšœ˜—Kšœžœ˜—K˜�K˜�šœžœ"ž˜2Kšœžœ˜K˜�K™#šžœžœ˜šžœžœžœ˜Kšœ$˜$—Kšžœ˜ Kšœ˜—K˜�K™Kšžœžœžœ˜.Kšžœžœ˜(šžœžœ˜Kšœžœ˜Kšœ žœ˜K˜—šžœ˜šžœžœ˜Kšœžœ˜Kšœ žœ˜—K˜—šžœ˜šžœžœ˜Kšœžœ˜Kšœ žœ˜—Kšœ˜—šžœ˜šžœžœ˜Kšœ˜Kšœ žœ˜—Kšœ˜—Kšžœ˜—K˜�šÐbkœžœ+žœž˜DK™@šžœžœ˜%Kšœ˜Kšœ˜Kšœ!˜!Kšœ˜—K˜�J™Ršžœžœ˜"šžœžœžœž˜!šžœžœ˜Kšœ žœžœ˜'K˜—šžœžœ˜Kšœ žœžœ˜'K˜—šžœžœ˜Kšœ žœžœ˜'K˜—Kšžœ˜—K˜�šžœžœžœž˜ šžœžœ˜Kšœžœžœ˜*K˜—šžœžœ˜Kšœžœžœ˜+K˜—šžœžœ˜Kšœžœžœ˜*K˜—Kšžœ˜—Kšœ˜—Kšžœ˜—K˜�K˜�šœžœ+žœž˜Dšœžœžœžœžœž˜*Kšžœžœžœžœ˜*Kšžœ˜—K˜�K™4šžœžœ˜"šžœžœžœž˜!šœ˜Kšœ[˜[šœ ˜ Kšœžœ˜*Kšœ6˜6—K˜—Kšžœ˜—šžœžœ˜ Jšžœžœ+˜MJ˜—K˜—K˜�K™5šžœžœ˜%K˜#šžœžœžœž˜!K˜Kšžœžœžœ˜PKšžœ˜—Kšœ˜—K˜�K™0šžœžœžœ˜5šžœžœžœžœ˜"Kšœ˜Kšžœ˜ —Kšœ%˜%Kšœ4˜4Kšœ˜Kšœ˜—Kšžœ˜—K˜�K˜�šœžœ+žœž˜FKšœ˜Kšœ¡=˜HKšœ¡?˜KKšœ¡=˜DKšœžœ¡C˜OKšœ ˜ K˜�K™8Kšžœžœ˜AKšžœžœ˜<Kšžœžœžœžœ˜RK˜�K™šžœžœ˜%Kšœžœ˜šžœžœžœž˜.šžœžœ˜Kšžœ)žœžœ˜6šžœžœžœž˜,KšœP˜PKšœi˜iKšžœ˜—K˜—Kšžœ˜—Kšœ˜—K˜�K˜�K™Qšžœžœžœ˜šžœ˜šžœ˜šžœžœ˜(Kšžœ˜šžœ˜šžœ˜Kšžœ˜Kšžœžœžœ˜+—K˜——šžœžœ ˜ Kšžœ˜—šžœ˜šžœ ˜Kšžœ˜Kšžœžœžœ˜)—K˜—Kšœ˜—šžœ˜šžœžœ˜"šžœžœ žœžœ žœžœ˜tKšžœ˜—šžœžœ žœžœ žœžœ˜dKšžœ˜—Kšœ˜—K˜——Kšžœ˜—K˜�Kšœ?™?Kšœ˜K˜šžœžœž˜šžœžœžœžœ˜LKšžœ,˜1šžœ˜šžœžœžœžœ žœžœ žœžœ ˜ªKšžœ˜Kšžœ˜———šžœ˜Kšžœ!˜%Kšžœžœžœ˜7—šžœžœžœ˜?šžœ˜šžœ˜ Kšžœ žœžœžœ˜3šž˜šžœžœ˜"Kšžœ ˜Kšžœžœžœžœžœžœ ˜]———Kšœ˜—šžœ˜šžœžœžœžœ˜Fšžœžœ˜"Kšžœ ˜Kšžœžœžœžœžœžœ˜^—Kšœ˜—K˜——Kšžœ˜—K˜�K˜�K™Qšžœ ˜Kšžœžœ˜šžœžœžœžœ˜!šžœ˜ Kšžœ"˜&Kšžœžœžœ˜>—Kšžœ˜——K˜�K™Kš žœžœžœžœžœ˜6K˜�K˜�K™?šžœžœ˜%Kšœ˜Kšœ˜Kšœ˜—K˜�K™Xšžœžœ˜%K™šžœžœ˜šžœ˜šžœžœžœžœ˜-Kšœ(˜(Kšžœ˜—Kšžœ˜—Kšœ˜—K™ šžœžœ˜šžœ˜šžœ˜šžœ˜šžœžœžœžœ˜-Kšœ!˜!Kšžœ˜—šžœ˜Kšœ˜šžœžœž˜'Kšœ˜Kšžœžœ)˜GKšœ˜Kšžœ˜—Kšœ˜——Kšœ˜—Kšžœ˜—Kšœ˜—Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜�—K™CKšœ-˜-šžœžœ˜Kšœžœ˜$šžœžœžœž˜,Kšœ)˜)Kšœ%˜%Kšž˜—K˜—K˜�K™K˜K˜ šžœžœž˜'šžœžœ˜4Kšžœ˜šžœžœžœž˜>K˜——Kšžœ˜—šžœžœ žœ˜CK˜�—K™Wšžœžœž¡˜K™UKšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜šžœžœžœ˜šžœ˜šžœ˜šžœ˜ Kšžœ˜šžœžœ ˜Kšžœ˜Kšžœ˜——šžœ˜ Kšžœ˜šžœžœ ˜Kšžœ˜Kšžœ˜——K˜—šžœ˜šžœ˜šžœ˜šžœ ˜Kšžœ˜šžœžœ˜Kšžœ˜Kšžœ˜——šžœ ˜Kšžœ˜šžœžœ ˜Kšžœ˜Kšžœ˜——K˜——K˜——Kšžœ˜ —K˜�šžœžœž˜šžœ˜ Kšžœ˜Kšžœžœžœ˜A—Kšžœ˜—K˜�šžœ4˜6Kšžœ˜šžœžœžœ$˜9Kšžœ˜šžœžœ$˜9Kšžœ˜Kšžœ˜—K˜�——šžœ4˜6Kšžœ˜šžœžœžœ$˜9Kšžœ˜šžœžœ$˜9Kšžœ˜Kšžœ˜———Kšžœ˜—K˜�K™Jš žœžœžœžœ$žœ˜XK™�K™(K˜)K˜�K™KšœF˜FKšœ.˜.K˜�K™+Kšžœžœ˜4K˜�Kšžœ˜—˜�K˜�—šœžœ+žœž˜Cšœ žœ˜ Kšœ"˜"K™�K™šžœžœ˜šžœžœžœ˜(Kšœ¡œ¡˜*Kšžœ˜ —šžœžœ˜šžœžœžœ˜!šžœžœžœ˜(KšœF˜FKšžœ˜——šž˜šžœžœžœ˜!šžœžœžœ˜(KšœF˜FKšžœ˜——šž˜šžœžœžœ˜"šžœžœžœ˜(KšœC˜CKšžœ˜——šž˜šžœžœžœ˜!šžœžœžœ˜(KšœI˜IKšžœ˜——šž˜šžœžœžœ˜!šžœžœžœ˜(KšœI˜IKšžœ˜——šž˜šžœžœžœ˜!šžœžœžœ˜(KšœF˜FKšž˜——šž˜šžœžœžœ˜!šžœžœžœ˜(KšœD˜DKšžœ˜——šž˜šžœžœžœ˜!šžœžœžœ˜(KšœF˜FKšžœ˜——šž˜šžœžœžœ˜!šžœžœžœ˜(KšœF˜FKšžœ˜——šž˜šžœžœžœ˜!šžœžœžœ˜(KšœF˜FKšžœ˜——šž˜šžœžœžœžœžœž˜HKšœF˜FKšžœ˜———————————Kšœ˜—Kšœ˜—K™�K™šžœžœ˜šžœžœ˜šžœžœžœ˜!šžœžœžœ˜(Kšœ˜šžœžœ˜Kšœ)˜)——Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜(Kšœ˜šžœžœ˜Kšœ(˜(——Kšžœ˜—Kšž˜šžœžœžœ˜"šžœžœžœ˜(Kšœ˜šžœžœ˜Kšœ%˜%——Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜(Kšœ˜šžœžœ˜Kšœ+˜+——Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜(Kšœ˜šžœžœ˜Kšœ+˜+——Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜(Kšœ˜šžœžœ˜Kšœ)˜)——Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜(Kšœ˜šžœžœ˜Kšœ'˜'——Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜'šžœžœ˜Kšœ˜—šž˜šžœžœž˜;Kšœ˜K˜�———Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜(šžœžœ˜Kšœ˜—šžœ˜šžœžœž˜<Kšœ˜—K˜�——Kšžœ˜————————Kšœ˜—Kšœ˜——Kšžœ˜—K˜�š œžœžœžœž˜=šžœžœžœž˜-Kšžœžœžœ˜'Kšžœ˜—Kšžœ˜ Kšžœ˜—K˜�K˜�šœžœ+žœž˜NKšœ˜Kšœ¡6˜BKšœ¡6˜BKšœžœ¡,˜=K˜�K™8š œžœ!žœžœžœ˜Lšžœžœžœžœžœžœžœ˜‰Kšœžœžœž˜—Kšžœ˜—K˜�K™8š œžœ!žœžœžœ˜Lšžœžœžœžœžœžœžœ˜‰Kšœžœžœžœ˜—Kšžœ˜—K˜�K˜�K™@šžœžœ˜&Kšœ&˜&Kšœ˜Kšœ˜Kšœ˜—K˜�Kšœ!™!Kš œžœžœ žœžœ˜=K˜�K™,K˜K˜šžœžœž˜šžœ˜Kšžœ!˜%Kšžœžœ˜5—Kšžœžœ˜2Kšžœ˜—Kšžœ žœžœžœ˜(š žœ žœžœžœžœ˜AK˜�—K™Kšžœžœ!˜8Kšžœžœ!˜8K˜�K™^š žœžœžœžœž˜7Kšœžœžœžœ˜HKšžœ˜—K˜�K™^šžœžœ˜šžœžœžœ˜ Kšœžœžœžœ˜IKšžœ˜ —šžœžœžœ˜Kšœžœžœžœ˜KKšžœ˜—Kšœ˜—K˜�K™šžœžœ˜&K™0Kšœ!˜!Kšœ ˜ K˜�K™Yšžœžœ˜šžœžœžœ˜%Kšœ&˜&Kšžœ˜—šžœžœž˜Kšœ$˜$Kšžœ˜—Kšœ˜—Kšœ1˜1K˜�šžœžœ˜šžœžœžœ˜%Kšœ$˜$—Kšžœ˜ Kšœ˜—Kšœ1˜1Kšœ˜—K˜�K˜�Kšœ;™;šžœžœ˜šžœžœ˜šžœžœžœ˜%Kšœ%˜%Kšžœ˜ —KšœC˜CKšœ˜—šžœ˜Kšžœ)˜-šžœ˜šžœžœžœ˜%Kšœ)˜)Kšžœ˜ —šœG˜Gšžœžœžœ˜šžœ˜Kšžœ+˜/Kšžœ¡+˜M—Kšžœ˜——Kšœ˜——Kšœ˜—šžœžœ˜šžœžœ˜šžœžœžœ˜%Kšœ%˜%Kšžœ˜ —KšœB˜BKšœ˜—šžœ˜Kšžœ&˜*šžœ˜šžœžœžœ˜%Kšœ)˜)Kšžœ˜ —KšœF˜FKšœ˜——Kšœ˜—K˜�K™#Kšœ&˜&K˜�K™^šžœ˜šžœ˜šžœ˜šžœ˜šžœžœž˜Kšœ˜Kšœ)˜)Kšžœ˜ —šžœžœ)žœ˜5Kšœ˜Kšœ˜Kšžœ˜—Kšœ,˜,KšœG˜GKšœ˜—šžœ˜šžœžœž˜Kšœ˜Kšžœ˜ —šžœžœ'žœ˜3Kšœ˜Kšžœ˜—Kšœ˜——šžœ˜šžœžœžœ$žœ˜4Kšœ˜Kšœ*˜*Kšž˜—šžœžœžœ$žœ˜4Kšœ˜Kšžœ˜——Kšœ˜—š žœžœžœžœž˜)Kšœ˜Kšžœ˜——K˜�K™^šžœ˜šžœ˜šžœ˜šžœ˜šžœžœžœžœ˜"Kšœ˜Kšœ'˜'Kšžœ˜—šžœžœžœž˜"Kšœ˜Kšœ'˜'Kšžœ˜—Kšœ˜—šžœ˜Kš žœžœžœžœžœ˜DKš žœžœžœžœžœ˜EKšœ˜——šžœ˜šžœ˜šžœžœžœžœ˜/Kšœ˜Kšœ'˜'Kšžœ˜ —šžœžœžœ)žœ˜9Kšœ˜Kšœ˜Kšžœ˜—Kšœ˜—šžœ˜šžœžœžœž˜.Kšœ˜Kšžœ˜—K˜—K˜——š žœžœžœžœž˜)Kšœ˜Kšžœ˜——K˜Kšœ ™ šžœžœ˜šžœžœžœ˜Kšžœ žœ žœ%˜BKšžœ˜ —K˜—K™�K™šžœžœ˜ šžœžœž˜Kšœ!˜!Kšžœ˜—K˜—K˜�K™šžœžœ˜šžœžœž˜Kšœ!˜!Kšœ žœ ˜Kšœ žœ ˜Kšžœ˜—šžœžœž˜Kšœžœ ˜Kšœžœ ˜Kšžœ˜—K˜K˜—Kšžœ˜—K˜šœžœCžœž˜bKšœ˜Kšœ¡P˜XKšœžœ¡O˜\Kšœ*žœ˜2K˜�š œžœžœžœžœ˜6Kšžœžœžœžœžœžœžœžœ˜GKšžœ˜K˜�—š œžœžœžœžœ˜8Kšžœžœžœžœžœžœžœžœ˜GKšžœ˜—K˜�Kšœžœžœžœ˜Ašžœžœžœ˜-Kšœ˜šžœ˜Kšžœ˜Kšžœ ˜$—šœžœžœžœ˜Kšœ žœ ˜Kšœ˜Kšœ˜šžœ žœ žœ žœ˜/Kšžœ)žœ žœ ˜FKšžœžœžœ˜FKšœ˜Kšžœ˜—šžœEž˜KKšœ žœ ˜—šžœ$žœ"ž˜NKšœ˜—šžœ žœ žœ˜šžœžœžœ˜šžœžœ+ž˜KKšœ žœ ˜—šžœžœžœ˜3Kšœ˜—Kšžœ˜—Kšœ˜—Kš žœ žœ žœžœ žœ˜Cšžœ žœ˜Kšžœžœ˜šžœžœ žœ˜Kšžœžœ˜Kšžœžœ˜——Kšžœ˜—šžœ ˜Kšžœ˜Kšžœžœžœ ˜&—šžœ˜ šžœžœžœžœ˜!Kšœžœ ˜Kšžœ˜—šžœ˜šžœžœžœ˜Kšœžœ ˜Kšœ˜Kšœ˜šžœ žœžœ žœ˜1Kšžœ+žœžœ ˜JKšžœžœžœ ˜RKšžœ˜ —šžœGž˜MKšœžœ ˜—šžœ$žœ$ž˜PKšœ˜—šžœžœ žœ˜ šžœžœžœ˜šžœžœ-ž˜MKšœžœ ˜—Kšžœžœžœ˜J—Kšžœ˜—Kšœ˜Kš žœžœ žœžœžœ˜Gšžœžœ˜Kšžœžœ˜šžœžœžœ˜Kšžœžœ˜Kšžœžœ˜——Kšžœ˜ —šžœ ˜Kšžœ˜Kšžœžœžœ˜%—Kšœ˜——Kšœ˜—Kšœ˜šžœžœžœžœ˜JKšœ˜šžœ˜Kšžœ˜Kšžœ ˜$—šœžœžœžœ˜Kšœ žœ ˜Kšœ˜Kšœ˜šžœ žœ žœ žœ˜0Kšžœ)žœ žœ ˜FKšœžœžœžœ!˜RKšžœ˜—šžœEž˜KKšœ žœ ˜—šžœ$žœ"ž˜NKšœ˜—Kš žœ žœ žœžœ žœ ˜Dšžœ žœ˜Kšžœžœ˜šžœžœ žœ˜Kšžœžœ˜Kšžœžœ˜——Kšžœ˜ —šžœ ˜Kšžœ˜Kšžœžœžœ ˜&—šžœ˜ šžœžœžœžœ˜!Kšœžœ ˜Kšžœ˜—šžœ˜šžœžœžœ˜Kšœžœ ˜Kšœ˜Kšœ˜šžœ)žœžœ žœ˜NKšžœ+žœžœ ˜Kšžœžœžœ˜3Kšœ˜Kšœ˜—Kšžœ˜—šžœžœ˜K˜šžœžœžœ žœ˜Ašžœ+žœžœ ˜Kšžœžœžœ˜3Kšœ˜Kšœ˜——Kšžœ˜—K˜—Kšœ˜šžœGž˜MKšœžœ ˜—Kšžœ$žœ$žœ˜fKš žœžœ žœžœžœ˜Išžœžœ˜Kšžœžœ˜šžœžœžœ˜Kšžœžœ˜Kšžœžœ˜——Kšžœ˜ —šžœ ˜Kšžœ˜Kšžœžœžœ˜%—Kšœ˜——Kšœ˜—Kšœ˜Kšžœ˜——Kšžœ˜J™�—�…—����ºZ��Ç�