EU2ControlAlpsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Louis Monier June 14, 1986 5:18:37 pm PDT
Bertrand Serlet June 14, 1986 10:35:55 pm PDT
DIRECTORY Boole, BooleCore, CoreCreate, CoreOps, CoreProperties, Dragon, EU2ControlAlps, EU2LeafUtils, EU2Utils, LayoutCheckpoint, PWCore, PWCoreRoute, RopeList;
EU2ControlAlpsImpl:
CEDAR
PROGRAM
IMPORTS Boole, BooleCore, CoreCreate, CoreOps, CoreProperties, EU2LeafUtils, EU2Utils, LayoutCheckpoint, PWCore, PWCoreRoute, RopeList
EXPORTS EU2ControlAlps =
BEGIN OPEN Boole, BooleCore, CoreCreate, EU2ControlAlps, EU2Utils;
ExprProc: TYPE ~ PROC [i: NAT ← 0] RETURNS [Expression];
AppendInput:
PROC [public: Wire, wr:
WR, inputD: Inputs]
RETURNS [ins: Inputs]~ {
AppendOneInput: PROC [wire: Wire] ~ {ins ← CONS[[input: wire, driver: inv], ins]};
inv: CellType ← EU2LeafUtils.AlpsExtract["InputDriver.sch"];
ins ← inputD;
CoreOps.VisitAtomicWires[FindWire[public, wr], AppendOneInput];
};
AppendOutput:
PROC [wire:
WR, expr: Expression, clock:
ROPE ←
NIL, outputDrivers: Outputs]
RETURNS [Outputs] ~ {
out: CellType ← EU2LeafUtils.AlpsExtract[IF clock=NIL THEN "OutputDriver.sch" ELSE "ClockedOutputDriver.sch"];
RETURN [
CONS[
[driver: out,
pas:
IF clock=
NIL
THEN
LIST[["VRef", "VRef"]]
ELSE LIST[["Clock", clock], ["VRef", "VRef"]],
output: wire, expr: expr],
outputDrivers]];
};
AppendState:
PROC [wire:
WR, expr: Expression, clock:
ROPE, outputDrivers: Outputs]
RETURNS [Outputs] ~ {
out: CellType ← EU2LeafUtils.AlpsExtract["StateOutputDriver.sch"];
IF clock=NIL THEN ERROR; -- need a clock to latch the state
RETURN [
CONS[
[driver: out,
pas: LIST[["Latch", clock], ["VRef", "VRef"]],
output: wire, expr: expr],
outputDrivers]];
};
-- To be generated by Alps (Ave, Serlet, programatori te salutant!)
CreateRamControl:
PUBLIC PROC
RETURNS [cellType: CellType] = {
IF EU2Utils.useRamControlCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["RamControl"]];
BEGIN
inputDrivers: Inputs ← NIL;
outputDrivers: Outputs ← NIL;
expr: Expression ← NIL;
-- public
public: Wire ← Union[
GenPGnEWires[], -- Vdd and Gnd
GenWiresCtrlToRam[], -- all Select lines, nPrech, dRamRead
GenWiresRamToCtrl[], -- ramAdr
WireList[
LIST["reject", "hold", "read", "write", Seq["dStateAd", 4], "enWrtIFUPhA", "enWrtIFUPhB", "phA", "nPhB", "VRef",
GenRegSelWire[field], -- selFieldSrc[0..2)
]]];
-- All the wires used as inputs (numbers)
dStateAd: Wire ← FindWire[public, "dStateAd"];
ramAdr: Wire ← FindWire[public, "ramAdr"];
aHi: Wire ← ramAdr[a][hi];
bHi: Wire ← ramAdr[b][hi];
cHi: Wire ← ramAdr[c][hi];
aLow: Wire ← ramAdr[a][low];
bLow: Wire ← ramAdr[b][low];
cLow: Wire ← ramAdr[c][low];
cAdr: Wire ← ramAdr[c];
-- Expressions (booleans)
read: Expression ← WireVar[public, "read"];
write: Expression ← WireVar[public, "write"];
reject: Expression ← WireVar[public, "reject"];
nReject: Expression ← Not[reject];
hold: Expression ← WireVar[public, "hold"];
nHold: Expression ← Not[hold];
AppendRamDriver:
PROC [output:
WR, expr: Expression] ~ {
outputDrivers ← AppendOutput[output , expr, "phA", outputDrivers];
};
IF aLow.size#2 OR bLow.size#2 OR cLow.size#2 THEN ERROR;
IF aHi.size#6 OR bHi.size#6 OR cHi.size#6 THEN ERROR;
-- Input inverters to the Alps blocks
inputDrivers ← AppendInput[public, "reject", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "hold", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "read", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "write", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "dStateAd", inputDrivers]; -- 4
inputDrivers ← AppendInput[public, ramAdr, inputDrivers]; -- 24
-- Enable Write on the KBus (IFU side); by luck, same timing as ram
outputDrivers ← AppendOutput["enWrtIFUPhA", EqualInt[public, cAdr, IFUAdr],
NIL, outputDrivers];
-- enWrtIFUPhA ← cAdr=IFUAdr
outputDrivers ← AppendOutput["enWrtIFUPhB", false,
NIL, outputDrivers];
-- enWrtIFUPhB ← false (if no // debug, never used, so could be removed)
-- Precharge of the ram
outputDrivers ← AppendOutput["nPrech", true, "nPhB", outputDrivers];
-- Output drivers, all of the same type: they follow PhA
FOR i:
INT
IN [0..nRows)
DO
AppendRamDriver[Index["selA", i], EqualInt[public, aHi, i]];
-- selHi[i][a] ← aAdrH=i
AppendRamDriver[Index["selB", i], EqualInt[public, bHi, i]];
-- selHi[i][b] ← bAdrH=i
expr ←
IF i=marAdr/4
THEN Or[reject, EqualInt[public, cHi, i]]
ELSE And[nReject, EqualInt[public, cHi, i]];
AppendRamDriver[Index["selC", i], expr];
-- selHi[i][c] ← (cAdrH=i).~reject for i#marAdr/4
-- selHi[marAdr/4][c] ← (cAdrH=i)+reject
ENDLOOP;
FOR i:
INT
IN [0..sizeSelLow)
DO
AppendRamDriver[Index["selALow", i], EqualInt[public, aLow, i]];
-- selLow[i][a] ← aAdrL=i
AppendRamDriver[Index["selBLow", i], EqualInt[public, bLow, i]];
-- selLow[i][b] ← bAdrL=i
expr ←
IF i=marAdr
MOD 4
THEN Or[reject, EqualInt[public, cLow, i]]
ELSE And[nReject, EqualInt[public, cLow, i]];
AppendRamDriver[Index["selCLow", i], expr];
-- selLow[i][c] ← (cAdrL=i).~reject for i#marAdr MOD 4
-- selHi[marAdr MOD 4][c] ← (cAdrL=i)+reject
ENDLOOP;
-- Control for Field register; located here because it requires cAdr; also same timing as ram
outputDrivers ← AppendOutput["selFieldSrc[0]",
And[nReject, nHold, EqualInt[public, cAdr, fieldAdr]], "phA", outputDrivers];
-- selFieldSrc[0] ← (cAdr=fieldAdr).~reject.~hold.PhA
outputDrivers ← AppendOutput["selFieldSrc[1]",
And[write, EqualInt[public, dStateAd, field]], NIL, outputDrivers];
-- selFieldSrc[1] ← (dStateAd=field).write
outputDrivers ← AppendOutput["selFieldSrc[2]",
And[read, EqualInt[public, dStateAd, field]], NIL, outputDrivers];
-- selFieldSrc[2] ← (dStateAd=field).read
-- reading the ram while debugging
outputDrivers ← AppendOutput["dRamRead",
And[read, EqualInt[public, dStateAd, ramA]], NIL, outputDrivers];
-- selFieldSrc[2] ← (dStateAd=ramA).read
cellType ← AlpsCell[
name: "RamControl",
public: public,
inputs: inputDrivers,
outputs: outputDrivers,
props: CoreProperties.Props[[$ContactPolyMetal2, NEW[INT ← 20]]]
];
END;
};
CreateBothAlps:
PUBLIC PROC
RETURNS [cellType: CellType] ~ {
ctrlTop: CellType ← CreateCondControl[];
ctrlBot: CellType ← CreateDPControl[];
public: Wire ← Union[
CopyAndDeleteNames[ctrlTop.public, LIST["Vdd", "Gnd", "VRef", "phB", "res0", "carryOut", "lz", "kernal", "il"]],
CopyAndDeleteNames[ctrlBot.public]
];
Vdd: Wire ← FindWire[public, "Vdd"];
Gnd: Wire ← FindWire[public, "Gnd"];
condSel: Wire ← FindWire[public, "condSel"];
reject: Wire ← FindWire[public, "reject"];
hold: Wire ← FindWire[public, "hold"];
read: Wire ← FindWire[public, "read"];
write: Wire ← FindWire[public, "write"];
res3BisP: Wire ← FindWire[public, "res3BisP"];
writePBus: Wire ← FindWire[public, "writePBus"];
aluOp: Wire ← FindWire[public, "aluOp"];
dStateAd: Wire ← FindWire[public, "dStateAd"];
il: Wire ← FindWire[public, "il"];
lz: Wire ← FindWire[public, "lz"];
kernal: Wire ← FindWire[public, "kernal"];
zero: Wire ← FindWire[public, "zero"];
ctrl8: Wire ← FindWire[public, "ctrl8"];
opL: Wire ← FindWire[public, "opL"];
opR: Wire ← FindWire[public, "opR"];
res: Wire ← FindWire[public, "res"];
carryOut: Wire ← FindWire[public, "carryOut"];
shift: Wire ← FindWire[public, "shift"];
carryABIn: Wire ← FindWire[public, "carryABIn"];
carryBAIn: Wire ← FindWire[public, "carryBAIn"];
conditionIn: Wire ← FindWire[public, "conditionIn"];
channelData: PWCoreRoute.ChannelData ←
NEW[PWCoreRoute.ChannelDataRec ← [
inX: FALSE,
bottomOrLeftWires: LIST[Vdd, Gnd, condSel, reject, res3BisP, writePBus, aluOp],
topOrRightWires: LIST[hold, read, write, dStateAd, il, lz, kernal, zero, ctrl8, opL, opR, res, carryOut, shift, carryABIn, carryBAIn, conditionIn],
trunkLayer: "metal",
branchLayer: "metal2",
extendTopOrRight: FALSE,
extend: TRUE,
wireWidthProc: PWCoreRoute.GndAndVdd25Met2MinWidth
]];
cellType ← Cell[
name: "BothAlps",
public: public,
instances:
LIST [
Instance[name: "BottomAlps",
type: PWCore.RotateCellType[ctrlBot, $FlipY]],
Instance[name: "TopAlps",
type: ctrlTop,
pa1: ["res0", "res[0]"]]
]
];
PWCore.SetLayout[cellType, $Channel, $ChannelData, channelData];
};
CreateCondControl:
PUBLIC PROC
RETURNS [cellType: CellType] ~ {
CondIs:
PROC [cond: Dragon.CondSelects]
RETURNS [expr: Expression] ~ {
expr ← EqualInt[public, condSel, Dragon.CondSelects[cond].ORD];
};
public: Wire ← Wires["Vdd", "Gnd", "phB", "condition", "VRef",
Seq["condSel", sizeCondSelects], -- from pads
"zero", "carryOut", "res0", -- from data path
"kernal", "lz", "il"]; -- output of DPControl alps block
condSel: Wire ← FindWire[public, "condSel"];
zero: Expression ← WireVar[public, "zero"];
lz: Expression ← WireVar[public, "lz"];
le: Expression ← Or[lz, zero];
kernal: Expression ← WireVar[public, "kernal"];
res0: Expression ← WireVar[public, "res0"];
overflow: Expression ← Xor[lz, res0];
carryOut: Expression ← WireVar[public, "carryOut"];
il: Expression ← WireVar[public, "il"];
cond: Expression ← OrList[
LIST[
And[CondIs[False], false],
And[CondIs[EZ], zero],
And[CondIs[LZ], lz],
And[CondIs[LE], le],
And[CondIs[AddressCheckFault], kernal],
And[CondIs[NE], Not[zero]],
And[CondIs[GE], Not[lz]],
And[CondIs[GZ], Not[le]],
And[CondIs[OvFl], overflow],
And[CondIs[BC], Not[carryOut]],
And[CondIs[IL], il],
And[CondIs[NotBC], carryOut],
And[CondIs[NotIL], Not[il]],
And[CondIs[ModeFault], true]
]];
inputDrivers: Inputs ← NIL;
outputDrivers: Outputs ← NIL;
IF EU2Utils.useCondControlCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["CondControl"]];
inputDrivers ← AppendInput[public, "condSel", inputDrivers]; -- 4
inputDrivers ← AppendInput[public, "zero", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "carryOut", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "res0", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "kernal", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "lz", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "il", inputDrivers]; -- 1
outputDrivers ← AppendState["condition", cond, "phB", outputDrivers];
cellType ← AlpsCell[
name: "CondControl",
public: public,
inputs: inputDrivers,
outputs: outputDrivers
];
};
-- Creates the control for the bottom of the Datapath
CreateDPControl:
PUBLIC
PROC
RETURNS [cellType: CellType] = {
IF EU2Utils.useDPControlCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["DPControl"]];
BEGIN
MakeSelExpr:
PROC [reg: PipeRange, exprProc: ExprProc, clock:
ROPE ←
NIL] ~ {
size: NAT ← sources[reg].sizeSel;
FOR i:
INT
IN [0..size)
DO
outputDrivers ← AppendOutput[
wire: Index[sources[reg].nameSel, i],
expr: exprProc[i],
clock: clock,
outputDrivers: outputDrivers];
ENDLOOP;
outputDrivers ← AppendOutput[
wire: Index[sources[reg].nameSel, size],
expr: And[write, EqualInt[public, dStateAd, reg]],
clock: NIL,
outputDrivers: outputDrivers];
outputDrivers ← AppendOutput[
wire: Index[sources[reg].nameSel, size+1],
expr: And[read, EqualInt[public, dStateAd, reg]],
clock: NIL,
outputDrivers: outputDrivers];
};
inputDrivers: Inputs ← NIL;
outputDrivers: Outputs ← NIL;
public: Wire ← Union[
WireList[LIST["Vdd", "Gnd", "phA", "phB", "carryBA", "carryBAIn", "carryAB", "carryABIn", "kernal", "il", "lz", "enWrtPBusPhA", "enWrtPBusPhB", "conditionIn", Seq["ctrl8", 8], "writePBus", "res3BisP", "reject", Seq["aluOp", sizeALUOps], "hold", "read", "write", Seq["dStateAd", 4], "VRef" ]],
Wires[GenRegSelWire[left],
GenRegSelWire[right],
GenRegSelWire[st2A],
GenRegSelWire[st2B],
GenRegSelWire[st3A],
GenRegSelWire[kReg],
GenRegSelWire[r2B],
GenRegSelWire[r3A],
GenRegSelWire[r3B],
GenRegSelWire[dataIn],
Seq["selcBusSrc", 3]],
GenWiresCtrlToALU[],
Wires["carryOut", Seq["res", 8], Seq["opL", 3], Seq["opR", 3], Seq["shift", 6], Seq["sh", wordSize+1]]];
-- All the wires used as inputs (numbers)
ctrl8: Wire ← FindWire[public, "ctrl8"];
leftSrc: Wire ← Range[ctrl8, 1, 2];
rightSrc: Wire ← Range[ctrl8, 3, 3];
st2ASrc: Wire ← Range[ctrl8, 6, 2];
res: Wire ← FindWire[public, "res"];
opL: Wire ← FindWire[public, "opL"];
opR: Wire ← FindWire[public, "opR"];
shift: Wire ← FindWire[public, "shift"];
aluOp: Wire ← FindWire[public, "aluOp"];
dStateAd: Wire ← FindWire[public, "dStateAd"];
-- Expressions (booleans)
reject: Expression ← WireVar[public, "reject"]; -- latched on PhB in the pad
nReject: Expression ← Not[reject];
read: Expression ← WireVar[public, "read"];
write: Expression ← WireVar[public, "write"];
hold: Expression ← WireVar[public, "hold"];
nHold: Expression ← Not[hold];
fetch: Expression ← WireVar[public, "res3BisP"];
store: Expression ← WireVar[public, "writePBus"];
st3AisC: Expression ← WireVar[public, ctrl8[0]];
opL0: Expression ← WireVar[public, opL[0]];
opR0: Expression ← WireVar[public, opR[0]];
carryOut: Expression ← WireVar[public, "carryOut"];
carryBAIn: Expression ← WireVar[public, "carryBAIn"];
carryABIn: Expression ← WireVar[public, "carryABIn"];
conditionIn: Expression ← WireVar[public, "conditionIn"];
-- 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
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
OpIs[FOP], -- neither FOP
OpIs[BndChk]]], -- nor BndChk
1 => And[nHold, OpIs[FOP]], -- fuOut
2 => And[nHold, OpIs[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
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
2 => Or[EqualInt[public, dStateAd, cBus], Not[read]],
ENDCASE => ERROR]};
-- selCBusSrc[r3B] ← (reject + ~fetch + ~store)
-- selCBusSrc[dataIn] ← ~reject . ~hold . fetch
-- selCBusSrc[enW] ← (dStAd=cBus) + ~read
-- Field Unit
ShExpr: ExprProc = {
RETURN[EqualInt[public, shift, i]]};
-- sh[i] ← (shift=i)
-- ALU
CarryInExpr: ExprProc = {
RETURN[
OrList[
LIST[
-- Or, And, LAdd, Xor, FOP, VAdd and VAdd2 -> false
And[OpIs[VSub], true], -- I hope Alps does some simplification!!!
And[OpIs[LSub], true],
And[OpIs[BndChk], true],
And[OpIs[SAdd], carryABIn], -- prev
And[OpIs[SSub], Not[carryABIn]], -- nprev
And[OpIs[UAdd], carryABIn],
And[OpIs[USub], Not[carryABIn]]
]]
]};
CarryBAExpr: ExprProc = {
RETURN[
OrList[
LIST[
-- SAdd, SSub, LAdd and LSub -> false
And[OpIs[VAdd], carryABIn],
And[OpIs[VAdd2], carryABIn],
And[OpIs[VSub], carryABIn],
And[OpIs[BndChk], carryABIn],
And[OpIs[Or], carryABIn],
And[OpIs[And], carryABIn],
And[OpIs[Xor], carryABIn],
And[OpIs[FOP], carryABIn], -- prev
And[OpIs[UAdd], carryOut], -- comp
And[OpIs[USub], Not[carryOut]] -- ncomp
]]
]};
CarryABExpr: ExprProc = {
RETURN[
If[And[nReject, Not[conditionIn]], carryBAIn, carryABIn] ]};
-- carryAB ← IF ~reject AND ~condition THEN carryBA ELSE carryAB
OpExpr: ExprProc = {
RETURN[
SELECT i
FROM
-- add sub xor or and
0 => Not[InSet[sub]], -- 1 0 1 1 1
1 => InSet[sub, and], -- 0 1 0 0 1
2 => InSet[add, xor], -- 1 0 1 0 0
3 => Not[InSet[add]], -- 0 1 1 1 1
4 => Not[InSet[sub]], -- 1 0 1 1 1
ENDCASE => ERROR];
};
OpType: TYPE = {add, sub, xor, or, and, none};
OpIs:
PROC [op: Dragon.ALUOps]
RETURNS [expr: Expression] ~ {
expr ← EqualInt[public, aluOp, Dragon.ALUOps[op].ORD];
};
InSet:
PROC [t1, t2: OpType ← none]
RETURNS [expr: Expression] ~ {
AddMatchType:
PROC [op: OpType]
RETURNS [expr: Expression]~ {
expr ←
SELECT op
FROM
add => And[OpIs[VAdd2], OpIs[SAdd], OpIs[LAdd], OpIs[VAdd], OpIs[UAdd]],
sub => And[OpIs[BndChk], OpIs[SSub], OpIs[LSub], OpIs[VSub], OpIs[USub]],
xor => OpIs[Xor],
or => And[OpIs[Or], OpIs[FOP]],
and => OpIs[And],
ENDCASE => ERROR;
};
expr ← AddMatchType[t1];
IF t2#none THEN expr ← And[expr, AddMatchType[t2]];
};
IsLispInt:
PROC [threeBit: Wire]
RETURNS [Expression] ~ {
RETURN[Or[EqualInt[public, threeBit, 0], EqualInt[public, threeBit, 7]]];
};
KernalExpr: ExprProc = {RETURN[EqualInt[public, res, 0]]};
ILExpr: ExprProc = {RETURN[Nand[IsLispInt[Range[res, 0, 3]], IsLispInt[opL], IsLispInt[opR]]]};
LZExpr: ExprProc = {RETURN[Xor[Xor[carryOut, opL0], opR0]]};
WrPBusPhAExpr: ExprProc = {
RETURN[And[nReject, nHold]]};
-- enWrtPBusPhA ← ~reject AND ~hold
WrPBusPhBExpr: ExprProc = {
RETURN[And[store, nHold]]};
-- enWrtPBusPhB ← store AND ~hold
-- Input to control in order
-- Input Drivers for the (few) signals coming straight from the pads
inputDrivers ← AppendInput[public, "reject", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "hold", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "write", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "read", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "res3BisP", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "writePBus", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "aluOp", inputDrivers]; -- 4
inputDrivers ← AppendInput[public, "dStateAd", inputDrivers]; -- 4
-- Input Drivers for the signals coming from the Data Path
inputDrivers ← AppendInput[public, "conditionIn", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "carryBAIn", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "carryABIn", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "ctrl8", inputDrivers]; -- 8
inputDrivers ← AppendInput[public, "shift", inputDrivers]; -- 6
inputDrivers ← AppendInput[public, "carryOut", inputDrivers]; -- 1
inputDrivers ← AppendInput[public, "res", inputDrivers]; -- 8
inputDrivers ← AppendInput[public, "opL", inputDrivers]; -- 3
inputDrivers ← AppendInput[public, "opR", inputDrivers]; -- 3
-- Outputs to Data path in order: bottom ones first
-- To pad frame
outputDrivers ← AppendOutput["enWrtPBusPhA", WrPBusPhAExpr[], , outputDrivers];
outputDrivers ← AppendOutput["enWrtPBusPhB", WrPBusPhBExpr[], , outputDrivers];
-- Bottom Registers
MakeSelExpr[dataIn, DataInExpr, "phB"];
outputDrivers ← AppendOutput[Index["selcBusSrc", 0], CBusExpr[0], , outputDrivers];
outputDrivers ← AppendOutput[Index["selcBusSrc", 1], CBusExpr[1], , outputDrivers];
outputDrivers ← AppendOutput[Index["selcBusSrc", 2], CBusExpr[2], , outputDrivers];
MakeSelExpr[r3B, R3BExpr, "phB"];
MakeSelExpr[r3A, R3AExpr, "phA"];
MakeSelExpr[st3A, St3AExpr, "phA"];
MakeSelExpr[st2B, St2BExpr, "phB"];
-- Field unit control
FOR i:
NAT
DECREASING
IN [0..wordSize+1)
DO
outputDrivers ← AppendOutput[Index["sh", i], ShExpr[i], NIL, outputDrivers];
ENDLOOP;
-- res2BA Register
MakeSelExpr[r2B, R2BExpr, "phB"];
-- ALU control
FOR i:
NAT
IN [0..5)
DO
outputDrivers ← AppendOutput[Index["op", i], OpExpr[i], NIL, outputDrivers];
ENDLOOP;
outputDrivers ← AppendOutput["carryIn", CarryInExpr[], NIL, outputDrivers];
-- Top Registers
MakeSelExpr[st2A, St2AExpr, "phA"];
MakeSelExpr[left, LeftExpr, "phA"];
MakeSelExpr[right, RightExpr, "phA"];
MakeSelExpr[kReg, KRegExpr, "phB"];
-- Carry feedback
outputDrivers ← AppendState["carryBA", CarryBAExpr[], "phB", outputDrivers];
outputDrivers ← AppendState["carryAB", CarryABExpr[], "phA", outputDrivers];
-- Sub-expressions to compute Condition
outputDrivers ← AppendOutput["il", ILExpr[], NIL, outputDrivers];
outputDrivers ← AppendOutput["lz", LZExpr[], NIL, outputDrivers];
outputDrivers ← AppendOutput["kernal", KernalExpr[], NIL, outputDrivers];
-- Generate the block Alps
cellType ← AlpsCell[
name: "DPControl",
public: public,
inputs: inputDrivers,
outputs: outputDrivers,
props: CoreProperties.Props[[$ContactPolyMetal2, NEW[INT ← 20]]]
];
END;
};
CopyAndDeleteNames:
PROC [public: Wire, names:
LIST
OF
ROPE ← NIL]
RETURNS [copiedAndDeleted: Wire] ~ {
listWires: LIST OF Wire ← NIL;
FOR i:
NAT
IN [0 .. public.size)
DO
name: ROPE ← CoreOps.GetShortWireName[public[i]];
IF ~RopeList.Memb[names, name] THEN listWires ← CONS[CoreOps.CopyWire[public[i]], listWires];
ENDLOOP;
copiedAndDeleted ← CoreOps.CreateWire[listWires];
};
CreateControl:
PUBLIC
PROC
RETURNS [cellType: CellType] ~ {
-- To build the public
IF EU2Utils.useControlCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["Control"]];
BEGIN
ctrlTop: CellType ← CreateRamControl[];
ctrlBot: CellType ← CreateBothAlps[];
public: Wire ← Union[
CopyAndDeleteNames[ctrlTop.public, LIST["Vdd", "Gnd", "VRef", "reject", "hold", "read", "write", "dStateAd", "phA"]],
CopyAndDeleteNames[ctrlBot.public]
];
-- goes throuh
condition: Wire ← FindWire[public, "condition"];
Vdd: Wire ← FindWire[public, "Vdd"];
Gnd: Wire ← FindWire[public, "Gnd"];
-- out to the left
reject: Wire ← FindWire[public, "reject"];
-- out to the right
hold: Wire ← FindWire[public, "hold"];
read: Wire ← FindWire[public, "read"];
write: Wire ← FindWire[public, "write"];
dStateAd: Wire ← FindWire[public, "dStateAd"];
ramAdr: Wire ← FindWire[public, "ramAdr"];
channelData: PWCoreRoute.ChannelData ←
NEW[PWCoreRoute.ChannelDataRec ← [
inX: FALSE,
bottomOrLeftWires: LIST[Vdd, Gnd, reject, condition],
topOrRightWires: LIST[ramAdr, hold, read, write, dStateAd, condition],
trunkLayer: "metal",
branchLayer: "metal2",
extendTopOrRight: FALSE,
extend: TRUE,
wireWidthProc: PWCoreRoute.GndAndVdd25Met2MinWidth
]];
cellType ← Cell[
name: "Control",
public: public,
instances:
LIST [
Instance[name: "BottomAlps", type: ctrlBot],
Instance[name: "TopAlps", type: ctrlTop]
]
];
PWCore.SetLayout[cellType, $Channel, $ChannelData, channelData];
END;
};
END.