GCImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Bryan Preas, August 21, 1986 6:42:42 pm PDT
DIRECTORY
Atom, CD, CDSimpleRules, Core, CoreFlat, CoreGeometry, CoreProperties, FS, GC, GCPrivate, IO, IPToolBox, IPTop, Process, Rope, Route, RouteDiGraph, RTCoreUtil, RTStructure, TerminalIO;
GCImpl: CEDAR PROGRAM
IMPORTS Atom, CD, CDSimpleRules, CoreProperties, FS, GCPrivate, IO, IPToolBox, IPTop, Process, Rope, Route, RouteDiGraph, RTStructure, TerminalIO
EXPORTS GC
SHARES GC = {
Error: PUBLIC ERROR[errorType: GC.ErrorType ← callingError, explanation: Rope.ROPENIL] = CODE;
Signal: PUBLIC SIGNAL[signalType: GC.ErrorType ← callingError, explanation: Rope.ROPENIL] = CODE;
CreateDesignRules: PUBLIC PROC [technologyKey: ATOM, horizLayer, vertLayer: Rope.ROPE, properties: GC.PropList ← NIL] 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".
BEGIN
hLayer, vLayer: GC.Layer;
designRules ← NEW[GC.DesignRulesRec];
designRules.technology ← CD.FetchTechnology[technologyKey];
hLayer ← CDSimpleRules.GetLayer[technologyKey, horizLayer];
vLayer ← CDSimpleRules.GetLayer[technologyKey, vertLayer];
designRules.horizLayer ← horizLayer;
designRules.vertLayer ← vertLayer;
designRules.horizRules ← Route.CreateDesignRules[technologyKey, hLayer, vLayer, horizontal, properties];
designRules.vertRules ← Route.CreateDesignRules[technologyKey, hLayer, vLayer, vertical, properties];
END;
CreateStructure: PUBLIC PROC [cellType: Core.CellType, flattenCellType: RTCoreUtil.FlattenCellTypeProc, pinFilter: RTStructure.CorePinFilterProc ← NIL, userData: REF ANYNIL, decoration: CoreGeometry.Decoration, defaultLib: CD.Design ← NIL] RETURNS [structure: RTStructure.Structure] ~ {
Derive the interconnection requirements from a Core Data structure.
RETURN[RTStructure.CreateFromCore[cellType, flattenCellType, pinFilter, interestingProperties, userData, decoration, defaultLib]]};
defaultParms: PUBLIC GC.Parms ← NEW[GC.ParmsRec];
CreateContext: PUBLIC PROC [name: Rope.ROPENIL, structure: RTStructure.Structure, designRules: GC.DesignRules, parms: GC.Parms, properties: GC.PropList ← NIL] 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];
IPTop.Geometrize[topology];
context ← NEW[GC.ContextRec ← [name: contextName, rules: designRules, structure: structure, properties: properties, parms: parms, topology: topology, topologicalOrder: NIL]];
};
DoInitialGlobalRoute: PUBLIC PROC [context: GC.Context] = {
Determine strategic paths for the wiring among the cells.
p: Process.Priority ← Process.GetPriority[];
Process.SetPriority[Process.priorityBackground];
GCPrivate.DoInitialGlobalRoute[context];
Process.SetPriority[p]};
DoImproveGlobalRoute: PUBLIC PROC [context: GC.Context] = {
Determine strategic paths for the wiring among the cells.
p: Process.Priority ← Process.GetPriority[];
Process.SetPriority[Process.priorityBackground];
Process.SetPriority[p]};
DoDetailRoute: PUBLIC PROC [context: GC.Context] RETURNS [result: GC.Result] = {
Determine actual wiring paths.
p: Process.Priority ← Process.GetPriority[];
Process.SetPriority[Process.priorityBackground];
result ← GCPrivate.DoDetailRoute[context];
Process.SetPriority[p]};
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];
};
InitialPlace: PUBLIC PROC [structure: RTStructure.Structure, initFile: Rope.ROPE] ~ {
temporary initial placement: read from a file
IF initFile # NIL THEN {
stream: IO.STREAMFS.StreamOpen[initFile];
DO
ENABLE IO.EndOfStream => EXIT;
token: ATOM ← IPToolBox.GetIdAtom[stream];
SELECT token FROM
$initialPlacement => GetInitialPlacement[structure, stream]
ENDCASE => {
TerminalIO.PutRope[Rope.Cat["Unknown Token: ", Atom.GetPName[token]]];
IPToolBox.RemoveBlock[stream];
TerminalIO.PutRope["\n\t Associated block is ignored"];
};
ENDLOOP;
}; --endIF
};
GetInitialPlacement: PROC[structure: RTStructure.Structure, stream: IO.STREAM] ={
FindName: PROC [structure: RTStructure.Structure, name: Rope.ROPE] RETURNS [inst: RTStructure.Instance ← NIL] ~ {
EachInstance: RTStructure.EachInstanceAction ~ {
IF Rope.Equal[instance.name, name] THEN {quit ← TRUE; inst ← instance}};
[] ← RTStructure.EnumerateInstances[structure, EachInstance];
};
IPToolBox.EnterBlock[stream];
UNTIL IPToolBox.ExitBlock[stream] DO
instName: Rope.ROPEIO.GetTokenRope[stream, IO.IDProc].token;
char: CHARIO.GetChar[stream];
instance: RTStructure.Instance ← FindName[structure, instName];
IF instance # NIL
THEN {
IPToolBox.EnterBlock[stream];
UNTIL IPToolBox.ExitBlock[stream] DO
token: ATOM ← IPToolBox.GetIdAtom[stream];
SELECT token FROM
$origin => {instance.position ← IPToolBox.GetIntVector[stream]^;
instance.placed ← TRUE};
$orient => instance.orientation ← GCPrivate.CDOrien[stream.GetInt];
ENDCASE => {
TerminalIO.PutRope[Rope.Cat["Unknown token: ", Atom.GetPName[token], ". associated value ignored"]];
[] ← stream.GetRefAny;
};
ENDLOOP;
}
ELSE {
TerminalIO.PutRope[Rope.Cat[instName, " ← Unknown instance. Block is ignored\n"]];
IPToolBox.RemoveBlock[stream]
};
ENDLOOP;
}; --GetInitialPlacement
Global frame variables
metalVerticalRules: PUBLIC GC.DesignRules ← CreateDesignRules[$cmosB, "metal2", "metal",];
metalHorizontalRules: PUBLIC GC.DesignRules ← CreateDesignRules[$cmosB, "metal", "metal2",];
sideProp: PUBLIC ATOM ← CoreProperties.RegisterProperty[$GCSide];
bottomSideValue: PUBLIC ATOM ← $bottom;
rightSideValue: PUBLIC ATOM ← $right;
topSideValue: PUBLIC ATOM ← $top;
leftSideValue: PUBLIC ATOM ← $left;
noSideValue: PUBLIC ATOM ← $none;
Used to specify the side on which a public pin is to be placed. sideProp with (mumble)Value should be a property/value on a public wire
interestingProperties: PUBLIC RTCoreUtil.PropertyKeys ← NEW[RTCoreUtil.PropertyKeysRec[1]];
interestingProperties.p[0] ← sideProp;
Used to specify all the properties that aer interesting to GC
}.