{
sample: BOOL ← MIdleAB AND NOT SuppressPSampleAB;
store: BOOL ← PCmdToMAB=Store OR PCmdToMAB=StoreHold;
fetchOrStore: BOOL ← PCmdToMAB=Fetch OR PCmdToMAB=FetchHold OR store;
ioFetch: BOOL ← PCmdToMAB=IOFetch OR PCmdToMAB=IOFetchHold;
ioStore: BOOL ← PCmdToMAB=IOStore OR PCmdToMAB=IOStoreHold;
PWantsM ← ((fetchOrStore AND nVQMatchB) OR (store AND ((NOT nQuadSharedB) OR nPageDirtyB)) OR ioFetch OR ioStore OR PCmdToMAB=StoreHold OR PCmdToMAB=FetchHold) AND NOT SuppressPSampleAB;
Assert[NOT MoreThanOneOf[MIsDoneBA OR SetWantWSA, MIdleAB]];
IF PhAb
AND MIsDoneBA
THEN
FOR i:
CARDINAL
IN [0..5]
DO
IF
EBFW[CurrentPDemandsBA, 7, i]
THEN {
CurrentPDemandsAB ← IBIW[FALSE, CurrentPDemandsBA, 7, i];
EXIT;
};
ENDLOOP;
IF SetWantWSA THEN CurrentPDemandsAB ← IBIW[store AND LatchSharedBA, IF MIsDoneBA THEN CurrentPDemandsAB ELSE CurrentPDemandsBA, 7, 3];
IF PhAb AND CheckFaultsBA AND FaultBitsBA#None THEN CurrentPDemandsAB ← 1;
IF PhBb AND NOT sample THEN CurrentPDemandsBA ← CurrentPDemandsAB;
IF PhBb
AND sample
THEN {
CurrentPDemandsBA ← IBIW[TRUE, 0, 7, 6]; -- start with only idle required.
IF fetchOrStore AND nVirtualBlockMatchB AND SomeDirtyBA THEN CurrentPDemandsBA ← IBIW[TRUE, CurrentPDemandsBA, 7, 0];
IF (fetchOrStore AND nMapValidB) OR (store AND nPageDirtyB) THEN CurrentPDemandsBA ← IBIW[TRUE, CurrentPDemandsBA, 7, 1];
IF fetchOrStore AND nVQMatchB THEN CurrentPDemandsBA ← IBIW[TRUE, CurrentPDemandsBA, 7, 2];
IF store AND NOT nQuadSharedB THEN CurrentPDemandsBA ← IBIW[TRUE, CurrentPDemandsBA, 7, 3];
IF ioFetch THEN CurrentPDemandsBA ← IBIW[TRUE, CurrentPDemandsBA, 7, 4];
IF ioStore THEN CurrentPDemandsBA ← IBIW[TRUE, CurrentPDemandsBA, 7, 5];
HoldTypeBA ← PCmdToMAB=StoreHold OR PCmdToMAB=FetchHold OR PCmdToMAB=IOFetchHold OR PCmdToMAB=IOStoreHold;
NotHoldTypeBA ← NOT (PCmdToMAB=NoOp OR PCmdToMAB=StoreHold OR PCmdToMAB=FetchHold OR PCmdToMAB=IOFetchHold OR PCmdToMAB=IOStoreHold);
DidRMBA ← fetchOrStore AND nMapValidB;
DirtyPageBA ← store AND (nMapValidB OR nPageDirtyB);
IsCleanBA ← nPageDirtyB AND NOT DirtyPageBA;
};
};
IF SenseSharedB THEN LatchSharedBA ← MSharedSense;
IF PhAb THEN nVQMatchB ← nQuadSharedB ← nPageDirtyB ← nMapValidB ← nVirtualBlockMatchB ← TRUE;
IF PhBb THEN nRQMatchA ← nRealBlockMatchA ← TRUE;
IF PhAb THEN MDoneAB ← MIsDoneBA AND (ECFW[CurrentPDemandsBA, 7, 0, 6]=0 OR (CheckFaultsBA AND FaultBitsBA#None));
Bus arbitration
MIdleAB indicates that the low level M controller has finished with the last request from P that caused it to become active and so the M bus should be given up.
Holding indicates that a series of XHold commands are in progress on P and so the M bus should not be given up.
IF PhBb
THEN {
fault: BOOL ← CheckFaultsBA AND FaultBitsBA#None;
HoldingBA ← HoldingAB AND NOT fault;
MIdleBA ← IF (ReleaseMBusBA AND ECFW[CurrentPDemandsAB, 7, 0, 6]=0) OR fault THEN TRUE ELSE MIdleAB;
MGntBA ← MGntAB;
MNewRqIBA ← (NOT NewRqAB) AND MIdleBA AND PWantsM AND MRqAB AND (NOT HoldingBA);
NewRqBA ← NewRqAB;
MRqIBA ← NOT MIdleBA OR PWantsM OR HoldingBA;
};
IF PhAb
THEN {
wonArbitration: BOOL ← MGntSenseA AND (NOT MNewRqEnableBA OR NewRqBA);
MRqAB ← MRqIBA;
MGntAB ← MGntSenseA;
MIdleAB ← IF (wonArbitration OR HoldingBA) AND NOT ECFW[CurrentPDemandsBA, 7, 0, 6]=0 THEN FALSE ELSE MIdleBA;
HoldingAB ← IF wonArbitration AND HoldTypeBA THEN TRUE ELSE IF NotHoldTypeBA THEN FALSE ELSE HoldingBA;
MHeldAB ← HoldingBA AND HoldingAB;
NewRqAB ← MNewRqIBA;
}
MNewRqEnableBA ← MGntBA;
Current sequence
{
prioritySequence: BitWord ← BitWordZero;
slaveSequence: BitWord ←
SELECT MCmdIn
FROM
ReadQuad => 020H,
WriteQuad => 010H,
WriteSingle => 08H,
ChangeFlags => 04H,
IOReadDone, IOWriteDone, DataTransport, IORead, IOWrite, Reserve9, Reserve10, Reserve11, Reserve12, Reserve13, Reserve14, NoOp => 01H,
ENDCASE => ERROR;
FOR i:
CARDINAL
IN [0..6]
DO
IF
EBFW[CurrentPDemandsAB, 7, i]
THEN {
prioritySequence ← IBIW[TRUE, 0, 7, i];
EXIT;
};
ENDLOOP;
SELECT prioritySequence
FROM
040H => {GetAdrCmdAB ← VictimReal;
CmdOutAB ← WriteQuad}; -- WriteQuad
020H => {GetAdrCmdAB ← RefVirtual;
CmdOutAB ← IORead}; -- IORead, map operation
010H => {GetAdrCmdAB ←
IF DidRMBA
THEN RefRealMap
ELSE RefRealAssemble;
CmdOutAB ← ReadQuad}; -- ReadQuad
008H => {GetAdrCmdAB ← RefRealAssemble;
CmdOutAB ← WriteSingle};-- WriteSingle
004H => {GetAdrCmdAB ← RefVirtual;
CmdOutAB ← IORead};-- IORead, I/O operation
002H => {GetAdrCmdAB ← RefVirtual;
CmdOutAB ← IOWrite};-- IOWrite
001H => {GetAdrCmdAB ← RefVirtual;
CmdOutAB ← NoOp};-- NoOp
ENDCASE => Assert[TRUE, "priority sequence is zero"];
IF PhBb AND DoneBA THEN CurrentSequenceBA ← IF MGntSense THEN prioritySequence ELSE slaveSequence;
};
IF PhAb THEN MCmdOutAB ← CmdOutBA;
IF PhBb
THEN {
CmdOutBA ← CmdOutAB;
IODoneCommandBA ← MCmdIn=IOReadDone OR MCmdIn=IOWriteDone;
};
ROMSequenceBA ← IF ForceIdleBA AND NOT ProceedCommandBA THEN 1 ELSE CurrentSequenceBA;
Slave control
IF PhBb THEN ROMSlaveBA ← IF ForceSlaveAB AND NOT IODoneCommandBA THEN TRUE ELSE NOT MGntAB;
Assert[NOT MoreThanOneOf[ForceSlaveA, IODoneCommandBA]];
IF ForceSlaveA THEN ForceSlaveAB ← TRUE;
IF PhAb AND IODoneCommandBA THEN ForceSlaveAB ← FALSE;
Cycle control
IF PhBb
THEN ROMCycleBA ←
SELECT
TRUE
FROM
(NOT DoneBA) AND (SenseReadyBA AND NOT MCmdIn=DataTransport) => CycleShifterAB,
(NOT DoneBA) AND NOT (SenseReadyBA AND NOT MCmdIn=DataTransport) => WShift[CycleShifterAB, 7, -1],
DoneBA AND NOT (ForceSlaveAB AND IODoneCommandBA) => IBIW[TRUE, 0, 7, 1],
DoneBA AND (ForceSlaveAB AND IODoneCommandBA) => IBIW[TRUE, 0, 7, 2],
ENDCASE => ERROR;
IF PhAb THEN CycleShifterAB ← ROMCycleBA;
Fault and Map Bits
IF MDataIToFaultsB THEN FaultBitsBA ← LOOPHOLE[ECFD[MDataI, 32, 29, 3]];
MFaultAB ← IF PhAb AND CheckFaultsBA THEN FaultBitsBA ELSE None;
IF MapBitsToMDataIA
THEN {
MDataI ← IBID[DidRMBA, MDataI, 32, 24]; -- read the map
MDataI ← IBID[DirtyPageBA, MDataI, 32, 25]; -- set the dirty bit
MDataI ← ICID[0, MDataI, 32, 26, 6]; -- zero the rest of the bits
};
Parity
IF CheckParityB THEN ParityBA ← ParityOut;
IF PhAb AND ParityBA THEN MNErrorDriveLow ← TRUE;
Match control
IF SampleRealQMatchA THEN MatchRealQAB ← NOT nRQMatchA;
MNSharedDriveLow ← DriveSharedC AND MatchRealQAB;
Reset
IF Resetb
THEN {
HoldingAB ← FALSE;
MIdleAB ← TRUE;
MNErrorDriveLow ← FALSE;
ForceSlaveAB ← FALSE;
};