//D1SimCon.bcpl // Last edited: 30 April 1980 get "d1.d" manifest [ get "d1pe.d" ] get "d1sim.d" manifest [ get "d1dmux.d" ] external [ // D1I0 @DMuxTab; @OldDMuxTab // Defined here SimControl ] //SimControl is called by DSimulate to check consistency of signals in the //control section and of other signals elsewhere in the machine that are //closely related to the control section (primarily signals that depend //upon task numbers). let SimControl(Tn,Correct,T1DTab,T2DTab,Tneven, block,ff,jcn,FFfunc,oldblock,oldjcn,oldFFfunc, lvT2RepeatCur,lvT2DoCBr,lvHoldReq) = valof [ let ctd = DMuxTab!dCTD let ctask = DMuxTab!dCTASK let Next = DMuxTab!dNEXT let cia = DMuxTab!dCIA //Following value correct at even clocks only let NextCL = (ctd lshift 4)+ctask //LastNext = ctd, CurrLast = ctask //T2RepeatCur is only valid for Tn ge 2, but need it for TNIA prediction //in one case, so done here. let oldSwitchUpx = OldDMuxTab>>C.bSwitchUpx let T2RepeatCur = (T2DTab>>C.bHoldA & oldSwitchUpx) ne 0 rv lvT2RepeatCur = T2RepeatCur let FFEQ = DMuxTab!dFFEQ //**Simulation of t1 signals dependent upon t0 and t1 signals** if Tn ge 1 do [ let T1FFeq = T1DTab!dFFEQ //**Simulation of stuff derived from values at Tn-2** test Tn ge 2 ifso [ let oldctask = OldDMuxTab!dCTASK let oldcia = OldDMuxTab!dCIA let oldNext = OldDMuxTab!dNEXT let oldStopTasks = OldDMuxTab>>C.StopTasks //StopTasks = TaskingOff & TOffIsOK ? 1,(TaskingOn ? 0,oldStopTasks) Correct>>C.StopTasks = (FFEQ & #40020) eq #40020 ? 1, (FFEQ < 0 ? 0,oldStopTasks) let oldRWIMTPCx = OldDMuxTab>>C.RWIMTPCx let oldSwitchx = OldDMuxTab>>C.bSwitchxa let oldBigBorBDisp = OldDMuxTab>>C.BigBorBDisp let oldMulStep = OldDMuxTab>>C.MulStep let oldDoCBr = OldDMuxTab>>C.bDoCBr Correct>>C.RIMorRTPCdly = not ((oldRWIMTPCx & 5B) eq 5B) //Back2x is the task 2 cycles back = oldLastx let cBack2x = nil test Tn eq 3 ifso //Tn eq 3 [ cBack2x = OldDMuxTab>>P1.CurrLastx NextCL = (Next lshift 4)+oldctask ] ifnot //Tn eq 2 [ cBack2x = OldDMuxTab>>P0.RepeatCurrC ne 0 ? not oldctask,OldDMuxTab>>P1.LastNextx ] //Because DblClock' ne (clk0' & clk1'), double-clocked flipflops on the //processor boards are unsimuable after multiphase instructions. let oldMultiPhase = (oldjcn & 347B) eq 147B if not oldMultiPhase do [ Correct>>P1.Back2x = cBack2x Correct>>P1.Back3x = OldDMuxTab>>P1.Back2x ] Correct>>P0.LasteqCurrx = oldctask ne oldNext let T2TrueNext = nil test T2RepeatCur ifso [ T2TrueNext = oldctask Correct>>C.MulStep = oldMulStep Correct>>C.BigBorBDisp = oldBigBorBDisp ] ifnot [ T2TrueNext = oldNext if oldSwitchx ne 0 do [ Correct>>C.MulStep = (T1FFeq & 4B) ne 0 Correct>>C.BigBorBDisp = (((T1FFeq & 3) ne 0) & 1) % (T1FFeq lshift 1) ] ] Correct!dCTASK = T2TrueNext let oldbnt = OldDMuxTab!dBNT //Predict Ready from OldReady, IsNext, and switch stuff let newReady = OldDMuxTab!dREADY & not ((100000B rshift oldbnt) & (oldSwitchx eq 0)) //Test FF=Notify' if (OldDMuxTab!dFFEQ & 10B) eq 0 then newReady = newReady % (100000B rshift (oldFFfunc & 17B)) if OldDMuxTab>>C.PreEmptingx eq 0 then newReady = newReady % (100000B rshift oldctask) Correct!dREADY = (T2RepeatCur ? OldDMuxTab!dREADY,newReady) & 77777B //**When NoWakeups in MCR changes at t1, the task 17 wakeup request may //**change after T1; this is a hardware bug for which a fix is pending. //**In the meantime disable simulation of signals dependent upon oldPEnc //**when NoWakeups is changing. if (DMuxTab!dMCR xor OldDMuxTab!dMCR) & 1 eq 0 do [ let oldPEnc = OldDMuxTab!dPENC let olddSwitchUp = (not oldStopTasks) & (oldPEnc > T2TrueNext) Correct!dBNT = (T2RepeatCur & (oldbnt > oldPEnc)) ? oldbnt,oldPEnc Correct>>C.TPCBypass = (oldctask eq oldPEnc) & oldblock Correct>>C.bSwitchUpx = not olddSwitchUp //We have block = T2dBlock because SimTest loads MIR with a random //instruction in which Block = the value previously there. Correct>>C.bSwitchxa = oldStopTasks ne 0 ? oldSwitchx, not (olddSwitchUp % ((oldPEnc < T2TrueNext) & (T2TrueNext ne 0) & (T2RepeatCur ? oldblock,block) )) ] //CIA is predicted from BNPC on Switch, from TNIA or CIA+1 on Switch', //or from old CIA on RepeatCurrent. Effects of pending dispatches and //branch conditions are included in BNPC, but only dispatch bits are //included in TNIA, so DoCBr has to be ORed in. let ccia,bctrue = nil,0 test T2RepeatCur ifso ccia = oldcia ifnot test oldSwitchx eq 0 //Can't predict CIA[0:1] because BNPC[0:1] unmuffled ifso ccia = (OldDMuxTab!dBNPC & 37777B)+(cia & 140000B) //Have to worry about the illegal use of Link←B, BigBDispatch←B, //BDispatch←B, or MulStep concurrent with IM/TPC read/write. ifnot [ test oldMultiPhase //Return function? ifso [ ccia = T2DTab>>C.LinkgBMuxa ne 0 ? T2DTab!dBMUX,(oldcia & 177700B)+((oldcia+1) & 77B) if OldDMuxTab>>C.MulStep ne 0 then ccia = ccia % (cia & 2) ] ifnot [ let cia01 = (oldjcn & 347B) eq 107B ? cia,oldcia ccia = (OldDMuxTab!dTNIA & 37777B)+(cia01 & 140000B) ] //DoCBr can be taken from OldDMuxTab at t3; at t2, the branch condition //result would be predicted from OldDMuxTab jcn and ff and from the //DMuxTab condition values (mufflered by ProcH) for Rodd, R<0, ALU //branch conditions and IOatta (?), or from OldDMuxTab condition values for //Cnt=0&-1. test Tneven ifso [ if (oldjcn < 200B) & ((oldjcn & 7B) ne 7B) & (oldjcn > 17B) do bctrue = BCResult(oldjcn & 7B) if (oldFFfunc rshift 3) eq 6B do bctrue = bctrue % BCResult(oldFFfunc & 7B) ] ifnot bctrue = oldDoCBr ] Correct!dCIA = ccia % bctrue rv lvT2DoCBr = bctrue //For T2IfuNextMacro for SimIFU //Propagate CIMrhPE and CIMlhPE to IMrhPE and IMlhPE Correct!dESTAT = (Correct!dESTAT & not(IMlhPE+IMrhPE)) + ((OldDMuxTab!dESTAT & (CIMrhPE+CIMlhPE))lshift 8) ] ifnot //Tn eq 1 (LastNext = Next, CurrLast unknown) [ NextCL = (Next lshift 4)+(DMuxTab!dNEXTCL & 17B) ] let T1cia = T1DTab!dCIA Correct!dCIAINC = (T1cia & 177700B)+((T1cia+1) & 77B) //B←Link if FF=ReadLink or Link←CPReg Correct>>C.BgLinkx = (T1FFeq & 3000B) eq 0 //Link←BMuxa if FF= WriteLink, Link←CPReg, BigBDispatch, or BDispatch Correct>>C.LinkgBMuxa = (T1FFeq & 6003B) ne 0 //CTD is always loaded from CTASK at t1 and t2. It may be something //else on intermediate clocks of polyphase instructions but never check //at these times. Correct!dCTD = T1DTab!dCTASK ] Correct!dNEXTCL = not ((NextCL lshift 8)+NextCL) //**Simulate signals derived from other signals without intervening flops** let PEnc = DMuxTab!dPENC let Bnt = DMuxTab!dBNT let ToPE = DMuxTab!dTOPE let Ready = DMuxTab>>C.Ready let Hold = DMuxTab>>C.bHoldA let Phase0 = DMuxTab>>C.Phase0 let Phase4 = DMuxTab>>C.Phase4 let RWTPCorRWIMx = not DMuxTab>>C.RWTPCorRWIM let Switchx = DMuxTab>>C.bSwitchxa let SwitchUpx = DMuxTab>>C.bSwitchUpx let BigBorBDisp = DMuxTab>>C.BigBorBDisp let MulStep = DMuxTab>>C.MulStep let DoCBr = DMuxTab>>C.bDoCBr //Predict PEnc from ToPE checking priority encoder let cPEnc = 15 let ToPEbits = (DMuxTab!dTOPE)+100000B while (ToPEbits & 1) eq 0 do [ ToPEbits = ToPEbits rshift 1 cPEnc = cPEnc-1 ] Correct!dPENC = cPEnc //1's in ToPE can be predicted from Ready and Bnt. let IsNext = (100000B rshift Bnt) & (Switchx eq 0) let cToPE = Ready & not IsNext Correct!dTOPE = cToPE % DMuxTab!dTOPE //Determine TNIA from CIA and jcn decoding, and then modify if a //dispatch is pending. //Note that the mufflered TNIA includes dispatch stuff but not //the branch condition result. let cDecCntx,cNextMacro = true,0 let ctnia,tniamask,cbrtypex = 0,37777B,37B let cRWIMTPCx,cRWTPCorRWIM = 17B,0 let jcnr3 = (jcn rshift 3) & 3 test jcn ge 200B ifso test jcn ge 300B ifso ctnia = (jcn lshift 6) & 7700B //global ifnot [ ctnia = (cia & 7700B)+(jcn & 77B) //local cbrtypex = 17B ] ifnot test jcn < 20B ifso [ ctnia = (ff lshift 4)+(jcn & 17B) //long cbrtypex = 33B ] ifnot test (jcn & 7B) eq 7B ifso test jcn < 40B ifso ctnia = 0 //undefined ifnot test jcn ge 100B ifso //return [ tniamask,cbrtypex = 0,35B if jcn ge 140B do [ cRWTPCorRWIM = true cRWIMTPCx = table [ 16B; 15B; 13B; 7B ] ! jcnr3 ] ] ifnot //ifujump [ tniamask,ctnia = 30003B,jcnr3 cbrtypex = 27B cNextMacro = 1 ] ifnot //cond br [ ctnia = (cia & 7700B)+((jcn rshift 1) & 60B)+ ((jcn rshift 2) & 6B) cbrtypex = 36B if (jcn & 7B) eq 3B then cDecCntx = false ] if (tniamask & 17B) eq 17B do Correct>>C.Call = (ctnia & 17B) eq 0 //If a multiply-step is occurring, tnia.14 is unknown unless already 1. if MulStep ne 0 then tniamask = tniamask & 177775B //If a BigBDispatch or BDispatch occurred in the last microinstruction //for this task, then tnia[8:15] or tnia[13:15] might be unknown unless //already 1. However, if (CTD eq CTASK) and (Tn ne 1), then the bits //affecting the B/BigB dispatch are on the BMux unless RepeatCur is true. let tniamask2x = BigBorBDisp ge 2 ? 377B,(BigBorBDisp ne 0) & 7B test (Tn < 2) % (ctd ne ctask) % T2RepeatCur ifso tniamask = tniamask & not tniamask2x ifnot ctnia = ctnia % (T2DTab!dBMUX & tniamask2x) Correct!dTNIA = (ctnia + (cia & 30000B & tniamask)) % ((not tniamask) & DMuxTab!dTNIA) Correct!dNEXT = Switchx eq 0 ? Bnt,ctask let dStartCycle = Phase4 % (RWTPCorRWIMx & Phase0) //Stop is false for SimTest (cleared by LoadMIR) but true for SimGo (?) // Correct>>C.Stop = false Correct>>C.preStartCyclea = dStartCycle & (not Tneven) Correct>>C.dStartCycle = dStartCycle Correct>>C.Phase0 = Tneven Correct>>C.Phase4 = 0 //**Bug here??? Correct>>C.RWTPCorRWIM = cRWTPCorRWIM Correct>>C.RWIMTPCx = cRWIMTPCx Correct>>C.bSWdx = Switchx //?? Correct>>C.GND = 0 Correct>>C.brtypex = cbrtypex //This is the correct logic function for RepeatCurrent, but the actions //that depend upon RepeatCurrent need to use the value of Hold that //develops at t1. let RepeatCur = (Hold & SwitchUpx) ne 0 let nexttask = RepeatCur ? ctask,Next Correct>>C.Nexteq0 = Next eq 0 Correct>>C.CTaskeq0 = ctask eq 0 Correct>>C.PEncGtTrueNextx = PEnc le nexttask Correct>>C.PEncLtTrueNextx = PEnc ge nexttask Correct>>C.PEnceqCTx = ctask ne PEnc Correct>>C.PreEmptingx = SwitchUpx % (block & not Hold) Correct>>C.RepeatCurz = RepeatCur Correct>>P0.RepeatCurrC = RepeatCur Correct>>P0.EMUx = ctask ne 0 Correct>>P1.NextMacro = cNextMacro //FF's decoded directly on ContA Correct!dFFEQ = FFfunc ge 360B ? 20B, //Notify selecton FFfunc into [ case 70B: 31B //BigBDispatch case 71B: 32B //BDispatch case 72B: 34B //Multiply case 140B: 70B //UseDMD case 141B: 20030B //MidasOn case 142B: (Switchx ne 0 ? 40030B,40010B) //TaskingOff case 143B: 100030B //TaskingOn case 147B: 4030B //Link←B case 176B: 2030B //B←RWCPReg case 177B: 1030B //B←Link default: 30B ] if FFfunc eq 63B then cDecCntx = false Correct>>P0.DecCntx = cDecCntx if (FFEQ & 20B) eq 0 then rv lvHoldReq = 1 //Handle LastNext and CurrLast stuff on ProcH/L Correct>>P0.CurreqNextx = ctask ne Next //Control store address is TNIA or BNPC based upon SWITCH let CSaddr = Switchx eq 0 ? DMuxTab!dBNPC, (DMuxTab!dTNIA % DoCBr) Correct>>C.RA = CSaddr rshift 1 Correct>>C.CSBDbx = selecton CSaddr & 4001B into [ case 0: 7B case 1: 13B case 4000B: 15B case 4001B: 16B ] resultis RepeatCur ] and BCResult(bc) = valof [ bc = table [ 10000B //ResEqZero' 4000B //ResLtZero' 2000B //AluCarry 40000B //CnteqZero' (T2) 400B //RmLtZero' 1B //RmOdd' 20000B //IOatta (T2) 1000B //Overflow' ] ! bc let Tab = bc ge 20000B ? OldDMuxTab,DMuxTab resultis ((Tab!dSTKRB & bc) eq 0) & 1 ]