DIRECTORY Core, CoreClasses, CoreCreate, CoreFlat, CoreOps, IO, Ports, Rosemary, RosemaryUser, Rope, SCLogic, SCParms, TerminalIO; SCArrayImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreFlat, CoreOps, IO, Ports, Rosemary, Rope, SCParms, TerminalIO EXPORTS SCLogic ~ BEGIN OPEN SCLogic; ClockEvalEnabled: BOOL = TRUE; MySCName: ROPE = Rosemary.Register[roseClassName: "SCArray", init: Init, evalSimple: Simple, scheduleIfClockEval: ClockEvalEnabled]; NumFlagsBits: NAT = 4; 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; NumBitsPerCycle: NAT = SCParms.numBitsPerCycle; 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 = ["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[LRM..GND] OF LevelSequence ]; Array: TYPE = REF ArrayRec; ArrayRec: TYPE = RECORD [ SEQUENCE size: NAT OF LevelSequence ]; 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: Level, -- flop 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 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 ramRdorWt: Level, -- flop to generate Prech 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 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: Array _ 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, vCamPartMch, rCamPartMch: Level, -- flops to delay PartMch vCamDrBLFF, rCamDrBLFF: Level, -- flops for CamDrBL vCamRdSR, rCamRdSR: ARRAY [0..2] OF Level, -- flops for RdCam; 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 resetDone: BOOLEAN, -- used to suppress error due to X's before Reset has been done tmpRAdrsIn, tmpVAdrsInOut: LevelSequence _ NIL, tmpFlagsIn: ARRAY [0..NumFlagsBits) OF Level, tmpxEnCamSel, tmpBCycle2, tmpxWtRam, tmpxRdRam, tmpramRdorWt, tmpxLdVCamWR, tmpxDrVCamBL, tmpxRdVCam, tmpxRdRCam, tmpVPValidIn, tmpRPValidIn, tmpxPartRMch, tmpPCtlPartVMch, tmpPWtInProg, tmpxDrRCamBL, tmpxLdRCamWR: Level ]; debug: BOOL _ FALSE; Reset, LdRML1, LdVML, ClrVPV, PCtlResetVictim, Spare, RamClock, xLdUse, PCtlDrABusVB, PCtlDrABusVP, PCtlPartVMch, xRdVCam, xLdVCamWR, xDrVCamBL, 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, nxSelWdData, nxByteSel, nxWdSel, WdWtData, BlkWtData, Modes, 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", "LdRML1", "LdVML", "ClrVPV", "PCtlResetVictim", CoreCreate.Seq["Spare", NumBitsPerCycle], "RamClock", "xLdUse", "PCtlDrABusVB", "PCtlDrABusVP", "PCtlPartVMch", "xRdVCam", "xLdVCamWR", "xDrVCamBL", CoreCreate.Seq["VAdrsInOut", NumAddressBits], "VPValidIn", "PCtlDrABusRB", "PCtlDrABusRP", "xRdRCam", "xPartRMch", "xDrRCamBL", "xLdRCamWR", "xEnCamSelExt", "BCycle2", 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", NumBytesPerWord], CoreCreate.Seq["nxWdSel", NumWordsPerLine], CoreCreate.Seq["WdWtData", NumBitsPerWord], CoreCreate.Seq["BlkWtData", NumBitsPerLine], CoreCreate.Seq["Modes", NumBitsPerWord], CoreCreate.Seq["RAdrsOut", NumAddressBits], CoreCreate.Seq["FlagsOut", NumFlagsBits], 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, "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, "BlkWtData"]; [] _ 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, "Reset", "LdRML1", "LdVML", "ClrVPV"]; Ports.InitPorts[ct, l, none, "PCtlResetVictim", "Spare", "xLdUse", "PCtlDrABusVB", "PCtlDrABusVP", "PCtlPartVMch", "xRdVCam", "xLdVCamWR", "xDrVCamBL"]; 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", "nxSelWdData", "RPValidIn"]; Ports.InitPorts[ct, l, drive, "RamClock"]; 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.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 [ArrayRec[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.tmpVAdrsInOut _ NEW [LevelSequenceRec[NumAddressBits]]; } ELSE cs _ NARROW[oldStateAny, CacheState]; cs.prevClk _ X; cs.vCamCSCmd1 _ X; cs.rCamCSCmd1 _ X; cs.aVct _ X; cs.vCamPartMch _ X; cs.rCamPartMch _ X; cs.ramRdorWt _ X; cs.pWtInProgB _ X; cs.ldSORdLatch _ 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..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..NumFlagsBits) 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; 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.bCycle[i] _ X; ENDLOOP; cs.vCamDrBLFF _ X; cs.rCamDrBLFF _ X; FOR i IN [0..2] DO cs.vCamRdSR[i] _ X; cs.rCamRdSR[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..NumFlagsBits) DO cs.tmpFlagsIn[i] _ X; ENDLOOP; cs.tmpBCycle2 _ X; cs.tmpxWtRam _ X; cs.tmpxRdRam _ X; cs.tmpramRdorWt _ X; cs.tmpxLdVCamWR _ 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.tmpxDrVCamBL _ 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..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..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, LdRML1, LdVML, ClrVPV] _ Ports.PortIndexes[cellType.public, "Reset", "LdRML1", "LdVML", "ClrVPV"]; [PCtlResetVictim, Spare, RamClock, xLdUse, PCtlDrABusVB, PCtlDrABusVP, PCtlPartVMch, xRdVCam, xLdVCamWR, xDrVCamBL, VAdrsInOut, VPValidIn] _ Ports.PortIndexes[cellType.public, "PCtlResetVictim", "Spare", "RamClock", "xLdUse", "PCtlDrABusVB", "PCtlDrABusVP", "PCtlPartVMch", "xRdVCam", "xLdVCamWR", "xDrVCamBL", "VAdrsInOut", "VPValidIn"]; [PCtlDrABusRB, PCtlDrABusRP, xRdRCam, xPartRMch, xDrRCamBL, xLdRCamWR, xEnCamSelExt, BCycle2, RAdrsIn, RPValidIn, FlagsIn] _ Ports.PortIndexes[cellType.public, "PCtlDrABusRB", "PCtlDrABusRP", "xRdRCam", "xPartRMch", "xDrRCamBL", "xLdRCamWR", "xEnCamSelExt", "BCycle2", "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, BlkWtData, Modes, RAdrsOut] _ Ports.PortIndexes[cellType.public, "SetSh", "ClrSh", "xRdRam", "xWtRam", "nxSelWdData", "nxByteSel", "nxWdSel", "WdWtData", "BlkWtData", "Modes", "RAdrsOut"]; [FlagsOut, BlkRdData, WdRdData, SetReschedule, ASh, AOw] _ Ports.PortIndexes[cellType.public, "FlagsOut", "BlkRdData", "WdRdData", "SetReschedule", "ASh", "AOw"]; [ARM, AVM, Clock, nClock] _ Ports.PortIndexes[cellType.public, "ARM", "AVM", "Clock", "nClock"]; 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 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]; IF ClockLToH[p, cs, clockEval] AND debug THEN PrintState[cs]; 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..NumFlagsBits) 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.tmpxLdVCamWR _ p[xLdVCamWR].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.tmpxDrVCamBL _ p[xDrVCamBL].l; END; CaptureH: PROC[p: Ports.Port, cs: CacheState] = BEGIN cs.tmpxEnCamSel _ p[xEnCamSel].l; cs.tmpramRdorWt _ Ports.OrL[p[xRdRam].l, p[xWtRam].l]; END; PrintLS: PROC[ls: LevelSequence] = BEGIN FOR i: NAT IN [0..ls.size) DO SELECT ls[i] FROM L => TerminalIO.PutRope["0"]; H => TerminalIO.PutRope["1"]; X => TerminalIO.PutRope["x"]; ENDCASE => ERROR; ENDLOOP; END; PrintState: PROC[cs: CacheState] = BEGIN FOR i: NAT IN [0..NumMemLines) DO TerminalIO.PutF["\nLine: %g VCam: ", IO.int[i]]; PrintLS[cs.vCam[i]]; TerminalIO.PutRope[" RCam: "]; PrintLS[cs.rCam[i]]; TerminalIO.PutRope[" Flags: "]; PrintLS[cs.flags[i]]; TerminalIO.PutRope[" Ram: "]; PrintLS[cs.ram[i]]; ENDLOOP; TerminalIO.PutF[" Victim: %g", IO.int[cs.victimIndex]]; 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.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 p[xLdUse].l = H THEN { FOR i IN [0..NumMemLines) DO IF cs.match[LVM][i] = H THEN cs.use[i] _ H ; ENDLOOP; }; }; IF p[Reset].l = H OR p[PCtlResetVictim].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) 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; 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 p[nxSelWdData].l = H THEN FOR i IN [0..NumBitsPerLine) DO cs.ram[RamIndex][i] _ p[BlkWtData].ls[i]; ENDLOOP ELSE { j _ IndexOfSelectedWord[p]; FOR i IN [0..NumBitsPerWord) DO k _ i/NumBitsPerByte; IF p[nxByteSel].ls[k] = L 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.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..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; FOR i: NAT IN [0..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..NumBitsPerLine) DO cs.ramRdLatch[k] _ H; -- Precharge value ENDLOOP; IF p[nxSelWdData].l = L 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 p[nxSelWdData].l = L THEN { IF ioRamIndex = 0 AND j = 1 THEN FOR k IN [0..NumBitsPerWord) DO l _ k/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..NumBitsPerWord) DO l _ k/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..NumBitsPerWord) DO l _ k/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..NumBitsPerWord) DO l _ k/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..NumBitsPerWord) DO l _ k/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..NumBitsPerWord) DO l _ k/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..NumBitsPerWord) DO l _ k/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..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; IndexOfSelectedWord: PROC[p: Ports.Port] RETURNS[INT _ 0] = BEGIN FOR i: INT IN [0..NumWordsPerLine) DO IF p[nxWdSel].ls[i] = L THEN RETURN [i] 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; 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..NumFlagsBits) DO cs.flagsRdLatch[j] _ IF rCamIndex >= 0 THEN cs.flags[rCamIndex][j] ELSE H; ENDLOOP; }; 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.vCamRdSR[2] = 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] 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] _ L; ENDLOOP; }; }; IF cs.rCamDrBLFF = 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.rCamWtReg[NumAddressBits-1]; }; 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.rCamWtReg[NumAddressBits-1]; }; }; 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; 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[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..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.vCamPartMch = L AND 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 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. ÂSCArrayImpl.mesa Created: Paraminder Sahai September 1, 1987 6:55:41 am PDT Paraminder Sahai September 27, 1987 0:53:06 am PDT Pradeep Sindhu January 21, 1988 3:52:02 pm PST Constants and Type Defs Two-D array containing Victim, RamSel, LRM, LVM, RML2, RML3, RML4, and GND The following are used to capture input signals that go to flops Signal Defs Public Procs Internal Procs 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 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 Rising edge of clock On Reset we set all the use bits to 0, and set victim to point to some location Do the computation for the PWtInProg path in SOInterface 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 ldSORdLatch in RamInterfaceCtl 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 Handle the effect of xEnCamSelExt Compute vCamIndex, rCamIndex, numX, and numH Change the state of flops clocked by nClock in CamInterfaceCtl's Handle latch that holds CSCmd1 On rising edge of clock: Change state of read flops in CamInterfaceCtl's If read ctl signal has been H for 2 cycles and exactly one select line is high then read Change state of write flops in CamInterfaceCtl's First load the write registers for vcam and rcam; note that valid bits are always enabled Then 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 Ê5þ˜šœ™IcodešÏnœ3™:K™2K™.K™—šÏk ˜ Kšœx˜x—J™KšÑbln œžœž˜Kšžœ[˜bKšžœ˜Kšœžœžœ ˜headšÏl™Kšœžœžœ˜Kšœ žœv˜„K˜Kšœžœ˜Kšœ žœ˜)Kšœ žœ˜Kšœžœ˜0Kšœžœ˜-Kšœžœ˜-Kšœžœ˜/Kšœžœ˜-Kšœžœ˜5Kšœžœ˜/KšœžœÏc˜AKšœ žœ¡˜CKšœ žœ˜)Kšœžœ˜4Kšœ žœ˜)šœ žœžœžœ˜2Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ8˜8—šœ žœžœžœ˜1Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ8˜8—Kšœ žœžœžœ4˜bK˜Kš œ'žœžœžœžœžœž™JKšœžœžœ ˜šœ žœžœ˜Kšžœžœ˜K˜—K˜Kšœ žœžœ ˜šœ žœžœ˜Kšžœžœžœžœ˜&K˜—K˜Kšœžœžœ ˜šœ žœžœ˜Kšžœžœžœ˜#K˜—K˜Kšœ žœ˜$Kšœžœžœžœžœžœžœžœ˜AKšœ žœžœ˜%šœžœžœ˜Kšœ˜Kšœžœ¡(˜>Kš œ žœžœžœžœžœžœ˜AKšœ¡˜+Kšœ žœžœ ¡˜>Kšœ¡%˜DKšœžœžœ ¡˜:Kšœ žœ¡˜0Kšœžœ¡˜/Kšœžœžœ ¡˜˜>Kšœžœžœ ˜=Kšœ"¡˜;Kšœ!¡˜5Kšœžœžœ¡e˜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šœÄžœ˜É—š  ™ š Ÿœžœžœžœž˜6Kšœ#žœ ˜Ä Kšœ4˜4KšœB˜BKšœ-˜-K˜Kšœ\žœ,˜‹Kšœ)˜)KšœZžœ,˜‰Kšœ'˜'Kšœ)˜)Kšœ*˜*Kšœ(˜(Kšœ(˜(Kšœ+˜+Kšœ)˜)Kšœ*˜*Kšœ+˜+KšœZžœ*˜‡Kšœ(˜(Kšœ,˜,Kšœ+˜+K˜KšœD˜DKšœ˜˜˜Kšœª˜ªKšœW˜WKšœ†˜†Kšœ*˜*KšœJ˜JKšžœ˜——š ™šŸœž˜Kšœžœ˜ K˜ Kšœ˜K˜K™,šžœ ž˜šžœ˜Kšœžœ˜Kšœ žœ ˜šžœ žœž˜Kšœžœ ˜1Kšžœ˜—Kšœ žœ!˜-Kšœžœ!˜,Kšœžœ!˜,Kšœžœ$˜7Kšœ žœ˜%šžœžœžœž˜!Kšœ žœ$˜3Kšžœ˜—Kšœžœ$˜9Kšœžœ$˜9Kšœžœ$˜6Kšœžœ$˜—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™&šžœžœžœžœ˜TKšžœ˜Kšžœ˜—K˜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š žœžœžœžœ$žœ˜PK™K™(K˜)K˜K™KšœF˜FKšœ.˜.K˜K™+Kšžœžœ˜4K˜Kšžœ˜—˜K˜—šœžœ+žœž˜Cšœ žœ˜ 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šžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜ Kšœ˜šžœžœ˜Kšœ+˜+——Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜ Kšœ˜šžœžœ˜Kšœ)˜)——Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜ Kšœ˜šžœžœ˜Kšœ'˜'——Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜šžœžœ˜Kšœ˜—šž˜šžœžœž˜;Kšœ˜K˜———Kšžœ˜—šž˜šžœžœžœ˜!šžœžœžœ˜ šžœžœ˜Kšœ˜—šžœ˜šžœžœž˜K˜K™,K˜K˜šžœžœž˜šžœ˜Kšžœ!˜%Kšžœžœ˜5—Kšžœžœ˜2Kšžœ˜—Kšžœ žœžœžœ˜(š žœ žœžœžœžœ˜BK˜—K™@šžœžœ˜&Kšœ ˜ Kšœ!˜!Kšœ˜—K˜K™Kšžœžœ!˜;Kšžœžœ!˜;K˜K™šžœžœ˜&K™/Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜K˜K™Xš žœžœžœžœžœžœ˜RKšœžœžœžœ˜IKšžœ˜—šžœžœžœ˜4šžœžœžœ˜ Kšœžœžœžœ˜IKšžœ˜ —šžœžœžœ˜Kšœžœžœžœ˜KKšžœ˜—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šœC˜CKšœ˜—šžœ˜Kšžœ˜"šžœ˜šžœžœžœ˜%Kšœ)˜)Kšžœ˜ —šœG˜Gšžœžœžœ˜šžœ˜Kšžœ+˜/Kšžœ˜!—Kšžœ˜——Kšœ˜——Kšœ˜—šžœžœ˜šžœžœ˜šžœžœžœ˜%Kšœ%˜%Kšžœ˜ —KšœB˜BKšœ˜—šžœ˜Kšžœ˜šžœ˜šžœžœžœ˜%Kšœ)˜)Kšžœ˜ —KšœF˜FKšœ˜——Kšœ˜—KšœF˜FKšœ˜—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šžœ žœ žœ%˜AKšžœ˜ —K˜—K˜šžœžœ˜šžœžœž˜Kšœ!˜!Kšœ!˜!Kšœ žœ ˜Kšœ žœ ˜Kšžœ˜—šžœžœž˜Kšœ žœ ˜Kšœ žœ ˜Kšžœ˜—K˜K˜—Kšžœ˜—K˜š œžœ:ž˜QKšœ˜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šœ˜—šžœžœ žœ žœ˜5šžœžœžœ˜šžœžœ+ž˜KKšœ žœ ˜—šžœžœžœ˜3Kšœ˜—Kšžœ˜—Kšœ˜—Kš žœ žœ žœ žœ žœ ˜Cšžœ žœ˜Kšžœžœ˜šžœžœ žœ˜Kšžœžœ˜Kšžœžœ˜——Kšžœ˜—šžœ ˜Kšžœ ˜Kšžœžœžœ ˜&—šžœ ˜ šžœžœžœžœ˜!Kšœ žœ ˜Kšžœ˜—šžœ˜šžœžœžœ˜Kšœ žœ ˜Kšœ ˜ Kšœ˜šžœ žœ žœ žœ˜1Kšžœ+žœ žœ ˜JKšžœžœžœ ˜RKšžœ˜ —šžœGž˜MKšœ žœ ˜—šžœ$žœ$ž˜PKšœ˜—šžœžœ žœ žœ˜8šžœžœžœ˜šžœžœ-ž˜MKšœ žœ ˜—Kšžœžœžœ˜J—Kšžœ˜—Kšœ˜Kš žœ žœ žœ žœ žœ ˜Gšžœ žœ˜Kšžœžœ˜šžœžœ žœ˜Kšžœžœ˜Kšžœžœ˜——Kšžœ˜ —šžœ ˜Kšžœ ˜Kšžœžœžœ ˜%—Kšœ˜——Kšœ˜—Kšœ˜šžœžœžœ˜,Kšœ ˜ šžœ˜Kšžœ˜Kšžœ ˜$—šœžœžœžœ˜Kšœ žœ ˜Kšœ ˜ Kšœ˜šžœ žœ žœ žœ˜/Kšžœ)žœ žœ ˜EKšœžœžœžœ!˜RKšžœ˜—šžœEž˜KKšœ žœ ˜—šžœ$žœ"ž˜NKšœ˜—Kš žœ žœ žœ žœ žœ ˜Bšžœ žœ˜Kšžœžœ˜šžœžœ žœ˜Kšžœžœ˜Kšžœžœ˜——Kšžœ˜ —šžœ ˜Kšžœ ˜Kšžœžœžœ ˜&—šžœ ˜ šžœžœžœžœ˜!Kšœ žœ ˜Kšžœ˜—šžœ˜šžœžœžœ˜Kšœ žœ ˜Kšœ ˜ Kšœ˜šžœ!žœ žœ žœ˜EKšžœ+žœ žœ ˜Jšžœžœžœ˜3Kšœ˜Kšœ ˜ —Kšžœ˜—šžœžœ˜K˜šžœžœ žœ žœ˜@šžœ+žœ žœ ˜Jšžœžœžœ˜3Kšœ˜Kšœ ˜ ——Kšžœ˜—K˜—Kšœ˜šžœGž˜MKšœ žœ ˜—Kšžœ$žœ$žœ˜fKš žœ žœ žœ žœ žœ ˜Gšžœ žœ˜Kšžœžœ˜šžœžœ žœ˜Kšžœžœ˜Kšžœžœ˜——Kšžœ˜ —šžœ ˜Kšžœ ˜Kšžœžœžœ ˜%—Kšœ˜——Kšœ˜—Kšœ˜Kšžœ˜——Kšžœ˜J™—…—¡Bâ