<> <> Imports BitOps, Dragon; Open BitOps, Dragon; MCtlSequencer: CELL[ <> 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> MDataI=INT[32], MCmdInEnumType["Dragon.MBusCommands"], MSharedSenseBOOL, MNErrorDriveLow>BOOL, MRqIBA>BOOL, MNewRqIBA>BOOL, MNewRqEnableBA>BOOL, MGntSenseA> ParityOut> MCmdDriveToDataTransportAB, MCmdDriveToNoOpAB, MNSharedDriveLowEnableC, SuppressPSampleAB, MDoneBA, SetWantWSA, CheckFaultsBA, SenseSharedB, ReleaseMBusBA, ForceIdleBA, DoneBA, ForceSlaveA, SenseReadyBA, MDataIToFaultsB, MapBitsToMDataIA, CheckParityB, SampleRealMatchA, DriveSharedC> GetAdrCmdAB>EnumType["CacheOps.PreFetchAdrCmd"], IsCleanBA, LatchSharedBA, MGntBA>BOOL, SomeDirtyBAINT[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, <> PWantsM: BOOL, CmdOutAB: MBusCommands EvalSimple <> { 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)); <<>> <> <<>> <> <> <<>> 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; <> { 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; <> <<>> 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; <<>> <> 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; <> 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 }; <> IF CheckParityB THEN ParityBA _ ParityOut; IF PhAb AND ParityBA THEN MNErrorDriveLow _ TRUE; <> IF SampleRealQMatchA THEN MatchRealQAB _ NOT nRQMatchA; MNSharedDriveLow _ DriveSharedC AND MatchRealQAB; <> IF Resetb THEN { HoldingAB _ FALSE; MIdleAB _ TRUE; MNErrorDriveLow _ FALSE; ForceSlaveAB _ FALSE; }; ENDCELL