SourceFromLayoutImpl.mesa,
Copyright c 1986 by Xerox Corporation. All rights reserved.
Don Curry May 1, 1987 10:55:38 am PDT
DIRECTORY CD, Core, CoreClasses, CoreGeometry, CoreOps, CoreProperties, RefTab, IO, PWCore, Rope, Rosemary, Sinix, SourceFromLayout, TerminalIO;
SourceFromLayoutImpl: CEDAR PROGRAM
IMPORTS CoreClasses, CoreGeometry, CoreOps, CoreProperties, RefTab, IO, PWCore, Rope, Rosemary, Sinix, TerminalIO
EXPORTS SourceFromLayout =
BEGIN
Wire:   TYPE = Core.Wire;
CellType:  TYPE = Core.CellType;
ROPE:   TYPE = Core.ROPE;
Object:  TYPE = CD.Object;
Signal: SIGNAL = CODE;
LayoutSource: PUBLIC PROC[obj: Object, name: ROPE] RETURNS[cell: CellType] = {
ect: CellType;
root: ROPE ← name.Substr[0, name.Index[0, "."]];
TerminalIO.PutF["Define Core Cell: %g\n", IO.rope[name]];
IF name.Length[]=0 THEN Signal[];
ect ← NARROW [Sinix.Extract[obj, PWCore.extractMode].result];
[] ← CoreOps.SetCellTypeName[ect, name];
MarkWeakTransistors[ect];
FixUpPublic[ect];
cell ← CopyCell[ect];
PWCore.SetLayout[cell, $Value, $PWCoreValue, obj];
[]←PWCore.Layout[cell]};
MarkWeakTransistors: PROC [cell: CellType] = {
SELECT cell.class FROM
CoreClasses.transistorCellClass => ERROR;
CoreClasses.recordCellClass  => {
data: CoreClasses.RecordCellType ← NARROW[cell.data];
FOR child: NAT IN [0..data.size) DO
IF data.instances[child].type.class # CoreClasses.transistorCellClass
THEN MarkWeakTransistors[ data.instances[child].type]
ELSE {
name: ROPENARROW
[CoreProperties.GetCellInstanceProp[data.instances[child], $CoreName]];
IF Rope.Equal[name, "driveWeak"] THEN
[] ← Rosemary.SetTransistorInstanceSize[data.instances[child], driveWeak]};
ENDLOOP };
ENDCASE => ERROR};
SortFlatWire: PROC[wire: Wire] = {
FOR i: NAT IN [0.. wire.size-1) DO
FOR j: NAT IN (i.. wire.size) DO
TwoWires: TYPE = RECORD [w1, w2: Wire];
n1: ROPE ← CoreOps.GetShortWireName[wire[i]];
n2: ROPE ← CoreOps.GetShortWireName[wire[j]];
IF Rope.Compare[n1, n2]=greater THEN
[wire[i], wire[j]] ← TwoWires[wire[j], wire[i]] ENDLOOP ENDLOOP};
FixUpPublic: PROC[cell: CellType] = {
pubs: Core.Wires ← NIL;
rec: CoreClasses.RecordCellType ← NARROW[cell.data];
PWCore.SortInstances[PWCore.extractMode.decoration, cell, PWCore.SortInY];
FOR i: INT DECREASING IN [0..cell.public.size) DO
IF GetWireSides[ cell, cell.public[i] ]#CoreGeometry.noSide
THEN pubs ← CONS[ cell.public[i], pubs]
ELSE TerminalIO.PutF["\nRemoving pseudo public: %g",
IO.rope[ CoreOps.GetShortWireName[cell.public[i] ] ] ]; ENDLOOP;
cell.public ← CoreOps.CreateWire[pubs];
SortFlatWire[cell.public];
SortFlatWire[rec.internal]};
GetWireSides: PROC[cell: CellType, wire: Wire]
RETURNS[sides: CoreGeometry.Sides ← CoreGeometry.noSide] = {
eachPin: CoreGeometry.EachPinProc = {sides[side] ← TRUE};
[]𡤌oreGeometry.EnumerateSides[PWCore.extractMode.decoration, cell, wire, eachPin]};
CopyCell: PROC[old: CellType] RETURNS[new: CellType] = {
Copy: PROC[oldWire: Wire] RETURNS[newWire: Wire] = {
IF (newWire←NARROW[RefTab.Fetch[table, oldWire].val])=NIL THEN {
newWire ← CoreOps.CreateWires[oldWire.size, CoreOps.GetShortWireName[oldWire]];
[]←RefTab.Store[table, oldWire, newWire];
FOR i: NAT IN [0..newWire.size) DO newWire[i] ← Copy[oldWire[i]] ENDLOOP}};
table:  RefTab.Ref ← RefTab.Create[];
name:  ROPE ← CoreOps.GetCellTypeName[old];
oldRec: CoreClasses.RecordCellType ← NARROW[old.data];
newRec: CoreClasses.RecordCellType ← NEW[CoreClasses.RecordCellTypeRec[oldRec.size]];
new ← CoreOps.CreateCellType
[old.class, Copy[old.public], newRec, Rope.Cat["Src", name]];
newRec.internal ← Copy[oldRec.internal];
FOR i: NAT IN [0..newRec.size) DO
newRec[i] ← NEW[CoreClasses.CellInstanceRec ← [
actual: Copy[oldRec[i].actual],
type: oldRec[i].type ]]; ENDLOOP };
END.