State
mAdrCtrA, mAdrCtrB: CARDINAL, -- static on both clocks though!
requireCountA, requireCountB: CARDINAL,
refreshCountA, refreshCountB: CARDINAL,
sMAdrLow, snMAdrLow, sMAdrHigh, snMAdrHigh: BOOL,
sCellAdr, snCellAdr: BitWord,
sReadEntry, snReadEntry, sWriteEntry, snWriteEntry: BOOL,
addressCycle, refreshCycle: BOOL
EvalSimple
Assert[NOT MoreThanOneOf[EntryIncMAdrCtr, EntryZeroMAdrCtr, EntryPAdrToMAdrCtr]];
Assert[NOT MoreThanOneOf[ShiftFeedBack, nShiftFeedBack]];
Assert[NOT MoreThanOneOf[ShiftEqual, nShiftEqual]];
Assert[NOT MoreThanOneOf[ShiftShift, nShiftShift]];
IF PhAh
THEN {
refreshCountA ← refreshCountB;
requireCountA ← requireCountB;
};
IF PhBh
THEN {
refreshCycle ← EntryRefresh OR (EntryGetAdrRefresh AND (requireCountA=31 OR IsNoOpBA));
addressCycle ← EntryGetAddress OR (EntryGetAdrRefresh AND NOT refreshCycle);-- this could be made better so that GetAddress cycles that do not require the select lines to the cells also cause refresh.
IF refreshCycle
THEN {
requireCountB ← 0;
refreshCountB ← (refreshCountA+1) MOD 512;
}
ELSE {
IF requireCountA<31 THEN requireCountB ← (requireCountA+1) MOD 32;
refreshCountB ← refreshCountA;
};
};
IF PhAh THEN mAdrCtrA ← IF EntryMDataIToMAdrCtr THEN ECFD[MDataI, 32, 30, 2] ELSE mAdrCtrB;
IF EntryIncMAdrCtr THEN mAdrCtrB ← (mAdrCtrA + 1) MOD 4;
IF EntryZeroMAdrCtr THEN mAdrCtrB ← 0;
IF EntryPAdrToMAdrCtr
THEN {
mAdrCtrB ← IBIW[PAdrLowToM, mAdrCtrB, 2, 1];
mAdrCtrB ← IBIW[PAdrHigh, mAdrCtrB, 2, 0];
};
IF PhBh AND NOT (EntryIncMAdrCtr OR EntryZeroMAdrCtr OR EntryPAdrToMAdrCtr) THEN mAdrCtrB ← mAdrCtrA; -- really should just have another bit coming out of the ROM to handle this case
MAdrLow ←
SELECT
TRUE
FROM
EntryMAdrCtrToMAdr => EBFW[mAdrCtrB, 2, 1],
refreshCycle => EBFW[refreshCountB, 9, 8],
ENDCASE => FALSE; -- don't really care what it is
nMAdrLow ← NOT MAdrLow;
MAdrHigh ← EBFW[mAdrCtrB, 2, 0];
IF EntryLowBitsAccessToMDataI
THEN {
MDataI ← IBID[PAdrHigh, MDataI, 32, 30];
MDataI ← IBID[PAdrLowToM, MDataI, 32, 31];
};
IF EntryLowBitsZeroToMDataI THEN MDataI ← ICID[0, MDataI, 32, 30, 2];
CellAdr ← IF DoExecuteBA THEN sCellAdr ELSE MWTW[refreshCountB, 9, 0, 8, 0, 8, 0, 8];
nCellAdr ← WNOT[CellAdr, 8];
IF refreshCycle THEN VirtualAccess ← EBFW[refreshCountB, 9, 8];
IF EntryVirtualAccess THEN VirtualAccess ← TRUE;
IF addressCycle OR EntrynVirtualAccess THEN VirtualAccess ← FALSE;
nVirtualAccess ← NOT VirtualAccess;
ShiftVictim ← PhAh AND EntryShiftVictim;
nShiftVictim ← NOT ShiftVictim;
VictimFeedback ← PhAb AND (NOT EntryShiftVictim OR DoHoldBA);
nVictimFeedback ← NOT VictimFeedback;
ForceDataSelect ← PhAb AND Resetb;
GetAddressDoneBA ← addressCycle;
SelCell ← ShiftExecute OR (PhAb AND refreshCycle);
SelVictimAdr ← PhAh AND ((addressCycle AND GetAdrCmdBA=VictimReal) OR (EntrySelectVictimOrOrphan AND NOT MatchRealBA AND NOT addressCycle));
SelMapAdr ← PhAh AND addressCycle AND GetAdrCmdBA=RefRealAssemble;
SelRealData ← PhAh AND (EntrySelRealData OR (EntrySelectVictimOrOrphan AND MatchRealBA));
SelPageFlag ← PhAh AND EntrySelPageFlag;
SelVictimData ← PhAh AND (EntrySelVictimData OR (EntrySelectVictimOrOrphan AND NOT MatchRealBA));
SelRealAdr ← PhAh AND EntrySelectVictimOrOrphan AND MatchRealBA AND NOT addressCycle;
FinishSharedStore ← EntryFinishSharedStore;
IF ShiftShift
THEN {
snMAdrLow ← NOT ShiftDataToEntryCtl;
snMAdrHigh ← NOT sMAdrLow;
snReadEntry ← NOT sMAdrHigh;
snWriteEntry ← NOT sReadEntry;
snCellAdr ← MWTW[WNOT[sCellAdr, 8], 8, 1, 7, snCellAdr, 8, 0, 7];
snCellAdr ← IBIW[NOT sWriteEntry, snCellAdr, 8, 7];
};
IF ShiftFeedBack
THEN {
snMAdrLow ← NOT sMAdrLow;
snMAdrHigh ← NOT sMAdrHigh;
snReadEntry ← NOT sReadEntry;
snWriteEntry ← NOT sWriteEntry;
snCellAdr ← WNOT[sCellAdr, 8];
};
IF ShiftEqual
THEN {
sMAdrLow ← NOT snMAdrLow;
sMAdrHigh ← NOT snMAdrHigh;
sReadEntry ← NOT snReadEntry;
sWriteEntry ← NOT snWriteEntry;
sCellAdr ← WNOT[snCellAdr, 8];
ShiftDataToCAMCtl ← EBFW[sCellAdr, 8, 0];
};
ReadEntry ← sReadEntry;
WriteEntry ← sWriteEntry;