RouteTechnologyImpl.mesa ///Route/RouteTechnologyImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bryan Preas, July 10, 1985 11:14:39 am PDT
last edited Bryan Preas, July 10, 1985 11:14:48 am PDT
DIRECTORY
CD,
CDAtomicObjects,
CDSimpleRules,
Route,
RouteTechnology;
RouteTechnologyImpl: CEDAR PROGRAM
IMPORTS CD, CDAtomicObjects, CDSimpleRules, Route
EXPORTS RouteTechnology
SHARES Route
=
BEGIN
Widths and Spacings
GetWidth: PUBLIC PROC [dr: Route.DesignRules, layer: Route.Layer] RETURNS [CD.Number] =
BEGIN
RETURN[CDSimpleRules.MinWidth[layer]]
END;
GetSpacing: PUBLIC PROC [dr: Route.DesignRules, layer: Route.Layer] RETURNS [CD.Number] =
BEGIN
RETURN[CDSimpleRules.MinDist[layer, layer]]
END;
ContactSize: PUBLIC PROC [contact: CD.Object] RETURNS [CD.Number] =
BEGIN
r: CD.Rect ← CD.InterestRect[contact];
RETURN[MAX[ABS[r.x2 - r.x1], ABS[r.y2 - r.y1]]]
END;
GetMaterialToContact: PUBLIC PROC [dr: Route.DesignRules, layer: Route.Layer, contact: CD.Object] RETURNS [dist: CD.Number] =
This is a hack. It needs to be replaced
BEGIN
matToContact: CD.Number ← GetSpacing[dr, layer] + ContactSize[contact]/2 + GetWidth[dr, layer]/2;
contactToContact: CD.Number ← GetSpacing[dr, layer] + ContactSize[contact];
RETURN[MAX[matToContact, contactToContact]]
END;
Layers
LToTech: PUBLIC PROC [layer: CD.Layer] RETURNS [tech: CD.Technology] =
BEGIN
tech ← CD.LayerTechnology[layer ! CD.Error => GOTO bad];
IF tech=NIL THEN ERROR Route.Error[callingError, "Invalid layer"];
EXITS bad => Route.Error[callingError, "Invalid layer"];
END;
Contacts
GetContact: PUBLIC PROC [layer1, layer2: Route.Layer] RETURNS [CD.Object] =
-- Create a big contact; may return the same object
-- on multiple calls; the contact object should be considered
-- to be read-only.
BEGIN
RETURN[CDSimpleRules.Contact[layer1, layer2]]
END;
GetBigContact: PUBLIC PROC [size: Route.Position, layer1, layer2: Route.Layer] RETURNS [obj: CD.Object ← NIL] =
-- Create a big contact; may return NIL (if big contacts aren't defined
-- may return the same object
-- on multiple calls; the contact object should be considered
-- to be read-only.
BEGIN
l1a: ATOMCD.LayerKey[layer1];
l2a: ATOMCD.LayerKey[layer2];
tech: CD.Technology ← LToTech[layer1];
IF tech # LToTech[layer2] THEN Route.Error[callingError, "Invalid layers"];
SELECT tech.key FROM
$cmos => NULL;
$cmosB => {
SELECT TRUE FROM
(l1a = $met2 AND l2a = $met) OR (l1a = $met AND l2a = $met2) => obj ← CDAtomicObjects.CreateAtomicOb[$C2LargeVia, size, tech];
(l1a = $pol AND l2a = $met) => obj �tomicObjects.CreateAtomicOb[$C2LargeSimpleCon, size, tech, layer1];
(l1a = $met AND l2a = $pol) => obj �tomicObjects.CreateAtomicOb[$C2LargeSimpleCon, size, tech, layer2];
ENDCASE => Route.Error[callingError, "Invalid layers"]};
ENDCASE => Route.Error[callingError, "Unsupported technology"]
END;
Simple Design Rules
CmosDesignRules: PUBLIC PROC [dr: Route.DesignRules, trunkLayer, branchLayer: Route.Layer] =
Define the routing design rules for CMOS double or single layer metal.
BEGIN
cndObj: CD.Object ← NARROW[GetContact[trunkLayer, branchLayer], CD.Object];
dr.trunkLayer ← trunkLayer;
dr.branchLayer ← branchLayer;
dr.branchWidth ← GetWidth[dr, branchLayer];
dr.branchSpacing ← GetSpacing[dr, branchLayer];
dr.branchToContact ← GetMaterialToContact[dr, branchLayer, cndObj];
dr.branchToBranch ← MAX[dr.branchWidth + dr.branchSpacing, dr.branchToContact];
dr.branchOffset ← dr.branchSpacing;
dr.trunkWidth ← GetWidth[dr, trunkLayer];
dr.trunkSpacing ← GetSpacing[dr, trunkLayer];
dr.trunkToContact ← GetMaterialToContact[dr, trunkLayer, cndObj];
dr.trunkOffset ← dr.trunkSpacing;
dr.contactSize ← ContactSize[cndObj];
dr.contactToContact ← dr.contactSize + MAX[dr.trunkSpacing, dr.branchSpacing];
dr.trunkToTrunk ← MAX[dr.trunkWidth + dr.trunkSpacing, dr.trunkToContact, dr.contactToContact];
dr.pinSpacing ← dr.contactSize/2 + dr.branchWidth/2 + dr.branchSpacing;
dr.trunkToEdge ← dr.trunkToTrunk;
END;
END.