DIRECTORY BE, BELayout, CoreCreate, CoreOps, Logic; BELayoutImpl: CEDAR PROGRAM IMPORTS BE, CoreCreate, CoreOps, Logic EXPORTS BELayout = BEGIN OPEN BELayout, CoreCreate; Signal: SIGNAL = CODE; debug: BOOL _ TRUE; 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]; }; StandardCellExpression: PUBLIC PROC [public: Wire, outputs: StdOutputs, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [cellType: CellType] = { 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]; }; 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 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]; }; 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]; END. ~BELayoutImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Louis Monier September 17, 1986 7:51:21 pm PDT Basics 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]". -- Conventions: all variables are atomic wires in the public -- all standard cells have an input "I" or Seq["I", n] and an output "X". -- 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; -- add instances in a global list insts 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]; }; 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 ΚE– "cedar" style˜codešœ™Kšœ Οmœ1™K™—šΟk œ˜ Kšžœ(˜*—J˜•StartOfExpansion[]šΠbnΟnŸœžœž˜Kšžœ˜&Kšžœ ˜Kšžœžœ˜ —head™Kš œžœžœ˜Kšœžœžœ˜—™K™Kšœ0™0K™MKšœV™VKš œ žœžœžœžœ˜6K˜š  œžœžœ$˜;Kšœ žœ˜%K˜—š  œžœžœžœ˜;Kšœ˜Kš žœžœžœžœΟc˜1Kšœžœžœ ˜+Kšœ˜K˜—K™K™—šœ˜Kšœ&˜&Kšœžœ‘(˜DKšœžœ˜'Kšœ5˜5Kšœ˜—Kšžœžœ˜—Kšžœ˜—Kšœ#‘'˜JK˜—Kšœ"žœ˜&Kš œžœžœžœžœ˜šžœ5žœ žœž˜Pšžœžœž˜'Kšœ žœ‘&˜9šœ˜KšœB˜BKšœ˜—Kšžœžœ˜—Kšžœ˜—šœ+˜+Jšœ(˜(Jšœ˜Jšœ ˜ Jšœ˜—Jšœ˜——™š  œžœžœžœžœ™KšŸœžœ™Kšœ™Kšœ™Kšžœ žœžœ™8Kšœ™Kšœ™—Kšœžœ™$Kšœžœ™ Kšžœ žœ!žœ™9Kšžœ žœ ™Kšœ ™ Kšœ'™'Kšžœžœ ™Kšœ™——™š œ˜Kšžœžœžœ˜šœ9˜9Kšœ žœ(˜7—Kšœ˜—š œ˜Kšžœžœžœ˜šœ9˜9Kšœ žœ<˜K—Kšœ˜—š  œ˜Kšžœžœžœ˜šœ9˜9Kšœ žœ=˜L—Kšœ˜—Kš œ˜Kšœ žœ˜Kšœ žœ˜ Kšœ žœ˜Kšœ žœ˜"Kšœ žœ˜ Kšœ žœ˜Kšœ žœ˜!Kšœ žœ˜—K˜Kšžœ˜K˜—…— 8ϋ