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 August 20, 1985 1:44:31 pm PDT
DIRECTORY
CD USING [Design, lambda, 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, propPrettyPrint, PropPrettyPrintProc, PutProp, RegisterProperty, StoreProperties],
CoreRecord 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],
SXOutputPrivate USING [GetAName, PrintActualProc, PrintFormalProc, PrintHeadProc, PrintInstanceEndProc, PrintInstanceHeadProc, PrintLocalNodeProc, PrintStartBodyProc, PrintStrayProc, QuoteProc]
;
SXOutputImplC: CEDAR PROGRAM
IMPORTS CDInstances, CDOrient, CDProperties, Convert, Core, CoreProperties, CoreOps, CoreRecord, ImagerTransformation, IO, Rope, SXAtoms, SXOutputPrivate
EXPORTS SXOutputPrivate =
BEGIN
OPEN SXOutputPrivate;
Stuff for SXOutputImplA
coreDesign: PUBLIC Core.Design;
coreCellBuffer: PUBLIC Core.CellType;
coreCellInstance: PUBLIC CoreRecord.RecordCellType;
coreInstanceBuffer: PUBLIC CoreRecord.CellInstance;
corePortBuffer, coreNodeBuffer, corePortInstances: PUBLIC LIST OF Core.Wire ← NIL;
strayBuffer: PUBLIC Core.Properties;
QuoteCore: PUBLIC QuoteProc =
Actually does not quote !
BEGIN
RETURN [Convert.RopeFromRope[from: name, quote: FALSE]]
END; -- QuoteCore
ComputeStray: PUBLIC PrintStrayProc =
Traverse and copy instance list transforming to l units
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/(CD.lambda*CD.lambda);
e.perim ← i.first.perim/CD.lambda;
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.
stray ← CONS [e, stray]
ENDLOOP;
strayBuffer ← CoreProperties.PutProp [strayBuffer, SXAtoms.strayInfo, stray]
Note that Core copies around the properties and there is no canonical order mantained.
END; -- ComputeStray
InsertCell: PUBLIC PrintHeadProc =
BEGIN
coreCellBuffer ← NEW [Core.CellTypeRec];
coreCellBuffer.name ← name;
coreCellBuffer.class ← CoreRecord.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 =
[cellName: ROPE]
BEGIN
coreCellBuffer.publicWire ← 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 [CoreRecord.CellInstanceRec];
coreInstanceBuffer.name ← QuoteCore [GetAName[inst]];
coreInstanceBuffer.actualWire ← 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.actualWire ← CoreOps.CreateRecordWire [name: "port instances", components: corePortInstances];
coreCellInstance.instances ← CONS [coreInstanceBuffer, coreCellInstance.instances];
corePortInstances ← NIL
END;  -- EndPortInstanceList
InsertInstances: PUBLIC PrintBodyEndProc =
BEGIN
END; -- InsertInstances
Stuff for Core
Compare: CoreProperties.PropCompareProc =
TYPE = PROC [prop: ATOM, value1, value2: REF ANY] RETURNS [equal: BOOLFALSE];
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 =>
We don't compare for now, because these are unordered lists.
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 =
TYPE = PROC [prop: ATOM, value: REF ANY] RETURNS [valCopy: REF ANY];
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]
By definition the list is unordered !
ENDLOOP;
valCopy ← newS};
SXAtoms.locInfo => {
oldL: WireLocation = NARROW [value];
valCopy ← NEW [SX.NodeLocation ← oldL^]};
SXAtoms.crystalAttr => {
new: Rope.ROPENARROW [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.PropPrettyPrintProc ~ BEGIN
TYPE = PROC [to: IO.STREAM, prop: ATOM, context, val: REF ANY]
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
Write: CoreProperties.PropWriteProc ~ BEGIN
TYPE = PROC [out: IO.STREAM, val: REF ANY, context: REF ANYNIL]
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 ANYNIL] RETURNS [val: REF ANY]
END; -- Read
SetDesignProp: PUBLIC PROCEDURE [cdD: CD.Design, coreD: Core.Design] =
Set a property on the design containing the technology and the definition of the layers. May raise Core.StructureError [MissingParameter].
BEGIN
techProp: SX.TechInfo;
technologyHandle: REF SX.TechHandle ← NARROW [CDProperties.GetProp [from: cdD.technology, prop: SXAtoms.spinifex]];
Check tech info is there.
IF (technologyHandle = NIL) THEN
[] ← SIGNAL Core.StructureError [type: MissingParameter, message: "Design has not a Spinifex technology"];
Store the technology and layer names.
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
We use an intermediate procedure call because we vary only one parameter. And because the Core interface has increased in complexity.
propertyProperties: Core.Properties ← NIL;
compare: REF CoreProperties.PropCompareProc = NEW [CoreProperties.PropCompareProc ← Compare];
copy: REF CoreProperties.PropCopyProc = NEW [CoreProperties.PropCopyProc ← Copy];
print: REF CoreProperties.PropPrettyPrintProc = NEW [CoreProperties.PropPrettyPrintProc ← 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.propPrettyPrint, value: print];
CoreProperties.StoreProperties [prop: property, properties: propertyProperties];
END; -- Register
Module initialization: register the properties with Core.
Register [SXAtoms.techInfo];
Register [SXAtoms.strayInfo];
Register [SXAtoms.locInfo];
Register [SXAtoms.crystalAttr];
Register [SXAtoms.cdDesignHint];
Register [SXAtoms.cdCellHint];
Register [SXAtoms.instanceTransf];
END.
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 CoreRecord, RecordCell became RecordCellType, InstanceRec became CellInstanceRec, Instance became CellInstance
changes to: DIRECTORY, SXOutputImplC, coreCellInstance, coreInstanceBuffer, InsertCell, CreateInstance