<> <> <> <> <> DIRECTORY Basics, Commander, Core, CoreClasses, CoreCreate, CoreOps, CoreProperties, Dragon, DragonRosemary, DragOpsCross, EqualCheck, IFU2, IFUPLA, IFUPLAFetchControl, IFUPLAInstrDecode, IFUPLAInterlock, IFUPLAMainPipeControl, IFUPLAStackControl, IFUSim, IO, Ports, REFBit, Rope, Rosemary, TerminalIO, UncountedAssignHack; IFU2Impl: CEDAR PROGRAM IMPORTS Basics, Commander, CoreClasses, CoreCreate, CoreOps, CoreProperties, DragonRosemary, EqualCheck, IFUPLA, IFUSim, IO, Rope, Rosemary, Ports, REFBit, TerminalIO, UncountedAssignHack EXPORTS IFU2 = BEGIN IFUInconsistent: PUBLIC ERROR = CODE; ROPE: TYPE = Rope.ROPE; II: TYPE = IFU2.II; IFUState: TYPE = IFU2.IFUState; IFUStateRec: TYPE = IFU2.IFUStateRec; ModSim: TYPE = IFU2.ModSim; ModSimRec: TYPE = IFU2.ModSimRec; ModuleSimProc: TYPE = IFU2.ModuleSimProc; IFURoseClass: ROPE = Rosemary.Register [roseClassName: "IFU", init: IFUInit, evalSimple: IFUSimple]; PortData: TYPE = RECORD [ name: ROPE, width: NAT _ 1, drive: Ports.Drive _ none ]; iITypes: ARRAY II OF PortData _ [ KBus: ["KBus", 32], EUAluOp2AB: ["EUAluOp2AB", 4, drive], EUCondSel2AB: ["EUCondSel2AB", 4, drive], EUCondition2B: ["EUCondition2B"], EURdFromPBus3AB: ["EURdFromPBus3AB", , drive], EUWriteToPBus3AB: ["EUWriteToPBus3AB", , drive], UserMode2BA: ["UserMode2BA", , drive], DPCmdA: ["DPCmdA", 8, drive], DPRejectB: ["DPRejectB"], DPFaultB: ["DPFaultB", 4], IPData: ["IPData", 32], IPCmdFetchA: ["IPCmdFetchA", , drive], IPRejectB: ["IPRejectB"], IPFaultingB: ["IPFaultingB"], DShA: ["DShA"], DShB: ["DShB"], DShRd: ["DShRd"], DShWt: ["DShWt"], DShIn: ["DShIn"], DShOut: ["DShOut"], ResetAB: ["ResetAB"], RescheduleAB: ["RescheduleAB"], PhA: ["PhA"], PhB: ["PhB"], NotPhA: ["NotPhA"], NotPhB: ["NotPhB"], Vdd: ["Vdd"], Gnd: ["Gnd"], PadVdd: ["PadVdd"], PadGnd: ["PadGnd"] ]; Two: TYPE = RECORD[w0, w1: WORD]; Swap: PROC[in: Two] RETURNS[out: Two] = {RETURN[[in.w1, in.w0]]}; ToStatus: PROC[word: Dragon.Word] RETURNS[DragOpsCross.StackedStatusWord] = {RETURN[LOOPHOLE[Swap[LOOPHOLE[word]]]]}; FromStatus: PROC[status: DragOpsCross.StackedStatusWord] RETURNS[Dragon.Word] = {RETURN[LOOPHOLE[Swap[LOOPHOLE[status]]]]}; IFUPre: PUBLIC ModuleSimProc = { OPEN state; LoadStage1Bc _ ph=B AND NOT NotBcLoadStage1AB; <> X2ASrcLit2Ac _ ph=A AND X2ASrcLit1BA; IF ph=A THEN { ResetAB _ p[II[ResetAB ].ORD].b; DPFaultAB _ DPFaultBA}; IF ph=B THEN { ResetBA _ ResetAB; RescheduleBA _ p[II[RescheduleAB ].ORD].b; IPData _ p[II[IPData].ORD].lc; IPRejectBA _ p[II[IPRejectB ].ORD].b; IPFaultingBA _ p[II[IPFaultingB ].ORD].b; DPFaultBA _ VAL[ p[II[DPFaultB ].ORD].c]; DPRejectBA _ p[II[DPRejectB ].ORD].b; EUCondition2BA _ p[II[EUCondition2B ].ORD].b }; IF p[II[DShA].ORD].b THEN { inputBit: BOOL = p[II[DShIn].ORD].b; DragonRosemary.Assert [ NOT p[II[DShRd].ORD].b, "Error in IFU shifter clocking sequence" ]; IF NOT p[II[DShB].ORD].b THEN { -- shift drShifterAB from drShifterBA drShifterAB.bits[0] _ inputBit; FOR i: NAT IN [1..drShifterAB.size) DO drShifterAB.bits[i] _ NOT drShifterBA.bits[i-1]; ENDLOOP} ELSE { -- mass copy drShifterAB from DShIn FOR i: NAT IN [0..drShifterAB.size) DO drShifterAB.bits[i] _ NOT inputBit; ENDLOOP } }; DragonRosemary.Assert[ NOT (p[II[DShRd].ORD].b AND p[II[DShWt].ORD].b), "Error in IFU shifter clocking sequence"]; <> IF p[II[DShWt].ORD].b THEN FOR pla: IFUPLA.PLAs IN IFUPLA.PLAs DO FOR sense: IFUPLA.Sense IN IFUPLA.Sense DO IF plaOffsets[pla][sense] > 0 THEN { offset: NAT = plaOffsets[pla][sense]; buf: REF ANY = plaBuffers[pla][sense]; FOR i: NAT IN [0..IFUPLA.plaSizes[pla][sense]) DO REFBit.Set[buf, i, drShifterAB.bits[offset+i]]; ENDLOOP}; ENDLOOP; ENDLOOP }; IFUPreRef: ModSim _ NEW[ModSimRec _ [IFUPre]]; IFUPost: PUBLIC ModuleSimProc = { OPEN state; IF p[II[DShRd].ORD].b THEN -- broadside copy into shift register FOR pla: IFUPLA.PLAs IN IFUPLA.PLAs DO FOR sense: IFUPLA.Sense IN IFUPLA.Sense DO IF plaOffsets[pla][sense] > 0 THEN { offset: NAT = plaOffsets[pla][sense]; buf: REF ANY = plaBuffers[pla][sense]; FOR i: NAT IN [0..IFUPLA.plaSizes[pla][sense]) DO drShifterAB.bits[offset+i] _ NOT REFBit.Get[buf, i]; ENDLOOP}; ENDLOOP; ENDLOOP; IF p[II[DShB].ORD].b THEN { -- shift drShifterBA from drShifterAB FOR i: NAT IN [0..drShifterAB.size) DO drShifterBA.bits[i] _ NOT drShifterAB.bits[i]; ENDLOOP}; p[II[DShOut].ORD].b _ drShifterBA.bits[drShifterAB.size-1]}; IFUPostRef: ModSim _ NEW[ModSimRec _ [IFUPost]]; IFUInstrDecode: PUBLIC ModuleSimProc = { OPEN state; X1ASrcSLimitAc _ ph=A AND x1ASrcSLimitBA; X1ADstSLimitAc _ ph=A AND x1ADstSLimitBA; SELECT ph FROM A => { }; ab => { IF NOT drShWt THEN { <> inTYPE: TYPE = IFUPLAInstrDecode.InstrDecodeIn; inRec: inTYPE _ [ reset: ResetAB, state: StateAB, instReady: InstReadyAB, op: DragOpsCross.Inst[VAL[OpAB]], alpha: AlphaAB, beta: BetaAB, pushPending: PushPendingAB, popPending: PopPendingAB, userMode0: UserMode0AB ]; NARROW[ plaBuffers[instrDecode0][input], REF inTYPE]^ _ inRec; NARROW[ plaBuffers[instrDecode1][input], REF inTYPE]^ _ inRec; NARROW[ plaBuffers[instrDecode2][input], REF inTYPE]^ _ inRec; NARROW[ plaBuffers[instrDecode3][input], REF inTYPE]^ _ inRec; NARROW[ plaBuffers[instrDecode4][input], REF inTYPE]^ _ inRec; NARROW[ plaBuffers[instrDecode5][input], REF inTYPE]^ _ inRec; NARROW[ plaBuffers[instrDecode6][input], REF inTYPE]^ _ inRec } }; B => { PLAEval[state, instrDecode0]; PLAEval[state, instrDecode1]; PLAEval[state, instrDecode2]; PLAEval[state, instrDecode3]; PLAEval[state, instrDecode4]; PLAEval[state, instrDecode5]; PLAEval[state, instrDecode6]; [ nextMacro: NextMacroBA, pcNext: PCNextBA, pcBusSrc: PCBusSrcBA, pcPipeSrc: PCPipeSrcBA, x2ALitSource: X2ALitSourceBA, kIsRtOp0: KIsRtOp0BA, push0: Push0BA ] _ NARROW[plaBuffers[instrDecode6][output], REF IFUPLAInstrDecode.InstrDecodeOut6]^; [ instStarting0: InstStarting0BA, microCycleNext: MicroCycleNextBA, protMicroCycle: ProtMicroCycleBA, pop0: Pop0BA, dPCmnd: DPCmndBA, dPCmndIsRd0: DPCmndIsRd0BA, dPCmndSel: DPCmndSelBA ] _ NARROW[plaBuffers[instrDecode5][output], REF IFUPLAInstrDecode.InstrDecodeOut5]^; [ flagSrc: FlagSrcBA, lSource: [LSourceLtBA, LSourceRtBA], sSource: [SSourceLtBA, SSourceRtBA], popSa: PopSaBA, popSb: PopSbBA ] _ NARROW[plaBuffers[instrDecode4][output], REF IFUPLAInstrDecode.InstrDecodeOut4]^; [ kPadsIn0: KPadsIn0BA, fCtlIsRtOp0: FCtlIsRtOp0BA, pushSc: PushScBA, cReg: [CRegLtBA, CRegRtBA, CRegOffBA, CRegModBA] ] _ NARROW[plaBuffers[instrDecode3][output], REF IFUPLAInstrDecode.InstrDecodeOut3]^; [ bReg: [BRegLtBA, BRegRtBA, BRegOffBA, BRegModBA] ] _ NARROW[plaBuffers[instrDecode2][output], REF IFUPLAInstrDecode.InstrDecodeOut2]^; [ aReg: [ARegLtBA, ARegRtBA, ARegOffBA, ARegModBA] ] _ NARROW[plaBuffers[instrDecode1][output], REF IFUPLAInstrDecode.InstrDecodeOut1]^; [ aluOp: AluOpBA, aluOpIsOp47: AluOpIsOp47BA, condSel: CondSelBA, condSelIsOp57: CondSelIsOp57BA, condEffect0: CondEffect0BA, x1ADstSLimit: x1ADstSLimitBA, x1ASrcSLimit: x1ASrcSLimitBA, x1ADstStack: X1ADstStackBA, x1ASrcStack: X1ASrcStackBA, <> <> xBusStackL: XBusStackLBA, xBusStackEldest: XBusStackEldestBA, cIsField0: CIsField0BA ] _ NARROW[plaBuffers[instrDecode0][output], REF IFUPLAInstrDecode.InstrDecodeOut0]^}; ba => NULL; ENDCASE => ERROR IFUInconsistent}; IFUInstrDecodeRef: ModSim _ NEW[ModSimRec _ [IFUInstrDecode]]; IFUMainPipeControl: PUBLIC ModuleSimProc = { OPEN state; MCPIN: REF IFUPLAMainPipeControl.MainPipeControlIn _ NARROW[plaBuffers[mainPipeControl][input]]; MCPOUT: REF IFUPLAMainPipeControl.MainPipeControlOut _ NARROW[plaBuffers[mainPipeControl][output]]; SELECT ph FROM A => { <<[>> <> <> <> <> <> <> <> <> <> <> <> LoadStage1Ac _ MCPOUT.loadStage1; LoadStage2Ac _ MCPOUT.loadStage2; LoadStage3Ac _ MCPOUT.loadStage3; Stage1BHoldingAB _ MCPOUT.stage1BHolding; NotBcLoadStage1AB _ MCPOUT.notBcLoadStage1; Stage2BNormalAB _ MCPOUT.stage2B=normal; Stage2BAbortAB _ MCPOUT.stage2B=abort; Stage3BCPipeNormalAB _ MCPOUT.stage3BCPipe=normal; Stage3BCPipeAbortAB _ MCPOUT.stage3BCPipe=abort; MicroExcptJmpAB _ MCPOUT.microExcptJmp; ExceptAB _ MCPOUT.except; RschClearAB _ MCPOUT.rschClear; RschWaitingAB _ MCPOUT.rschWaiting; IF NOT drShWt THEN MCPIN.rschClear _ RschClearAB; PLAEval[state, mainPipeControl]; RschWaitingAB _ MCPOUT.rschWaiting}; ab => { LoadStage1Ac _ FALSE; LoadStage2Ac _ FALSE; LoadStage3Ac _ FALSE}; B => { IF NOT drShWt THEN MCPIN^ _ [ reset: ResetBA, -- Pre dPReject: DPRejectBA, -- Pre dPFaulting: DPFaultBA # none, -- Pre protMicroCycle: ProtMicroCycleBA, -- InstrDecode microExcptJmpBubble: MicroExcptJmpAB=bubble, stage2BAbort: Stage2BAbortAB, stage1BHold: Stage1BHoldBA, -- Interlock condEffect1: CondEffect1BA, -- ControlPipe condEffect2: CondEffect2BA, -- ControlPipe eUCondition2: EUCondition2BA, -- Pre trapsEnabled2: TrapsEnabled2BA, -- Status eStkOverflow2: EStkOverflow2BA, -- ControlPipe instStarting2: InstStarting2BA, -- ControlPipe reschedule: RescheduleBA, rschWaiting: RschWaitingAB, push2: Push2AB, instFault2: InstFault2BA, -- ControlPipe iStkNearlyFull: IStkNearlyFullBA, -- StackControl rschClear: RschClearAB ]; -- PRESERVE PhA change PLAEval[state, mainPipeControl]; Stage2ANormalBA _ MCPOUT.stage2A=normal; Stage2ABubbleBA _ MCPOUT.stage2A=bubble; Stage3ANormalBA _ MCPOUT.stage3A=normal; Stage3AAbortBA _ MCPOUT.stage3A=abort}; ba => { }; ENDCASE => ERROR IFUInconsistent}; IFUMainPipeControlRef: ModSim _ NEW[ModSimRec _ [IFUMainPipeControl]]; IFUMicroCycle: PUBLIC ModuleSimProc = { OPEN state; SELECT ph FROM A => { <> StateAB _ (SELECT MicroExcptJmpAB FROM none => StateBA MOD 128, -- 0sss ssss bubble => StateBA MOD 128+128, -- 1sss ssss microJump => 48, -- 0011 0000 resetting => 112, -- exception 0111 0000 trap => 116, -- exception 0111 0100 cJump => 120, -- exception 0111 1000 ENDCASE => ERROR IFUInconsistent) }; ab => { }; B => { StateBA _ SELECT MicroCycleNextBA FROM clear => 0, hold => StateAB, next => StateAB +1, ENDCASE => ERROR IFUInconsistent}; ba => { }; ENDCASE => ERROR IFUInconsistent}; IFUMicroCycleRef: ModSim _ NEW[ModSimRec _ [IFUMicroCycle]]; IFUStatus: PUBLIC ModuleSimProc = { OPEN state; SELECT ph FROM A => { UserMode0AB _ userMode [0][a] _ nextUserModeBA; trapsEnabled [0][a] _ nextTrapsEnabledBA; IF LoadStage1Ac THEN { userMode [1][a] _ userMode [0][b]; trapsEnabled [1][a] _ trapsEnabled [0][b]}; IF LoadStage2Ac THEN SELECT TRUE FROM Stage2ABubbleBA => { userMode [2][a] _ TRUE; trapsEnabled [2][a] _ FALSE}; Stage2ANormalBA => { userMode [2][a] _ userMode [1][b]; trapsEnabled [2][a] _ trapsEnabled [1][b]}; ENDCASE => IFUInconsistent; IF LoadStage3Ac THEN { userMode [3][a] _ userMode [2][b]; trapsEnabled [3][a] _ trapsEnabled [2][b]} }; ab => NULL; B => { status: DragOpsCross.StackedStatusWord; SELECT FlagSrcBA FROM same => { nextUserModeBA _ userMode [0][a]; nextTrapsEnabledBA _ trapsEnabled [0][a]}; clear => { nextUserModeBA _ FALSE; nextTrapsEnabledBA _ FALSE}; stack => { nextUserModeBA _ ToStatus[LFStkTopAB].userMode; nextTrapsEnabledBA _ ToStatus[LFStkTopAB].trapsEnabled}; lev3 => { nextUserModeBA _ userMode [3][a]; nextTrapsEnabledBA _ trapsEnabled [3][a]}; ENDCASE => ERROR IFUInconsistent; userMode [0][b] _ userMode [0][a]; trapsEnabled [0][b] _ trapsEnabled [0][a]; IF LoadStage1Bc THEN { userMode [1][b] _ userMode [1][a]; trapsEnabled [1][b] _ trapsEnabled [1][a] }; userMode [2][b] _ userMode [2][a]; trapsEnabled [2][b] _ trapsEnabled [2][a]; p[II[ UserMode2BA].ORD].b _ userMode [2] [b]; TrapsEnabled2BA _ trapsEnabled [2] [b]; status _ ToStatus[LFPipe3BA]; status.version _ IFU2.CurrentIFUVersion; status.userMode _ userMode [3][a]; status.trapsEnabled _ trapsEnabled [3][a]; LFPipe3BA _ FromStatus[status]}; ba => NULL; ENDCASE => ERROR IFUInconsistent} ; <> <> <