CoreRouteFlatImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Don Curry December 7, 1987 11:29:29 am PST
Massoud Pedram July 8, 1988 2:23:24 pm PDT
DIRECTORY
Atom, CD, CDBasics, Core, CoreClasses, CoreFlat, CoreGeometry, CoreOps, CoreProperties, CoreRoute, CoreRouteFlat, DABasics, IO, PWCore, RefTab, Rope, Route, Sisyph, SymTab, TerminalIO;
CoreRouteFlatImpl:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CoreFlat, CoreGeometry, CoreOps, CoreProperties, CoreRoute, IO, PWCore, RefTab, Sisyph, SymTab, TerminalIO
EXPORTS CoreRouteFlat =
Types
Structure: TYPE = CoreRouteFlat.Structure;
Instance: TYPE = CoreRouteFlat.Instance;
TwoInstances: TYPE = RECORD[i0,i1: 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
ComparePosition:
PROC [pos1, pos2:
CD.Position]
RETURNS [
BOOL] = {
RETURN[
IF pos1.y = pos2.y
THEN pos1.x <= pos2.x
ELSE pos1.y < pos2.y]};
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],
layObject: PWCore.Layout[instance.type],
props: CopyProps[instance.properties, instance.type.properties, propKeys]]];
actuals: RefTab.Ref ← CoreOps.CreateBindingTable[instance.type.public, instance.actual];
structure.instances ← CONS[inst, structure.instances];
FOR list:
LIST
OF Instance←structure.instances, list.rest
WHILE list#
NIL
AND list.rest#
NIL
DO
IF ComparePosition[list.first.position, list.rest.first.position]
THEN EXIT
ELSE [list.first, list.rest.first] ← TwoInstances[list.rest.first, list.first] ENDLOOP;
FOR side: DABasics.Side
IN DABasics.Side
DO
instPins: CoreRoute.WirePins ←
CoreRoute.LayPins[instance.type, side];
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];
AddONodePin[pin, wp.wire, act, structure.oNodes, 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.InstONode ← net.instONodes, ins.rest
WHILE ins#
NIL
DO
IF ins.first.oNode.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];
schObj: CD.Object ← CoreGeometry.GetObject[schDeco, root];
rootInstance: Instance ←
NEW[CoreRouteFlat.InstanceRec ← [
name: rootName,
schIR: CD.InterestRect[schObj],
rootInstance: TRUE,
props: CopyProps[properties, root.properties, propKeys]]];
structure ←
NEW[CoreRouteFlat.StructureRec ←[
name: rootName,
instances: LIST[rootInstance],
nets: SymTab.Create[],
oNodes: RefTab.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 oNodes 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];
AddONodePin[pin, wires.first, NIL, structure.oNodes, net, rootInstance, propKeys];
index ← index + 1 ENDLOOP ENDLOOP};
AddONodePin:
PROC[
pin: CoreRouteFlat.Pin,
wire: Core.Wire,
actual: Core.Wire,
oNodes: RefTab.Ref, -- wire to oNode
net: CoreRouteFlat.Net,
inst: Instance,
propKeys: Atoms] = {
oNode: CoreRouteFlat.ONode ← NARROW[RefTab.Fetch[oNodes, wire].val];
IF oNode=
NIL
THEN {
shortName: Rope.ROPE ← CoreOps.GetShortWireName[wire];
oNode ← NEW[CoreRouteFlat.ONodeRec ← [name: shortName, public: actual=NIL]];
[] ← RefTab.Store[oNodes, wire, oNode];
oNode.properties ← CopyProps[wire.properties, NIL, propKeys]};
FOR nns:
LIST
OF CoreRouteFlat.NetONode ← inst.netONodes, nns.rest
WHILE nns#
NIL
DO
IF nns.first.oNode=oNode THEN EXIT;
REPEAT
FINISHED => {
-- first pin of this oNode for this instance
inst.netONodes ← CONS[CoreRouteFlat.NetONode[net, oNode], inst.netONodes];
net.instONodes ← CONS[CoreRouteFlat.InstONode[inst, oNode], net.instONodes];
IF actual#
NIL
THEN
net.properties ← CopyProps[actual.properties, net.properties, propKeys];
net.properties ← CopyProps[wire.properties, net.properties, propKeys]} ENDLOOP;
FOR pins:
LIST
OF CoreRouteFlat.Pin ← oNode.pins, pins.rest
WHILE pins#
NIL
DO
IF pins.first=pin
THEN
EXIT;
REPEAT
FINISHED =>
{oNode.pins ← CONS[pin, oNode.pins]} ENDLOOP};
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
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.NetONode ← inst.netONodes, nn.rest
WHILE nn#
NIL
DO
PrintNetONode[nn.first] ENDLOOP};
PrintNetONode:
PROC[nONode: CoreRouteFlat.NetONode] ~ {
TerminalIO.PutF[" NetONode
: %g %g%g\n",
IO.rope[nONode.net.name],
IO.rope[nONode.oNode.name],
IO.rope[IF nONode.oNode.public THEN " (public)" ELSE ""]];
FOR pins:
LIST
OF CoreRouteFlat.Pin ← nONode.oNode.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"];