CacheMInterfaceMSequencer.rose
Last edited by: Barth, July 30, 1984 4:58:19 pm PDT
Last edited by: Curry, January 29, 1985 9:30:00 pm PST
Imports BitOps, Dragon;
Open BitOps, Dragon;
CELLTYPE "MSequencer"
PORTS[
Timing and housekeeping interface
Vdd, Gnd<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
MCmdIn<EnumType["Dragon.MBusCommands"],
MCmdOutAB>EnumType["Dragon.MBusCommands"],
MCmdDriveC>BOOL,
MDataI=INT[32],
MParityI=BOOL,
MDataDriveC>BOOL,
MSharedSense<BOOL,
MNSharedDriveHighC>BOOL,
MNSharedDriveLowC>BOOL,
MNErrorDriveLow>BOOL,
MRqIBA>BOOL,
MNewRqIBA>BOOL,
MNewRqEnableC>BOOL,
MGntSenseA<BOOL,
Sequencer ROM interface
SuppressPSampleAB, MIsDoneAB, SetWantWSA, CheckFaultsAB, SenseSharedB, ReleaseMBusBA, ForceIdleAB, DoneAB, ForceSlaveBA, SenseReadyBA, MDataIToFaultsB, MapBitsToMDataIA, ACheckParityA, BCheckParityB, SampleRealMatchA, MCmdDriveA, MDataDriveA, DriveSharedHighA, DriveSharedLowA, MasterEnableMBusDriveAB, MCmdDriveToDataTransportAB, MCmdDriveToNoOpAB<BOOL,
Control steel wool
GetAdrCmdBA>EnumType["CacheOps.PreFetchAdrCmd"],
IsCleanBA, LatchSharedBA, MasterBA, MatchRealQuadAB, MatchRealBlockAB, ContinueBA>BOOL,
OneDirtyBA, SomeDirtyBA, MDataDriveDelayedA<BOOL,
ROMSequenceBA>INT[7],
ROMSlaveBA>BOOL,
ROMCycleBA>INT[7],
MRamRegParityOut<BOOL
]
State
PhALast, PhC: BOOL, -- hacks to emulate A rise to B fall strobes
MCmdDriveEnable, MDataDriveEnable, DriveSharedHighEnable, DriveSharedLowEnable: BOOL,
MIdleAB, MIdleBA, HoldingAB, HoldingBA: BOOL,
MGntAB, MGntBA, MRqAB, NewRqAB, NewRqBA: BOOL,
CurrentPDemandsAB, CurrentPDemandsBA: BitWord,
CurrentSequenceBA, CycleShifterAB: BitWord,
HoldTypeBA, NotHoldTypeBA, DidRMBA, DirtyPageBA: BOOL,
IODoneCommandBA, ForceSlave, ParityAB, ParityBA: BOOL,
CmdOutBA: MBusCommands,
FaultBitsBA: PBusFaults,
Intermediate values, not really state bits
PWantsM, EnableMBusDrive, ZapABit, EarlyIdleAB, ReallySuppressPSampleAB: BOOL,
CmdOutAB: MBusCommands
EvalSimple
IF PhBb THEN PhALast ← FALSE;
IF PhAb THEN PhALast ← TRUE;
PhC ← PhAb OR PhBb OR PhALast;
EarlyIdleAB ← MGntAB AND DoneAB AND ECFW[CurrentPDemandsAB, 7, 0, 4]=1;
ReallySuppressPSampleAB ← SuppressPSampleAB OR EarlyIdleAB;
Master sequencer
{
sample: BOOL ← MIdleAB AND NOT ReallySuppressPSampleAB;
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 ReallySuppressPSampleAB;
ZapABit ← PhAb AND MIsDoneAB AND (NOT EBFW[CurrentPDemandsBA, 7, 0] OR OneDirtyBA);
Assert[NOT MoreThanOneOf[ZapABit, SetWantWSA]];
IF PhAb THEN CurrentPDemandsAB ← CurrentPDemandsBA;
IF ZapABit 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, CurrentPDemandsBA, 7, 3];
IF PhAb AND CheckFaultsAB AND FaultBitsBA#Dragon.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 ← MIsDoneAB AND (ECFW[CurrentPDemandsAB, 7, 0, 6]=0 OR (CheckFaultsAB AND FaultBitsBA#Dragon.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 ← CheckFaultsAB AND FaultBitsBA#Dragon.None;
HoldingBA ← HoldingAB AND NOT fault;
MIdleBA ← IF (ReleaseMBusBA AND ECFW[CurrentPDemandsAB, 7, 0, 6]=0) OR EarlyIdleAB 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 MGntBA 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;
};
MNewRqEnableC ← PhC AND MGntBA;
Current sequence
{
prioritySequence: BitWord ← BitWordZero;
slaveSequence: BitWord ← IF ForceIdleAB THEN 1 ELSE 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;
CmdOutAB ← SELECT prioritySequence FROM
040H => WriteQuad,
020H => IORead,
010H => ReadQuad,
008H => WriteSingle,
004H => IORead,
002H => IOWrite,
001H => NoOp,
ENDCASE => NoOp;
IF PhBb AND DoneAB THEN CurrentSequenceBA ← IF MGntAB THEN prioritySequence ELSE slaveSequence;
IF PhBb THEN {
GetAdrCmdBA ← SELECT prioritySequence FROM
040H => VictimReal,
020H => RefVirtual,
010H => IF DidRMBA THEN RefRealMap ELSE RefRealAssemble,
008H => RefRealAssemble,
004H => RefVirtual,
002H => RefVirtual,
001H => RefVirtual,
ENDCASE => RefVirtual;
};
};
IF PhAb THEN MCmdOutAB ← SELECT TRUE FROM
MCmdDriveToDataTransportAB => DataTransport,
MCmdDriveToNoOpAB => NoOp,
ENDCASE => CmdOutBA;
IF PhBb THEN {
CmdOutBA ← CmdOutAB;
IODoneCommandBA ← MCmdIn=IOReadDone OR MCmdIn=IOWriteDone;
};
ROMSequenceBA ← IF (ForceSlaveBA AND NOT IODoneCommandBA) OR Resetb THEN 1 ELSE CurrentSequenceBA;
Slave control
IF ForceSlaveBA THEN ForceSlave ← TRUE;
IF PhBb THEN ROMSlaveBA ← IF ForceSlave AND NOT IODoneCommandBA THEN TRUE ELSE NOT MGntAB;
Assert[NOT MoreThanOneOf[ForceSlaveBA, IODoneCommandBA]];
IF PhAb AND IODoneCommandBA THEN ForceSlave ← FALSE;
IF PhBb THEN MasterBA ← MGntBA AND NOT ForceSlave;
Cycle control
IF PhBb THEN ContinueBA ← NOT SenseReadyBA OR MCmdIn=DataTransport;
IF Resetb THEN ROMCycleBA ← 20H ELSE IF PhBb THEN ROMCycleBA ← SELECT TRUE FROM
NOT DoneAB AND NOT ContinueBA => CycleShifterAB,
NOT DoneAB AND ContinueBA => WShift[CycleShifterAB, 7, -1],
DoneAB AND NOT (ForceSlave AND IODoneCommandBA) => IBIW[TRUE, 0, 7, 1],
DoneAB AND (ForceSlave 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]];
IF PhAb THEN MFaultAB ← IF CheckFaultsAB THEN FaultBitsBA ELSE Dragon.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 BCheckParityB THEN ParityBA ← MRamRegParityOut AND (MatchRealQuadAB OR MasterEnableMBusDriveAB);
IF PhAb AND ParityBA THEN MNErrorDriveLow ← TRUE;
IF ACheckParityA THEN ParityAB ← MRamRegParityOut AND ContinueBA;
IF PhBb AND ParityAB THEN MNErrorDriveLow ← TRUE;
M bus control
EnableMBusDrive ← MatchRealQuadAB OR MasterEnableMBusDriveAB;
IF SampleRealMatchA THEN {
MatchRealQuadAB ← NOT nRQMatchA;
MatchRealBlockAB ← NOT nRealBlockMatchA;
};
IF NOT PhC THEN MCmdDriveEnable ← MDataDriveEnable ← DriveSharedHighEnable ← DriveSharedLowEnable ← FALSE;
IF MCmdDriveA AND EnableMBusDrive THEN MCmdDriveEnable ← TRUE;
IF (MDataDriveA AND EnableMBusDrive) OR MDataDriveDelayedA THEN MDataDriveEnable ← TRUE;
IF DriveSharedHighA THEN DriveSharedHighEnable ← TRUE;
IF DriveSharedLowA AND EnableMBusDrive THEN DriveSharedLowEnable ← TRUE;
MCmdDriveC ← PhC AND MCmdDriveEnable;
MDataDriveC ← PhC AND MDataDriveEnable;
MNSharedDriveHighC ← PhC AND DriveSharedHighEnable;
MNSharedDriveLowC ← PhC AND DriveSharedLowEnable;
Reset
IF Resetb THEN {
HoldingAB ← FALSE;
MIdleAB ← TRUE;
MNErrorDriveLow ← FALSE;
ForceSlave ← FALSE;
};
ENDCELLTYPE