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:
ROPE ←
NARROW
[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.