DIRECTORY CD USING [Design, Position, Rect], CDInstances USING [InstRectO], CDOrient USING [CreateTransform], CDProperties USING [GetProp], Convert USING [RopeFromRope], Core USING [CellType, CellTypeRec, Design, Properties, StructureError, Wire], CoreOps USING [CreateAtomWire, CreateRecordWire, FetchCellType, InsertCellType], CoreProperties USING [GetProp, propCompare, PropCompareProc, propCopy, PropCopyProc, propPrint, PropPrintProc, PutProp, RegisterProperty, StoreProperties], CoreClasses USING [CellInstance, CellInstanceRec, RecordCellType, recordCellClass], ImagerTransformation USING [Copy, Equal, Transformation], IO USING [atom, int, PutF, rope, STREAM], Rope USING [Compare, Equal, ROPE], SX USING [AreaPerimRec, NodeLocation, SpinifexLayerIndex, TechHandle, TechInfo, TechRec], SXAtoms USING [cdCellHint, cdDesignHint, crystalAttr, instanceTransf, locInfo, spinifex, strayInfo, techInfo], SXAccess, SXOutputPrivate USING [GetAName, PrintActualProc, PrintFormalProc, PrintHeadProc, PrintInstanceEndProc, PrintInstanceHeadProc, PrintLocalNodeProc, PrintStartBodyProc, PrintStrayProc, QuoteProc] ; SXOutputImplC: CEDAR PROGRAM IMPORTS CDInstances, CDOrient, CDProperties, Convert, Core, CoreProperties, CoreOps, CoreClasses, ImagerTransformation, IO, Rope, SXAtoms, SXAccess, SXOutputPrivate EXPORTS SXOutputPrivate = BEGIN OPEN SXOutputPrivate; coreDesign: PUBLIC Core.Design; coreCellBuffer: PUBLIC Core.CellType; coreCellInstance: PUBLIC CoreClasses.RecordCellType; coreInstanceBuffer: PUBLIC CoreClasses.CellInstance; corePortBuffer, coreNodeBuffer, corePortInstances: PUBLIC LIST OF Core.Wire _ NIL; strayBuffer: PUBLIC Core.Properties; QuoteCore: PUBLIC QuoteProc = BEGIN RETURN [Convert.RopeFromRope[from: name, quote: FALSE]] END; -- QuoteCore ComputeStray: PUBLIC PrintStrayProc = BEGIN stray: LIST OF SX.AreaPerimRec _ NIL; -- unordered ti: SX.TechInfo = NARROW [CoreProperties.GetProp [coreDesign.properties, SXAtoms.techInfo]]; strayBuffer _ NIL; FOR i: LIST OF SX.AreaPerimRec _ node.dim, i.rest WHILE i # NIL DO e: SX.AreaPerimRec; e.layer _ i.first.layer; e.area _ i.first.area/(SXAccess.design.technology.lambda*SXAccess.design.technology.lambda); e.perim _ i.first.perim/SXAccess.design.technology.lambda; stray _ CONS [e, stray] ENDLOOP; strayBuffer _ CoreProperties.PutProp [strayBuffer, SXAtoms.strayInfo, stray] END; -- ComputeStray InsertCell: PUBLIC PrintHeadProc = BEGIN coreCellBuffer _ NEW [Core.CellTypeRec]; coreCellBuffer.name _ name; coreCellBuffer.class _ CoreClasses.recordCellClass; CoreOps.InsertCellType [design: coreDesign, cellType: coreCellBuffer ! Core.StructureError => GOTO duplicate]; EXITS duplicate => ERROR END; -- InsertCell InsertPort: PUBLIC PrintFormalProc = BEGIN dummy: IO.STREAM; port: Core.Wire _ CoreOps.CreateAtomWire [name: qName]; internalNode: Core.Wire _ CoreOps.CreateAtomWire [name: qName]; ComputeStray [dummy, node]; port.properties _ internalNode.properties _ strayBuffer; corePortBuffer _ CONS [port, corePortBuffer]; coreNodeBuffer _ CONS [internalNode, coreNodeBuffer] END; -- InsertPort EndPortList: PUBLIC PrintStartBodyProc = BEGIN coreCellBuffer.public _ CoreOps.CreateRecordWire [name: "ports", components: corePortBuffer]; corePortBuffer _ NIL END; InsertNode: PUBLIC PrintLocalNodeProc = BEGIN dummy: IO.STREAM; internalNode: Core.Wire _ CoreOps.CreateAtomWire [name: GetAName[node]]; ComputeStray [dummy, node]; internalNode.properties _ strayBuffer; coreNodeBuffer _ CONS [internalNode, coreNodeBuffer] END; -- InsertNode CreateInstance: PUBLIC PrintInstanceHeadProc = BEGIN cell: Core.CellType = CoreOps.FetchCellType [coreDesign, defName]; t: ImagerTransformation.Transformation; pos, size: CD.Position; ir: CD.Rect; IF cell = NIL THEN ERROR; coreInstanceBuffer _ NEW [CoreClasses.CellInstanceRec]; coreInstanceBuffer.name _ QuoteCore [GetAName[inst]]; coreInstanceBuffer.actual _ NIL; coreInstanceBuffer.type _ cell; ir _ CDInstances.InstRectO [inst]; pos _ [x: ir.x1, y: ir.y1]; size _ [x: ir.x2 - ir.x1, y: ir.y2 - ir.y1]; t _ CDOrient.CreateTransform [cellSize: size, cellInstOrient: inst.orientation, cellInstPos: pos]; coreInstanceBuffer.properties _ CoreProperties.PutProp [on: coreInstanceBuffer.properties, prop: SXAtoms.cdCellHint, value: inst]; coreInstanceBuffer.properties _ CoreProperties.PutProp [on: coreInstanceBuffer.properties, prop: SXAtoms.instanceTransf, value: t] END; -- CreateInstance InsertPortInstance: PUBLIC PrintActualProc = BEGIN portInst: Core.Wire _ CoreOps.CreateAtomWire [name: qActualNode]; corePortInstances _ CONS [portInst, corePortInstances] END; -- InsertPortInstance EndPortInstanceList: PUBLIC PrintInstanceEndProc = BEGIN coreInstanceBuffer.actual _ CoreOps.CreateRecordWire [name: "port instances", components: corePortInstances]; coreCellInstance.instances _ CONS [coreInstanceBuffer, coreCellInstance.instances]; corePortInstances _ NIL END; -- EndPortInstanceList Compare: CoreProperties.PropCompareProc = BEGIN Stray: TYPE = REF SX.AreaPerimRec; WireLocation: TYPE = REF SX.NodeLocation; SELECT prop FROM SXAtoms.techInfo => { t1: SX.TechInfo = NARROW [value1]; t2: SX.TechInfo = NARROW [value2]; RETURN [(Rope.Compare[t1.name, t2.name]=equal)]}; SXAtoms.strayInfo => RETURN [TRUE]; SXAtoms.locInfo => { l1: WireLocation = NARROW [value1]; l2: WireLocation = NARROW [value2]; RETURN [(l1.xy.x=l2.xy.x)AND(l1.xy.y=l2.xy.y)AND(l1.layer=l2.layer)]}; SXAtoms.crystalAttr => RETURN [Rope.Equal[NARROW[value1, Rope.ROPE], NARROW[value2, Rope.ROPE], TRUE]]; SXAtoms.cdDesignHint, SXAtoms.cdCellHint => RETURN [(value1 = value2)]; SXAtoms.instanceTransf => RETURN [ImagerTransformation.Equal[NARROW[value1, ImagerTransformation.Transformation], NARROW[value2, ImagerTransformation.Transformation]]]; ENDCASE => [] _ SIGNAL Core.StructureError [InvariantFailed, "programming error"] END; -- Compare Copy: CoreProperties.PropCopyProc = BEGIN Stray: TYPE = LIST OF SX.AreaPerimRec; WireLocation: TYPE = REF SX.NodeLocation; SELECT prop FROM SXAtoms.techInfo => { oldT: SX.TechInfo = NARROW [value]; valCopy _ NEW [SX.TechRec _ oldT^]}; SXAtoms.strayInfo => { newS: Stray _ NIL; oldS: Stray = NARROW [value]; FOR s: Stray _ oldS, s.rest WHILE s # NIL DO newS _ CONS [s.first, newS] ENDLOOP; valCopy _ newS}; SXAtoms.locInfo => { oldL: WireLocation = NARROW [value]; valCopy _ NEW [SX.NodeLocation _ oldL^]}; SXAtoms.crystalAttr => { new: Rope.ROPE _ NARROW [value, Rope.ROPE]; valCopy _ new}; SXAtoms.cdDesignHint, SXAtoms.cdCellHint => valCopy _ value; SXAtoms.instanceTransf => valCopy _ ImagerTransformation.Copy [NARROW[value, ImagerTransformation.Transformation]]; ENDCASE => [] _ SIGNAL Core.StructureError [InvariantFailed, "programming error"] END; -- Copy Print: CoreProperties.PropPrintProc ~ BEGIN SELECT prop FROM SXAtoms.techInfo => { techProp: SX.TechInfo = NARROW [val, SX.TechInfo]; IO.PutF [stream: to, format: "The technology of the design is %l%g%l\n", v1: IO.rope ["b"], v2: IO.rope [techProp.name], v3: IO.rope ["B"]]; FOR i: SX.SpinifexLayerIndex IN SX.SpinifexLayerIndex DO IO.PutF [stream: to, format: "%g\t\t\t%g\t\t\t%g\n", v1: IO.int [i], v2: IO.atom [techProp.layers[i].id], v3: IO.rope [techProp.layers[i].thymeName]] ENDLOOP}; SXAtoms.strayInfo => { stray: LIST OF SX.AreaPerimRec = NARROW [val, LIST OF SX.AreaPerimRec]; FOR s: LIST OF SX.AreaPerimRec _ stray, s.rest WHILE s # NIL DO IO.PutF [stream: to, format: "(layer = %g, a = %g, p = %g) ", v1: IO.int [s.first.layer], v2: IO.int [s.first.area], v3: IO.int [s.first.perim]] ENDLOOP}; SXAtoms.locInfo => { loc: REF SX.NodeLocation = NARROW [val, REF SX.NodeLocation]; IO.PutF [stream: to, format: "(layer = %g, x = %g, y = %g) ", v1: IO.int [loc.layer], v2: IO.int [loc.xy.x], v3: IO.int [loc.xy.x]]}; SXAtoms.crystalAttr => IO.PutF [stream: to, format: "%g", v1: IO.rope [NARROW [val, Rope.ROPE]]]; SXAtoms.cdDesignHint, SXAtoms.cdCellHint => IO.PutF [stream: to, format: "CD hint %g", v1: IO.rope [IF val=NIL THEN "= NIL" ELSE "# NIL"]]; SXAtoms.instanceTransf => { t: ImagerTransformation.Transformation _ NARROW [val, ImagerTransformation.Transformation]; IF t.integerTrans THEN IO.PutF [stream: to, format: "Translation: (tx = %g, ty = %g)", v1: IO.int [t.tx], v2: IO.int [t.ty]] ELSE IO.PutF [stream: to, format: "Transformation looks insane"]}; ENDCASE => IO.PutF [stream: to, format: "Unknown property"]; END; -- Print SetDesignProp: PUBLIC PROCEDURE [cdD: CD.Design, coreD: Core.Design] = BEGIN techProp: SX.TechInfo; technologyHandle: REF SX.TechHandle _ NARROW [CDProperties.GetProp [from: cdD.technology, prop: SXAtoms.spinifex]]; IF (technologyHandle = NIL) THEN [] _ SIGNAL Core.StructureError [type: MissingParameter, message: "Design has not a Spinifex technology"]; techProp _ NEW [SX.TechRec]; techProp.name _ cdD.technology.name; FOR layer: SX.SpinifexLayerIndex IN [0 .. technologyHandle.numSpinifexLayers) DO techProp.layers[layer].id _ technologyHandle.spinifexLayerNames[layer].layerId; techProp.layers[layer].thymeName _ technologyHandle.spinifexLayerNames[layer].thymeName ENDLOOP; coreD.properties _ CoreProperties.PutProp [on: coreD.properties, prop: SXAtoms.techInfo, value: techProp]; coreD.properties _ CoreProperties.PutProp [on: coreD.properties, prop: SXAtoms.cdDesignHint, value: cdD] END; -- SetDesignProp Register: PROC [property: ATOM] ~ BEGIN propertyProperties: Core.Properties _ NIL; compare: REF CoreProperties.PropCompareProc = NEW [CoreProperties.PropCompareProc _ Compare]; copy: REF CoreProperties.PropCopyProc = NEW [CoreProperties.PropCopyProc _ Copy]; print: REF CoreProperties.PropPrintProc = NEW [CoreProperties.PropPrintProc _ Print]; [] _ CoreProperties.RegisterProperty [property]; propertyProperties _ CoreProperties.PutProp [on: propertyProperties, prop: CoreProperties.propCompare, value: compare]; propertyProperties _ CoreProperties.PutProp [on: propertyProperties, prop: CoreProperties.propCopy, value: copy]; propertyProperties _ CoreProperties.PutProp [on: propertyProperties, prop: CoreProperties.propPrint, value: print]; CoreProperties.StoreProperties [prop: property, properties: propertyProperties]; END; -- Register Register [SXAtoms.techInfo]; Register [SXAtoms.strayInfo]; Register [SXAtoms.locInfo]; Register [SXAtoms.crystalAttr]; Register [SXAtoms.cdDesignHint]; Register [SXAtoms.cdCellHint]; Register [SXAtoms.instanceTransf]; END. φSXOutputImplC.mesa Copyright (C) 1985 by Xerox Corporation. All rights reserved. Spinifex output to Core. Written by gbb August 7, 1985 1:04:35 pm PDT gbb November 7, 1985 11:27:26 am PST Stuff for SXOutputImplA Actually does not quote ! Traverse and copy instance list transforming to l units strayBuffer _ CoreProperties.PutProp [strayBuffer, ti.layers[e.layer].id, e] This scheme cannot be used, because it would require that the layer ids be registered with Core. We want to avoid this registration because it is technology dependent. The information on the technology is attached as a property to the Core design. It has been suggested with little success that Core owns a standard set of properties required to interchange information between tools. This scheme would allow the tools to be really independent, and Core would be the central data structure it claims to be. Note that Core copies around the properties and there is no canonical order mantained. [cellName: ROPE] InsertInstances: PUBLIC PrintBodyEndProc = BEGIN END; -- InsertInstances Stuff for Core TYPE = PROC [prop: ATOM, value1, value2: REF ANY] RETURNS [equal: BOOL _ FALSE]; We don't compare for now, because these are unordered lists. TYPE = PROC [prop: ATOM, value: REF ANY] RETURNS [valCopy: REF ANY]; By definition the list is unordered ! TYPE = PROC [to: IO.STREAM, prop: ATOM, context, val: REF ANY] Write: CoreProperties.PropWriteProc ~ BEGIN TYPE = PROC [out: IO.STREAM, val: REF ANY, context: REF ANY _ NIL] SELECT context FROM SXAtoms.techInfo => { techProp: SX.TechInfo = NARROW [val, SX.TechInfo]; CoreProperties.PropRopeWrite [out, techProp.name, context]; FOR i: SX.SpinifexLayerIndex IN SX.SpinifexLayerIndex DO Stored only once per design, so don't care for compactness. CoreProperties.PropAtomWrite [out, techProp.layers[i].id, context]; CoreProperties.PropRopeWrite [out, techProp.layers[i].thymeName, context] ENDLOOP}; SXAtoms.strayInfo => { stray: LIST OF SX.AreaPerimRec = NARROW [val, LIST OF SX.AreaPerimRec]; FOR s: LIST OF SX.AreaPerimRec _ stray, s.rest WHILE s # NIL DO CoreProperties.PropIntWrite [out, s.first.layer, context]; CoreProperties.PropIntWrite [out, s.first.area, context]; CoreProperties.PropIntWrite [out, s.first.perim, context] ENDLOOP}; SXAtoms.locInfo => { loc: REF SX.NodeLocation = NARROW [val, REF SX.NodeLocation]; CoreProperties.PropIntWrite [out, loc.layer, context]; CoreProperties.PropIntWrite [out, loc.xy.x, context]; CoreProperties.PropIntWrite [out, loc.xy.x, context] SXAtoms.crystalAttr => CoreProperties.PropRopeWrite [out, NARROW [val, Rope.ROPE], context]; SXAtoms.cdDesignHint, SXAtoms.cdCellHint => NULL; SXAtoms.instanceTransf => { t: ImagerTransformation.Transformation _ NARROW [val, ImagerTransformation.Transformation]; CoreProperties.PropRealWrite [out, t.a, context]; CoreProperties.PropRealWrite [out, t.b, context]; CoreProperties.PropRealWrite [out, t.c, context]; CoreProperties.PropRealWrite [out, t.d, context]; CoreProperties.PropRealWrite [out, t.e, context]; CoreProperties.PropRealWrite [out, t.f, context]; CoreProperties.PropIntWrite [out, t.tx, context]; CoreProperties.PropIntWrite [out, t.ty, context]; CoreProperties.PropBoolWrite [out, t.integerTrans, context]; CoreProperties.PropNatWrite [out, t.form, context]}; ENDCASE => IO.PutF [stream: to, format: "Unknown property"]; END; -- Write Read: CoreProperties.PropWriteProc ~ BEGIN TYPE = PROC [in: IO.STREAM, context: REF ANY _ NIL] RETURNS [val: REF ANY] END; -- Read Set a property on the design containing the technology and the definition of the layers. May raise Core.StructureError [MissingParameter]. Check tech info is there. Store the technology and layer names. We use an intermediate procedure call because we vary only one parameter. And because the Core interface has increased in complexity. Module initialization: register the properties with Core. gbb August 7, 1985 4:40:59 pm PDT Amended because of small changes in the Core definition modules changes to: InsertPort, EndPortList, InsertNode, InsertPortInstance, EndPortInstanceList gbb August 13, 1985 11:01:18 am PDT Amended because of changes in the Core definition modules changes to: DIRECTORY, Register: the operations on properties are now passed as properties instead of as parameters. gbb August 20, 1985 1:43:11 pm PDT Core definition module was changed. CoreRecordCells became CoreClasses, RecordCell became RecordCellType, InstanceRec became CellInstanceRec, Instance became CellInstance changes to: DIRECTORY, SXOutputImplC, coreCellInstance, coreInstanceBuffer, InsertCell, CreateInstance Κ ό˜code™K™>K™K™,K™$—code2šΟk ˜ Kšœœ˜"Kšœ œ ˜Kšœ œ˜!Kšœ œ ˜Kšœœ˜KšœœC˜MKšœœC˜PKšœœ‡˜›Kšœ œB˜SKšœœ˜9Kšœœœ˜)Kšœœœ˜"KšœœQ˜YKšœœa˜nK˜ Kšœœ¬˜ΑJ˜—šΡaox œ ˜Iunitšœqœ*˜€Kšœ˜—š˜Lšœ˜—™Mšœ œ ˜Kšœœ˜%Kšœœ˜4Kšœœ˜4Kš œ3œœœ œ˜RKšœ œ˜$šΟn œœ ˜K™Kš˜Kšœ*œ˜7KšœΟc ˜—šŸ œœ˜%Kšœ0Οgœ™7Kš˜Kš œœœœœ  ˜2Kšœœ œD˜\Kšœœ˜š œœœœ!œœ˜BKšœœ˜K˜Kšœ\˜\šœ:˜:KšœL™LK™χK™‚—Kšœœ ˜Kš˜—KšœL˜LK™VKšœ ˜—šŸ œœ˜"Kš˜Kšœœ˜(Kšœ˜Kšœ3˜3Kšœ^œ ˜nš˜Kšœ ˜—Kšœ  ˜—šΟb œœ˜$Kš˜Kšœœœ˜Kšœ7˜7Kšœ?˜?Kšœ˜Kšœ8˜8Kšœœ˜-Kšœœ˜4Kšœ  ˜—š’ œœ˜(Jšœ œ™Kš˜Kšœ]˜]Kšœ˜Kšœ˜—šŸ œœ˜'Kš˜Kšœœœ˜KšœH˜HKšœ˜Kšœ&˜&Kšœœ˜4Kšœ  ˜—šŸœœ˜.Kš˜KšœB˜BKšœ'˜'Kšœ œ ˜Kšœœ˜ Kšœœœœ˜Kšœœ˜7Kšœ5˜5Kšœœ˜ Kšœ˜Kšœ"˜"KšœI˜IKšœb˜bKšœ‚˜‚Kšœ‚˜‚Kšœ ˜—šŸœœ˜,Kš˜KšœA˜AKšœœ˜6Kšœ ˜—šŸœœ˜2Kš˜Kšœm˜mKšœœ2˜SKšœ˜Kšœ ˜—šŸœœ™*Kš™Kšœ ™——™šŸœ"˜)Kšœœœœœœ œœ™PKš˜Kšœœœœ˜"Kšœœœœ˜)šœ˜šœ˜Jš œœ œœ œ ˜EJšœ+˜1—šœ˜J™šœ˜šœ˜Kšœ œ œœ ˜2KšœKœœœ ˜Œšœœœ˜8Kšœ7œœ#œ%˜•Kšœ˜ ——šœ˜Kšœœœœœœœœ˜Gš œœœœœœ˜?Kšœ@œœœ˜Jšœ˜ ——šœ˜Kš œœœœœœ˜=Kšœ@œœœ˜…—šœ˜Kšœ%œœ œ˜J—šœ+˜+Kš œ-œœœœ œ ˜_—šœ˜Kšœ)œ,˜[šœ˜KšœBœœ ˜e—Kšœœ;˜B—Kšœœ/˜<—Kšœ ˜ —šŸœ!™+Kšœœœœœœ œœœ™Bšœ™šœ™Kšœ œ œœ ™2Kšœ;™;šœœœ™8K™;KšœC™CKšœI™IKšœ™ ——šœ™Kšœœœœœœœœ™Gš œœœœœœ™?Kšœ:™:Kšœ9™9Kšœ9™9Jšœ™ ——šœ™Kš œœœœœœ™=Kšœ6™6Kšœ5™5Kšœ4™4—šœ™Kšœ#œ œ ™E—Kšœ,œ™1šœ™Kšœ)œ,™[Kšœ1™1Kšœ1™1Kšœ1™1Kšœ1™1Kšœ1™1Kšœ1™1Kšœ1™1Kšœ1™1Kšœ<™