BELayoutImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Last Edited by: Louis Monier September 17, 1986 7:51:21 pm PDT
DIRECTORY
BE, BELayout, CoreCreate, CoreOps, Logic;
BELayout
Impl:
CEDAR
PROGRAM
IMPORTS BE, CoreCreate, CoreOps, Logic
EXPORTS BELayout =
BEGIN OPEN BELayout, CoreCreate;
Standard Cell Generation
-- Every operator must correspond to a RootProc.
-- For every node, the proc is called with the arity of the node as argument.
-- The resulting CellType proc[node.size] must have a public "Vdd, Gnd, X, Seq[I, b]".
RootProc: TYPE = PROC [n: NAT] RETURNS [ct: CellType];
SetLayout:
PROC [op:
BE.Operator, layoutProc: RootProc] ~ {
op.data ← NEW[RootProc ← layoutProc];
};
OpToRootCT:
PROC [node:
BE.Node]
RETURNS [ct: CellType] ~ {
proc: RootProc;
IF node.op.data=NIL THEN ERROR; -- no layoutProc
proc ← NARROW[node.op.data, REF RootProc]^;
ct ← proc[node.size];
};
-- Conventions: all variables are atomic wires in the public
-- all standard cells have an input "I" or Seq["I", n] and an output "X".
StandardCellExpression:
PUBLIC PROC [public: Wire, outputs: StdOutputs, name:
ROPE ←
NIL, props: Properties ←
NIL]
RETURNS [cellType: CellType] = {
-- add instances in a global list insts; all bindings refer to public; output bound to out
-- new internals go into a list of WR named wrs;
AddInst:
PROC [ct: CellType, pas:
LIST
OF
PA ←
NIL, insts: CoreCreate.CellInstances]
RETURNS [newInsts: CoreCreate.CellInstances] ~ {
newInsts ← CONS[CoreCreate.InstanceList[type: ct, pas: pas], insts];
};
-- add instances in a global list insts
ExprToCT:
PROC [public: Wire, out: Wire, node: BE.Node] ~ {
root: CellType;
pas: LIST OF PA ← LIST[["X", out]];
inputW: Wire;
root ← OpToRootCT[node];
inputW ← CoreCreate.FindWire[root.public, "I"];
FOR i:
NAT
IN [0..node.size)
DO
WITH node[i]
SELECT
FROM
w: Wire => pas ← CONS[[inputW[i], w], pas]; -- a variable
c: BE.Constant => {
ct: CellType ← IF c=true THEN Logic.Vdd[] ELSE Logic.Gnd[];
insts ← AddInst[ct, , insts]; -- binding by default to Vdd or Gnd
pas ← CONS[[inputW[i], IF c=true THEN "Vdd" ELSE "Gnd"], pas];
};
nodei: BE.Node => {
internal: Wire ← CoreOps.CreateWire[];
wrs ← CONS[internal, wrs]; -- not an input: add to global internals
pas ← CONS[[inputW[i], internal], pas];
ExprToCT[public: public, out: internal, node: nodei];
};
ENDCASE => ERROR;
ENDLOOP;
insts ← AddInst[root, pas, insts]; -- add this instance to the global list
};
insts: CoreCreate.CellInstances ← NIL;
wrs: LIST OF WR ← NIL;
FOR listOutputs: StdOutputs ← outputs, listOutputs.rest
WHILE listOutputs#
NIL
DO
WITH listOutputs.first.expr
SELECT
FROM
w: Wire => ERROR; -- out ← in: confusion or amplifier???
node: BE.Node => {
ExprToCT[public: public, out: listOutputs.first.wire, node: node];
};
ENDCASE => ERROR;
ENDLOOP;
cellType ← CoreCreate.Cell[public: public,
onlyInternal: CoreCreate.WireList[wrs],
instances: insts,
name: name,
props: props];
};
Connection with Core
EqualInt: PUBLIC PROC [wire: Wire, int: INT] RETURNS [expr: Expression] = {
Andify: PROC [wire: Wire] = {
var: Variable ← wire;
max ← max / 2;
IF int>=max THEN int ← int - max ELSE var ← BE.Not[var];
expr ← BE.And[var, expr];
};
count: NAT ← CoreOps.WireBits[wire];
max: INT ← 1;
WHILE count>0 DO max ← max * 2; count ← count -1 ENDLOOP;
IF int>=max THEN Signal[];
expr ← true;
CoreOps.VisitAtomicWires[wire, Andify];
IF int#0 THEN Signal[];
};
Initialization
InvProc: RootProc = {
IF n#1 THEN ERROR;
ct ← Cell[public: Wires["Vdd", "Gnd", Seq["I", 1], "X"],
instances: LIST[Instance[Logic.Inv[], ["I", "I[0]"]]]];
};
Xor2Proc: RootProc = {
IF n#2 THEN ERROR;
ct ← Cell[public: Wires["Vdd", "Gnd", Seq["I", 2], "X"],
instances: LIST[Instance[Logic.Xor2[], ["I-A", "I[0]"], ["I-B", "I[1]"]]]];
};
XNor2Proc: RootProc = {
IF n#2 THEN ERROR;
ct ← Cell[public: Wires["Vdd", "Gnd", Seq["I", 2], "X"],
instances: LIST[Instance[Logic.Xnor2[], ["I-A", "I[0]"], ["I-B", "I[1]"]]]];
};
IFProc: RootProc = {};
SetLayout[BE.notOpr, InvProc];
SetLayout[BE.andOpr, Logic.And];
SetLayout[BE.orOpr, Logic.Or];
SetLayout[BE.nandOpr, Logic.Nand];
SetLayout[BE.norOpr, Logic.Nor];
SetLayout[BE.xorOpr, Xor2Proc];
SetLayout[BE.xnorOpr, XNor2Proc];
SetLayout[BE.ifOpr, IFProc];