DIRECTORY
RoseTypes, Cache, RoseCreate, IO, BitOps, CacheOps, Cucumber, Dragon, Random, PrintTV, AMBridge, SwitchTypes;

CacheImpl: CEDAR PROGRAM
IMPORTS RoseCreate, BitOps, CacheOps, Cucumber, Dragon, Random, PrintTV, AMBridge, IO
EXPORTS Cache

= BEGIN OPEN
RoseTypes, Cache;

PBusCommands: TYPE = Dragon.PBusCommands;
PBusFaults: TYPE = Dragon.PBusFaults;
MBusCommands: TYPE = Dragon.MBusCommands;


RegisterCells: PROC =
BEGIN
END;
otherss: SymbolTable _ RoseCreate.GetOtherss["Cache.partsAssertions"];

OldCache: TYPE = RECORD [args: CacheArgs, ct: CellType];
oldCache: LIST OF OldCache _ NIL;
Cache: PUBLIC PROC [args: CacheArgs] RETURNS [ct: CellType]
= BEGIN
FOR old: LIST OF OldCache _ oldCache, old.rest WHILE old # NIL DO
IF old.first.args = args THEN RETURN [old.first.ct]
ENDLOOP;
ct _ RoseCreate.RegisterCellType[name: CacheName[args],
expandProc: NIL,
ioCreator: CreateCacheIO, driveCreator: CreateCacheDrive, initializer: InitializeCache,
evals: [EvalSimple: CacheEvalSimple],
tests: LIST[],
ports: CreateCachePorts[args]
,
typeData: NEW [CacheArgs _ args]];
oldCache _ CONS[[args, ct], oldCache];
END;

CacheName: PROC [args: CacheArgs] RETURNS [name: ROPE] = {
to: IO.STREAM _ IO.ROS[]; to.PutRope["Cache"];
TRUSTED {PrintTV.Print[tv: AMBridge.TVForReferent[NEW [CacheArgs _ args]], put: to, depth: 2]};
name _ IO.RopeFromROS[to]};

CreateCachePorts: PROC [args: CacheArgs] RETURNS [ports: Ports] = {ports _ RoseCreate.PortsFromFile["Cache.Cache.rosePorts"]};

CacheSwitchIORef: TYPE = REF CacheSwitchIORec;
CacheSwitchIORec: TYPE = RECORD [
PhA: SwitchTypes.SwitchVal
,PhB: SwitchTypes.SwitchVal
,PData: PACKED ARRAY [0 .. 32) OF SwitchTypes.SwitchVal
,PCmdA: PACKED ARRAY [0 .. 6) OF SwitchTypes.SwitchVal
,PRejectB: SwitchTypes.SwitchVal
,PFaultB: PACKED ARRAY [0 .. 4) OF SwitchTypes.SwitchVal
,MCmdAB: PACKED ARRAY [0 .. 4) OF SwitchTypes.SwitchVal
,MDataAB: PACKED ARRAY [0 .. 32) OF SwitchTypes.SwitchVal
,MParityAB: SwitchTypes.SwitchVal
,MNShared: SwitchTypes.SwitchVal
,MNError: SwitchTypes.SwitchVal
,MRq: SwitchTypes.SwitchVal
,MNewRq: SwitchTypes.SwitchVal
,MGnt: SwitchTypes.SwitchVal
,ResetAB: SwitchTypes.SwitchVal
,DHoldAB: SwitchTypes.SwitchVal
,DShiftAB: SwitchTypes.SwitchVal
,DExecuteAB: SwitchTypes.SwitchVal
,DNSelectAB: SwitchTypes.SwitchVal
,DDataInAB: SwitchTypes.SwitchVal
,DDataOutAB: SwitchTypes.SwitchVal
];

