<> <> <> <> DIRECTORY CD, CDAtomicObjects, CDSimpleRules, Route, RouteTechnology; RouteTechnologyImpl: CEDAR PROGRAM IMPORTS CD, CDAtomicObjects, CDSimpleRules, Route EXPORTS RouteTechnology SHARES Route = BEGIN <> 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] = <> 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; <> 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; <> 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: ATOM _ CD.LayerKey[layer1]; l2a: ATOM _ CD.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 _CDAtomicObjects.CreateAtomicOb[$C2LargeSimpleCon, size, tech, layer1]; (l1a = $met AND l2a = $pol) => obj _CDAtomicObjects.CreateAtomicOb[$C2LargeSimpleCon, size, tech, layer2]; ENDCASE => Route.Error[callingError, "Invalid layers"]}; ENDCASE => Route.Error[callingError, "Unsupported technology"] END; <> CmosDesignRules: PUBLIC PROC [dr: Route.DesignRules, trunkLayer, branchLayer: Route.Layer] = <> 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.