CoreRouteFlatImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Don Curry December 2, 1987 12:14:28 pm PST
DIRECTORY
Atom, CD, CDBasics, Core, CoreClasses, CoreFlat, CoreGeometry, CoreOps, CoreProperties, CoreRoute, CoreRouteFlat, DABasics, GC, IO, PWCore, RefTab, Rope, Route, Sisyph, SymTab, TerminalIO;
CoreRouteFlatImpl:
CEDAR
PROGRAM
IMPORTS Atom, CD, CDBasics, CoreFlat, CoreGeometry, CoreOps, CoreProperties, CoreRoute, CoreRouteFlat, GC, IO, PWCore, RefTab, Rope, Sisyph, SymTab, TerminalIO
EXPORTS CoreRouteFlat =
BEGIN
Types
Structure: TYPE = CoreRouteFlat.Structure;
Instance: TYPE = CoreRouteFlat.Instance;
CellType: TYPE = Core.CellType;
Atoms: TYPE = LIST OF ATOM;
LeafProc:
TYPE =
PROC[
flatCell: CoreFlat.FlatCellTypeRec,
instance: CoreClasses.CellInstance,
bindings: CoreFlat.Bindings, -- cell.public to flatWires wrt root
position: CD.Position];
layDeco: CoreGeometry.Decoration ← PWCore.extractMode.decoration;
schDeco: CoreGeometry.Decoration ← Sisyph.mode.decoration;
Exported Procedures
FlattenToLayout:
PUBLIC
PROC[
root: CellType,
propKeys: Atoms ← NIL,
properties: Core.Properties ←
NIL ]
RETURNS [structure: Structure] = {
EachLeaf: LeafProc = {
instName: Rope.ROPE ← CoreFlat.CellTypePathRope[root, flatCell];
schObj: CD.Object ← CoreGeometry.GetObject[schDeco, instance.type];
inst: Instance ←
NEW[CoreRouteFlat.InstanceRec ← [
name: instName,
flatCell: NEW[CoreFlat.FlatCellTypeRec ← flatCell],
position: position,
schIR: CD.InterestRect[schObj],
cdObject: PWCore.Layout[instance.type],
props: CopyProps[instance.properties, instance.type.properties, propKeys]]];
nodes: RefTab.Ref ← RefTab.Create[];
actuals: RefTab.Ref ← CoreOps.CreateBindingTable[instance.type.public, instance.actual];
structure.instances ← CONS[inst, structure.instances];
FOR side: DABasics.Side
IN DABasics.Side
DO
instPins: CoreRoute.WirePins ←
CoreRoute.FilteredCellTypeLayoutPins[instance.type, side];
FOR instPins ← instPins, instPins.rest
WHILE instPins#
NIL
DO
wp: CoreRoute.WirePin ← instPins.first;
pin: CoreRouteFlat.Pin ← [range: [wp.min, wp.max], side: side, layer: wp.layer];
net: CoreRouteFlat.Net ← BoundInternalNet[wp.wire, root, bindings, structure];
act: Core.Wire ← NARROW[RefTab.Fetch[actuals, wp.wire].val];
AddNodePin[pin, wp.wire, act, nodes, net, inst, propKeys];
ENDLOOP ENDLOOP;
CoreRoute.FlushLayPinCache[instance.type];
CoreRoute.FlushSchPinCache[instance.type]};
rootName: Rope.ROPE ← CoreOps.GetCellTypeName[root];
TerminalIO.PutF["Flatten %g into routing structure.\n", IO.rope[rootName]];
structure ← CreateRootStructure[root, properties, propKeys];
FlattenWithSchLocs[root, EachLeaf]};
IsPublic:
PUBLIC
PROC[net: CoreRouteFlat.Net]
RETURNS [isPublic:
BOOLEAN] ~ {
FOR ins:
LIST
OF CoreRouteFlat.InstNode ← net.instNodes, ins.rest
WHILE ins#
NIL
DO
IF ins.first.node.public THEN RETURN[TRUE] ENDLOOP;
RETURN[FALSE]};
TranslateRange:
PUBLIC
PROC[instance: Instance, pin: CoreRouteFlat.Pin]
RETURNS [range: CoreRouteFlat.Range]~ {
range ←
SELECT pin.side
FROM
top, bottom => [instance.position.x + pin.range.min, instance.position.x + pin.range.max],
left, right => [instance.position.y + pin.range.min, instance.position.y + pin.range.max],
ENDCASE => ERROR};
PrintStructure:
PUBLIC
PROC[structure: Structure] ~ {
TerminalIO.PutF["Core Route Flat Structure: %g\n", IO.rope[structure.name]];
FOR insts:
LIST
OF Instance ← structure.instances, insts.rest
WHILE insts#
NIL
DO
PrintInstance[insts.first] ENDLOOP};
Auxiliary Procedures
CreateRootStructure:
PROC
[root: CellType, properties: Core.Properties, propKeys: Atoms]
RETURNS[structure: Structure] ~ {
rootName: Rope.ROPE ← CoreOps.GetCellTypeName[root];
bindings: RefTab.Ref ← CoreFlat.InitialBindingTable[root];
nodes: RefTab.Ref ← RefTab.Create[];
rootInstance: Instance ←
NEW[CoreRouteFlat.InstanceRec ← [
name: rootName,
rootInstance: TRUE,
props: CopyProps[properties, root.properties, propKeys]]];
structure ←
NEW[CoreRouteFlat.StructureRec ←[
name: rootName,
instances: LIST[rootInstance],
nets: SymTab.Create[],
outerInstance: rootInstance,
bindings: bindings,
auxLabels: SymTab.Create[] ] ];
FOR side: DABasics.Side
IN DABasics.Side
DO
step: INT ← 8*8; -- Just to record order of nodes on each side
index: INT ← 0;
wires: Core.Wires ← CoreRoute.OrderedAtomicSchWires[root, side];
FOR wires ← wires, wires.rest
WHILE wires#
NIL
DO
pin: CoreRouteFlat.Pin ← [range: [index*step, index*step + step/2], side: side];
net: CoreRouteFlat.Net ← BoundInternalNet[wires.first, root, bindings, structure];
AddNodePin[pin, wires.first, NIL, nodes, net, rootInstance, propKeys];
index ← index + 1 ENDLOOP ENDLOOP};
AddNodePin:
PROC[
pin: CoreRouteFlat.Pin,
wire: Core.Wire,
actual: Core.Wire,
nodes: RefTab.Ref, -- wire to node
net: CoreRouteFlat.Net,
inst: Instance,
propKeys: Atoms] = {
node: CoreRouteFlat.Node ← NARROW[RefTab.Fetch[nodes, wire].val];
IF node=
NIL
THEN {
shortName: Rope.ROPE ← CoreOps.GetShortWireName[wire];
node ← NEW[CoreRouteFlat.NodeRec ← [name: shortName, public: actual=NIL]];
[] ← RefTab.Store[nodes, wire, node];
net.instNodes ← LIST[CoreRouteFlat.InstNode[inst, node]];
inst.netNodes ← LIST[CoreRouteFlat.NetNode[net, node]];
net.properties ← CopyProps[wire.properties, net.properties, propKeys];
net.properties ← CopyProps[actual.properties, net.properties, propKeys];
node.properties ← CopyProps[wire.properties, NIL, propKeys]};
node.pins ← CONS[pin, node.pins ]};
BoundInternalNet:
PROC[
wire: Core.Wire,
root: CellType,
bindings: CoreFlat.Bindings,
structure: Structure ]
RETURNS[net: CoreRouteFlat.Net] = {
name: Rope.ROPE ← BoundFlatWireName[wire, root, bindings];
IF (net ←
NARROW[SymTab.Fetch[structure.nets, name].val])=
NIL
THEN {
net ← NEW[CoreRouteFlat.NetRec ← [name: name]];
[] ← SymTab.Store[structure.nets, name, net]} };
BoundFlatWireName:
PROC[wire: Core.Wire, root: CellType, bindings: CoreFlat.Bindings]
RETURNS[Rope.ROPE] = {
flatWire: CoreFlat.FlatWire ← NARROW [RefTab.Fetch[bindings, wire].val];
RETURN[CoreRoute.LabelFlatWire[root, flatWire^]]};
CopyProps:
PROC[primary, secondary: Core.Properties ←
NIL, propKeys: Atoms]
RETURNS [destProperties: Core.Properties ← NIL] ~ {
FOR keys: Atoms ← propKeys, keys.rest
WHILE keys#
NIL
DO
val: REF ← CoreProperties.GetProp[primary, keys.first];
IF val=NIL THEN val ← CoreProperties.GetProp[secondary, keys.first];
destProperties ← CoreProperties.PutProp[destProperties, keys.first, val] ENDLOOP};
FlattenWithSchLocs:
PROC[
root: CellType,
leafProc: LeafProc ] = {
Loc: TYPE = CD.Position;
PathName:
PROC[flatInstance: CoreFlat.FlatCellTypeRec ← [ ]]
RETURNS[name: Rope.ROPE] = {
RETURN[
IF flatInstance = CoreFlat.rootCellType
THEN CoreOps.GetCellTypeName[root]
ELSE CoreFlat.CellTypePathRope[root, flatInstance]]};
FlattenCell: CoreFlat.BoundFlatCellProc = {
childLoc: REF Loc;
IF instance#
NIL
THEN {
parentPath: Rope.ROPE ← PathName[flatParent];
childPath: Rope.ROPE ← PathName[flatCell];
childTran: DABasics.Transformation ←
CoreGeometry.GetTrans[schDeco, instance];
parentLoc: REF Loc ← NARROW[SymTab.Fetch[locations, parentPath].val];
childLoc ← NEW[Loc ← CDBasics.AddPoints[childTran.off, parentLoc^ ]];
IF childTran.orient#original THEN ERROR; -- Rotated instances are not allowed.
IF NOT SymTab.Insert[locations, childPath, childLoc] THEN ERROR};
IF instance=
NIL
OR (PWCore.GetLayoutAtom[cell]=
NIL
AND cell.class.recast#
NIL)
THEN CoreFlat.NextBoundCellType
[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, FlattenCell]
ELSE leafProc[flatCell, instance, bindings, childLoc^]};
locations: SymTab.Ref ← SymTab.Create[];
[] ← SymTab.Store[locations, PathName[], NEW[Loc ← [0,0] ] ];
FlattenCell[root]};
PrintInstance:
PROC[inst: Instance] ~ {
TerminalIO.PutF[" Instance: %g\n", IO.rope[inst.name]];
TerminalIO.PutF[" Pos: [%g, %g]\n", IO.int[inst.position.x], IO.int[inst.position.y]];
TerminalIO.PutF[" SchIR: [%g, %g, %g, %g]\n",
IO.int[inst.schIR.x1], IO.int[inst.schIR.y1], IO.int[inst.schIR.x2], IO.int[inst.schIR.y2]];
FOR nn:
LIST
OF CoreRouteFlat.NetNode ← inst.netNodes, nn.rest
WHILE nn#
NIL
DO
PrintNetNode[nn.first] ENDLOOP};
PrintNetNode:
PROC[nNode: CoreRouteFlat.NetNode] ~ {
TerminalIO.PutF[" NetNode
: %g %g%g\n",
IO.rope[nNode.net.name],
IO.rope[nNode.node.name],
IO.rope[IF nNode.node.public THEN " (public)" ELSE ""]];
FOR pins:
LIST
OF CoreRouteFlat.Pin ← nNode.node.pins, pins.rest
WHILE pins#
NIL
DO
PrintPin[pins.first] ENDLOOP};
PrintPin:
PROC[pin: CoreRouteFlat.Pin] ~ {
TerminalIO.PutF[" Pin
: %6g %5g [%g, %g]\n",
IO.rope[SideNames[pin.side]],
IO.atom[CD.LayerKey[pin.layer]],
IO.int[pin.range.min],
IO.int[pin.range.max]]};
SideNames:
ARRAY DABasics.Side
OF Rope.
ROPE ←
[bottom: "Bottom", top: "Top", left: "Left", right: "Right"];
Attributes, Layout and Decorate ($Hybrid, $GC)
Attributes: PWCore.AttributesProc = {
layAtom: ATOM ← PWCore.GetLayoutAtom[cellType];
hLayer: Rope.ROPE ← "metal";
vLayer: Rope.ROPE ← "metal2";
rules: GC.DesignRules;
structure: Structure;
prop: REF ← CoreProperties.GetCellTypeProp[cellType, $VerticalLayer];
IF prop#NIL THEN {
name: IO.ROPE ← WITH prop SELECT FROM
atom: ATOM => Atom.GetPName[atom],
rope: IO.ROPE => rope,
ENDCASE => ERROR;
IF name.Find["2"]=-1 THEN {hLayer ← "metal2"; vLayer ← "metal"}};
rules ← SELECT layAtom FROM
HybridAtom => GC.CreateDesignRules[$cmosB, $Hybrid, hLayer, vLayer],
GlobalAtom => GC.CreateDesignRules[$cmosB, $cmosB, hLayer, vLayer],
ENDCASE => ERROR;
structure ← CoreRouteFlat.FlattenToLayout[cellType, LIST[$w]];
CoreProperties.PutCellTypeProp[cellType, $GCRules, rules];
CoreProperties.PutCellTypeProp[cellType, $GCStruc, structure]};
Layout: PWCore.LayoutProc = {
name: Rope.ROPE ← CoreOps.GetCellTypeName[cellType];
result: GC.Result;
context: GC.Context;
rules: GC.DesignRules ← NARROW[CoreProperties.GetCellTypeProp[cellType, $GCRules]];
struc: Structure ← NARROW[CoreProperties.GetCellTypeProp[cellType, $GCStruc]];
GC.InitialPlace[struc];
context ← GC.CreateContext[name, struc, rules];
GC.DoInitialGlobalRoute[context];
result ← GC.DoDetailRoute[context];
RETURN[result.object]};
Decorate: PWCore.DecorateProc = {
CompareFlatInstances: PUBLIC CoreRoute.CompareFlatCTProc = {
FOR insts: LIST OF Instance ← struc.instances, insts.rest WHILE insts#NIL DO
IF CoreFlat.FlatCellTypeEqualRec[insts.first.flatCell^, flatCT1] THEN RETURN[TRUE];
IF CoreFlat.FlatCellTypeEqualRec[insts.first.flatCell^, flatCT2] THEN RETURN[FALSE];
ENDLOOP; ERROR};
WireToLabels: PROC[wire: Core.Wire] RETURNS [labels: LIST OF Route.Label ← NIL] = {
flatWire: CoreFlat.FlatWire = NARROW[RefTab.Fetch[struc.bindings, wire].val];
label: Route.Label = CoreRoute.LabelFlatWire[cellType, flatWire^];
auxLabels: LIST OF Rope.ROPE = NARROW[SymTab.Fetch[struc.auxLabels, label].val];
labels ← CONS [label, auxLabels]};
struc: Structure ← NARROW[CoreProperties.GetCellTypeProp[cellType, $GCStruc]];
CoreRoute.DecorateRoutedArea[
cellType: cellType,
obj: obj,
wireToLabels: WireToLabels,
compareCT: CompareFlatInstances]};
HybridAtom: ATOM ← PWCore.RegisterLayoutAtom[$Hybrid, Layout, Decorate, Attributes];
GlobalAtom: ATOM ← PWCore.RegisterLayoutAtom[$GC, Layout, Decorate, Attributes];
END.