CacheSimpleIORef: TYPE = REF CacheSimpleIORec;
CacheSimpleIORec: TYPE = RECORD [
fill0: [0 .. 32767],
PhA: BOOLEAN
,fill1: [0 .. 32767],
PhB: BOOLEAN
,PData: ARRAY [0..2) OF CARDINAL
,fill3: [0 .. 1023],
PCmdA: PBusCommands
,fill4: [0 .. 32767],
PRejectB: BOOLEAN
,fill5: [0 .. 4095],
PFaultB: PBusFaults
,fill6: [0 .. 4095],
MCmdAB: MBusCommands
,MDataAB: ARRAY [0..2) OF CARDINAL
,fill8: [0 .. 32767],
MParityAB: BOOLEAN
,fill9: [0 .. 32767],
MNShared: BOOLEAN
,fill10: [0 .. 32767],
MNError: BOOLEAN
,fill11: [0 .. 32767],
MRq: BOOLEAN
,fill12: [0 .. 32767],
MNewRq: BOOLEAN
,fill13: [0 .. 32767],
MGnt: BOOLEAN
,fill14: [0 .. 32767],
ResetAB: BOOLEAN
,fill15: [0 .. 32767],
DHoldAB: BOOLEAN
,fill16: [0 .. 32767],
DShiftAB: BOOLEAN
,fill17: [0 .. 32767],
DExecuteAB: BOOLEAN
,fill18: [0 .. 32767],
DNSelectAB: BOOLEAN
,fill19: [0 .. 32767],
DDataInAB: BOOLEAN
,fill20: [0 .. 32767],
DDataOutAB: BOOLEAN
];

CacheDriveRef: TYPE = REF CacheDriveRec;
CacheDriveRec: TYPE = RECORD [driveRecordInitialPadding: DriveTagType, drive: PACKED ARRAY CachePort OF DriveLevel];
CachePort: TYPE = {
PhA, PhB, PData, PCmdA, PRejectB, PFaultB, MCmdAB, MDataAB, MParityAB, MNShared, MNError, MRq, MNewRq, MGnt, ResetAB, DHoldAB, DShiftAB, DExecuteAB, DNSelectAB, DDataInAB, DDataOutAB, CachePortTypePad21, CachePortTypePad22, CachePortTypePad23};

CreateCacheIO: PROC [ct: CellType, switch: BOOL] RETURNS [ioAsAny: REF ANY] --IOCreator-- = {
args: REF CacheArgs _ NARROW[ct.typeData];
{OPEN args;
ioAsAny _ IF switch THEN NEW[CacheSwitchIORec] ELSE NEW[CacheSimpleIORec];
};
};

CreateCacheDrive: PROC [ct: CellType] RETURNS [driveAsAny: REF ANY] --DriveCreator-- = {
args: REF CacheArgs _ NARROW[ct.typeData];
{OPEN args;
driveAsAny _ NEW[CacheDriveRec];
};
};

CacheStateRef: TYPE = REF CacheStateRec;
CacheStateRec: TYPE = RECORD [

phALast: BOOL _ FALSE, -- hack to improve simulation performance
cache: CacheOps.Cache,
randomStream: Random.RandomStream,
cycleNo: INT _ 0,
skipRejects: BOOL _ FALSE,
rejectCycles: NAT _ 0,
cmdAB: PBusCommands _ NoOp,
address, fetchData, storeDataBA: Dragon.HexWord _ 0,
cmdType: {noOp, reset, fetch, store} _ noOp,
pageFault, writeFault, firstBOfCmdBA: BOOL _ FALSE

];

InitializeCache: Initializer = {
args: REF CacheArgs _ NARROW [cell.type.typeData];
{OPEN args;
drive: CacheDriveRef _ NARROW[cell.realCellStuff.newDriveAsAny];
sw: CacheSwitchIORef _ NARROW[cell.realCellStuff.switchIO];
newIO: CacheSimpleIORef _ NARROW[cell.realCellStuff.newIO];
state: CacheStateRef _ NEW[CacheStateRec];
cell.realCellStuff.state _ state;
BEGIN OPEN drive, newIO, state;

cache _ cacheParm;
skipRejects _ skipRejectsParm;

END;
};
};

