CacheMCtlSequencer.rose
Last edited by: Barth, June 22, 1984 4:57:07 pm PDT
Imports BitOps, Dragon;
Open BitOps, Dragon;
MCtlSequencer: CELL[
Timing and housekeeping interface
Vdd, Gnd<BOOL,
LatchBias<BOOL,
Buffered timing and housekeeping interface
PhAb, PhBb<BOOL,
Resetb<BOOL,
Cell control
nVQMatchB, nQuadSharedB=BOOL,
nRQMatchA=BOOL,
nPageDirtyB, nMapValidB=BOOL,
nRealBlockMatchA, nVirtualBlockMatchB=BOOL,
P control <=> M control
MDoneAB, MHeldAB>BOOL,
MFaultAB>EnumType["Dragon.PBusFaults"],
PCmdToMAB<EnumType["Dragon.PBusCommands"],
Internal main memory interface
MDataI=INT[32],
MCmdIn<EnumType["Dragon.MBusCommands"],
MCmdOutAB>EnumType["Dragon.MBusCommands"],
MSharedSense<BOOL,
MNSharedDriveLowC>BOOL,
MNErrorDriveLow>BOOL,
MRqIBA>BOOL,
MNewRqIBA>BOOL,
MNewRqEnableBA>BOOL,
MGntSenseA<BOOL,
MRAMDriver interface
ParityOut<BOOL,
Sequencer ROM interface
MCmdDriveToDataTransportAB, MCmdDriveToNoOpAB, MNSharedDriveLowEnableC, SuppressPSampleAB, MDoneBA, SetWantWSA, CheckFaultsBA, SenseSharedB, ReleaseMBusBA, ForceIdleBA, DoneBA, ForceSlaveA, SenseReadyBA, MDataIToFaultsB, MapBitsToMDataIA, CheckParityB, SampleRealMatchA, DriveSharedC<BOOL,
Control steel wool
GetAdrCmdAB>EnumType["CacheOps.PreFetchAdrCmd"],
IsCleanBA, LatchSharedBA, MGntBA>BOOL,
SomeDirtyBA<BOOL,
ROMSequenceBA>INT[7], ROMSlaveBA>BOOL, ROMCycleBA>INT[7]
]
State
MIdleAB, MIdleBA, HoldingAB, HoldingBA: BOOL,
MGntAB, MRqAB, NewRqAB, NewRqBA: BOOL,
CurrentPDemandsAB, CurrentPDemandsBA: BitWord,
CurrentSequenceBA, CycleShifterAB: BitWord,
HoldTypeBA, NotHoldTypeBA, DidRMBA, DirtyPageBA: BOOL,
IODoneCommandBA, ForceSlaveAB, ParityBA, MatchRealQAB: BOOL,
CmdOutBA: MBusCommands,
FaultBitsBA: PBusFaults,
Intermediate values, not really state bits
PWantsM: BOOL,
CmdOutAB: MBusCommands
EvalSimple
Master sequencer
{
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;
};
ENDCELL