CacheEntry.rose
Last edited by: Barth, May 22, 1984 8:16:56 pm PDT
Imports BitOps, BitSwOps, Dragon;
Open BitOps, BitSwOps, Dragon;
Cedar
memBits: TYPE = ARRAY [0..5) OF BitWord;
;
CacheEntry: CELL[
Timing and housekeeping interface
Vdd, Gnd<BOOL,
Buffered timing and housekeeping interface
PhAb, PhBb, nPhBb<BOOL,
Resetb<BOOL,
CAM interface
VirtualPage, nVirtualPage<INT[24],
VirtualBlock, nVirtualBlock<INT[6],
RealPage, nRealPage<INT[24],
RealBlock, nRealBlock<INT[6],
CAMPageAccess, nCAMPageAccess=SWITCH[24]-S-X,
CAMBlockAccess, nCAMBlockAccess=SWITCH[6]-S-X,
RAM access
PBits, nPBits=SWITCH[66]-S-X,
MBits, nMBits=SWITCH[66]-S-X,
Cell control
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-S-X,
MAdrLow, nMAdrLow<BOOL,
PAdrLow, nPAdrLow<BOOL,
PStore<BOOL,
VictimFeedback, nVictimFeedback, ShiftVictim, nShiftVictim<BOOL,
ForceDataSelect<BOOL,
Victim shift
VictimIn<BOOL,
VictimOut>BOOL
]
InitData
cellNumber: BitWord
State
vpValid, nvpValid: BOOL,
rpValid, nrpValid: BOOL,
rpDirty, nrpDirty: BOOL,
master, nmaster: BOOL,
shared, nshared: BOOL,
victim, nvictim: BOOL,
tip, ntip: BOOL,
broken, nbroken: BOOL,
hexVirtualPage, hexRealPage, hexBlock: HexWord,
words: ARRAY [0..4) OF HexWord,
parity: ARRAY [0..4) OF BOOL,
virtualPage, nvirtualPage: BitDWord,
realPage, nrealPage: BitDWord,
block, nblock: BitWord,
data: ARRAY [0..2) OF ARRAY BOOLEAN OF memBits,
vpMatch, vblMatch, rpMatch, rblMatch: BOOL,
selVMap, vSelCell, selRMap, rSelCell: BOOL,
decodeSelect, victimAdrSelect, victimDataSelect, victimFlagSelect: BOOL,
realMatchSelect, dataSelect, addressSelect, virtualDataSelect: BOOL,
thisCellAdr: BitWord
Initializer
thisCellAdr ← cellNumber;
EvalSimple
oldMemBits: ARRAY [0..2) OF memBits;
RWB: PROC [access: BOOL, bus, nBus: Switch, bit, nbit: BOOL] RETURNS [newBus, nNewBus: Switch, newBit, newnBit: BOOL] = {
s: SwitchTypes.Strength ← IF access THEN drive ELSE none;
IF access THEN {
bit ← (NOT nbit) AND bus.val=H;
nbit ← (NOT bit) AND nBus.val=H;
bit ← (NOT nbit) AND bus.val=H;
};
nNewBus ← SIBISS[bit, nBus, [[none, X], [s, L]]];
newBus ← SIBISS[nbit, bus, [[none, X], [s, L]]];
newBit ← bit;
newnBit ← nbit;
};
RWW: PROC [access: BOOL, busD, nBusD: SwitchMWord, field, nfield: BitWord, fieldWidth: CARDINAL] RETURNS [newField, newnField: BitWord] = TRUSTED {
s: SwitchTypes.Strength ← IF access THEN drive ELSE none;
IF access THEN FOR i:CARDINAL IN [0..fieldWidth) DO
field ← IBIW[(NOT EBFW[nfield, fieldWidth, i]) AND busD[i].val=H, field, fieldWidth, i];
nfield ← IBIW[(NOT EBFW[field, fieldWidth, i]) AND nBusD[i].val=H, nfield, fieldWidth, i];
field ← IBIW[(NOT EBFW[nfield, fieldWidth, i]) AND busD[i].val=H, field, fieldWidth, i];
ENDLOOP;
SCWTS[field, fieldWidth, 0, fieldWidth, nBusD, fieldWidth, 0, fieldWidth, [[none, X], [s, L]]];
SCWTS[nfield, fieldWidth, 0, fieldWidth, busD, fieldWidth, 0, fieldWidth, [[none, X], [s, L]]];
newField ← field;
newnField ← nfield;
};
RWD: PROC [access: BOOL, busD, nBusD: SwitchMWord, field, nfield: BitDWord, fieldWidth: CARDINAL] RETURNS [newField, newnField: BitDWord] = TRUSTED {
s: SwitchTypes.Strength ← IF access THEN drive ELSE none;
IF access THEN FOR i:CARDINAL IN [0..fieldWidth) DO
field ← IBID[(NOT EBFD[nfield, fieldWidth, i]) AND busD[i].val=H, field, fieldWidth, i];
nfield ← IBID[(NOT EBFD[field, fieldWidth, i]) AND nBusD[i].val=H, nfield, fieldWidth, i];
field ← IBID[(NOT EBFD[nfield, fieldWidth, i]) AND busD[i].val=H, field, fieldWidth, i];
ENDLOOP;
SCDTS[field, fieldWidth, 0, fieldWidth, nBusD, fieldWidth, 0, fieldWidth, [[none, X], [s, L]]];
SCDTS[nfield, fieldWidth, 0, fieldWidth, busD, fieldWidth, 0, fieldWidth, [[none, X], [s, L]]];
newField ← field;
newnField ← nfield;
};
RWM: PROC [access: BOOL, busD, nBusD: SwitchMWord, field, nfield: BitMWord, fieldWidth: CARDINAL] = TRUSTED {
s: SwitchTypes.Strength ← IF access THEN drive ELSE none;
IF access THEN FOR i:CARDINAL IN [0..fieldWidth) DO
IBIM[(NOT EBFM[nfield, fieldWidth, i]) AND busD[i].val=H, field, fieldWidth, i];
IBIM[(NOT EBFM[field, fieldWidth, i]) AND nBusD[i].val=H, nfield, fieldWidth, i];
IBIM[(NOT EBFM[nfield, fieldWidth, i]) AND busD[i].val=H, field, fieldWidth, i];
ENDLOOP;
SCMTS[field, fieldWidth, 0, fieldWidth, nBusD, fieldWidth, 0, fieldWidth, [[none, X], [s, L]]];
SCMTS[nfield, fieldWidth, 0, fieldWidth, busD, fieldWidth, 0, fieldWidth, [[none, X], [s, L]]];
};
Assert[NOT MoreThanOneOf[PAdrLow, nPAdrLow]];
Assert[NOT MoreThanOneOf[MAdrLow, nMAdrLow]];
Assert[MAdrLow OR nMAdrLow];
Assert[NOT MoreThanOneOf[VictimFeedback, ShiftVictim]];
Assert[NOT MoreThanOneOf[VictimFeedback, nVictimFeedback]];
Assert[NOT MoreThanOneOf[ShiftVictim, nShiftVictim]];
Assert[NOT MoreThanOneOf[ShiftVictim, PhBb]];
FOR i:[0..2) IN [0..2) DO
oldMemBits[i] ← data[i][TRUE];
ENDLOOP;
vpMatch ← DAND[nVirtualPage, virtualPage]=BitDWordZero AND DAND[nvirtualPage, VirtualPage]=BitDWordZero;
vblMatch ← WAND[nVirtualBlock, block]=0 AND WAND[nblock, VirtualBlock]=0;
rpMatch ← DAND[nRealPage, realPage]=BitDWordZero AND DAND[nrealPage, RealPage]=BitDWordZero;
rblMatch ← WAND[nRealBlock, block]=0 AND WAND[nblock, RealBlock]=0;
selVMap ← NOT broken AND vpValid AND vpMatch;
vSelCell ← selVMap AND vblMatch;
selRMap ← NOT broken AND rpValid AND rpMatch;
rSelCell ← selRMap AND rblMatch;
IF selVMap AND PhBb THEN {
nMapValid ← FALSE;
IF nrpDirty THEN nMatchPageClean ← FALSE;
};
IF rSelCell AND PhBb THEN nRealMatch ← FALSE;
decodeSelect ← SelCell AND CellAdr=thisCellAdr AND CellAdr=WNOT[nCellAdr, 8];
victimAdrSelect ← SelVictimAdr AND victim;
victimDataSelect ← SelVictimData AND victim;
realMatchSelect ← SelRealData AND rSelCell;
IF NOT PhAb THEN dataSelect ← FALSE;
IF decodeSelect OR realMatchSelect OR victimDataSelect OR ForceDataSelect THEN dataSelect ← TRUE;
IF NOT PhAb THEN victimFlagSelect ← FALSE;
IF decodeSelect OR ForceDataSelect THEN victimFlagSelect ← TRUE;
IF NOT PhAb THEN addressSelect ← FALSE;
IF decodeSelect OR victimAdrSelect THEN addressSelect ← TRUE;
IF PhBb AND vSelCell THEN {
nVirtualMatch ← FALSE;
IF PStore AND rpDirty AND (nshared OR FinishSharedStore) THEN {master ← TRUE; nmaster ← FALSE};
IF shared THEN nMatchCellShared ← FALSE;
IF tip THEN nMatchTIP ← FALSE;
};
TRUSTED {
busD: SwitchMWord ← DESCRIPTOR[PBits];
nBusD: SwitchMWord ← DESCRIPTOR[nPBits];
access: BOOL ← PhBb AND vSelCell AND (NOT (PStore AND (nrpDirty OR (shared AND NOT FinishSharedStore))));
IF NOT PAdrLow THEN { -- mumbo jumbo to ensure that at least one of these if clauses executes so that the instructions get updated
dataFD: BitMWord ← DESCRIPTOR[data[0][FALSE]];
dataTD: BitMWord ← DESCRIPTOR[data[0][TRUE]];
RWM[access AND nPAdrLow, busD, nBusD, dataTD, dataFD, 66];
};
IF PAdrLow THEN {
dataFD: BitMWord ← DESCRIPTOR[data[1][FALSE]];
dataTD: BitMWord ← DESCRIPTOR[data[1][TRUE]];
RWM[access, busD, nBusD, dataTD, dataFD, 66];
};
};
TRUSTED {
busD: SwitchMWord ← DESCRIPTOR[MBits];
nBusD: SwitchMWord ← DESCRIPTOR[nMBits];
access: BOOL ← dataSelect;
IF nMAdrLow THEN {
dataFD: BitMWord ← DESCRIPTOR[data[0][FALSE]];
dataTD: BitMWord ← DESCRIPTOR[data[0][TRUE]];
RWM[access, busD, nBusD, dataTD, dataFD, 66];
};
IF MAdrLow THEN {
dataFD: BitMWord ← DESCRIPTOR[data[1][FALSE]];
dataTD: BitMWord ← DESCRIPTOR[data[1][TRUE]];
RWM[access, busD, nBusD, dataTD, dataFD, 66];
};
[RPValid, nRPValid, rpValid, nrpValid] ← RWB[access, RPValid, nRPValid, rpValid, nrpValid];
[Master, nMaster, master, nmaster] ← RWB[access, Master, nMaster, master, nmaster];
[Shared, nShared, shared, nshared] ← RWB[access, Shared, nShared, shared, nshared];
[TIP, nTIP, tip, ntip] ← RWB[access, TIP, nTIP, tip, ntip];
[Broken, nBroken, broken, nbroken] ← RWB[access, Broken, nBroken, broken, nbroken];
};
{
access: BOOL ← victimFlagSelect;
[Victim, nVictim, victim, nvictim] ← RWB[access AND NOT (thisCellAdr=0 AND Resetb), Victim, nVictim, victim, nvictim];
};
{
access: BOOL ← dataSelect OR (SelPageFlag AND selRMap);
[VPValid, nVPValid, vpValid, nvpValid] ← RWB[access, VPValid, nVPValid, vpValid, nvpValid];
[RPDirty, nRPDirty, rpDirty, nrpDirty] ← RWB[access, RPDirty, nRPDirty, rpDirty, nrpDirty];
};
TRUSTED {
busD: SwitchMWord ← DESCRIPTOR[CAMPageAccess];
nBusD: SwitchMWord ← DESCRIPTOR[nCAMPageAccess];
[virtualPage, nvirtualPage] ← RWD[(addressSelect AND VirtualAccess) OR (rSelCell AND SelRealAdr), busD, nBusD, virtualPage, nvirtualPage, 24];
};
TRUSTED {
busD: SwitchMWord ← DESCRIPTOR[CAMPageAccess];
nBusD: SwitchMWord ← DESCRIPTOR[nCAMPageAccess];
[realPage, nrealPage] ← RWD[(addressSelect AND nVirtualAccess) OR (selVMap AND SelMapAdr), busD, nBusD, realPage, nrealPage, 24];
};
TRUSTED {
busD: SwitchMWord ← DESCRIPTOR[CAMBlockAccess];
nBusD: SwitchMWord ← DESCRIPTOR[nCAMBlockAccess];
[block, nblock] ← RWW[addressSelect, busD, nBusD, block, nblock, 6];
};
IF ShiftVictim THEN nvictim ← NOT VictimIn;
IF VictimFeedback THEN nvictim ← NOT victim;
IF PhBb THEN victim ← NOT nvictim; -- this is where nPhBb is used
VictimOut ← IF broken THEN VictimIn ELSE victim;
IF victim AND nmaster AND PhBb THEN nVictimClean ← FALSE;
IF thisCellAdr=0 AND Resetb THEN {
victim ← TRUE;
nvictim ← FALSE;
};
hexVirtualPage ← ELFD[virtualPage, 24, 0, 24];
hexRealPage ← ELFD[realPage, 24, 0, 24];
hexBlock ← ELFW[block, 6, 0, 6];
TRUSTED {
assembleWord: BitDWord;
diff: BOOLFALSE;
FOR i:[0..2) IN [0..2) DO
IF oldMemBits[i]#data[i][TRUE] THEN {diff ← TRUE; EXIT};
ENDLOOP;
IF diff OR Resetb THEN FOR k:[0..2) IN [0..2) DO
FOR j:[0..2) IN [0..2) DO
desc: BitMWord ← DESCRIPTOR[data[j][TRUE]];
FOR i:[0..32) IN [0..32) DO
assembleWord ← IBID[EBFM[desc, 66, (2*i)+k], assembleWord, 32, i];
ENDLOOP;
words[2*k+j] ← ELFD[assembleWord, 32, 0, 32];
parity[2*k+j] ← EBFM[desc, 66, 64+k];
ENDLOOP;
ENDLOOP;
}
ENDCELL