Directory IO; Imports Atom, BitOps, CacheOps, Cucumber, Dragon; Library CacheMInterface, CachePInterface, CacheEntries; Cache: CELL [ PhA, PhBBOOL, -- Tristate PFaultB>EnumType["Dragon.PBusFaults"], -- Tristate PNPError>BOOL, -- Tristate MDataBA=INT[32], MCmdBA=EnumType["Dragon.MBusCommands"], MNShared=BOOL, MParityBA=BOOL, MNError>BOOL, MReadyBABOOL, MNewRq>BOOL, MGntBOOL -- changes during each PhA following a PhB that DShift is asserted, continues to be driven through the PhB following the PhA it changes ] State phALast: BOOL _ FALSE, -- hack to improve simulation performance cache: CacheOps.Cache, cycleNo: INT _ 0, skipRejects: BOOL _ FALSE, rejectCycles: NAT _ 0, cmdAB: PBusCommands _ NoOp, address, fetchData, storeData: Dragon.HexWord _ 0, cmdType: {noOp, fetch, store} _ noOp, pageFault, writeFault, storeParity, storeParityErrorBA, storeParityErrorAB, firstBOfCmdBA, resetBA, resettingAB, dHoldBA, holdingAB, rejectedB: BOOL _ FALSE EvalSimple IF PhA THEN BEGIN holdingAB _ dHoldBA; resettingAB _ resetBA; IF NOT phALast THEN BEGIN storeParityErrorAB _ storeParityErrorBA OR (cmdType=store AND storeParity#CacheOps.Parity32[storeData]); IF NOT dHoldBA AND cmdType=store AND rejectCycles=0 AND NOT (pageFault OR writeFault) THEN CacheOps.Write[cache, address, storeData]; phALast _ TRUE; END; IF rejectCycles=0 THEN address _ BitOps.ELFD[container: PData, containerWidth: 32, fieldPosition: 0, fieldWidth: 32]; cmdAB _ IF resetBA THEN NoOp ELSE PCmdA; PRejectB _ FALSE; PFaultB _ None; END; IF PhB THEN BEGIN dHoldBA _ DHoldAB; resetBA _ ResetAB; IF phALast THEN BEGIN IF NOT holdingAB THEN BEGIN storeParityErrorBA _ NOT resettingAB AND storeParityErrorAB; IF resettingAB THEN BEGIN rejectCycles _ 0; cycleNo _ 0; cache _ CacheOps.NewCache[cache]; END ELSE cycleNo _ cycleNo+1; IF rejectCycles=0 THEN BEGIN pageFault _ writeFault _ FALSE; SELECT cmdAB FROM Fetch, FetchHold => BEGIN cmdType _ fetch; [data: fetchData, rejectCycles: rejectCycles, pageFault: pageFault] _ CacheOps.Access[cache, address, read, cycleNo]; END; Store, StoreHold => BEGIN cmdType _ store; [rejectCycles: rejectCycles, pageFault: pageFault, writeProtect: writeFault] _ CacheOps.Access[cache, address, write, cycleNo]; END; IOFetch, IOStore, IOFetchHold, IOStoreHold => BEGIN Dragon.Assert[ FALSE, "Cache doesn't yet implement IO operations" ]; -- for now cmdType _ noOp; END; ENDCASE => cmdType _ noOp; IF skipRejects THEN rejectCycles _ 0; IF pageFault OR writeFault THEN rejectCycles _ MAX[1, rejectCycles]; firstBOfCmdBA _ TRUE; END ELSE BEGIN -- rejected on previous PhB Dragon.Assert[ cmdAB = NoOp ]; rejectCycles _ rejectCycles-1; firstBOfCmdBA _ FALSE; END; END; phALast _ FALSE; END; IF storeParityErrorAB THEN PNPError _ FALSE; IF cmdType # noOp THEN BEGIN PFaultB _ (SELECT TRUE FROM rejectCycles=1 AND pageFault => PageFault, rejectCycles=1 AND writeFault => WriteProtectFault, ENDCASE => None); PRejectB _ rejectCycles>0; SELECT TRUE FROM cmdType=store AND firstBOfCmdBA => BEGIN storeData _ BitOps.ELFD[container: PData, containerWidth: 32, fieldPosition: 0, fieldWidth: 32]; storeParity _ PParityB; END; cmdType=fetch AND rejectCycles=0 AND NOT pageFault => BEGIN PData _ BitOps.ILID[source: fetchData, container: PData, containerWidth: 32, fieldPosition: 0, fieldWidth: 32]; PParityB _ CacheOps.Parity32[fetchData]; END; ENDCASE => NULL; -- neither write nor read PBus END; END; Initializer WITH initData SELECT FROM pl: Atom.PropList => BEGIN r: REF; IF (r _ pl.GetPropFromList[$Cache]) # NIL THEN cache _ NARROW[r, CacheOps.Cache]; skipRejects _ (pl.GetPropFromList[$SkipRejects] # NIL AND NARROW[pl.GetPropFromList[$SkipRejects], REF BOOL]^); END; ENDCASE => ERROR Expand PKillRequestB: BOOL; LatchBias: BOOL; PhAb, nPhAb, PhBb, nPhBb:BOOL; PhAh, PhBh:BOOL; Resetb:BOOL; VirtualPage, nVirtualPage:INT[24]; VirtualBlock, nVirtualBlock:INT[6]; RealPage, nRealPage:INT[24]; RealBlock, nRealBlock:INT[6]; CAMPageAccess, nCAMPageAccess:SWITCH[24]; CAMBlockAccess, nCAMBlockAccess:SWITCH[6]; PBits, nPBits:SWITCH[66]; MBits, nMBits:SWITCH[66]; nVirtualMatch, nMatchPageClean, nMatchCellShared:BOOL; nMapValid, nRealMatch, nVictimClean:BOOL; nMatchTIP:BOOL; CellAdr, nCellAdr:INT[8]; VirtualAccess, nVirtualAccess, SelCell, SelVictimAdr, SelMapAdr, SelRealData, SelPageFlag, SelVictimData, SelRealAdr:BOOL; FinishSharedStore:BOOL; VPValid, nVPValid, RPValid, nRPValid, RPDirty, nRPDirty, Master, nMaster, Shared, nShared, Victim, nVictim, TIP, nTIP, Broken, nBroken:BIT; MAdrLow, nMAdrLow:BOOL; PAdrLow, nPAdrLow:BOOL; PStore:BOOL; VictimFeedback, nVictimFeedback, ShiftVictim, nShiftVictim:BOOL; ForceDataSelect:BOOL; MDoneAB, MHeldAB:BOOL; MFaultAB:EnumType["Dragon.PBusFaults"]; PAdrHigh, PAdrLowToM:BOOL; PCmdToMAB:EnumType["Dragon.PBusCommands"]; DoShiftBA, DoExecuteBA, DoHoldBA, ShiftDataToPCAM:BOOL; ShiftDataToMCtlPads:BOOL; pInterface: PInterface[]; mInterface: MInterface[]; cacheEntries: CacheEntries[] BlackBoxTest cacheTester[instructions, drive, handle]; ENDCELL; CEDAR CacheTester: TYPE = PROC[i: CacheIORef, d: REF CacheDrive, h: CellTestHandle]; cacheTester: CacheTester; RegisterCacheTester: PUBLIC PROC[ct: CacheTester]={ cacheTester _ ct}; CacheStateHandler: Cucumber.Handler = NEW[Cucumber.HandlerRep _ [ PrepareWhole: CacheStatePrepareProc, PartTransfer: CacheTransferProc ]]; CacheStatePrepareProc: PROC [ whole: REF ANY, where: IO.STREAM, direction: Cucumber.Direction, data: REF ANY ] RETURNS [ leaveTheseToMe: Cucumber.SelectorList ] -- Cucumber.Bracket -- = {leaveTheseToMe _ LIST[$cache]}; CacheTransferProc: PROC [ whole: REF ANY, part: Cucumber.Path, where: IO.STREAM, direction: Cucumber.Direction, data: REF ANY ] -- Cucumber.PartTransferProc -- = TRUSTED {Cucumber.Transfer[ what: NARROW[whole, REF CacheStateRec].cache, where: where, direction: direction ]}; Cucumber.Register[CacheStateHandler, CODE[CacheStateRec]]; ¸Cache.rose Last edited by: Barth, May 31, 1984 6:02:04 pm PDT Last edited by: McCreight, June 12, 1984 5:57:32 pm PDT Signal names obey the following convention: If a signal x is computed during PhA and remains valid throughout the following PhB, it is denoted as xAB. If x is computed during PhA and can change during the following PhB (as, for example, in precharged logic), it is denoted as xA. In this latter case, a client wanting to use x during PhB must receive it in his own latch open during PhA. xBA and xB are defined symmetrically. Positive logic is assumed (asserted = TRUE = 1 = more positive logic voltage); negative-logic signals have an extra "N" at or very near the beginning of the signal name (e.g., PNPError for PBus Negative-TRUE Parity Error). Timing and housekeeping interface Processor interface Main memory interface Serial debugging interface All the following signals change during PhA and propagate during the remainder of PhA and PhB, giving an entire clock cycle for them to propagate throughout the machine. Each user must receive them into a latch open during PhB. The effects of changes are intended to happen throughout the following PhA, PhB pair. Who knows? Temporary until we decide whether to use latches with bias Buffered timing and housekeeping interface CAM interface RAM access The left PBits should be sampled by M during PhB. Cell control P control <=> M control, all change during PhA Debug interface ÊɘJšœ ™ Jšœ2™2Jšœ7™7J˜Jšœ Ïkœ˜ Jšœ1˜1J˜J˜7J˜šœœ˜ J˜Jšœ™J™šœ!™!Jšœ œ˜Jšœ œ˜Jšœœ˜—J˜šœ™Jšœœ˜Jšœ œ˜Jšœ&˜&Jšœ œÏc ˜Jšœ'ž ˜2Jšœ œž ˜—J˜šœ™Jšœœ˜Jšœ'˜'Jšœ œ˜Jšœ œ˜Jšœœ˜ Jšœ œ˜Jšœœ˜ Jšœœ˜ Jšœœ˜ —J˜šœ™Jšœ»™»Jšœœ˜ Jšœœž˜,Jšœ œž1˜@Jšœ œž;˜LJšœ œž+˜