EU2Impl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Louis Monier June 15, 1986 1:54:26 am PDT
McCreight, May 12, 1986 12:23:08 pm PDT
Bertrand Serlet June 15, 1986 0:57:35 am PDT
Barth, April 19, 1986 5:25:00 pm PST
DIRECTORY CoreClasses, CoreCreate, CoreIO, CoreProperties, Dragon, DragonRosemary, EU2, EU2Arith, EU2Inner, EU2Utils, PadFrame, Ports, PWCore, Rosemary;
EU2Impl: CEDAR PROGRAM
IMPORTS CoreClasses, CoreCreate, CoreIO, CoreProperties, DragonRosemary, EU2Arith, EU2Inner, EU2Utils, PadFrame, Ports, PWCore, Rosemary
EXPORTS EU2 =
BEGIN OPEN EU2, EU2Arith, EU2Utils, CoreCreate;
useCachedEU2: BOOLFALSE;
public: Wire ← GenWiresForBonnie[];
Vdd: PUBLIC NAT ← PortIndex[public, "Vdd"];
Gnd: PUBLIC NAT ← PortIndex[public, "Gnd"];
PadVdd: PUBLIC NAT ← PortIndex[public, "PadVdd"];
PadGnd: PUBLIC NAT ← PortIndex[public, "PadGnd"];
PhA: PUBLIC NAT ← PortIndex[public, "PhA"];
PhB: PUBLIC NAT ← PortIndex[public, "PhB"];
VRef: PUBLIC NAT ← PortIndex[public, "VRef"];
DPRejectB: PUBLIC NAT ← PortIndex[public, "DPRejectB"];
DPData: PUBLIC NAT ← PortIndex[public, "DPData"];
KBus: PUBLIC NAT ← PortIndex[public, "KBus"];
EURes3BisPBus3AB: PUBLIC NAT ← PortIndex[public, "EURes3BisPBus3AB"];
EUWriteToPBus3AB: PUBLIC NAT ← PortIndex[public, "EUWriteToPBus3AB"];
EUAluOp2AB: PUBLIC NAT ← PortIndex[public, "EUAluOp2AB"];
EUCondSel2AB: PUBLIC NAT ← PortIndex[public, "EUCondSel2AB"];
EUCondition2B: PUBLIC NAT ← PortIndex[public, "EUCondition2B"];
DShA: PUBLIC NAT ← PortIndex[public, "DShA"];
DShB: PUBLIC NAT ← PortIndex[public, "DShB"];
DShRd: PUBLIC NAT ← PortIndex[public, "DShRd"];
DShWt: PUBLIC NAT ← PortIndex[public, "DShWt"];
DShIn: PUBLIC NAT ← PortIndex[public, "DShIn"];
DShOut: PUBLIC NAT ← PortIndex[public, "DShOut"];
DHold: PUBLIC NAT ← PortIndex[public, "DHold"];
DStAd: PUBLIC NAT ← PortIndex[public, "DStAd"];
CreateEU2: PUBLIC PROC [ typeData: REF EUTypeData ← NIL, fullEU: BOOLFALSE] RETURNS [ cellType: CellType ] = {
name: ROPE ← "EU2";
props: Properties ← CoreProperties.Props[[$ClusterInfo, typeData]];
cellType ← SELECT TRUE FROM
~fullEU => CoreClasses.CreateUnspecified[public, name, props],
fullEU AND ~useCachedEU2 => CreateFullEU2[props],
ENDCASE => CoreIO.RestoreCellType["EU2"];
[] ← Rosemary.SetFixedWire[cellType.public[Vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[Gnd], L];
[] ← Rosemary.SetFixedWire[cellType.public[PadVdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[PadGnd], L];
[] ← Ports.InitPort[cellType.public[DPData], lc, none];
[] ← Ports.InitPort[cellType.public[KBus], lc, none];
[] ← Ports.InitPort[cellType.public[EUAluOp2AB], c, none];
[] ← Ports.InitPort[cellType.public[EUCondition2B], b, drive];
[] ← Ports.InitPort[cellType.public[EUCondSel2AB], c, none];
[] ← Ports.InitPort[cellType.public[DStAd], c, none];
[] ← Ports.InitPort[cellType.public[DShOut], b, drive];
[] ← Rosemary.BindCellType[cellType: cellType, roseClassName: EU2RoseClass];
};
EU2RoseClass: ROPE = Rosemary.Register[roseClassName: "EU2", init: EU2Init, evalSimple: EU2Simple];
EU2Init: Rosemary.InitProc = {
state: EU2State ← NEW[EU2StateRec -- [ nRegs ] -- ];
state.data ← NARROW[CoreProperties.GetCellTypeProp[cellType, $ClusterInfo]];
FOR i: NAT IN [0..nRegs) DO
state.ram[i] ← 0;
ENDLOOP;
stateAny ← state;
};
EU2Simple: Rosemary.EvalProc = {
state: EU2State ← NARROW[stateAny];
{OPEN state;
aAdr, bAdr, cAdr: CARD; -- actually, only bytes
lSrc, rSrc, stSrc: NAT;
st3IsC: BOOL;
EUAluLeftSrc1BA: Dragon.ALULeftSources;
2 bits {aBus(0), rBus(1), cBus(2), reserve3(3)}
EUAluRightSrc1BA: Dragon.ALURightSources;
3 bits {bBus(0), rBus(1), cBus(2), kBus(3), fCtlReg(4)}
EUStore2ASrc1BA: Dragon.Store2ASources;
2 bits {bBus(0), rBus(1), cBus(2), reserve3(3)}
-- PhA phase. Note that rejectBA alone inhibits almost any state change during PhA
p[KBus].d ← p[DPData].d ← none;
IF p[PhA].b THEN {
-- Better be first! We use the latched version of reject here, so no race.
simRegs[cBus] ← IF rejectBA THEN simRegs[r3B] ELSE simRegs[dataIn];
-- Updating the RAM addresses and various control bits; notice the role of reject
[aAdr, bAdr, cAdr, st3IsC, lSrc, rSrc, stSrc] ← EU2Arith.ExplodeKReg[simRegs[kReg]];
EUStore2ASrc1BA ← VAL[stSrc];
EUAluRightSrc1BA ← VAL[rSrc];
EUAluLeftSrc1BA ← VAL[lSrc];
IF rejectBA THEN cAdr ← marAdr; -- force address
-- On every PhA with RejectBA the faulty address is saved in ram[euMAR]; the EU generates the appropriate cAdr when RejectBA is sensed, so the rule is: we always write into the register file!
IF cAdr # junkAdr THEN {
IF data # NIL AND data.noteStore # NIL AND NOT data.storeNoted THEN {
data.noteStore[data: data.data, reg: cAdr, value: simRegs[cBus]];
data.storeNoted ← TRUE;
};
SELECT cAdr FROM
IFUAdr      => {p[KBus].d ← drive; p[KBus].lc ← simRegs[cBus]};
IN [stackAdr .. bogusAdr) => ram[cAdr] ← simRegs[cBus];
ENDCASE      => DragonRosemary.Assert[FALSE, "EU cAdr out of range"];
IF cAdr=fieldAdr THEN simRegs[field] ← simRegs[cBus];
};
IF ~rejectBA AND ~conditionBA THEN carryAB ← carryBA;
IF ~rejectBA THEN {
simRegs[left] ← SELECT EUAluLeftSrc1BA FROM
aBus  => ram[aAdr],
rBus  => simRegs[r2B],
cBus  => simRegs[cBus],
ENDCASE => ERROR;
simRegs[right] ← SELECT EUAluRightSrc1BA FROM
bBus  => ram[bAdr],
rBus  => simRegs[r2B],
cBus  => simRegs[cBus],
kBus  => p[KBus].lc,
fCtlReg => simRegs[field],
ENDCASE => ERROR;
simRegs[st2A] ← SELECT EUStore2ASrc1BA FROM
bBus   => ram[bAdr],
cBus   => simRegs[cBus],
rBus   => simRegs[r2B],
ENDCASE => ERROR;
simRegs[r3A] ← simRegs[r2B];
simRegs[st3A] ← IF st3IsC THEN simRegs[cBus] ELSE simRegs[st2B];
p[DPData].d ← drive; -- Send address to Cache only once: the cache latches it.
p[DPData].lc ← simRegs[r2B];
};
}
ELSE IF data # NIL THEN data.storeNoted ← FALSE;
-- PhiB phase. Most of the computations take place during PhB
IF p[PhB].b THEN {
aluOut, fuOut: CARD; -- temporary
overflow, c32, lz, ez, il: BOOL;
aluOps: Dragon.ALUOps ← VAL[p[EUAluOp2AB].c];
DPRejectB is valid at the end of PhiB but bogus on PhiA, so it must be latched by PhiB.
rejectBA ← p[DPRejectB].b;
-- Receive RAM addresses and control bits on KBus form IFU
simRegs[kReg] ← p[KBus].lc;
-- PBus: notice that in case of reject during a store, we keep sending the data even though it is useless
DragonRosemary.Assert[NOT (p[EUWriteToPBus3AB].b AND p[EURes3BisPBus3AB].b)];
simRegs[r3B] ← simRegs[r3A]; -- copy address
simRegs[dataIn] ← p[DPData].lc; -- latch whatever comes form the pads
-- In case of a fetch, an op, or a move, we are done
IF p[EUWriteToPBus3AB].b THEN { -- store in progress: sending data
p[DPData].d ← drive;
p[DPData].lc ← simRegs[st3A] -- send data to Cache (Store)
};
-- Data pipe
simRegs[st2B] ← simRegs[st2A];
-- ALU computation
[aluOut, c32, carryBA] ← EU2Arith.ALUOperation[aluOps, simRegs[left], simRegs[right], carryAB];
-- FU computation
fuOut ← IF aluOps=FOP THEN FieldOp[simRegs[left], simRegs[st2A], simRegs[right]] ELSE 0;
-- Now pick up the result
simRegs[r2B] ← SELECT aluOps FROM
BndChk => simRegs[left],
FOP => fuOut,
ENDCASE => aluOut;
-- Condition and trap generation
overflow ← ((c32 # EBFLC[aluOut, 0]) # (EBFLC[simRegs[left], 0] # EBFLC[simRegs[right], 0]));
lz ← (c32#(EBFLC[simRegs[left], 0]#EBFLC[simRegs[right], 0]));
ez ← aluOut=0;
il ← LispTest[simRegs[left]] OR LispTest[simRegs[right]] OR LispTest[aluOut];
conditionBA ← SELECT Dragon.CondSelects[VAL[p[EUCondSel2AB].c]] FROM
False  => FALSE,
EZ   => ez,
LZ   => lz, -- VSub<0
LE   => ez OR lz, -- VSub<=0,
AddressCheckFault => aluOut < KernalLimit,
NE  => ~ez,
GE   => ~lz, -- VSub>=0
GZ   => ~(ez OR lz), -- VSub>0,
OvFl  => overflow,
BC   => ~c32,
IL   => il, -- the 3 high-order bits must be the same for both operands and result
NotBC  => c32,
NotIL  => ~il,
ModeFault  => TRUE,
ENDCASE => ERROR Rosemary.Stop["Invalid EUCondition2B Code"];
p[EUCondition2B].b ← conditionBA;
};
}};
globalPos: NAT ← 0; -- add the increment, then put the pad
SetFirst: PROC [pos: NAT] = {globalPos ← pos};
Next: PROC [] RETURNS [NAT] = {RETURN[Move[1]]};
Move: PROC [delta: NAT] RETURNS [NAT] = {
globalPos ← globalPos+delta;
RETURN[globalPos]};
CreateFullEU2: PROC [props: Properties ← NIL] RETURNS [cellType: CellType] = {
vSize: NAT = 52-8;
hSize: NAT = 52;
shrink: NAT = 4;
left: NAT = 0;
bottom: NAT = left+vSize;
right: NAT = bottom+hSize;
top: NAT = right+vSize;
iL: CellInstances ← LIST [Instance[PWCore.RotateCellType[EU2Inner.CreateEU2Inner[], $Rot90]]];
-- Left side
SetFirst[left+15-shrink];
iL ← PadFrame.AddPad[iL, "DShA", $In, Next[], ["toChip", "shiftA"]]; -- new: 12
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, "DShB", $In, Next[], ["toChip", "shiftB"]];
iL ← PadFrame.AddPad[iL, "DShRd", $In, Next[], ["toChip", "read"]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, "DShWt", $In, Next[], ["toChip", "write"]];
iL ← PadFrame.AddPad[iL, "DShIn", $In, Next[], ["toChip", "shIn"]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Next[]];
iL ← PadFrame.AddPad[iL, "DShOut", $Out, Next[], ["fromChip", "shOut"]];
iL ← PadFrame.AddPad[iL, "DHold", $In, Next[], ["toChip", "hold"]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Next[]];
iL ← PadFrame.AddPad[iL, public[DStAd][0], $In, Next[], ["toChip", "dStateAd[0]"]];
iL ← PadFrame.AddPad[iL, public[DStAd][1], $In, Next[], ["toChip", "dStateAd[1]"]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Next[]];
iL ← PadFrame.AddPad[iL, public[DStAd][2], $In, Next[], ["toChip", "dStateAd[2]"]];
iL ← PadFrame.AddPad[iL, public[DStAd][3], $In, Next[], ["toChip", "dStateAd[3]"]];
iL ← PadFrame.AddPad[iL, NIL, $Copyright, Next[]];
iL ← PadFrame.AddPad[iL, NIL, $Logo, Next[]];
iL ← PadFrame.AddPad[iL, NIL, $Name, Next[]];
-- Bottom side
SetFirst[bottom+1];
FOR i: NAT IN [0..16) DO
index: NAT ← 31-2*i;
iL ← PadFrame.AddPad[iL, public[DPData][index], $IOTst, Move[2],
["toChip", Index["fromPBus", index]],
["fromChip", Index["toPBus", index]],
["enWA", "enWrtPBusPhA"],
["enWB", "enWrtPBusPhB"]];
iL ← PadFrame.AddPad[iL, public[DPData][index-1], $IOTst, Next[],
["toChip", Index["fromPBus", index-1]],
["fromChip", Index["toPBus", index-1]],
["enWA", "enWrtPBusPhA"],
["enWB", "enWrtPBusPhB"]];
ENDLOOP;
SetFirst[bottom];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
-- Right side
SetFirst[right+13-shrink];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]]; -- new: 106
iL ← PadFrame.AddPad[iL, "DPRejectB", $In, Next[], ["toChip", "reject"]];
iL ← PadFrame.AddPad[iL, "PhA", $Clk, Next[], ["Clock", "phA"], ["nClock", "nPhA"]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, "PhB", $Clk, Next[], ["Clock", "phB"], ["nClock", "nPhB"]];
iL ← PadFrame.AddPad[iL, "VRef", $Analog, Next[]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, "EUCondition2B", $Out, Next[], ["fromChip", "condition"]];
iL ← PadFrame.AddPad[iL, "EURes3BisPBus3AB", $In, Next[], ["toChip", "res3BisP"]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Next[]];
iL ← PadFrame.AddPad[iL, "EUWriteToPBus3AB", $In, Next[], ["toChip", "writePBus"]];
iL ← PadFrame.AddPad[iL, public[EUAluOp2AB][0], $In, Next[], ["toChip", "aluOp[0]"]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Next[]];
iL ← PadFrame.AddPad[iL, public[EUAluOp2AB][1], $In, Next[], ["toChip", "aluOp[1]"]];
iL ← PadFrame.AddPad[iL, public[EUAluOp2AB][2], $In, Next[], ["toChip", "aluOp[2]"]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Next[]];
iL ← PadFrame.AddPad[iL, public[EUAluOp2AB][3], $In, Next[], ["toChip", "aluOp[3]"]];
iL ← PadFrame.AddPad[iL, public[EUCondSel2AB][0], $In, Next[], ["toChip", "condSel[0]"]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, public[EUCondSel2AB][1], $In, Next[], ["toChip", "condSel[1]"]];
iL ← PadFrame.AddPad[iL, public[EUCondSel2AB][2], $In, Next[], ["toChip", "condSel[2]"]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, public[EUCondSel2AB][3], $In, Next[], ["toChip", "condSel[3]"]];
-- Top side
SetFirst[top+1]; -- first at 143
FOR i: NAT IN [0..16) DO
index: NAT ← 31-2*i;
iL ← PadFrame.AddPad[iL, public[KBus][index], $IOTst, Move[2],
["toChip", Index["fromIFU", index]],
["fromChip", Index["toIFU", index]],
["enWA", "enWrtIFUPhA"],
["enWB", "enWrtIFUPhB"]];
iL ← PadFrame.AddPad[iL, public[KBus][index-1], $IOTst, Next[],
["toChip", Index["fromIFU", index-1]],
["fromChip", Index["toIFU", index-1]],
["enWA", "enWrtIFUPhA"],
["enWB", "enWrtIFUPhB"]];
ENDLOOP;
SetFirst[top];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
cellType ← Cell[name: "EU2",
public: public,
onlyInternal: GenWiresForOnion[],
instances: iL,
props: props];
PWCore.SetLayout[cellType, $PadFrame, PadFrame.padFrameParamsProp, NEW[PadFrame.PadFrameParametersRec ← [nbPadsX: hSize, nbPadsY: vSize, horizLayer: "metal2", vertLayer: "metal"]]];
};
-- The first version, with a large square pad frame; don't touch!!!
CreateSquareEU2: PROC [props: Properties ← NIL] RETURNS [cellType: CellType] = {
vSize: NAT = 52;
hSize: NAT = 52;
left: NAT = 0;
bottom: NAT = left+vSize;
right: NAT = bottom+hSize;
top: NAT = right+vSize;
iL: CellInstances ← LIST [Instance[PWCore.RotateCellType[EU2Inner.CreateEU2Inner[], $Rot90]]];
-- Left side
SetFirst[15];
iL ← PadFrame.AddPad[iL, "DShA", $In, Next[], ["toChip", "shiftA"]]; -- on 16
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, "DShB", $In, Next[], ["toChip", "shiftB"]];
iL ← PadFrame.AddPad[iL, "DShRd", $In, Next[], ["toChip", "read"]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, "DShWt", $In, Next[], ["toChip", "write"]];
iL ← PadFrame.AddPad[iL, "DShIn", $In, Next[], ["toChip", "shIn"]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Next[]];
iL ← PadFrame.AddPad[iL, "DShOut", $Out, Next[], ["fromChip", "shOut"]];
iL ← PadFrame.AddPad[iL, "DHold", $In, Next[], ["toChip", "hold"]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Next[]];
iL ← PadFrame.AddPad[iL, public[DStAd][0], $In, Next[], ["toChip", "dStateAd[0]"]];
iL ← PadFrame.AddPad[iL, public[DStAd][1], $In, Next[], ["toChip", "dStateAd[1]"]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Next[]];
iL ← PadFrame.AddPad[iL, public[DStAd][2], $In, Next[], ["toChip", "dStateAd[2]"]];
iL ← PadFrame.AddPad[iL, public[DStAd][3], $In, Next[], ["toChip", "dStateAd[3]"]];
iL ← PadFrame.AddPad[iL, NIL, $Copyright, Next[]];
iL ← PadFrame.AddPad[iL, NIL, $Logo, Next[]];
iL ← PadFrame.AddPad[iL, NIL, $Name, Next[]];
-- Bottom side
SetFirst[bottom+1];
FOR i: NAT IN [0..16) DO
index: NAT ← 31-2*i;
iL ← PadFrame.AddPad[iL, public[DPData][index], $IOTst, Move[2],
["toChip", Index["fromPBus", index]],
["fromChip", Index["toPBus", index]],
["enWA", "enWrtPBusPhA"],
["enWB", "enWrtPBusPhB"]];
iL ← PadFrame.AddPad[iL, public[DPData][index-1], $IOTst, Next[],
["toChip", Index["fromPBus", index-1]],
["fromChip", Index["toPBus", index-1]],
["enWA", "enWrtPBusPhA"],
["enWB", "enWrtPBusPhB"]];
ENDLOOP;
SetFirst[bottom];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
-- Right side
SetFirst[117];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]]; -- 118
iL ← PadFrame.AddPad[iL, "DPRejectB", $In, Next[], ["toChip", "reject"]];
iL ← PadFrame.AddPad[iL, "PhA", $Clk, Next[], ["Clock", "phA"], ["nClock", "nPhA"]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, "PhB", $Clk, Next[], ["Clock", "phB"], ["nClock", "nPhB"]];
iL ← PadFrame.AddPad[iL, "VRef", $Analog, Next[]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, "EUCondition2B", $Out, Next[], ["fromChip", "condition"]];
iL ← PadFrame.AddPad[iL, "EURes3BisPBus3AB", $In, Next[], ["toChip", "res3BisP"]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Next[]];
iL ← PadFrame.AddPad[iL, "EUWriteToPBus3AB", $In, Next[], ["toChip", "writePBus"]];
iL ← PadFrame.AddPad[iL, public[EUAluOp2AB][0], $In, Next[], ["toChip", "aluOp[0]"]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Next[]];
iL ← PadFrame.AddPad[iL, public[EUAluOp2AB][1], $In, Next[], ["toChip", "aluOp[1]"]];
iL ← PadFrame.AddPad[iL, public[EUAluOp2AB][2], $In, Next[], ["toChip", "aluOp[2]"]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Next[]];
iL ← PadFrame.AddPad[iL, public[EUAluOp2AB][3], $In, Next[], ["toChip", "aluOp[3]"]];
iL ← PadFrame.AddPad[iL, public[EUCondSel2AB][0], $In, Next[], ["toChip", "condSel[0]"]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, public[EUCondSel2AB][1], $In, Next[], ["toChip", "condSel[1]"]];
iL ← PadFrame.AddPad[iL, public[EUCondSel2AB][2], $In, Next[], ["toChip", "condSel[2]"]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, public[EUCondSel2AB][3], $In, Next[], ["toChip", "condSel[3]"]];
-- Top side
SetFirst[top+1]; -- first at 159
FOR i: NAT IN [0..16) DO
index: NAT ← 31-2*i;
iL ← PadFrame.AddPad[iL, public[KBus][index], $IOTst, Move[2],
["toChip", Index["fromIFU", index]],
["fromChip", Index["toIFU", index]],
["enWA", "enWrtIFUPhA"],
["enWB", "enWrtIFUPhB"]];
iL ← PadFrame.AddPad[iL, public[KBus][index-1], $IOTst, Next[],
["toChip", Index["fromIFU", index-1]],
["fromChip", Index["toIFU", index-1]],
["enWA", "enWrtIFUPhA"],
["enWB", "enWrtIFUPhB"]];
ENDLOOP;
SetFirst[top];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Next[]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "Gnd", $Gnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadGnd", $PadGnd, Move[3]];
iL ← PadFrame.AddPad[iL, "PadVdd", $PadVdd, Move[3]];
iL ← PadFrame.AddPad[iL, "Vdd", $Vdd, Next[]];
cellType ← Cell[name: "EU2",
public: public,
onlyInternal: GenWiresForOnion[],
instances: iL,
props: props];
PWCore.SetLayout[cellType, $PadFrame, PadFrame.padFrameParamsProp, NEW[PadFrame.PadFrameParametersRec ← [nbPadsX: hSize, nbPadsY: vSize, horizLayer: "metal2", vertLayer: "metal"]]];
};
END.