CacheEvalSimple: SimpleEval =
BEGIN
args: REF CacheArgs _ NARROW[cell.type.typeData];
drive: CacheDriveRef _ NARROW[cell.realCellStuff.newDriveAsAny];
sw: CacheSwitchIORef _ NARROW[cell.realCellStuff.switchIO];
newIO: CacheSimpleIORef _ NARROW[cell.realCellStuff.newIO];
state: CacheStateRef _ NARROW[cell.realCellStuff.state];
BEGIN OPEN drive, newIO, args, state;

IF PhA THEN
BEGIN

IF NOT phALast THEN
BEGIN
IF cmdType=store AND rejectCycles=0 AND NOT (pageFault OR writeFault) THEN
CacheOps.Write[cache, address, storeDataBA];
phALast _ TRUE;
END;

IF rejectCycles=0 THEN
address _ BitOps.ELFD[container: PData, containerWidth: 32, fieldPosition: 0, fieldWidth: 32];
cmdAB _ PCmdA;
PRejectB _ FALSE;
PFaultB _ none;
END;

IF PhB THEN
BEGIN

IF phALast THEN
BEGIN
IF ResetAB THEN
BEGIN
randomStream _ Random.Create[seed: randomSeed];
rejectCycles _ randomStream.ChooseInt[1, 5];
cmdType _ reset;
cycleNo _ 0;
cache _ CacheOps.NewCache[cache];
pageFault _ writeFault _ FALSE;
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;

rejectCycles _ (SELECT TRUE FROM
skipRejects => INT[0],
rejectCycles>0 => rejectCycles+randomStream.ChooseInt[0, 1],
ENDCASE => rejectCycles);

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;
phALast _ FALSE;
END;

SELECT TRUE FROM
cmdType=store AND firstBOfCmdBA =>
storeDataBA _ BitOps.ELFD[container: PData, containerWidth: 32, fieldPosition: 0, fieldWidth: 32];
cmdType=fetch AND rejectCycles=0 AND NOT pageFault =>
PData _ BitOps.ILID[source: fetchData, container: PData, containerWidth: 32, fieldPosition: 0, fieldWidth: 32];
ENDCASE => NULL; -- neither write nor read PData
END;

drive[PData] _
IF (PhB AND cmdType=fetch AND rejectCycles=0 AND NOT pageFault) THEN drive ELSE ignore;

PFaultB _ (SELECT TRUE FROM
NOT PhB => none,
rejectCycles=1 AND pageFault => page,
rejectCycles=1 AND writeFault => write,
ENDCASE => none);
PRejectB _ PhB AND rejectCycles>0;
drive[PFaultB] _ drive[PRejectB] _
IF PhA OR (PhB AND cmdType#noOp) THEN drive ELSE ignore;


END;
END;



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 ]};

randomSeed: INT _ -1;

Cucumber.Register[CacheStateHandler, CODE[CacheStateRec]];


RegisterCells[];

END.
���º��CacheImpl.Mesa
created by RoseTranslate 3.1.3 of September 5, 1985 12:14:34 pm PDT
created from Cache.Rose of September 9, 1985 4:18:38 pm PDT
created for McCreight.pa
created at September 23, 1985 3:29:37 pm PDT
Signal Type decls
explicitly requested CEDAR:
CacheTester: TYPE = PROC[i: CacheIORef, d: REF CacheDrive, h: CellTestHandle];
cacheTester: CacheTester;

