IFP.rose
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by: Curry, August 21, 1984 12:37:19 pm PDT
IFP is a special section of the IFU which performs three separate functions to aid in the control of the two Weitek Floating Point devices WTL 1164 (Multiplier) and WTL 1165 (ALU):
It maintains a shadow copy of the mode register by duplicating the effects of a FPOP Set-Mode instruction so that this register may be read using a LIFUR instruction.
It maintains the mask and flag registers. All the flags are sticky except for the top 3 (Exact Zero, Exact Infinity and Exact NonZero are used by the compare operation to represent Eq, Lt and Gt). These mask and flag registers are written by the SIFUR instruction and the flags are modified by returned status. These registers may be read using the LIFUR intruction.
It generates Reject and FPFault when an unmasked flag is set.
The IFP talks to FP (Rose simulation of the two chips) all of whose state changes on down edge of PhA (ie are BA signals). This was required to be able to use PhA of the KBus to pass most of the control signals to FP (saves about a dozen pins).
The only guaranteed state associated with FPOps are the Mode, Mask and Flag registers. There are no FPOps which allow 'partial' operations which assume the previous state of internal FP chip registers (ie AM, AL, BM, BL etc). Each FPOp loads all its operands from the stack, waits a function specific numer of cycles then moves any results back to the stack.
Imports BitOps, Dragon, DragonFP, DragonIFU;
IFP: CELL [
FPStatusB  <EnumType["DragonFP.Status"],
FPCSLoadBA  <EnumType["DragonFP.CSLoad"],
FPCSUAluBA <EnumType["DragonFP.CSUnload"],
FPCSUMultBA <EnumType["DragonFP.CSUnload"],
KBus    =INT[32], -- F, L, U Driven from IPipe in PhA
Lev0BaddrBA <INT[8],
EPRejectB  =BOOL,
EPFaultB   =EnumType["Dragon.PBusFaults"],
PhA, PhB  <BOOL
]
State
maskFlagsAB, maskFlagsBA: Dragon.HexWord,
modeAB,   modeBA:   DragonFP.Mode,
csUnload0AB, csUnload1BA, csUnload1AB, csUnload2BA: BOOL,
functionAB:  DragonFP.Function,
statusBA:   DragonFP.Status,
cAddrBA:  Dragon.HexByte,
rejectBA:   BOOL
EvalSimple
IF PhA THEN {
Active used for Assertions only
active: BOOL ← FPCSLoadBA=load OR FPCSUAluBA=unload OR FPCSUMultBA=unload;
Dragon.Assert[NOT (rejectBA AND active)]; -- IPipe should insure this
Dragon.Assert[NOT Dragon.MoreThanOneOf[
FPCSLoadBA=load OR FPCSUAluBA=unload OR FPCSUMultBA=unload,
cAddrBA = DragonIFU.PRtoByte[ifuFPMaskFlags],
Lev0BaddrBA = DragonIFU.PRtoByte[ifuFPMaskFlags],
Lev0BaddrBA = DragonIFU.PRtoByte[ifuFPMode] ] ];
csUnload0AB ← FPCSUAluBA=unload OR FPCSUMultBA=unload;
csUnload1AB ← csUnload1BA;
IF FPCSLoadBA=load
THEN [ ,functionAB] 𡤍ragonFP.ExtractLoadFunction[KBus]
ELSE functionAB ← 0;
IF Lev0BaddrBA = DragonIFU.PRtoByte[ifuFPMaskFlags] THEN {
Dragon.Assert[NOT active];
KBus ← Dragon.LTD[maskFlagsBA] };
IF Lev0BaddrBA = DragonIFU.PRtoByte[ifuFPMode] THEN {
Dragon.Assert[NOT active];
KBus ← BitOps.ICID[LOOPHOLE[modeBA], [0, 0], 32, 16, 16]};
IF cAddrBA = DragonIFU.PRtoByte[ifuFPMaskFlags]
THEN {
Dragon.Assert[NOT (active OR csUnload2BA)];
maskFlagsAB ← Dragon.LFD[KBus]}
ELSE maskFlagsAB ← IF csUnload2BA
THEN
Dragon.LFD[
BitOps.IBID[TRUE,
BitOps.ICID[0,
Dragon.LTD[maskFlagsBA],
32, 16, 3],
32, LOOPHOLE[statusBA, CARDINAL] + 16] ]
ELSE maskFlagsBA };
IF PhB THEN {
maskFlagsBA ← maskFlagsAB;
modeBA ← IF (functionAB / 64) = 3
THEN DragonFP.SetMode[modeAB, functionAB]
ELSE modeAB;
csUnload1BA ← csUnload0AB;
csUnload2BA ← csUnload1AB;
IF csUnload1AB THEN {
statusBA ← FPStatusB;
IF NOT BitOps.EBFD[
Dragon.LTD[maskFlagsAB], 32, LOOPHOLE[FPStatusB]]
THEN {EPFaultB𡤏PFault; EPRejectB←TRUE}
ELSE {EPFaultB←None;  EPRejectB←FALSE} };
cAddrBA ← BitOps.ECFD[KBus, 32, 16, 8];
rejectBA ← EPRejectB };
ENDCELL