GCPWCore.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Preas, July 11, 1986 10:15:48 am PDT
Massoud Pedram March 11, 1988 6:25:40 pm PST
DIRECTORY CD, PW, CDIO, CDSymbolicObjects, Core, CoreClasses, CoreFlat, CoreGeometry, CoreOps, CoreProperties, GC, PWCore, PWPins, Rope, RTCoreUtil, RTStructure, Sinix, Sisyph, DABasics, GCHybrid;
GCPWCore: CEDAR PROGRAM
IMPORTS CDSymbolicObjects, CoreGeometry, CoreOps, CoreProperties, GC, PWCore, PWPins, RTCoreUtil, Sisyph, PW, GCHybrid
= BEGIN
EachInstanceProc : TYPE = PROC [decoration: CoreGeometry.Decoration, cellInstance: CoreClasses.CellInstance] RETURNS [quit: BOOLFALSE];
EnumerateInstances: PUBLIC PROC [decoration: CoreGeometry.Decoration, cellType: Core.CellType, EachInstance: EachInstanceProc] RETURNS [quit: BOOLFALSE] ~ {
rct: CoreClasses.RecordCellType ← NARROW[cellType.data];
IF rct.size # 0 THEN {
FOR i: NAT IN [0..rct.size) DO
[] ← EnumerateInstances[decoration, CoreOps.Recast[me: rct[i].type], EachInstance];
[] ← EachInstance[decoration, rct[i]];
ENDLOOP;
};
};
HybridProcs
HybridLayoutAtom: ATOM ← PWCore.RegisterLayoutAtom[$Hybrid, HybridLayout, HybridDecorate, HybridAttributes];
HybridLayout: PWCore.LayoutProc = {
result: GC.Result;
context: GC.Context;
structure: RTStructure.Structure;
name: Rope.ROPE ← CoreOps.GetCellTypeName[cellType];
hMaterial: Rope.ROPE ← "metal";
vMaterial: Rope.ROPE ← "metal2";
design: CD.Design ← PW.OpenDesign["SimpleBPCTest.dale"];
rules: GC.DesignRules ← GC.CreateDesignRules[technologyKey, rulesKey, hMaterial, vMaterial];
structure ← GC.CreateStructure[cellType, RTCoreUtil.defaultFlatten, extractMode.decoration];
GCHybrid.DiddleCells[design, structure];
GC.InitialPlace[structure];
context ← GC.CreateContext["BPCAutoLayout", structure, rules];
GC.DoInitialGlobalRoute[context, none, goodInternal];
IPMainViewer.BuildViewer["GCTest2"];
IPMainViewer.SetTopTo[NARROW[context.topology], structure.name, FALSE];
result ← GC.DoDetailRoute[context, hybrid];
RETURN[result.object]};
HybridDecorate: PUBLIC PWCore.DecorateProc = {
EachPublicPin: PWPins.InstanceEnumerator = {
name: Rope.ROPE ← CDSymbolicObjects.GetName[inst];
wire: Core.Wire ← CoreOps.FindWire[cellType.public, name];
pins: LIST OF CoreGeometry.Instance;
IF wire=NIL THEN RETURN;
pins ← CoreGeometry.GetPins[extractMode.decoration, wire];
CoreGeometry.PutPins[extractMode.decoration, wire, CONS [[inst.ob, inst.trans], pins]];
};
CoreOps.VisitRootAtomics[cellType.public, SmashPins];
CoreGeometry.PutIR[extractMode.decoration, cellType, CD.InterestRect[obj]];
[] ← PWPins.EnumerateEdgePins[obj, EachPublicPin];
};
-- Puts on public wires a property indicating their side
HybridAttributes: PUBLIC PWCore.AttributesProc = {-- [cellType: Core.CellType]
FindSideForEachPin: CoreGeometry.EachWirePinProc = {
[wire: Core.Wire, instance: CD.Instance, min: INT, max: INT, side: CoreGeometry.Side, layer: CD.Layer] RETURNS [quit: BOOLFALSE]
PushPropOnAtomic: PROC [wire: Core.Wire] ~ {
CoreProperties.PutWireProp[wire, GC.sideProp, ref];
};
ref: REFSELECT side FROM
bottom => GC.bottomSideValue,
top => GC.topSideValue,
right => GC.rightSideValue,
left => GC.leftSideValue,
ENDCASE => GC.noSideValue;
IF wire.size=0 THEN CoreProperties.PutWireProp[wire, GC.sideProp, ref]
ELSE CoreOps.VisitRootAtomics[wire, PushPropOnAtomic];
};
EachInstance: EachInstanceProc = {-- [decoration: CoreGeometry.Decoration, cellInstance: CoreClasses.CellInstance]
object: CD.Object ← CoreGeometry.GetObject[decoration, cellInstance.type];
box: DABasics.Rect ← object.bbox;
trans: DABasics.Position ← CoreGeometry.GetTrans[decoration, cellInstance].off;
-- Need to decompose coordinates later.--
CoreProperties.PutCellInstanceProp[cellInstance, GC.originProp, NEW[DABasics.Position ← [x: trans.x, y: trans.y]]];
CoreProperties.PutCellInstanceProp[cellInstance, GC.sizeProp, NEW[DABasics.Position ← [x: box.x2-box.x1, y: box.y2-box.y1]]];
CoreProperties.PutCellTypeProp[cellInstance.type, GC.sizeProp, NEW[DABasics.Position ← [x: box.x2-box.x1, y: box.y2-box.y1]]];
};
decoration: CoreGeometry.Decoration ← Sisyph.mode.decoration;
DO
IF CoreGeometry.HasObject[decoration, cellType] THEN {
[] ← CoreGeometry.EnumerateWireSides[decoration, cellType, FindSideForEachPin];
[] ← EnumerateInstances[decoration, cellType, EachInstance];
EXIT};
IF cellType.class.recast = NIL THEN EXIT;
cellType ← CoreOps.Recast[cellType];
ENDLOOP;
};
GCProcs
GCLayoutAtom: ATOM ← PWCore.RegisterLayoutAtom[$GC, GCLayout, GCDecorate, GCAttributes];
The cellType to layout is a record cellType containing elements to be routed; the layout proc flattens the Core description and calls the general cell router.
GCLayout: PWCore.LayoutProc = {
result: GC.Result;
context: GC.Context;
structure: RTStructure.Structure;
name: Rope.ROPE ← CoreOps.GetCellTypeName[cellType];
hMaterial: Rope.ROPE ← "metal";
vMaterial: Rope.ROPE ← "metal2";
rules: GC.DesignRules ← GC.CreateDesignRules[technologyKey, rulesKey, hMaterial, vMaterial];
structure ← GC.CreateStructure[cellType, RTCoreUtil.defaultFlatten, extractMode.decoration];
GC.InitialPlace[structure];
context ← GC.CreateContext["BPCAutoLayout", structure, rules];
GC.DoInitialGlobalRoute[context, power, goodInternal];
IPMainViewer.BuildViewer["GCTest2"];
IPMainViewer.SetTopTo[NARROW[context.topology], structure.name, FALSE];
result ← GC.DoDetailRoute[context, generalCell];
RETURN[result.object]};
GCDecorate: PUBLIC PWCore.DecorateProc = {
EachPublicPin: PWPins.InstanceEnumerator = {
name: Rope.ROPE ← CDSymbolicObjects.GetName[inst];
wire: Core.Wire ← CoreOps.FindWire[cellType.public, name];
pins: LIST OF CoreGeometry.Instance;
IF wire=NIL THEN RETURN;
pins ← CoreGeometry.GetPins[extractMode.decoration, wire];
CoreGeometry.PutPins[extractMode.decoration, wire, CONS [[inst.ob, inst.trans], pins]];
};
CoreOps.VisitRootAtomics[cellType.public, SmashPins];
CoreGeometry.PutIR[extractMode.decoration, cellType, CD.InterestRect[obj]];
[] ← PWPins.EnumerateEdgePins[obj, EachPublicPin];
};
-- Puts on public wires a property indicating their side
GCAttributes: PUBLIC PWCore.AttributesProc = {-- [cellType: Core.CellType]
FindSideForEachPin: CoreGeometry.EachWirePinProc = {
[wire: Core.Wire, instance: CD.Instance, min: INT, max: INT, side: CoreGeometry.Side, layer: CD.Layer] RETURNS [quit: BOOLFALSE]
PushPropOnAtomic: PROC [wire: Core.Wire] ~ {
CoreProperties.PutWireProp[wire, GC.sideProp, ref];
};
ref: REFSELECT side FROM
bottom => GC.bottomSideValue,
top => GC.topSideValue,
right => GC.rightSideValue,
left => GC.leftSideValue,
ENDCASE => GC.noSideValue;
IF wire.size=0 THEN CoreProperties.PutWireProp[wire, GC.sideProp, ref]
ELSE CoreOps.VisitRootAtomics[wire, PushPropOnAtomic];
};
EachInstance: EachInstanceProc = {-- [decoration: CoreGeometry.Decoration, cellInstance: CoreClasses.CellInstance]
object: CD.Object ← CoreGeometry.GetObject[decoration, cellInstance.type];
box: DABasics.Rect ← object.bbox;
trans: DABasics.Position ← CoreGeometry.GetTrans[decoration, cellInstance].off;
-- Need to decompose coordinates later.--
CoreProperties.PutCellInstanceProp[cellInstance, GC.originProp, NEW[DABasics.Position ← [x: trans.x, y: trans.y]]];
CoreProperties.PutCellInstanceProp[cellInstance, GC.sizeProp, NEW[DABasics.Position ← [x: box.x2-box.x1, y: box.y2-box.y1]]];
CoreProperties.PutCellTypeProp[cellInstance.type, GC.sizeProp, NEW[DABasics.Position ← [x: box.x2-box.x1, y: box.y2-box.y1]]];
};
decoration: CoreGeometry.Decoration ← Sisyph.mode.decoration;
DO
IF CoreGeometry.HasObject[decoration, cellType] THEN {
[] ← CoreGeometry.EnumerateWireSides[decoration, cellType, FindSideForEachPin];
[] ← EnumerateInstances[decoration, cellType, EachInstance];
EXIT};
IF cellType.class.recast = NIL THEN EXIT;
cellType ← CoreOps.Recast[cellType];
ENDLOOP;
};
technologyKey: ATOM ← $cmosB;  -- $cmosA or $cmosB
rulesKey: ATOM ← $Hybrid; -- $Hybrid or $cmosB
libName: Rope.ROPE ← "CMOSB";
extractMode: Sinix.Mode ← PWCore.extractMode;
SmashPins: PROC [wire: Core.Wire] = {CoreGeometry.PutPins[extractMode.decoration, wire, NIL]};
END.