RouteTechnologyImpl.mesa
Copyright Ó 1985, 1987 by Xerox Corporation. All rights reserved.
Bryan Preas, July 10, 1985 11:14:39 am PDT
last edited Bryan Preas, July 16, 1987 4:55:54 pm PDT
DIRECTORY
CD, CDAtomicObjects, CDSimpleRules, DABasics, Route, RoutePrivate, RouteTechnology;
RouteTechnologyImpl: CEDAR PROGRAM
IMPORTS CD, CDAtomicObjects, CDSimpleRules, Route
EXPORTS RouteTechnology = {
Widths and Spacings
GetWidth: PUBLIC PROC [layer: CD.Layer] RETURNS [CD.Number] = {
RETURN[CDSimpleRules.MinWidth[NIL, layer]]};
GetSpacing: PUBLIC PROC [layer: CD.Layer] RETURNS [CD.Number] = {
RETURN[CDSimpleRules.MinSpace[NIL, layer, layer]]};
ContactSize: PUBLIC PROC [contact: CD.Object] RETURNS [CD.Number] = {
r: CD.Rect ← CD.InterestRect[contact];
RETURN[MAX[ABS[r.x2 - r.x1], ABS[r.y2 - r.y1]]]};
GetMaterialToContact: PUBLIC PROC [layer: CD.Layer, contact: CD.Object] RETURNS [dist: CD.Number] = {
This is a hack. It needs to be replaced
matToContact: CD.Number ← GetSpacing[layer] + ContactSize[contact]/2 + GetWidth[layer]/2;
contactToContact: CD.Number ← GetSpacing[layer] + ContactSize[contact];
RETURN[MAX[matToContact, contactToContact]]};
Layers
LToTech: PUBLIC PROC [layer: CD.Layer] RETURNS [tech: CD.Technology] = {
tech ← CD.LayerTechnology[layer ! CD.Error => GOTO bad];
IF tech=NIL THEN Route.Error[callingError, "Invalid layer"];
EXITS bad => Route.Error[callingError, "Invalid layer"]};
Contacts
GetContact: PUBLIC PROC [layer1, layer2: CD.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.
RETURN[CDSimpleRules.Contact[NIL, layer1, layer2]]};
GetBigContact: PUBLIC PROC [size: DABasics.Position, layer1, layer2: CD.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.
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"]};
Simple Design Rules
CmosDesignRules: PUBLIC PROC [designRuleParms: Route.DesignRulesParameters] RETURNS[designRules: Route.DesignRules ← NEW[Route.DesignRulesRec]] = {
Define the routing design rules for CMOS double or single layer metal.
cndObj: CD.Object;
designRules.trunkDirection ← designRuleParms.trunkDirection;
designRules.branchDirection ← IF designRuleParms.trunkDirection = horizontal THEN vertical ELSE horizontal;
designRules.trunkLayer ← IF designRuleParms.trunkDirection = horizontal THEN designRuleParms.horizLayer ELSE designRuleParms.vertLayer;
designRules.branchLayer ← IF designRuleParms.trunkDirection = horizontal THEN designRuleParms.vertLayer ELSE designRuleParms.horizLayer;
cndObj ← GetContact[designRules.trunkLayer, designRules.branchLayer];
designRules.branchWidth ← GetWidth[designRules.branchLayer];
designRules.branchSpacing ← GetSpacing[designRules.branchLayer];
designRules.branchToContact ← GetMaterialToContact[designRules.branchLayer, cndObj];
designRules.trunkToTrunk ← designRuleParms.trunkToTrunk;
designRules.branchToBranch ← MAX[designRules.branchWidth + designRules.branchSpacing, designRules.branchToContact];
designRules.branchOffset ← designRules.branchSpacing;
designRules.trunkWidth ← GetWidth[designRules.trunkLayer];
designRules.trunkSpacing ← GetSpacing[designRules.trunkLayer];
designRules.trunkToContact ← GetMaterialToContact[designRules.trunkLayer, cndObj];
designRules.trunkOffset ← designRules.trunkSpacing;
designRules.contactSize ← ContactSize[cndObj];
designRules.contactToContact ← designRules.contactSize + MAX[designRules.trunkSpacing, designRules.branchSpacing];
designRules.pinSpacing ← designRuleParms.pinSpacing;
designRules.trunkToEdge ← designRuleParms.trunkToEdge};
DesignRulesParameters: PUBLIC PROC [technology: CD.Technology, horizLayer, vertLayer: CD.Layer, trunkDirection: DABasics.Direction] RETURNS[designRuleParms: Route.DesignRulesParameters] = {
Define the routing design rules for CMOS double or single layer metal.
trunkLayer: CD.Layer ← IF trunkDirection = horizontal THEN horizLayer ELSE vertLayer;
branchLayer: CD.Layer ← IF trunkDirection = horizontal THEN vertLayer ELSE horizLayer;
cndObj: CD.Object ← GetContact[trunkLayer, branchLayer];
contactToContact: DABasics.Number ← ContactSize[cndObj] + MAX[GetSpacing[trunkLayer], GetSpacing[branchLayer]];
trunkToTrunk: DABasics.Number ← MAX[GetWidth[trunkLayer] + GetSpacing[trunkLayer], GetMaterialToContact[trunkLayer, cndObj], contactToContact];
pinSpacing: DABasics.Number ← ContactSize[cndObj]/2 + GetWidth[branchLayer]/2 + GetWidth[branchLayer];
trunkToEdge: DABasics.Number ← MAX[GetSpacing[branchLayer], GetSpacing[trunkLayer]] + MAX[ContactSize[cndObj], GetWidth[trunkLayer]]/2;
designRuleParms ← NEW[Route.DesignRulesParametersRec ← [technology: technology, horizLayer: horizLayer, vertLayer: vertLayer, trunkDirection: trunkDirection, trunkToTrunk: trunkToTrunk, pinSpacing: pinSpacing, trunkToEdge: trunkToEdge]]};
}.