GCImpl.mesa
Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved.
Bryan Preas, September 16, 1987 4:26:06 pm PDT
Massoud Pedram July 8, 1988 4:32:04 pm PDT
Don Curry December 7, 1987 11:27:08 am PST
DIRECTORY
Atom, CD, CDSimpleRules, Core, CoreGeometry, CoreFlat, CoreOps, CoreProperties, CoreRoute, CoreRouteFlat, DABasics, DesignRules, FS, GC, GCHybrid, GCPrivate, IO, IP, IPBasicOps, IPCoTab, IPTop, IPTypeTab, Process, PW, PWCore, RefTab, Rope, Route, NewRouteTechnology, RouteDiGraph, SymTab;
GCImpl: CEDAR PROGRAM
IMPORTS Atom, CD, CDSimpleRules, CoreFlat, CoreOps, CoreProperties, CoreRoute, CoreRouteFlat, DesignRules, GC, GCHybrid, GCPrivate, IPBasicOps, IPTop, Process, PW, PWCore, RefTab, Rope, NewRouteTechnology, RouteDiGraph, SymTab
EXPORTS GC = BEGIN
Errors
Error: PUBLIC ERROR
[errorType: GC.ErrorType ← callingError, explanation: Rope.ROPENIL] = CODE;
Signal: PUBLIC SIGNAL
[signalType: GC.ErrorType ← callingError, explanation: Rope.ROPENIL] = CODE;
Design Rules
CreateDesignRules: PUBLIC PROC [technologyKey: ATOM, rulesKey: ATOM, horizLayer, vertLayer: Rope.ROPE] RETURNS [designRules: GC.DesignRules] = {
Define the general cell design rules. technologyKey values must correspond to one of the ChipNDale technologies. horizLayer, vertLayer should be "poly", "metal" or "metal2".
rules: DesignRules.Rules ← DesignRules.GetRuleSet[rulesKey];
technology: CD.Technology ← rules.technology;
hLayer: CD.Layer ← CDSimpleRules.GetLayer[technology.key, horizLayer];
vLayer: CD.Layer ← CDSimpleRules.GetLayer[technology.key, vertLayer];
designRules ← NEW[GC.DesignRulesRec ← [
horizLayer: horizLayer,
vertLayer: vertLayer,
horizParams: NewRouteTechnology.DesignRulesParameters[rules, hLayer, vLayer, horizontal],
vertParams: NewRouteTechnology.DesignRulesParameters[rules, hLayer, vLayer, vertical], 
technology: technology]];
designRules.horizRules ← NewRouteTechnology.CmosDesignRules[rules, designRules.horizParams];
designRules.vertRules ← NewRouteTechnology.CmosDesignRules[rules, designRules.vertParams]};
General Cell Context and Result
defaultParms: PUBLIC GC.Parms ← NEW[GC.ParmsRec];
CreateContext: PUBLIC PROC [name: Rope.ROPENIL, structure: CoreRouteFlat.Structure, designRules: GC.DesignRules, parms: GC.Parms] RETURNS [context: GC.Context] = {
Create a General Cell context. The General Cell context definition includes the design rules (conductor and via widths and spacings) for the routing channels as well as the circuit structure definition.
contextName: Rope.ROPEIF name # NIL THEN name ELSE structure.name;
topology:   IPTop.Ref ← IPTop.ReDefineChs [top: IPTop.CreateFromStructure[structure], maxChWidth: TRUE];
SetIPTypes[structure, topology];
SetIPComps[structure, topology];
IPTop.Geometrize[topology];
context ← NEW[GC.ContextRec ← [name: contextName, rules: designRules, structure: structure, parms: parms, topology: topology, topologicalOrder: NIL]]};
DoInitialGlobalRoute: PUBLIC PROC [context: GC.Context, layoutStyle: GC.LayoutStyle] = {
Determine strategic paths for the wiring among the cells.
p: Process.Priority ← Process.GetPriority[];
Process.SetPriority[Process.priorityBackground];
GCPrivate.DoInitialGlobalRoute[context, layoutStyle];
Process.SetPriority[p]};
DoImproveGlobalRoute: PUBLIC PROC [context: GC.Context, layoutStyle: GC.LayoutStyle] = {
Determine strategic paths for the wiring among the cells.
p: Process.Priority ← Process.GetPriority[];
Process.SetPriority[Process.priorityBackground];
GCPrivate.DoImproveGlobalRoute[context, layoutStyle];
Process.SetPriority[p]};
DoDetailRoute: PUBLIC PROC [context: GC.Context, layoutStyle: GC.LayoutStyle] RETURNS [result: GC.Result] = {
Determine actual wiring paths.
p: Process.Priority ← Process.GetPriority[];
Process.SetPriority[Process.priorityBackground];
result ← GCPrivate.DoDetailRoute[context, layoutStyle];
Process.SetPriority[p]};
InitialPlace: PUBLIC PROC [structure: CoreRouteFlat.Structure] ~ {
FOR insts: LIST OF CoreRouteFlat.Instance ← structure.instances, insts.rest
WHILE insts#NIL DO insts.first.placed ← TRUE ENDLOOP};
SetIPTypes: PROC[structure: CoreRouteFlat.Structure, topology: IPTop.Ref] ~ {
EachTypeProc: CoreRouteFlat.EachObjectAction ~ {
IF object.heirarchyLevel = this THEN {
type: IPTypeTab.CoType ← IPTypeTab.FetchCoType[topology.types, object.name];
size: IP.IntVector ← CD.InterestSize[object.layObject];
shapeRec: REF IP.ShapeRep ← NEW[IP.ShapeRep ← [dim: IPBasicOps.NuNatVector[size.x, size.y]]];
type.shapeInfo ← [shapeRec, NIL, NIL];
};
}; --EachTypeProc
[] ← CoreRouteFlat.EnumerateObjects[structure, EachTypeProc];
}; --SetIPTypes
SetIPComps: PROC[structure: CoreRouteFlat.Structure, topology: IPTop.Ref] ~ {
FOR insts: LIST OF CoreRouteFlat.Instance ← structure.instances, insts.rest
WHILE insts#NIL DO
IF insts.first#structure.outerInstance THEN {
co: IPCoTab.Component ← NARROW[insts.first.any];
type: IPTypeTab.CoType ← co.type;
size: IP.IntVector ← CD.InterestSize[insts.first.layObject];
shapeRec: REF IP.ShapeRep ← NEW[IP.ShapeRep ← [dim: IPBasicOps.NuNatVector[size.x, size.y]]];
co.shape ← shapeRec^;
type.shapeInfo.shape ← shapeRec}
ENDLOOP};
Clean Up
Destroy: PUBLIC PROC [context: GC.Context] ~ {
Remove circular references so garbage collection can work
DestroyNode: RouteDiGraph.EnumNodeProc = {
channel: GCPrivate.Channel ← NARROW[node.nodeInfo];
channel.topoOrder ← NIL};
IPTop.DestroySelf[NARROW[context.topology]];
RouteDiGraph.DestroyGraph[graph: NARROW[context.topologicalOrder], enumNode: DestroyNode];
GCPrivate.DestroyChannels[context]};
Attributes, Layout and Decorate ($Hybrid, $GC)
Attributes: PWCore.AttributesProc = {
structure: CoreRouteFlat.Structure ← CoreRouteFlat.FlattenToLayout[cellType, LIST[$w]];
CoreProperties.PutCellTypeProp[cellType, $GCStruc, structure]};
GCLayout: PWCore.LayoutProc = {
name: Rope.ROPE ← CoreOps.GetCellTypeName[cellType];
hLayer: Rope.ROPE ← "metal";
vLayer: Rope.ROPE ← "metal2";
result: GC.Result;
context: GC.Context;
rules: GC.DesignRules;
struc: CoreRouteFlat.Structure ← NARROW[CoreProperties.GetCellTypeProp[cellType, $GCStruc]];
prop: REF ← CoreProperties.GetCellTypeProp[cellType, $VerticalLayer];
IF prop#NIL THEN {
name: IO.ROPEWITH 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 ← GC.CreateDesignRules[$cmosB, $VTI, hLayer, vLayer];
GC.InitialPlace[struc];
context ← GC.CreateContext[name, struc, rules];
GC.DoInitialGlobalRoute[context, ic];
GC.DoImproveGlobalRoute[context, ic];
result ← GC.DoDetailRoute[context, ic];
RETURN[result.object]};
HybridLayout: PWCore.LayoutProc = {
name: Rope.ROPE ← CoreOps.GetCellTypeName[cellType];
hLayer: Rope.ROPE ← "metal";
vLayer: Rope.ROPE ← "metal2";
result: GC.Result;
context: GC.Context;
rules: GC.DesignRules;
struc: CoreRouteFlat.Structure ← NARROW[CoreProperties.GetCellTypeProp[cellType, $GCStruc]];
design: CD.Design ← PW.OpenDesign["SimpleBPCTest.dale"];
prop: REF ← CoreProperties.GetCellTypeProp[cellType, $VerticalLayer];
IF prop#NIL THEN {
name: IO.ROPEWITH 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 ← GC.CreateDesignRules[$cmosB, $Hybrid, hLayer, vLayer];
GCHybrid.DiddleCells[design, struc];
GC.InitialPlace[struc];
context ← GC.CreateContext[name, struc, rules];
GC.DoInitialGlobalRoute[context, hybrid];
GC.DoImproveGlobalRoute[context, hybrid];
result ← GC.DoDetailRoute[context, hybrid];
RETURN[result.object]};
Decorate: PWCore.DecorateProc = {
CompareFlatInstances: PUBLIC CoreRoute.CompareFlatCTProc = {
root is first instance in struc.instances
FOR insts: LIST OF CoreRouteFlat.Instance ← struc.instances.rest, 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: CoreRouteFlat.Structure ← NARROW[CoreProperties.GetCellTypeProp[cellType, $GCStruc]];
CoreRoute.DecorateRoutedArea[
cellType: cellType,
obj: obj,
wireToLabels: WireToLabels,
compareCT: CompareFlatInstances]};
HybridAtom: ATOM ← PWCore.RegisterLayoutAtom[$Hybrid, HybridLayout, Decorate, Attributes];
GlobalAtom: ATOM ← PWCore.RegisterLayoutAtom[$GC, GCLayout, Decorate, Attributes];
Global Frame Variables
metalVerticalRules: PUBLIC GC.DesignRules ← CreateDesignRules[$cmosB, $Hybrid, "metal2", "metal"];
metalHorizontalRules: PUBLIC GC.DesignRules ← CreateDesignRules[$cmosB, $Hybrid, "metal", "metal2"];
interestingProperties: PUBLIC LIST OF ATOMNIL; -- props interesting to GC
technologyKey: ATOM ← $cmosB;  -- $cmosA or $cmosB
END.