IFUPLAInstrDecode1.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by TWilliams, August 27, 1984 4:58:00 pm PDT
Last edited by Herrmann, August 14, 1985 12:57:15 pm PDT
Last edited by Curry, October 9, 1985 5:20:49 pm PDT
McCreight, October 18, 1985 12:18:24 pm PDT
DIRECTORY
Basics,
DragOpsCross,
IFUPLA,
PLAOps;
IFUPLAInstrDecode1: CEDAR PROGRAM
IMPORTS IFUPLA, PLAOps EXPORTS IFUPLA =
BEGIN OPEN IFUPLA, PLAOps;
instr:  BoolExpr;
m:   InstrDecodeOut;
GenInstrDecodePLA1: PUBLIC GenInstrDecodePLAProc = {
GenInstrDecodePLAExceptions: PROC = {
Delayed:   InstrDecodeOut = [
nextMacro:   dontGet,
pcNext:    fromPCBus,
pclsPipeSrc:   old -- holdLastEntry in IFUPLA --,
microCycleNext:  hold];
Overrides the one defined in IFUPLA. The speculation is that whenever holdLastEntry is really necessary, Pipe0AB is also cyc, and the desired effect is obtained that way.
ifuAddr:  BoolExpr ← BE[m:[alpha:   360B],  d:[alpha:   360B]]; -- last 16
delayInstr: BoolExpr ← BE[m:[pipeCycle0:  TRUE], d:[pipeCycle0: TRUE]];
userMode: BoolExpr ← BE[m:[userMode:  TRUE], d:[userMode:  TRUE]];
popping:  BoolExpr ← BE[m:[popPending: TRUE], d:[popPending: TRUE]];
pushing:  BoolExpr ← BE[m:[pushPending: TRUE], d:[pushPending: TRUE]];
empty:  BoolExpr ← BE[m:[iStkEmpty:  TRUE], d:[iStkEmpty: TRUE]];
state0:   BoolExpr ← BE[m:[state: ByteTopSig[8]],  d:[state:   0]];
Do High Priority Exceptions
Set[m:[state: ByteTopSig[8]], d:[state: reseting], out: [
macroJump: FALSE,
nextMacro: dontGet,
fetchDisable: TRUE,
pcNext: fromPCBus,
pcBusSrc: trapGen,
lSource: [ zero, one ],
sSource: [ zero, zero ] ]];
Set[m:[state: ByteTopSig[8]], d:[state: reset],  out: [
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: trapGen,
lSource: [ zero, one ],
sSource: [ zero, zero ] ]];
m ← [
macroJump:   TRUE,
nextMacro: dontGet,
pcNext:    fromPCBus,
pcBusSrc:    trapGen,
lSource:    [ l3, zero ],
sSource:    [ s3, zero ],
setStatusFrom3Lev: TRUE];
Set[ m:[state: ByteTopSig[8]],d:[state: dpFault], out: m];
Set[ m:[state: ByteTopSig[8]],d:[state: cTrap],  out: m];
Set[ m:[state: ByteTopSig[8]],d:[state: cJump],  out: [
macroJump:   TRUE,
nextMacro: dontGet,
pcNext:    fromPCBus,
pcBusSrc:    pipe3,
lSource:    [ l3, zero ],
sSource:    [ s3, zero ],
setStatusFrom3Lev: TRUE ]];
Delayed Low Priority Exceptions
Set[s:delayInstr, m:[state: ByteTopSig[8]], d:[state: ipFault],  out: Delayed];
Set[s:delayInstr, m:[state: ByteTopSig[8]], d:[state: rschlWait],  out: Delayed];
Set[s:delayInstr, m:[state: ByteTopSig[8]], d:[state: iStkOFlow],  out: Delayed];
Set[s:delayInstr, m:[state: ByteTopSig[8]], d:[state: eStkOFlow], out: Delayed];
Low Priority Exceptions
Set[s:Not[delayInstr], m:[state: ByteTopSig[8]], d:[state: ipFault],  out: Trap];
Set[s:Not[delayInstr], m:[state: ByteTopSig[8]], d:[state: rschlWait],  out: Trap];
Set[s:Not[delayInstr], m:[state: ByteTopSig[8]], d:[state: iStkOFlow],  out: Trap];
Set[s:Not[delayInstr], m:[state: ByteTopSig[8]], d:[state: eStkOFlow], out: Trap];
Not An Exception
currentBE[m:[state: ByteTopSig[1]], d:[state: 0]]; -- Not Exception
Set[s:And[current,    delayInstr],  out: Delayed];
current ← And[current, Not[delayInstr]];
Instruction not ready
Set[s:current,      m:[instReady: TRUE], d:[instReady: FALSE],  out: Delayed];
current ← And[current, BE[ m:[instReady: TRUE], d:[instReady: TRUE]]];
Returns must wait for push or pop and must trap if instruction stack empty.
instr ← And[current, BE[m:[op: InstrTopSig[8]], d:[op: dRET]]];
Set[s: And[instr,   Or[popping, pushing]],     out: Delayed];
Set[s: And[instr, Not[Or[popping, pushing]],    empty], out: Trap];
Set[s: And[instr, Not[Or[popping, pushing]],  Not[empty]], out: [
macroJump:   TRUE,
nextMacro: dontGet,
pcNext:    fromPCBus,
pcBusSrc:    stack,
lSource:    [ zero, stack ],
sSource:    [ l, alpha ],
pop:     TRUE ]];
instr ← And[current, BE[m:[op: InstrTopSig[8]], d:[op: dRETN]]];
Set[s: And[instr,   Or[popping, pushing]],     out: Delayed];
Set[s: And[instr, Not[Or[popping, pushing]],    empty], out: Trap];
Set[s: And[instr, Not[Or[popping, pushing]],  Not[empty]], out: [
macroJump:   TRUE,
nextMacro: dontGet,
pcNext:    fromPCBus,
pcBusSrc:    stack,
lSource:    [ zero, stack ],
pop:     TRUE ]];
instr ← And[current, BE[m:[op: InstrTopSig[8]], d:[op: dRETK]]];
Set[s: And[instr,   userMode],         out: MultiByteXop];
instr ← And[instr, Not[userMode]];
Set[s: And[instr, state0,  Or[popping, pushing]],     out: Delayed];
Set[s: And[instr, state0,  Not[Or[popping, pushing]],    empty], out: Trap];
Set[s: And[instr, state0, Not[Or[popping, pushing]],  Not[empty]], out: [
nextMacro: dontGet,
pcNext: fromPCBus,
microCycleNext: next,
bReg:     abStackTop,
cReg:     ifuStatus] ];
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 1], out: NoOpMicro];
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 2], out: NoOpMicro];
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 2], out: [pop: TRUE]];
... just add it in. This pop logically belongs with state 4, but can be piped ahead because the pop doesn't actually happen until three cycles later. This allows a return following a RETK to proceed without wait states.
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 3], out: NoOpMicro];
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 3], out: [kPadsIn: TRUE]];
... just add it in. Note that the [kPadsIn: TRUE] follows the microinstruction that generates an IFU destination register address (ifuStatus) by three cycles. That's because kPadsIn is not pipelined, so it's generated at stage 0B to apply to the destination register address that has reached stage 3B.
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 4], out: [
macroJump:   TRUE,
nextMacro:   dontGet,
pcNext:    fromPCBus,
pcBusSrc:    stack,
lSource:    [ zero, stack ],
sSource:    [ l, alpha ]]];
ALS
Look for the case of a Call - ALS sequence broken by a Reschedule which returns with an empty IStack. ALS (L←S+alpha) => that the stack is expected to contain some local values which (if IStack is empty) have been swapped out.
instr ← And[current, BE[m:[op: InstrTopSig[8]], d:[op: dALS]] ];
Set[s: And[instr,  popping],          out: Delayed];
Set[s: And[instr, Not[popping],  empty, Not[pushing]], out: Trap];
Set[s: And[instr, Not[popping], Or[Not[empty], pushing]],  out:[lSource: [s, alpha]]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dASL],     out:[sSource: [l, alpha]]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dAL],     out:[lSource: [l, alpha]]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dAS],     out:[sSource: [s, alpha]]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dDIS],     out:[popSa: TRUE]];
LIP
must check addr to determine if IFU or EU.
must wait for push or pop if IFU.
instr ← And[current, BE[m:[op: InstrTopSig[8]], d:[op: dLIP]]];
Set[s: And[instr,   Not[ifuAddr]], out: [
bReg: [ zero, alpha ],
cReg: [ s, offset, one ],
pushSc: TRUE ] ];
Set[s: And[instr,   ifuAddr, Or[popping, pushing]], out: Delayed];
Set[s: And[instr,   ifuAddr, Not[Or[popping, pushing]]], out: [
bReg: [zero, alpha],
kIsRtOp: TRUE,
cReg: [ s, offset, one ],
pushSc: TRUE ] ];
SIP
trap if userMode.
instr ← And[current, BE[m:[op: InstrTopSig[8]], d:[op: dSIP]]];
Set[s: And[instr,    userMode],      out: MultiByteXop];
instr ← And[instr, Not[userMode]];
Set[s: And[instr,   Not[ifuAddr]], out: [
bReg: abStackTop,
cReg: [ zero, alpha ],
popSb: TRUE ] ];
instr ← And[instr,  ifuAddr]; -- costs 3 PLA lines, makes SIP to non-IFU destinations faster.
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 0], out:[
nextMacro: dontGet,
pcNext: fromPCBus,
microCycleNext: next,
bReg: abStackTop,
cReg: [ zero, alpha ] ] ];
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 1], out:NoOpMicro];  -- wait
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 2], out:NoOpMicro];  -- wait
Set[s: instr, m:[state: ByteTopSig[8]], d:[state: 3], out:[popSa: TRUE, kPadsIn: TRUE ]] };
Note: kPadsIn is not piped - it is to be applied on the following ph A
GenInstrDecodePLAXfers: PROC = {
Used in RR and RJB instructions
src0:   BoolExpr ← BE[m:[alpha: 300B], d:[alpha: 0B]];
src1:   BoolExpr ← BE[m:[alpha: 300B], d:[alpha: 100B]];
srTop:   BoolExpr ← BE[m:[alpha: 200B], d:[alpha: 200B]];
srPop:   BoolExpr ← BE[m:[alpha: 300B], d:[alpha: 300B]];
opt:   BoolExpr ← BE[m:[alpha: 040B], d:[alpha: 040B]];
aux:   BoolExpr ← BE[m:[alpha: 020B], d:[alpha: 020B]];
m ← [
aReg: abStackTop,
xaSource: alpha,
popSa: TRUE,
aluOp: VSub,
condEffect: macroJump,
condSel: EZ,
macroJump: FALSE,
nextMacro: get,
pclsPipeSrc: offSetPCnewLS ]; -- pcOffSetSrc: betaS
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJEBB], out:m];
m.condSel ← NE;
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJNEBB], out:m];
m ← [
aReg: abStackTop,
xaSource: alpha,
popSa: TRUE,
aluOp: VSub,
condEffect: macroJump,
condSel: EZ,
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: offSetPC, -- pcOffSetSrc: betaS,
pclsPipeSrc: seqPCnewLS];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJNEBBJ], out:m];
m.condSel ← NE;
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJEBBJ], out:m];
dRJ*B and dRJ*BJ - Bit 4 distinguishes between them
instr ← And[current, BE[m:[op: InstrTopSig[4]], d:[op: dRJEB]]]; -- RJ*B and RJ*BJ
Main Body
Set[s:current, m:[op: InstrTopSig[5]], d:[op: dRJEB], out:[ -- RJ*B
aluOp: VSub,
condSelIsOp57: TRUE,
condEffect: macroJump,
macroJump: FALSE,
nextMacro: get,
pclsPipeSrc: offSetPCnewLS ] ]; -- pcOffSetSrc: betaS
Set[s:current, m:[op: InstrTopSig[5]], d:[op: dRJEBJ], out:[ -- RJ*BJ
aluOp: VSub,
condSelIsOp57: TRUE,
condEffect: macroJump,
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: offSetPC, -- pcOffSetSrc: betaS,
pclsPipeSrc: seqPCnewLS] ];
AReg
Set[s: And[  src0, instr],        out:[aReg:[ cBase, offset, zero ]]];
Set[s: And[  src1, instr],        out:[aReg:[ cBase, offset, one ]]];
Set[s: And[  srTop, instr],        out:[aReg:[ s, offset, zero ]]];
BReg
Set[s: And[ Not[opt],   aux, instr],     out:[bReg:[ aBase, alpha47 ]]];
Set[s: And[ Not[opt],  Not[aux], instr],     out:[bReg:[ l,   alpha47 ]]];
Set[s: And[opt, instr], m:[alpha: 010B], d:[alpha: 000B], out:[bReg:[ cBase, alpha47 ]]];
Set[s: And[opt, instr], m:[alpha: 004B], d:[alpha: 000B], out:[bReg:[ cBase, alpha47 ]]];
Set[s: And[opt, instr], m:[alpha: 015B], d:[alpha: 014B], out:[bReg:[ s, offset, zero  ]]];
Set[s: And[opt, instr], m:[alpha: 015B], d:[alpha: 015B], out:[bReg:[ s, offset, minus1 ]]];
Stack
Set[s: And[srPop, instr],          out:[popSa: TRUE]];
Set[s: And[opt, instr], m:[alpha: 016B], d:[alpha: 016B], out:[popSb: TRUE]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJ1], out: DefaultMicro]; -- to mark as ~Xops
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJ2], out: DefaultMicro]; -- to mark as ~Xops
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJ3], out: DefaultMicro]; -- to mark as ~Xops
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJ5], out: DefaultMicro]; -- to mark as ~Xops
instr ← And[current, BE[m:[op: InstrTopSig[8]], d:[op: dJS]]];
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 0], out:[ -- ifuXBus ← [S]
nextMacro: dontGet,
pcNext: fromPCBus,
microCycleNext: next,
bReg: abStackTop,
cReg: ifuXBus ]];
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 1], out:NoOpMicro]; -- wait
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 2], out:NoOpMicro]; -- wait
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 3], out:NoOpMicro]; -- wait
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 3], out:[kPadsIn: TRUE]]; -- not piped
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 4], out:[ -- S ← S-1
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: offSetPC,  -- pcOffSetSrc: xA,
popSa: TRUE ]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJB], out:[
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: offSetPC ]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJDB], out:[
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: offSetPC ]]; -- pcOffSetSrc: alphaBetaS
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dJQB], out:[
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: alpBetGamDel ]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dLFC], out:[
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: offSetPC,  -- pcOffSetSrc: alphaBetaS,
pclsPipeSrc: seqPCnewLS,
push: TRUE ]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dDFC], out:[
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: alpBetGamDel,
pclsPipeSrc: seqPCnewLS,
push: TRUE ]];
Set[s:current, m:[op: InstrTopSig[8]], d:[op: dKFC], out:[
bReg:     ifuStatusABReg,
kIsRtOp:    TRUE,
cReg:     cStackTop,
pushSc:    TRUE,
macroJump:   TRUE,
nextMacro: dontGet,
pcNext:    fromPCBus,
pcBusSrc:    xopGen,
pclsPipeSrc:   seqPCnewLS,
push:     TRUE,
clearUserMode:  TRUE ]];
instr ← And[current, BE[m:[op: InstrTopSig[8]], d:[op: dSFC]]];
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 0], out:[ -- ifuXBus ← [S]
nextMacro: dontGet,
pcNext: fromPCBus,
microCycleNext: next,
bReg: abStackTop,
cReg: ifuXBus ]];
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 1], out:NoOpMicro]; -- wait
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 2], out:NoOpMicro]; -- wait
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 3], out:NoOpMicro]; -- wait
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 3], out:[kPadsIn: TRUE]]; -- not piped
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 4], out:[ -- S ← S-1
macroJump: TRUE,
nextMacro: dontGet,
pcNext: fromPCBus,
pcBusSrc: xA,
popSa: TRUE,
pclsPipeSrc: seqPCnewLS,
push: TRUE ]];
instr ← And[current, BE[m:[op: InstrTopSig[8]], d:[op: dSFCI]]];
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 0], out:[ -- ifuXBus ← [S]^
nextMacro: dontGet,
pcNext:    fromPCBus,
microCycleNext:  next,
bReg:     abStackTop,
cReg:     ifuXBus,
dpCmnd: Fetch,
dpCmndIsRd: TRUE ]];
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 1], out:NoOpMicro]; -- wait
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 2], out:NoOpMicro]; -- wait
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 3], out:NoOpMicro]; -- wait
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 3], out:[kPadsIn: TRUE]]; -- not piped
Set[s:instr, m:[state: ByteTopSig[8]], d:[state: 4], out:[ -- S ← S-1
macroJump:   TRUE,
nextMacro: dontGet,
pcNext:    fromPCBus,
pcBusSrc:    xA,
pclsPipeSrc:   seqPCnewLS,
push:     TRUE ]] };
current ← old;
GenInstrDecodePLAExceptions[];
GenInstrDecodePLAXfers[]};
END.