<> <> <> Imports BitOps, Dragon; Open BitOps, Dragon; CELLTYPE "MSequencer" PORTS[ <> Vdd, Gnd> <> PhAb, PhBb> nVQMatchB, nQuadSharedB=BOOL, nRQMatchA=BOOL, nPageDirtyB, nMapValidB=BOOL, nRealBlockMatchA, nVirtualBlockMatchB=BOOL, <

M control>> MDoneAB, MHeldAB>BOOL, MFaultAB>EnumType["Dragon.PBusFaults"], PCmdToMAB> MCmdInEnumType["Dragon.MBusCommands"], MCmdDriveC>BOOL, MDataI=INT[32], MParityI=BOOL, MDataDriveC>BOOL, MSharedSenseBOOL, MNSharedDriveLowC>BOOL, MNErrorDriveLow>BOOL, MRqIBA>BOOL, MNewRqIBA>BOOL, MNewRqEnableC>BOOL, MGntSenseA> SuppressPSampleAB, MIsDoneAB, SetWantWSA, CheckFaultsAB, SenseSharedB, ReleaseMBusBA, ForceIdleAB, DoneAB, ForceSlaveBA, SenseReadyBA, MDataIToFaultsB, MapBitsToMDataIA, ACheckParityA, BCheckParityB, SampleRealMatchA, MCmdDriveA, MDataDriveA, DriveSharedHighA, DriveSharedLowA, MasterEnableMBusDriveAB, MCmdDriveToDataTransportAB, MCmdDriveToNoOpAB> GetAdrCmdBA>EnumType["CacheOps.PreFetchAdrCmd"], IsCleanBA, LatchSharedBA, MasterBA, MatchRealQuadAB, MatchRealBlockAB, ContinueBA>BOOL, OneDirtyBA, SomeDirtyBA, MDataDriveDelayedAINT[7], ROMSlaveBA>BOOL, ROMCycleBA>INT[7], MRamRegParityOut> 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; <> { 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)); <<>> <> <<>> <> <> <<>> 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; <> { 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; <> <<>> 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; <<>> <> 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; <> 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 }; <> 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; <> 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; <> IF Resetb THEN { HoldingAB _ FALSE; MIdleAB _ TRUE; MNErrorDriveLow _ FALSE; ForceSlave _ FALSE; }; ENDCELLTYPE