EU2ALUImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Louis Monier June 14, 1986 5:19:35 pm PDT
DIRECTORY BitHacks, CoreClasses, CoreCreate, CoreOps, EU2ALU, EU2LeafUtils, EU2Utils, IO, LayoutCheckpoint, PWCore, PWCoreRoute;
EU2ALUImpl: CEDAR PROGRAM
IMPORTS BitHacks, CoreCreate, CoreOps, EU2LeafUtils, EU2Utils, IO, LayoutCheckpoint, PWCore, PWCoreRoute
EXPORTS EU2ALU =
BEGIN OPEN CoreCreate, EU2ALU, EU2LeafUtils, EU2Utils;
-- Buses: (left, right, aluOut, st2A, r2B, cBus)[0..32), Vdd, Gnd
-- From ctrl: carryIn, op[0..5)
-- To ctrl: p0to31, carry[31], aluOut[0..8), left[0..3), right[0..3), right[19..32)
-- Coming out of this channel:
p0to31, carry[31], carryOut, aluOut[0..8), left[0..3), right[0..3), right[19..32)
CreateALU: PUBLIC PROC RETURNS [cellType: CellType] = {
-- To build the internal and public
Vdd: Wire ← CoreOps.CreateWire[name: "Vdd"];
Gnd: Wire ← CoreOps.CreateWire[name: "Gnd"];
left: Wire ← Bus["left"];
right: Wire ← Bus["right"];
st2A: Wire ← Bus["st2A"];
r2B: Wire ← Bus["r2B"];
cBus: Wire ← Bus["cBus"];
aluOut: Wire ← Bus["aluOut"];
P: Wire ← Bus["P"];
G: Wire ← Bus["G"];
carry: Wire ← Bus["carry"];
carryOut: Wire ← CoreOps.CreateWire[name: "carryOut"];
op: Wire ← Seq["op", 5];
tree: Wire ← TreeWires[];
internal: Wire ← Union[
WireList[LIST[
Vdd, Gnd, op, carryOut, left, right, st2A, r2B, cBus, aluOut, P, G, carry]],
tree];
zero: Wire ← FindWire[internal, "p0to31"];
carryIn: Wire ← FindWire[internal, "carry"][31];
public: Wire ← Wires[Vdd, Gnd, op, carryOut, carryIn, zero, left, right, st2A, r2B, cBus, aluOut];
-- To build the channel
res: Wire ← Range[aluOut, 0, 8];
opL: Wire ← Range[left, 0, 3];
opR: Wire ← Range[right, 0, 3];
fd: Wire ← Range[right, 19, 13];
channelData: PWCoreRoute.ChannelData ← NEW[PWCoreRoute.ChannelDataRec ← [
inX: FALSE,
bottomOrLeftWires: LIST[Vdd, Gnd, zero, carryIn, carryOut, res, opL, opR, fd],
topOrRightWires: LIST[Vdd, Gnd],
trunkLayer: "metal",
branchLayer: "metal2",
wireWidthProc: PWCoreRoute.GndAndVdd25Met2MinWidth
]];
IF EU2Utils.useALUCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["ALU"]];
PrintStart["ALU"];
cellType ← Cell[
name: "ALU",
public: public,
internal: internal,
instances: LIST [
Instance[CreateFunctionBlock[]],
Instance[CreateCarryProp[]]
]
];
PWCore.SetLayout[cellType, $Channel, $ChannelData, channelData];
PrintStop["ALU"];
};
-- Function Blocks: generate P and G, combine C to produce aluOut
-- (left, right, aluOut, st2A, r2B, cBus, G, P, carry)[0..32), op[0..5), Vdd, Gnd
CreateFunctionBlock: PROC RETURNS [cellType: CellType] = {
cellType ← SequenceCell[name: "FunctionBlock",
baseCell: Extract["ALUFnBlock.sch"], count: wordSize,
sequencePorts: Wires["left", "right", "aluOut", "st2A", "r2B", "cBus", "G", "P", "carry"]];
PWCore.SetArrayX[cellType];
};
-- Carry Propagator: a tree laid out as an array
-- top, 0, 0:1, 1, 0:3, 2, 2:3, 3, 0:7, ...
-- Bottom: (P, G, carry)[0..32).
-- Next level p0to1, p2to3, ... then p0to3, p4to7... and finally p0to31; same with g.
CreateCarryProp: PROC RETURNS [cellType: CellType] = {
AttachInst: PROC ~ {
left, right, mid: NAT;
pas: LIST OF PANIL;
FOR pos: NAT DECREASING IN [1..32) DO-- root already placed
[left, right, mid] ← F[pos];
pas ← LIST[
["Cin", Index["carry", right]],
["C", Index["carry", mid]],
["G", IO.PutFR["g%gto%g", IO.int[left], IO.int[right]]],
["P", IO.PutFR["p%gto%g", IO.int[left], IO.int[right]]],
["left", Index["left", pos]], -- just buses
["right", Index["right", pos]],
["st2A", Index["st2A", pos]],
["r2B", Index["r2B", pos]],
["cBus", Index["cBus", pos]]
];
IF BitHacks.ODD[pos] THEN { -- leaf cell
pas ← CONS[["Pleft", Index["P", left]], pas];
pas ← CONS[["Gleft", Index["G", left]], pas];
pas ← CONS[["Pright", Index["P", right]], pas];
pas ← CONS[["Gright", Index["G", right]], pas];
}
ELSE {
pas ← CONS[["Pleft", IO.PutFR["p%gto%g", IO.int[left], IO.int[mid]]], pas];
pas ← CONS[["Gleft", IO.PutFR["g%gto%g", IO.int[left], IO.int[mid]]], pas];
pas ← CONS[["Pright", IO.PutFR["p%gto%g", IO.int[mid+1], IO.int[right]]], pas];
pas ← CONS[["Gright", IO.PutFR["g%gto%g", IO.int[mid+1], IO.int[right]]], pas];
};
instances ← CONS[InstanceList[cp, pas], instances];
ENDLOOP;
};
cp: CellType ← Extract["ALUCP.sch"];
instances: LIST OF CellInstance ← NIL;
-- The tree: 31 instances
AttachInst[];
-- The top, a bit special: just apply f0to31 to carry[0] to get carryOut, ignore the rest
instances ← CONS[
Instance[cp,
["Gleft", "Gnd"], ["Pleft", "Gnd"], ["Gright", "g0to31"], ["Pright", "p0to31"],
["Cin", "carryOut"], ["C", "carry[0]"], ["G", "fakos"], ["P", "fakos"],
["left", "left[0]"], ["right", "right[0]"], ["st2A", "st2A[0]"],
["r2B", "r2B[0]"], ["cBus", "cBus[0]"]],
instances];
cellType ← Cell[
name: "CarryProp",
public: Union[
Wires["Vdd", "Gnd",
Bus["left"], Bus["right"], Bus["st2A"], Bus["r2B"], Bus["cBus"],
Bus["P"], Bus["G"], Bus["carry"], "carryOut"],
TreeWires[]],
onlyInternal: Wires["fakos"],
instances: instances];
PWCore.SetAbutX[cellType];
};
-- Wire generation
F: PROC [pos: NAT] RETURNS [left, right, mid: NAT] ~ {
width: NAT ← 1;
level: NAT ← pos;
WHILE BitHacks.EVEN[level] DO
IF level=0 THEN ERROR; -- no infinite loop!
width ← 2*width; level ← level/2;
ENDLOOP;
RETURN[left: pos-width, right: pos+width-1, mid: pos-1];
};
-- All the extra wires that wire up the tree (p0to1, g0to3, ...)
TreeWires: PROC RETURNS [Wire] ~ {
wrs: LIST OF WRNIL;
-- p and g tree
MakeWire: PROC [first, width: NAT] ~ {
mid, half, last: NAT;
IF width=1 THEN RETURN; -- bottom already taken care of.
-- Up in the tree: f0to3, f4to7 => f0to7 with c7 => c3
last ← first+width-1;
-- root
wrs ← CONS[IO.PutFR["p%gto%g", IO.int[first], IO.int[last]], wrs];
wrs ← CONS[IO.PutFR["g%gto%g", IO.int[first], IO.int[last]], wrs];
-- siblings
half ← width/2;
mid ← first+half-1;
MakeWire[first, half];
MakeWire[mid+1, half];
};
MakeWire[0, 32];
RETURN[WireList[wrs]];
};
END.
 TO DO
Layout of the XOR in the FB.