IFP.rose
Last edited by: Curry, July 16, 1984 4:46:29 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 and thereby save 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
maskAB,  maskBA:  CARDINAL,
flagsAB,  flagsBA:  CARDINAL,
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[fpMaskFlags],
Lev0BaddrBA = DragonIFU.PRtoByte[fpMaskFlags],
Lev0BaddrBA = DragonIFU.PRtoByte[fpMode] ] ];
csUnload0AB ← FPCSUAluBA=unload OR FPCSUMultBA=unload;
csUnload1AB ← csUnload1BA;
functionAB ← IF FPCSLoadBA=load
THEN DragonFP.ExtractFunction[KBus]
ELSE 0;
IF Lev0BaddrBA = DragonIFU.PRtoByte[fpMaskFlags] THEN {
Dragon.Assert[NOT active];
KBus ← BitOps.ICID[maskBA, [0, 0], 32, 0, 16];
KBus ← BitOps.ICID[flagsBA, KBus, 32, 16, 16] };
IF Lev0BaddrBA = DragonIFU.PRtoByte[fpMode] THEN {
Dragon.Assert[NOT active];
KBus ← BitOps.ICID[LOOPHOLE[modeBA], [0, 0], 32, 16, 16]};
IF cAddrBA = DragonIFU.PRtoByte[fpMaskFlags]
THEN {
Dragon.Assert[NOT active];
maskAB ← BitOps.ECFD[KBus,32,0,16];
flagsAB ← BitOps.ECFD[KBus,32,16,16]}
ELSE {
maskAB ← maskBA;
flagsAB ← flagsBA};
flagsAB ← IF csUnload2BA
THEN BitOps.IBIW[TRUE, BitOps.ICIW[0, flagsBA, 16, 0, 3], 16, LOOPHOLE[statusBA]]
ELSE flagsBA };
IF PhB THEN {
maskBA ← maskAB;
flagsBA ← flagsAB;
modeBA ← IF (functionAB / 64) = 3
THEN DragonFP.SetMode[modeAB, functionAB]
ELSE modeAB;
csUnload1BA ← csUnload0AB;
csUnload2BA ← csUnload1AB;
IF csUnload1AB THEN {
statusBA ← FPStatusB;
IF NOT BitOps.EBFW[maskAB, 16, LOOPHOLE[FPStatusB]]
THEN {EPFaultB𡤏PFault; EPRejectB←TRUE}
ELSE {EPFaultB←None;  EPRejectB←FALSE} };
cAddrBA ← BitOps.ECFD[KBus, 32, 16, 8];
rejectBA ← EPRejectB };
ENDCELL