RegisterCacheTester: PUBLIC PROC[ct: CacheTester]={
cacheTester _ ct};
Ê
��˜�Icodešœ™KšœC™CKšœ;™;Kšœ™Kšœ,™,K˜�K˜�šÏk	˜	KšœœM˜m—K˜�šÐbl	œœ˜KšœL˜UKšœ˜
—K˜�šœœ˜K˜—K˜�šœ™Kšœœ˜)Kšœœ˜%Kšœœ˜)K˜�—K˜�šÏn
œœ˜Kš˜Kšœ˜—K˜FK˜�Kšœ
œœ!˜8Kšœ
œœœ˜!šŸœœœœ˜;Kšœ˜šœœœœœ˜AKšœœœ˜3Kšœ˜—˜7Kšœœ˜K˜WK˜%Kšœœ˜K˜K˜Kšœ
œ˜"—Kšœœ˜&Kšœ˜—K˜�šŸ	œœœœ˜:Kš	œœœœœ˜.Kšœ+œ*˜_Kšœœ˜—K˜�KšŸœœœN˜~K˜�Kšœœœ˜.šœœœ˜!K˜K˜Kšœœœœ˜7Kšœœœ
œ˜6K˜ Kšœ
œœ
œ˜8Kšœ	œœ
œ˜7Kšœ
œœœ˜9K˜!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šœœœ2œœœ
˜tšœœ˜K˜ô—K˜�šŸ
œœœœœœÏc
œ˜]šœœ
œ˜*Kšœœ˜Kšœ
œœœœœ˜JK˜—K˜—K˜�šŸœœœœœ œ˜Xšœœ
œ˜*Kšœœ˜Kšœ
œ˜ K˜—K˜—K˜�Kšœœœ˜(šœœœ˜J˜�Jšœ	œœ )˜@J˜J˜"Jšœ	œ˜Jšœ
œœ˜Jšœœ˜J˜J˜4J˜,Jšœ&œ˜2J˜�K˜—K˜�˜ šœœ
œ˜2Kšœœ˜Kšœœ#˜@Kšœœ˜;Kšœœ˜;Kšœœ˜*K˜!šœœ˜J˜�J˜J˜J˜�Kšœ˜—K˜—K˜—K˜�˜Kš˜Kšœœ
œ˜1Kšœœ#˜@Kšœœ˜;Kšœœ˜;šœœ˜8šœœ˜%J˜�šœ˜Jš˜J˜�šœœ	˜Jš˜šœœœœœ
˜JJ˜,—Jšœ
œ˜Jšœ˜J˜�—šœ˜JšœœI˜^—J˜Jšœœ˜J˜Jšœ˜J˜�—šœ˜Jš˜J˜�šœ	˜Jš˜šœ	˜Jš˜J˜/J˜,J˜J˜J˜!Jšœœ˜Jš˜—Jšœ˜šœ˜Jš˜Jšœœ˜šœ˜˜Jš˜J˜J˜uJšœ˜—˜Jš˜J˜J˜Jšœ˜—˜-Jš˜Jšœœ2 
˜PJ˜Jšœ˜—Jšœ˜J˜�—šœœœ˜ Jšœœ˜J˜<Jšœ˜J˜�—Jšœœœœ˜DJšœœ˜Jš˜—š˜Jšœ ˜!J˜ J˜Jšœœ˜Jšœ˜—Jšœ
œ˜Jšœ˜J˜�—šœœ˜šœœ˜"JšœœI˜b—šœœœœ
˜5Jšœœ\˜o—Jšœœ ˜0—Jšœ˜J˜�—˜Jšœœœœœœœ˜WJ˜�—šœœœ˜Jšœ
˜Jšœœ˜%Jšœœ˜'Jšœ
˜—Jšœœ˜"˜"Jš
œœœœœ˜8—˜�J˜�——Kšœ˜—Kšœ˜—K˜�šœ™J˜�J™NJ™J™�™3J™—J˜�šœ&œ˜AJ˜$J˜J˜—J˜�šŸœœ
œœ	œœ'œœœ+ œ˜¹Jšœœ
˜ J˜�—šŸœœ
œœœœ'œœ œ˜¡Jšœœœ=˜pJ˜�—Jšœœ˜J˜�Jšœ%œ˜:—K˜�K˜�K˜K˜�Kšœ˜—�…—����!F��-��