--Cache.Mesa
--created by RoseTranslate from Cache.Rose of June 12, 1984 5:57:33 pm PDT for mccreight.pa at June 12, 1984 5:58:11 pm PDT
DIRECTORY
RoseTypes, RoseCreate, IO, Atom, BitOps, CacheOps, Cucumber, Dragon, NumTypes, SwitchTypes, EnumTypes, CachePInterface, CacheMInterface, CacheEntries;
Cache: CEDAR PROGRAM
IMPORTS RoseCreate, Atom, BitOps, CacheOps, Cucumber, Dragon, NumTypes, SwitchTypes, EnumTypes, CachePInterface, CacheMInterface, CacheEntries =
BEGIN OPEN
RoseTypes;
--Signal Type decls
PBusCommands: TYPE = Dragon.PBusCommands;
PBusFaults: TYPE = Dragon.PBusFaults;
MBusCommands: TYPE = Dragon.MBusCommands;
RegisterCells: PROC =
BEGIN
CreateCachePorts[];
[] ← RoseCreate.RegisterCellClass[className: "Cache",
expandProc: CacheExpand,
ioCreator: CreateCacheIO, initializer: InitializeCache,
evals: [EvalSimple: CacheEvalSimple],
blackBox: CacheBBTest, stateToo: NIL,
ports: CachePorts,
drivePrototype: NEW [CacheDrive]];
END;
CreateCachePorts: PROC = {CachePorts ← RoseCreate.PortsFromFile["Cache.Cache.rosePorts"]};
CacheIORef: TYPE = REF CacheIORec;
CacheIORec: TYPE = MACHINE DEPENDENT RECORD [
fill0(0:0..14): [0..32767],
PhA(0:15..15): BOOLEAN,
fill1(1:0..14): [0..32767],
PhB(1:15..15): BOOLEAN,
fill2(2:0..14): [0..32767],
Vdd(2:15..15): BOOLEAN,
fill3(3:0..14): [0..32767],
Gnd(3:15..15): BOOLEAN,
fill4(4:0..14): [0..32767],
PadVdd(4:15..15): BOOLEAN,
fill5(5:0..14): [0..32767],
PadGnd(5:15..15): BOOLEAN,
PData(6:0..31): ARRAY [0..2) OF CARDINAL,
fill7(8:0..14): [0..32767],
PParityB(8:15..15): BOOLEAN,
fill8(9:0..11): [0..4095],
PCmdA(9:12..15): PBusCommands,
fill9(10:0..14): [0..32767],
PRejectB(10:15..15): BOOLEAN,
fill10(11:0..12): [0..8191],
PFaultB(11:13..15): PBusFaults,
fill11(12:0..14): [0..32767],
PNPError(12:15..15): BOOLEAN,
MDataBA(13:0..31): ARRAY [0..2) OF CARDINAL,
fill13(15:0..11): [0..4095],
MCmdBA(15:12..15): MBusCommands,
fill14(16:0..14): [0..32767],
MNShared(16:15..15): BOOLEAN,
fill15(17:0..14): [0..32767],
MParityBA(17:15..15): BOOLEAN,
fill16(18:0..14): [0..32767],
MNError(18:15..15): BOOLEAN,
fill17(19:0..14): [0..32767],
MReadyBA(19:15..15): BOOLEAN,
fill18(20:0..14): [0..32767],
MRq(20:15..15): BOOLEAN,
fill19(21:0..14): [0..32767],
MNewRq(21:15..15): BOOLEAN,
fill20(22:0..14): [0..32767],
MGnt(22:15..15): BOOLEAN,
fill21(23:0..14): [0..32767],
ResetAB(23:15..15): BOOLEAN,
fill22(24:0..14): [0..32767],
DHoldAB(24:15..15): BOOLEAN,
fill23(25:0..14): [0..32767],
DShiftAB(25:15..15): BOOLEAN,
fill24(26:0..14): [0..32767],
DExecuteAB(26:15..15): BOOLEAN,
fill25(27:0..14): [0..32767],
DNSelectAB(27:15..15): BOOLEAN,
fill26(28:0..14): [0..32767],
DDataInAB(28:15..15): BOOLEAN,
fill27(29:0..14): [0..32767],
DDataOutAB(29:15..15): BOOLEAN];
-- port indices:
CacheDrive: TYPE = MACHINE DEPENDENT RECORD [
fill0(0:0..14): [0 .. 32768),
PhA(0:15..15): BOOLEAN,
fill1(1:0..14): [0 .. 32768),
PhB(1:15..15): BOOLEAN,
fill2(2:0..14): [0 .. 32768),
Vdd(2:15..15): BOOLEAN,
fill3(3:0..14): [0 .. 32768),
Gnd(3:15..15): BOOLEAN,
fill4(4:0..14): [0 .. 32768),
PadVdd(4:15..15): BOOLEAN,
fill5(5:0..14): [0 .. 32768),
PadGnd(5:15..15): BOOLEAN,
fill6(6:0..14): [0 .. 32768),
PData(6:15..15): BOOLEAN,
fill7(7:0..14): [0 .. 32768),
PParityB(7:15..15): BOOLEAN,
fill8(8:0..14): [0 .. 32768),
PCmdA(8:15..15): BOOLEAN,
fill9(9:0..14): [0 .. 32768),
PRejectB(9:15..15): BOOLEAN,
fill10(10:0..14): [0 .. 32768),
PFaultB(10:15..15): BOOLEAN,
fill11(11:0..14): [0 .. 32768),
PNPError(11:15..15): BOOLEAN,
fill12(12:0..14): [0 .. 32768),
MDataBA(12:15..15): BOOLEAN,
fill13(13:0..14): [0 .. 32768),
MCmdBA(13:15..15): BOOLEAN,
fill14(14:0..14): [0 .. 32768),
MNShared(14:15..15): BOOLEAN,
fill15(15:0..14): [0 .. 32768),
MParityBA(15:15..15): BOOLEAN,
fill16(16:0..14): [0 .. 32768),
MNError(16:15..15): BOOLEAN,
fill17(17:0..14): [0 .. 32768),
MReadyBA(17:15..15): BOOLEAN,
fill18(18:0..14): [0 .. 32768),
MRq(18:15..15): BOOLEAN,
fill19(19:0..14): [0 .. 32768),
MNewRq(19:15..15): BOOLEAN,
fill20(20:0..14): [0 .. 32768),
MGnt(20:15..15): BOOLEAN,
fill21(21:0..14): [0 .. 32768),
ResetAB(21:15..15): BOOLEAN,
fill22(22:0..14): [0 .. 32768),
DHoldAB(22:15..15): BOOLEAN,
fill23(23:0..14): [0 .. 32768),
DShiftAB(23:15..15): BOOLEAN,
fill24(24:0..14): [0 .. 32768),
DExecuteAB(24:15..15): BOOLEAN,
fill25(25:0..14): [0 .. 32768),
DNSelectAB(25:15..15): BOOLEAN,
fill26(26:0..14): [0 .. 32768),
DDataInAB(26:15..15): BOOLEAN,
fill27(27:0..14): [0 .. 32768),
DDataOutAB(27:15..15): BOOLEAN];
CacheStateRef: TYPE = REF CacheStateRec;
CacheStateRec: TYPE = RECORD [
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
];
CacheExpand: ExpandProc = {
PrivateLookupNode: PROC [name: ROPE] RETURNS [node: Node] = {node ← RoseCreate.LookupNode[from: thisCell, path: LIST[name]]};
PhA: Node ← PrivateLookupNode["PhA"];
PhB: Node ← PrivateLookupNode["PhB"];
Vdd: Node ← PrivateLookupNode["Vdd"];
Gnd: Node ← PrivateLookupNode["Gnd"];
PadVdd: Node ← PrivateLookupNode["PadVdd"];
PadGnd: Node ← PrivateLookupNode["PadGnd"];
PData: Node ← PrivateLookupNode["PData"];
PParityB: Node ← PrivateLookupNode["PParityB"];
PCmdA: Node ← PrivateLookupNode["PCmdA"];
PRejectB: Node ← PrivateLookupNode["PRejectB"];
PFaultB: Node ← PrivateLookupNode["PFaultB"];
PNPError: Node ← PrivateLookupNode["PNPError"];
MDataBA: Node ← PrivateLookupNode["MDataBA"];
MCmdBA: Node ← PrivateLookupNode["MCmdBA"];
MNShared: Node ← PrivateLookupNode["MNShared"];
MParityBA: Node ← PrivateLookupNode["MParityBA"];
MNError: Node ← PrivateLookupNode["MNError"];
MReadyBA: Node ← PrivateLookupNode["MReadyBA"];
MRq: Node ← PrivateLookupNode["MRq"];
MNewRq: Node ← PrivateLookupNode["MNewRq"];
MGnt: Node ← PrivateLookupNode["MGnt"];
ResetAB: Node ← PrivateLookupNode["ResetAB"];
DHoldAB: Node ← PrivateLookupNode["DHoldAB"];
DShiftAB: Node ← PrivateLookupNode["DShiftAB"];
DExecuteAB: Node ← PrivateLookupNode["DExecuteAB"];
DNSelectAB: Node ← PrivateLookupNode["DNSelectAB"];
DDataInAB: Node ← PrivateLookupNode["DDataInAB"];
DDataOutAB: Node ← PrivateLookupNode["DDataOutAB"];
NodeCreateHack1: PROC [name: ROPE] RETURNS [node: Node] = {node ← RoseCreate.CreateNode[within: thisCell, name: name, type: NumTypes.boolType]};
PKillRequestB: Node ← NodeCreateHack1["PKillRequestB"];
LatchBias: Node ← NodeCreateHack1["LatchBias"];
PhAb: Node ← NodeCreateHack1["PhAb"];
nPhAb: Node ← NodeCreateHack1["nPhAb"];
PhBb: Node ← NodeCreateHack1["PhBb"];
nPhBb: Node ← NodeCreateHack1["nPhBb"];
PhAh: Node ← NodeCreateHack1["PhAh"];
PhBh: Node ← NodeCreateHack1["PhBh"];
Resetb: Node ← NodeCreateHack1["Resetb"];
NodeCreateHack2: PROC [name: ROPE] RETURNS [node: Node] = {node ← RoseCreate.CreateNode[within: thisCell, name: name, type: NumTypes.NumType[24]]};
VirtualPage: Node ← NodeCreateHack2["VirtualPage"];
nVirtualPage: Node ← NodeCreateHack2["nVirtualPage"];
NodeCreateHack3: PROC [name: ROPE] RETURNS [node: Node] = {node ← RoseCreate.CreateNode[within: thisCell, name: name, type: NumTypes.NumType[6]]};
VirtualBlock: Node ← NodeCreateHack3["VirtualBlock"];
nVirtualBlock: Node ← NodeCreateHack3["nVirtualBlock"];
RealPage: Node ← NodeCreateHack2["RealPage"];
nRealPage: Node ← NodeCreateHack2["nRealPage"];
RealBlock: Node ← NodeCreateHack3["RealBlock"];
nRealBlock: Node ← NodeCreateHack3["nRealBlock"];
CAMPageAccess: Node ← RoseCreate.CreateNode[within: thisCell, name: "CAMPageAccess", type: SwitchTypes.Bundle[24]];
nCAMPageAccess: Node ← RoseCreate.CreateNode[within: thisCell, name: "nCAMPageAccess", type: SwitchTypes.Bundle[24]];
CAMBlockAccess: Node ← RoseCreate.CreateNode[within: thisCell, name: "CAMBlockAccess", type: SwitchTypes.Bundle[6]];
nCAMBlockAccess: Node ← RoseCreate.CreateNode[within: thisCell, name: "nCAMBlockAccess", type: SwitchTypes.Bundle[6]];
NodeCreateHack4: PROC [name: ROPE] RETURNS [node: Node] = {node ← RoseCreate.CreateNode[within: thisCell, name: name, type: SwitchTypes.Bundle[66]]};
PBits: Node ← NodeCreateHack4["PBits"];
nPBits: Node ← NodeCreateHack4["nPBits"];
MBits: Node ← NodeCreateHack4["MBits"];
nMBits: Node ← NodeCreateHack4["nMBits"];
nVirtualMatch: Node ← NodeCreateHack1["nVirtualMatch"];
nMatchPageClean: Node ← NodeCreateHack1["nMatchPageClean"];
nMatchCellShared: Node ← NodeCreateHack1["nMatchCellShared"];
nMapValid: Node ← NodeCreateHack1["nMapValid"];
nRealMatch: Node ← NodeCreateHack1["nRealMatch"];
nVictimClean: Node ← NodeCreateHack1["nVictimClean"];
nMatchTIP: Node ← NodeCreateHack1["nMatchTIP"];
CellAdr: Node ← RoseCreate.CreateNode[within: thisCell, name: "CellAdr", type: NumTypes.NumType[8]];
nCellAdr: Node ← RoseCreate.CreateNode[within: thisCell, name: "nCellAdr", type: NumTypes.NumType[8]];
VirtualAccess: Node ← NodeCreateHack1["VirtualAccess"];
nVirtualAccess: Node ← NodeCreateHack1["nVirtualAccess"];
SelCell: Node ← NodeCreateHack1["SelCell"];
SelVictimAdr: Node ← NodeCreateHack1["SelVictimAdr"];
SelMapAdr: Node ← NodeCreateHack1["SelMapAdr"];
SelRealData: Node ← NodeCreateHack1["SelRealData"];
SelPageFlag: Node ← NodeCreateHack1["SelPageFlag"];
SelVictimData: Node ← NodeCreateHack1["SelVictimData"];
SelRealAdr: Node ← NodeCreateHack1["SelRealAdr"];
FinishSharedStore: Node ← NodeCreateHack1["FinishSharedStore"];
NodeCreateHack5: PROC [name: ROPE] RETURNS [node: Node] = {node ← RoseCreate.CreateNode[within: thisCell, name: name, type: SwitchTypes.bitType]};
VPValid: Node ← NodeCreateHack5["VPValid"];
nVPValid: Node ← NodeCreateHack5["nVPValid"];
RPValid: Node ← NodeCreateHack5["RPValid"];
nRPValid: Node ← NodeCreateHack5["nRPValid"];
RPDirty: Node ← NodeCreateHack5["RPDirty"];
nRPDirty: Node ← NodeCreateHack5["nRPDirty"];
Master: Node ← NodeCreateHack5["Master"];
nMaster: Node ← NodeCreateHack5["nMaster"];
Shared: Node ← NodeCreateHack5["Shared"];
nShared: Node ← NodeCreateHack5["nShared"];
Victim: Node ← NodeCreateHack5["Victim"];
nVictim: Node ← NodeCreateHack5["nVictim"];
TIP: Node ← NodeCreateHack5["TIP"];
nTIP: Node ← NodeCreateHack5["nTIP"];
Broken: Node ← NodeCreateHack5["Broken"];
nBroken: Node ← NodeCreateHack5["nBroken"];
MAdrLow: Node ← NodeCreateHack1["MAdrLow"];
nMAdrLow: Node ← NodeCreateHack1["nMAdrLow"];
PAdrLow: Node ← NodeCreateHack1["PAdrLow"];
nPAdrLow: Node ← NodeCreateHack1["nPAdrLow"];
PStore: Node ← NodeCreateHack1["PStore"];
VictimFeedback: Node ← NodeCreateHack1["VictimFeedback"];
nVictimFeedback: Node ← NodeCreateHack1["nVictimFeedback"];
ShiftVictim: Node ← NodeCreateHack1["ShiftVictim"];
nShiftVictim: Node ← NodeCreateHack1["nShiftVictim"];
ForceDataSelect: Node ← NodeCreateHack1["ForceDataSelect"];
MDoneAB: Node ← NodeCreateHack1["MDoneAB"];
MHeldAB: Node ← NodeCreateHack1["MHeldAB"];
MFaultAB: Node ← RoseCreate.CreateNode[within: thisCell, name: "MFaultAB", type: EnumTypes.EnumType["Dragon.PBusFaults"]];
PAdrHigh: Node ← NodeCreateHack1["PAdrHigh"];
PAdrLowToM: Node ← NodeCreateHack1["PAdrLowToM"];
PCmdToMAB: Node ← RoseCreate.CreateNode[within: thisCell, name: "PCmdToMAB", type: EnumTypes.EnumType["Dragon.PBusCommands"]];
DoShiftBA: Node ← NodeCreateHack1["DoShiftBA"];
DoExecuteBA: Node ← NodeCreateHack1["DoExecuteBA"];
DoHoldBA: Node ← NodeCreateHack1["DoHoldBA"];
ShiftDataToPCAM: Node ← NodeCreateHack1["ShiftDataToPCAM"];
ShiftDataToMCtlPads: Node ← NodeCreateHack1["ShiftDataToMCtlPads"];
[] ← RoseCreate.CreateCell[within: thisCell, instanceName: "pInterface", className: "PInterface", interfaceNodes: ""];
[] ← RoseCreate.CreateCell[within: thisCell, instanceName: "mInterface", className: "MInterface", interfaceNodes: ""];
[] ← RoseCreate.CreateCell[within: thisCell, instanceName: "cacheEntries", className: "CacheEntries", interfaceNodes: ""];
};
CreateCacheIO: IOCreator = {
cell.realCellStuff.newIO ← NEW [CacheIORec];
cell.realCellStuff.oldIO ← NEW [CacheIORec];
};
InitializeCache: Initializer = {
IF leafily THEN
BEGIN
ioRec: CacheIORef ← NARROW[cell.realCellStuff.newIO];
state: CacheStateRef ← NEW [CacheStateRec];
cell.realCellStuff.state ← state;
BEGIN OPEN ioRec, state;
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
END;
END;
};
CacheEvalSimple: CellProc =
BEGIN
newIO: CacheIORef ← NARROW[cell.realCellStuff.newIO];
state: CacheStateRef ← NARROW[cell.realCellStuff.state];
BEGIN OPEN newIO, state;
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;
END;
END;
CacheBBTest: CellTestProc =
BEGIN
instructions: CacheIORef ← NARROW[io];
drive: REF CacheDrive ← NARROW[driveAsAny];
BEGIN OPEN instructions;
cacheTester[instructions, drive, handle];
END;
END;
CachePorts: Ports ← NEW [PortsRep[28]];
--explicitly requested 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]];
RegisterCells[];
END.