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
Error: PUBLIC ERROR[errorType: GC.ErrorType ← callingError, explanation: Rope.ROPE ← NIL] = CODE;
Signal:
PUBLIC
SIGNAL[signalType:
GC.ErrorType ← callingError, explanation: Rope.
ROPE ←
NIL] =
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
ANY ←
NIL, 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.
ROPE ←
NIL, 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.ROPE ← IF 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.STREAM ← FS.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.ROPE ← IO.GetTokenRope[stream, IO.IDProc].token;
char: CHAR ← IO.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
}.