EU2DPControlImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Louis Monier March 25, 1986 5:31:15 pm PST
DIRECTORY Boole, BooleCore, CoreCreate, EU2DPControl, EU2LeafUtils, EU2Utils, Ports, Rosemary;
EU2DPControlImpl: CEDAR PROGRAM
IMPORTS Boole, BooleCore, CoreCreate, EU2LeafUtils, EU2Utils
EXPORTS EU2DPControl =
BEGIN OPEN Boole, BooleCore, CoreCreate, EU2DPControl, EU2Utils;
ExprProc: TYPE ~ PROC [i: NAT] RETURNS [Expression];
AppendInput: PROC [name: ROPE, public: Wire, inputD: Inputs] RETURNS [ins: Inputs]~ {
wire: Wire ← FindWire[public, name];
inv: CellType ← EU2LeafUtils.AlpsExtract["InputDriver.sch"];
IF wire.size=0 THEN RETURN [CONS[[input: wire, driver: inv], inputD]];
ins ← inputD;
FOR i: INT IN [0..wire.size) DO
ins ← CONS[[input: Index[wire, i], driver: inv], ins];
ENDLOOP;
};
AppendOutput: PROC [wire: WR, expr: Expression, clock: ROPE, outputDrivers: Outputs] RETURNS [Outputs] ~ {
out: CellType ← EU2LeafUtils.AlpsExtract["ClockedOutputDriver.sch"];
RETURN [CONS[
[driver: out, pas: LIST[["Clock", clock]], output: wire, expr: expr],
outputDrivers]];
};
-- Creates the control for the bottom of the Datapath, i.e. everything but the ram and the KBus pads
CreateDPControl: PUBLIC PROC RETURNS [cellType: CellType] = {
MakeSelExpr: PROC [reg: PipeRange, exprProc: ExprProc, clock: ROPE] ~ {
FOR i: INT IN [0..sources[reg].sizeSel) DO
outputDrivers ← AppendOutput[
wire: Index[sources[reg].nameSel, i],
expr: exprProc[i],
clock: clock,
outputDrivers: outputDrivers];
ENDLOOP;
};
inputDrivers: Inputs ← NIL;
outputDrivers: Outputs ← NIL;
public: Wire ← Union[ -- beware of the order!
Wires["hold"],  -- a hack for now!!!
GenPGnEWires[], GenClockWires[],
GenWiresCtrlToPads[],
GenWiresPadsToCtrl[],
GenWiresDBus[],
GenWiresCtrlToRegs[],
GenWiresCtrlToALU[],
GenWiresCtrlToFU[],
GenWiresDPToCtrl[]];
-- composite wires to be interpreted as numbers
leftSrc: Wire ← FindWire[public, "leftSrc"];
rightSrc: Wire ← FindWire[public, "rightSrc"];
st2ASrc: Wire ← FindWire[public, "st2ASrc"];
aluOp: Wire ← FindWire[public, "aluOp"];
fd: Wire ← FindWire[public, "fd"];
insertFd: Wire ← FindWire[fd, "insertFd"];
maskFd: Wire ← FindWire[fd, "maskFd"];
shiftFd: Wire ← FindWire[fd, "shiftFd"];
-- expressions on one bit
reject: Expression ← WireVar[public, "reject"]; -- latched on PhB, simple driver!!!
nReject: Expression ← Not[reject];
nHold: Expression ← Not[WireVar[public, "hold"]];
loadField: Expression ← WireVar[public, "loadField"];
st3AisC: Expression ← WireVar[public, "st3AisC"];
fetch: Expression ← WireVar[public, "res3BisP"];
store: Expression ← WireVar[public, "writePBus"];
-- PhA latches
LeftExpr: ExprProc = {RETURN[And[nReject, nHold, EqualInt[public, leftSrc, i]]]};
-- selLeftSrc[i] ← PhA . (leftSrc=i) . ~reject . ~hold
RightExpr: ExprProc = {RETURN[And[nReject, nHold, EqualInt[public, rightSrc, i]]]};
-- selRightSrc[i] ← PhA . (rightSrc=i) . ~reject . ~hold
St2AExpr: ExprProc = {RETURN[And[nReject, nHold, EqualInt[public, st2ASrc, i]]]};
-- selSt2ASrc[i] ← PhA . (st2ASrc=i) . ~reject . ~hold
FieldExpr: ExprProc = {RETURN[And[nReject, nHold, loadField]]};
-- selFieldSrc ← PhA . loadField . ~reject . ~hold
R3AExpr: ExprProc = {RETURN[And[nReject, nHold]]};
-- selRes3ABSrc ← PhA . ~reject . ~hold
St3AExpr: ExprProc = {RETURN[
SELECT i FROM
0 => And[nReject, nHold, Not[st3AisC]],
1 => And[nReject, nHold, st3AisC],
ENDCASE => ERROR]};
-- selSt3ABSrc[st2B] ← PhA . ~st3AisC . ~reject . ~hold
-- selSt3ABSrc[cBus] ← PhA . st3AisC . ~reject . ~hold
-- PhB latches
KRegExpr: ExprProc = {RETURN[nHold]};
-- selKRegAdr ← PhB . ~hold
R2BExpr: ExprProc = {RETURN[
SELECT i FROM
0 => And[nHold, Nor[    -- aluOut
EqualInt[public, aluOp, FOP],  -- neither FOP
EqualInt[public, aluOp, BndChk]]],  -- nor BndChk
1 => And[nHold, EqualInt[public, aluOp, FOP]],  -- fuOut
2 => And[nHold, EqualInt[public, aluOp, BndChk]], -- left
ENDCASE => ERROR]};
-- selRes2BASrc[aluOut] ← PhB . ~hold . (aluOp=FOP)
-- selRes2BASrc[fuOut] ← PhB . ~hold . (aluOp#FOP)
-- selRes2BASrc[left] ← PhB . ~hold . (aluOp=BndChk)
St2BExpr: ExprProc = {RETURN[nHold]};
-- selSt2BASrc ← PhB . ~hold
R3BExpr: ExprProc = {RETURN[nHold]};
-- selRes3BASrc[tBus] ← PhB . ~hold
DataInExpr: ExprProc = {RETURN[nHold]};
-- selDataInSrc ← PhB . ~hold
-- Special guys
PDriverExpr: ExprProc = {RETURN[
SELECT i FROM
0 => nHold, -- st3A
1 => nHold, -- r2B
ENDCASE => ERROR]};
-- selPDriverSrc[st3A] ← PhB . ~hold
-- selPDriverSrc[r2B] ← PhA . ~hold  (reject???)
CBusExpr: ExprProc = {RETURN[ -- use the non-latched reject and a simple driver, no clock!!!
SELECT i FROM
0 => Nand[nReject, store, fetch],  -- r3B
1 => And[nReject, nHold, fetch],  -- dataIn
ENDCASE => ERROR]};
-- selCBusSrc[r3B] ← PhA . (reject + ~fetch + ~store)
-- selCBusSrc[dataIn] ← PhA . ~reject . ~hold . fetch
-- Field Unit
InsertExpr: ExprProc = {RETURN[And[nHold, WireVar[public, "insertFd"]]]};
-- insert ← ~hold . insertFd
MaskExpr: ExprProc = {RETURN[
And[nHold, WireVar[public, Index["maskFd", i]]]]};
-- mask[i] ← ~hold . maskFd[i]
ShiftExpr: ExprProc = {RETURN[
And[nHold, WireVar[public, Index["shiftFd", i]]]]};
-- shift[i] ← ~hold . shiftFd[i]
ShExpr: ExprProc = {RETURN[
And[nHold, EqualInt[public, shiftFd, i]]]};
-- mask[i] ← ~hold . (shiftFd=i)
-- ALU
CarryInExpr: ExprProc = {RETURN[true]};
-- carryIn ← a big mess!!!
OpExpr: ExprProc = {RETURN[true]};
-- op[i] ← a big mess!!!
-- Carry and condition
-- Data path in order
MakeSelExpr[kReg, KRegExpr, "phB"];
MakeSelExpr[right, RightExpr, "phA"];
MakeSelExpr[field, FieldExpr, "phA"];
MakeSelExpr[left, LeftExpr, "phA"];
MakeSelExpr[st2A, St2AExpr, "phA"];
-- aluCtrl
MakeSelExpr[r2B, R2BExpr, "phB"];
-- fuCtrl
MakeSelExpr[st2B, St2BExpr, "phB"];
MakeSelExpr[st3A, St3AExpr, "phA"];
MakeSelExpr[pDriver, PDriverExpr, "none"];
MakeSelExpr[r3A, R3AExpr, "phA"];
MakeSelExpr[r3B, R3BExpr, "phB"];
MakeSelExpr[cBus, CBusExpr, "none"];
MakeSelExpr[dataIn, DataInExpr, "phB"];
-- To pad frame
enWrtPBus ← PhA+PhB.writePBus
enWrtIFU ← PhA.(cAdr=IFUAdr)  -- in EU2RamControl
condition ←
-- Input Drivers for the signals coming from the Data Path
inputDrivers ← AppendInput["leftSrc", public, inputDrivers];  -- 2
inputDrivers ← AppendInput["rightSrc", public, inputDrivers];  -- 3
inputDrivers ← AppendInput["st2ASrc", public, inputDrivers];  -- 2
inputDrivers ← AppendInput["zero", public, inputDrivers];  -- 1
inputDrivers ← AppendInput["carryOut", public, inputDrivers];  -- 1
inputDrivers ← AppendInput["res", public, inputDrivers];  -- 8
inputDrivers ← AppendInput["opL", public, inputDrivers];  -- 3
inputDrivers ← AppendInput["opR", public, inputDrivers];  -- 3
inputDrivers ← AppendInput["fd", public, inputDrivers];  -- 13
-- Input Drivers for the (few) signals coming straight from the pads
inputDrivers ← AppendInput["st3AisC", public, inputDrivers];  -- 1
inputDrivers ← AppendInput["res3BisP", public, inputDrivers];  -- 1
inputDrivers ← AppendInput["writePBus", public, inputDrivers]; -- 1
inputDrivers ← AppendInput["reject", public, inputDrivers];  -- 1
inputDrivers ← AppendInput["aluOp", public, inputDrivers];  -- 4
inputDrivers ← AppendInput["condSel", public, inputDrivers];  -- 4
-- Generate the block Alps
cellType ← NIL;
cellType ← AlpsCell[
name: "DPControl",
public: public,
inputs: inputDrivers,
outputs: outputDrivers
];
};
END.
-- Inputs to the Alps blocks
leftSrc, rightSrc, st2ASrc, loadField, zero,   -- form DP
st3AisC, res3BisP, writePBus, reject, aluOp, condSel -- form pads
-- PhA latches
-- aluLeft
selLeftSrc[i] ← ClockedDriver[PhA, (leftSrc=i) AND ~reject]
dReadLeft ← ClockedDriver[]
-- aluRight
selRightSrc[i] ← ClockedDriver[PhA, (rightSrc=i) AND ~reject]
dReadRight ← ClockedDriver[]
-- store2AB
selSt2ASrc[i] ← ClockedDriver[PhA, (st2ASrc=i) AND ~reject]
dReadSt2A ← ClockedDriver[]
-- result3AB
selRes3ABSrc ← ClockedDriver[PhA, ~reject]
dReadRes3AB ← ClockedDriver[]
-- store3AB
selSt3ABSrc[cBus] ← ClockedDriver[PhA, st3AisC AND ~reject]
selSt3ABSrc[s2Bus] ← ClockedDriver[PhA, ~st3AisC AND ~reject]
dReadSt3AB ← ClockedDriver[]
-- field
selFieldSrc ← ClockedDriver[PhA, loadField AND ~reject]
dReadField ← ClockedDriver[]
-- PhB latches
-- ramAdr
selRamAdr ← ClockedDriver[PhB, true]
-- result2BA
selRes2BASrc[aluBus] ← ClockedDriver[PhB, ~(aluOp=FOP)]
selRes2BASrc[fuBus] ← ClockedDriver[PhB, (aluOp=FOP)]
dReadRes2BA ← ClockedDriver[]
-- cBusResult3BA
selRes3BASrc[tBus] ← ClockedDriver[PhB, ]
selRes3BASrc[dBus] ← ClockedDriver[PhB, ]
dReadRes2BA ← ClockedDriver[]
-- store2BA
selSt2BASrc ← ClockedDriver[PhB, true]
-- PBus driver
1. PhA AND ~reject:
drive PBus (send address to cache from adBus)
2. PhA AND reject:
don't drive PBus (cache has latched the address)
3. PhB AND EUWriteToPBus3AB:
drive PBus (send data for store from dBus, even if there is a reject)
4. PhB AND ~EUWriteToPBus3AB AND reject:
nothing on PBus (copy faulty address to res3B)
5. PhB AND ~EUWriteToPBus3AB AND ~reject AND ~EURes3BisPBus3AB:
nothing on PBus (copy faulty address to res3B)
6. PhB AND ~EUWriteToPBus3AB AND ~reject AND EURes3BisPBus3AB:
read on PBus (get data from cache into res3B)
Combining 4 and 5, and using a OR (~a AND b) = a OR b:
4.5. PhB AND ~EUWriteToPBus3AB AND (reject OR ~EURes3BisPBus3AB):
nothing on PBus (copy faulty address to res3B)