DIRECTORY AMBridge USING [TVForATOM, TVForROPE, TVForReferent], AMTypes USING [TV], Basics USING [CompareINT], CD USING [Instance, InstanceList, Layer, LayerKey, Number, Position, Rect, Technology], CDBasics USING [Extend, SizeOfRect --, Surround--], CDSequencer USING [Command, ImplementCommand], CDMenus USING [CreateEntry], CoreGeometry, CDOps USING [InstList], CMosB USING [cmosB, lambda], Core, CoreClasses USING [Transistor, transistorCellClass], CoreFlat USING [EachInternalWireProc, EachWireInstanceProc, EnumerateAtomicWireLeaves], CoreOps USING [GetWireIndex, PrintCellType, ToBasic], CDOrient USING [MapRect], CoreProperties USING [GetCellInstanceProp, GetWireProp, PutWireProp, RegisterProperty], CStitching, GList USING [CompareProc, Sort], IO USING [int, PutFR, real, rope, STREAM], Jasmine, PrintTV USING [Print], Process USING [priorityBackground, SetPriority], Real USING [Float, Round], Rope, Sinix, SinixOps, SymTab USING [Create, Fetch, Ref, Store], TerminalIO USING [RequestRope, TOS, WriteF, WriteRope]; JasmineImpl: CEDAR PROGRAM IMPORTS AMBridge, Basics, CD, CDBasics, CDSequencer, CDMenus, CDOps, CMosB, CoreClasses, CoreFlat, CoreGeometry, CoreOps, CDOrient, CoreProperties, CStitching, GList, IO, PrintTV, Process, Real, Rope, Sinix, SinixOps, SymTab, TerminalIO EXPORTS Jasmine = BEGIN OPEN Jasmine; resolutionistorProp: ATOM = CoreProperties.RegisterProperty[$JasmineResistor]; capacitorProp: ATOM = CoreProperties.RegisterProperty[$JasmineCapacitor]; inductorProp: ATOM = CoreProperties.RegisterProperty[$JasmineInductor]; transistorProp: ATOM = CoreProperties.RegisterProperty[$JasmineTransistor]; modelProp: ATOM = CoreProperties.RegisterProperty[$JasmineModel]; CDTechnology: CD.Technology = CMosB.cmosB; lambda: CD.Number = CMosB.lambda; CDCut: ATOM = $cut; CDMetal1: ATOM = $met; CDMetal2: ATOM = $met2; CDNDif: ATOM = $ndif; CDOGlass: ATOM = $ovg; CDPDif: ATOM = $pdif; CDPoly: ATOM = $pol; CDVia: ATOM = $cut2; CDRect: ATOM = $Rect; CDCell: ATOM = $Cell; CDNXtor: ATOM = $C2Trans; CDPXtor: ATOM = $C2WellTrans; CDNXtorL: ATOM = $C2LTrans; CDPXtorL: ATOM = $CLWellTrans; LayerObject: TYPE = {cut, met1, met2, ndif, oglass, pdif, poly, via, nXtor, pXtor, nXtorL, pXtorL}; LayersInTile: TYPE = REF LayersInTileRec; LayersInTileRec: TYPE = RECORD[ primary: PACKED ARRAY LayerObject OF BOOL _ ALL[FALSE], secondary: PACKED ARRAY LayerObject OF BOOL _ ALL[FALSE], coreWire: Core.Wire _ NIL, coreTrans: CoreClasses.Transistor _ NIL ]; MergeRect: TYPE = REF MergeRectRec; MergeRectRec: TYPE = RECORD [r: CD.Rect _ [0,0,0,0]]; ContactArea: CD.Rect = [0, 0, 32, 32]; TransArea: CD.Rect = [0, 0, 64, 64]; LTransArea: CD.Rect = [0, 0, 112, 144]; RelArea: TYPE = {smallerThan, largerThan, equalTo}; Error: SIGNAL [msg: Core.ROPE] = CODE; none: REF INT = NEW[INT]; spaceTile: REF = NIL; tranCount: NAT; md: PUBLIC MapDimension _ NIL; locations: PUBLIC LIST OF MacroLocation _ NIL; Volts: TYPE = REAL; kOhm: TYPE = REAL; pF: TYPE = REAL; mA: TYPE = REAL; nH: TYPE = REAL; --diagnostics db: BOOL _ FALSE; resolution: PUBLIC Resolution _ high; CornerStitchWire: PUBLIC PROC [root: Core.CellType, wire: Core.Wire] RETURNS [tesselation: CStitching.Tesselation] = { AddWireGeometry: CoreFlat.EachInternalWireProc = { AccumulateLayer: PROC [wireLayer: CD.Layer] = { data _ NEW[LayersInTileRec]; layer _ SELECT CD.LayerKey[wireLayer] FROM CDCut => cut, CDMetal1 => met1, CDMetal2 => met2, CDNDif => ndif, CDOGlass => oglass, CDPDif => pdif, CDPoly => poly, ENDCASE => via; data.primary[layer] _ TRUE; data.coreWire _ wire; }; InsertWireRectangle: CStitching.RectProc -- [plane: Tesselation, rect: Rect, oldValue: REF, data: REF] -- = { WITH oldValue SELECT FROM tileLayer: LayersInTile => IF NOT tileLayer.primary[layer] THEN tileLayer.secondary[layer] _ TRUE; ENDCASE --tile=NIL-- => CStitching.ChangeRect[plane: tesselation, rect: rect, new: data]; }; geometry: LIST OF CD.Instance _ NARROW[CoreProperties.GetWireProp[wire, wireGeometryProp]]; inst: CD.Instance _ NIL; wireRect: CD.Rect; FOR geom: LIST OF CD.Instance _ geometry, geom.rest UNTIL geom=NIL DO inst _ geom.first; IF inst.ob.class.objectType = CDRect THEN { AccumulateLayer[inst.ob.layer]; wireRect _ CDOrient.MapRect[ itemInCell: IF layer=cut OR layer=via THEN CDBasics.Extend[[0,0,inst.ob.size.x,inst.ob.size.y], inst.ob.size.x/2] ELSE [0,0,inst.ob.size.x,inst.ob.size.y], cellSize: inst.ob.size, cellInstOrient: inst.orientation, cellInstPos: inst.location ]; CStitching.ChangeEnumerateArea[plane: tesselation, rect: wireRect, eachRect: InsertWireRectangle, data: data, skip: none]; }; ENDLOOP; }; --AddWireGeometry AddTransistorGeometry: CoreFlat.EachWireInstanceProc --[bindings: HashTable.Table, path: PackedPath, instance: CoreClasses.CellInstance, wire: Core.Wire] RETURNS [flatten: BOOL _ TRUE]-- = { AccumulateTransistor: PROC [tranInst: CD.Instance, tranData: CoreClasses.Transistor] = { data _ NEW[LayersInTileRec]; layer _ SELECT tranInst.ob.class.objectType FROM CDNXtor => nXtor, CDPXtor => pXtor, CDNXtorL => nXtorL, ENDCASE => pXtorL; data.primary[layer] _ TRUE; data.coreTrans _ tranData; }; InsertTransistor: CStitching.RectProc -- [plane: Tesselation, rect: Rect, oldValue: REF, data: REF] -- = { WITH oldValue SELECT FROM tileLayer: LayersInTile => IF NOT tileLayer.primary[layer] THEN tileLayer.secondary[layer] _ TRUE; ENDCASE --tile=NIL-- => CStitching.ChangeRect[plane: tesselation, rect: rect, new: data]; }; basic: Core.CellType _ CoreOps.ToBasic[instance.type]; IF basic.class=CoreClasses.transistorCellClass THEN { trans: CoreClasses.Transistor _ NARROW[instance.type.data]; inst: CD.Instance _ NARROW[CoreProperties.GetCellInstanceProp[instance, instanceProp]]; xtor: CD.Rect _ CDOrient.MapRect[ itemInCell: [0, 0, inst.ob.size.x, inst.ob.size.y], cellSize: inst.ob.size, cellInstOrient: inst.orientation, cellInstPos: inst.location ]; flatten _ FALSE; AccumulateTransistor[inst, trans]; CStitching.ChangeEnumerateArea[plane: tesselation, rect: xtor, eachRect: InsertTransistor, data: data, skip: none]; }; }; --AddTransistorGeometry data: LayersInTile; layer: LayerObject; wireGeometryProp: ATOM = CoreGeometry.Decoration.geometryProp; instanceProp: ATOM = CoreGeometry.Decoration.transfProp; tesselation _ CStitching.NewTesselation[]; CoreFlat.EnumerateAtomicWireLeaves[root: root, rootWire: wire, eachInternalWire: AddWireGeometry, eachWireInstance: AddTransistorGeometry]; }; --CornerStitchWire EstablishTopography: PUBLIC PROC [tesselation: CStitching.Tesselation] = { DefineJasmineObjects: CStitching.TileProc --PROC [tile: Tile, data: REF]-- = { ElectJasmineObject: PROC [nomination, elected: JasmineObject] = { tileValue.object _ SELECT CompareRelativeArea[CDBasics.SizeOfRect[CStitching.Area[tile]], CDBasics.SizeOfRect[CDStandardArea[elected]]] FROM smallerThan, equalTo => elected, ENDCASE => tileValue.object _ nomination; }; --ElectJasmineObject Discriminate: PROC [primLayer: LayerObject] = { SELECT primLayer FROM cut => { SELECT TRUE FROM tLayer.secondary[met1] => { SELECT TRUE FROM tLayer.secondary[ndif] => ElectJasmineObject[m1Wire, nDifCont]; tLayer.secondary[pdif] => ElectJasmineObject[m1Wire, pDifCont]; tLayer.secondary[poly] => ElectJasmineObject[m1Wire, polyCont]; tLayer.secondary[met1] => ElectJasmineObject[m1Wire, Via]; tLayer.secondary[met2] => ElectJasmineObject[m2Wire, Via]; ENDCASE => tileValue.object _ m1Wire; }; tLayer.secondary[met2] => { SELECT TRUE FROM tLayer.secondary[ndif] => ElectJasmineObject[m2Wire, nDifCont]; tLayer.secondary[poly] => ElectJasmineObject[m2Wire, polyCont]; ENDCASE => tileValue.object _ m2Wire; }; ENDCASE => Error["Isolated Cut layer."]; }; met1 => { SELECT TRUE FROM tLayer.secondary[cut] => { SELECT TRUE FROM tLayer.secondary[met2] => ElectJasmineObject[m1Wire, Via]; tLayer.secondary[ndif] => ElectJasmineObject[m1Wire, nDifCont]; tLayer.secondary[pdif] => ElectJasmineObject[m1Wire, pDifCont]; tLayer.secondary[poly] => ElectJasmineObject[m1Wire, polyCont]; ENDCASE => tileValue.object _ m1Wire; }; tLayer.secondary[met2] => ElectJasmineObject[m1Wire, Via]; ENDCASE => tileValue.object _ m1Wire; }; met2 => { SELECT TRUE FROM tLayer.secondary[cut] => { SELECT TRUE FROM tLayer.secondary[met1] => ElectJasmineObject[m2Wire, Via]; tLayer.secondary[ndif] => ElectJasmineObject[m2Wire, nDifCont]; tLayer.secondary[pdif] => ElectJasmineObject[m2Wire, pDifCont]; tLayer.secondary[poly] => ElectJasmineObject[m2Wire, polyCont]; ENDCASE => tileValue.object _ m2Wire; }; tLayer.secondary[met1] => ElectJasmineObject[m2Wire, Via]; ENDCASE => tileValue.object _ m2Wire; }; ndif => { SELECT TRUE FROM tLayer.secondary[cut] => { SELECT TRUE FROM tLayer.secondary[met1] => ElectJasmineObject[nDifWire, nDifCont]; tLayer.secondary[met2] => ElectJasmineObject[nDifWire, nDifCont]; ENDCASE => tileValue.object _ nDifWire; }; ENDCASE => tileValue.object _ nDifWire; }; oglass => { --do we care ???-- }; pdif => { SELECT TRUE FROM tLayer.secondary[cut] => { SELECT TRUE FROM tLayer.secondary[met1] => ElectJasmineObject[pDifWire, pDifCont]; tLayer.secondary[met2] => ElectJasmineObject[pDifWire, pDifCont]; ENDCASE => tileValue.object _ pDifWire; }; ENDCASE => tileValue.object _ pDifWire; }; poly => { SELECT TRUE FROM tLayer.secondary[cut] => { SELECT TRUE FROM tLayer.secondary[met1] => ElectJasmineObject[polyWire, polyCont]; tLayer.secondary[met2] => ElectJasmineObject[polyWire, polyCont]; ENDCASE => tileValue.object _ polyWire; }; ENDCASE => tileValue.object _ polyWire; }; via => tileValue.object _ Via; nXtor => {tileValue.object _ nTran; tileValue.data _ tLayer.coreTrans}; nXtorL => {tileValue.object _ nTranL; tileValue.data _ tLayer.coreTrans}; pXtor => {tileValue.object _ pTran; tileValue.data _ tLayer.coreTrans}; pXtorL => {tileValue.object _ pTranL; tileValue.data _ tLayer.coreTrans}; ENDCASE => NULL; }; --Discriminate tLayer: LayersInTile = NARROW[tile.value]; tileValue: JasmineObjectInLayer _ NEW[JasmineObjectRec]; FOR layer: LayerObject IN LayerObject DO wire: Core.Wire = tLayer.coreWire; IF tLayer.primary[layer] THEN { Discriminate[layer]; IF wire#NIL AND CoreProperties.GetWireProp[from: wire, prop: modelProp]=NIL THEN CoreProperties.PutWireProp[on: wire, prop: modelProp, value: tileValue]; CStitching.ChangeTile[plane: tesselation, tile: tile, new: tileValue]; PrintJasmineObjectData[tile, db]; EXIT; }; ENDLOOP; }; --DefineJasmineObjects CStitching.EnumerateArea[plane: tesselation, rect: CStitching.all, eachTile: DefineJasmineObjects, skip: spaceTile]; MergeJasmineTiles[tesselation]; }; --EstablishTopography MergeJasmineTiles: PROC [tesselation: CStitching.Tesselation] = { MergeTiles: CStitching.TileProc --PROC [tile: Tile, data: REF]-- = { MergeTransistorTiles: PROC [keyTile: CStitching.Tile] = { MarkTile: CStitching.TileProc = { td: JasmineObjectInLayer _ NARROW[tile.value]; SELECT td.object FROM nTran, pTran, nTranL, pTranL => IF td.private=NIL THEN { td.private _ $Merge; CStitching.ChangeTile[plane: tesselation, tile: tile, new: td]; }; ENDCASE => NULL; }; tdata: JasmineObjectInLayer _ NARROW[keyTile.value]; CStitching.EnumerateArea[plane: tesselation, rect: CDBasics.Extend[CStitching.Area[keyTile], lambda/4], eachTile: MarkTile, skip: spaceTile]; IF tdata.private=$Merge AND tdata.object#Ignore THEN { tdata.object _ Ignore; tdata.data _ NIL; CStitching.ChangeTile[plane: tesselation, tile: keyTile, new: tdata]; }; }; --MergeTransistorTiles MergeWireTiles: PROC [keyTile: CStitching.Tile] = { MarkTile: CStitching.TileProc = { td: JasmineObjectInLayer _ NARROW[tile.value]; SELECT td.object FROM m1Wire, m2Wire, nDifWire, pDifWire, polyWire => IF td.private=NIL THEN { td.private _ $Merge; CStitching.ChangeTile[plane: tesselation, tile: tile, new: td]; }; ENDCASE => NULL; }; tdata: JasmineObjectInLayer _ NARROW[keyTile.value]; CStitching.EnumerateArea[plane: tesselation, rect: CDBasics.Extend[CStitching.Area[keyTile], lambda/4], eachTile: MarkTile, skip: spaceTile]; IF tdata.private=$Merge AND tdata.object#Ignore THEN { tdata.object _ Ignore; tdata.data _ NIL; CStitching.ChangeTile[plane: tesselation, tile: keyTile, new: tdata]; mergedWires _ CONS[CStitching.Area[keyTile], mergedWires]; }; }; --MergeWireTiles tileValue: JasmineObjectInLayer _ NARROW[tile.value]; mergedRect: MergeRect _ NEW[MergeRectRec]; mergedWires: LIST OF CD.Rect; SELECT tileValue.object FROM m1Wire, m2Wire, nDifWire, pDifWire, polyWire => { mergedRect.r _ CStitching.Area[tile]; tileValue.data _ mergedRect; CStitching.ChangeTile[plane: tesselation, tile: tile, new: tileValue]; }; nTran, pTran, nTranL, pTranL => { IF tileValue.private=NIL THEN tileValue.private _ $Keep; CStitching.ChangeTile[plane: tesselation, tile: tile, new: tileValue]; MergeTransistorTiles[tile]; }; ENDCASE => NULL; }; --MergeTiles CStitching.EnumerateArea[plane: tesselation, rect: CStitching.all, eachTile: MergeTiles, skip: spaceTile]; }; --MergeJasmineTiles CreateModel: PUBLIC PROC [tesselation: CStitching.Tesselation] RETURNS [model: SymTab.Ref] = { InsertMacro: CStitching.TileProc --PROC [tile: Tile, data: REF]-- = { WireAspect: PROC [r: CD.Rect] RETURNS [ar: AspectType] = { ar _ SELECT TRUE FROM (r.x2-r.x1)>(r.y2-r.y1) => horiz, (r.x2-r.x1)<(r.y2-r.y1) => vert, ENDCASE => square; }; Branching: PROC [r: CD.Rect] RETURNS [branch: BranchType] = { N, E, W, S: INT _ 0; --score-- [N, E, W, S] _ ScoreAdjacentTiles[tile]; SELECT (N+S+E+W) FROM 4 => branch _ fourWay; 3 => SELECT TRUE FROM N+(E+W)=3 => branch _ inverseT; N+(E+S)=3 => branch _ rightT; N+(W+S)=3 => branch _ leftT; S+(E+W)=3 => branch _ T; ENDCASE => ERROR; 2 => SELECT TRUE FROM N+S =2 => branch _ straight; N+E =2 => branch _ L; N+W=2 => branch _ reverseL; S+E =2 => branch _ inverseL; S+W=2 => branch _ inverseRevL; ENDCASE => ERROR; 1 => branch _ straight; 0 => Error["Adjacent tile score = 0 => isolated tile!"]; ENDCASE => Error["Adjacent tile score > 4."]; }; ContactResistance: PROC [r: CD.Rect] RETURNS [R: kOhm] = { R _ SELECT tileValue.object FROM nDifCont => 30, pDifCont => 120, polyCont => 25, Via => 1, ENDCASE => ERROR; R _ R*1E-3; }; WireResistance: PROC [r: CD.Rect] RETURNS [R: kOhm] = { Squares: PROC [CStitching.Rect] RETURNS [sqrs: REAL] = { normLength _ (r.x2-r.x1)/lambda; normWidth _ (r.y2-r.y1)/lambda; IF normLength > normWidth THEN sqrs _ Real.Float[normLength]/normWidth ELSE sqrs _ Real.Float[normWidth]/normLength; }; m1Resistivity: REAL _ 0.065; m2Resistivity: REAL _ 0.042; polyResistivity: REAL _ 3.5; nDifResistivity: REAL _ 35; pDifResistivity: REAL _ 120; R _ SELECT tileValue.object FROM m1Wire => Squares[r]*m1Resistivity, m2Wire => Squares[r]*m2Resistivity, polyWire => Squares[r]*polyResistivity, nDifWire => Squares[r]*nDifResistivity, pDifWire => Squares[r]*pDifResistivity ENDCASE => ERROR; R _ R*1E-3; }; WireInductance: PROC [r: CD.Rect] RETURNS [L: nH] = { pi: REAL = 3.14159276; L _ (1.25663706*1E-6*normLength*1E+9)/(8*pi); }; WireCapacitance: PROC [r: CD.Rect] RETURNS [C: pF _ 0.1] = { jasmineMacro.wireArea _ normLength*normWidth; jasmineMacro.wirePerimeter _ (2*normLength)+(2*normWidth); }; TransistorParameters: PROC [r: CD.Rect] = { tranData: CoreClasses.Transistor _NARROW[tileValue.data]; GateAspect: PROC RETURNS [aspect: TranAspect _ chanTied] = { FOR regions: LIST OF REF CStitching.Region _ CStitching.ListArea[tesselation, CDBasics.Extend[CStitching.Area[tile], lambda]], regions.rest UNTIL regions=NIL DO rd: JasmineObjectInLayer _ NARROW[regions.first.value]; IF rd.object = polyWire THEN { aspect _ gateTied; EXIT; }; ENDLOOP; }; jasmineMacro.xtorType _ SELECT tileValue.object FROM nTran, nTranL => nE, pTran, pTranL => pE, ENDCASE => ERROR; jasmineMacro.xtorAspect _ GateAspect[]; jasmineMacro.xtorLength _ tranData.length; jasmineMacro.xtorWidth _ tranData.width; tranCount _ tranCount.SUCC; }; --TransistorParameters tileValue: JasmineObjectInLayer _ NARROW[tile.value]; normLength, normWidth: INT; jasmineMacro: JasmineMacro _ NEW[JasmineMacroRec]; macroLocation:MacroLocation _ NEW[MacroLocationRec _ [0, 0]]; jasmineMacro.macroType _ tileValue.object; SELECT jasmineMacro.macroType FROM m1Wire, m2Wire, nDifWire, pDifWire, polyWire => { mergedRect: MergeRect _ NARROW[tileValue.data]; jasmineMacro.wireAspect _ WireAspect[mergedRect.r]; jasmineMacro.resistance _ WireResistance[mergedRect.r]; jasmineMacro.inductance _ WireInductance[mergedRect.r]; jasmineMacro.capacitance _ WireCapacitance[mergedRect.r]; --jasmineMacro.branch _ Branching[mergedRect.r]; }; nDifCont, pDifCont, polyCont, Via => { jasmineMacro.resistance _ ContactResistance[CStitching.Area[tile]]; jasmineMacro.branch _ Branching[CStitching.Area[tile]]; }; nTran, nTranL, pTran, pTranL => { TransistorParameters[CStitching.Area[tile]]; }; ENDCASE => NULL; Map[macroLocation, tile]; locations _ CONS[macroLocation, locations]; IF jasmineMacro.macroType#Ignore THEN [] _ SymTab.Store[x: model, key: MapConvert[macroLocation], val: jasmineMacro]; }; --InsertMacro md _ NEW[MapDimensionRec _ [mapXMax: 1, mapXMin: 100, mapYMax: 1, mapYMin: 100]]; model _ SymTab.Create[]; tranCount _ 0; locations _ NIL; --reset the cache CStitching.EnumerateArea[plane: tesselation, rect: CStitching.all, eachTile: InsertMacro]; locations _ OrderMapLocations[locations]; }; --CreateModel CompareRelativeArea: PROC [p1, p2: CD.Position] RETURNS [rs: RelArea] = { IF (p1.x*p1.y) = (p2.x*p2.y) THEN rs _ equalTo; IF (p1.x*p1.y) < (p2.x*p2.y) THEN rs _ smallerThan; IF (p1.x*p1.y) > (p2.x*p2.y) THEN rs _ largerThan; }; CDStandardArea: PROC [jObj: JasmineObject] RETURNS [area: CD.Rect] = { area _ SELECT jObj FROM nDifCont, pDifCont, polyCont, Via => ContactArea, nTran, pTran => TransArea, nTranL, pTranL => LTransArea, ENDCASE => [0, 0, INT.FIRST, INT.FIRST]; }; ScoreAdjacentTiles: PROC [startingTile: CStitching.Tile] RETURNS [N, E, W, S: INT _ 0] = { tWest, tEast, tSouth, tNorth: CStitching.Tile; n: CStitching.Number = CStitching.NEdge[startingTile]; e: CStitching.Number = CStitching.EEdge[startingTile]; s: CStitching.Number = CStitching.SEdge[startingTile]; w: CStitching.Number = CStitching.WEdge[startingTile]; --trace down Eastern edge tEast _ CStitching.NE[startingTile]; WHILE CStitching.SEdge[tEast]>=s DO IF tEast.value#spaceTile THEN {E _ 1; EXIT}; TRUSTED {tEast _ LOOPHOLE[tEast.wS]}; ENDLOOP; IF tEast.value#spaceTile THEN E _ 1; --trace left, along Southern edge TRUSTED {tSouth _ LOOPHOLE[startingTile.wS]}; WHILE CStitching.WEdge[tSouth]>=w DO IF tSouth.value#spaceTile THEN {S _ 1; EXIT}; tSouth _ tSouth.sW; ENDLOOP; IF tSouth.value#spaceTile THEN S _ 1; --trace up Western edge tWest _ CStitching.SW[startingTile]; WHILE CStitching.NEdge[tWest]<=n DO IF tWest.value#spaceTile THEN {W _ 1; EXIT}; tWest _ tWest.eN; ENDLOOP; IF tWest.value#spaceTile THEN W _ 1; --trace right, along Northern edge to starting point TRUSTED {tNorth _ LOOPHOLE[startingTile.eN]}; WHILE CStitching.EEdge[tNorth]<=e DO IF tNorth.value#spaceTile THEN {N _ 1; EXIT}; TRUSTED {tNorth _ LOOPHOLE[tNorth.nE]}; ENDLOOP; IF tNorth.value#spaceTile THEN N _ 1; }; --ScoreAdjacentTiles MapConvert: PUBLIC PROC [ml: MacroLocation] RETURNS [sym: Core.ROPE] = { sym _ IO.PutFR["[%g, %g]", IO.int[ml.mapX], IO.int[ml.mapY]]; }; OrderMapLocations: PROC [unordered: LIST OF MacroLocation] RETURNS [ordered: LIST OF MacroLocation] = { Compare: GList.CompareProc --[ref1, ref2: REF ANY] RETURNS [Basics.Comparison]-- = { location1: MacroLocation _ NARROW[ref1]; location2: MacroLocation _ NARROW[ref2]; RETURN [Basics.CompareINT[location1.mapX, location2.mapX]]; }; ordered _ NARROW[GList.Sort[unordered, Compare]]; }; Map: PROC [modLoc: MacroLocation, tile: CStitching.Tile] = { x, y, scale: INT _ 0; r: CStitching.Rect _ CStitching.Area[tile]; SELECT resolution FROM high => scale _ 1; medium => {--see individual transistors+contacts & some wires--}; low => {--see only accumulated transistor+contacts-- }; ENDCASE => NULL; x _ Real.Round[Real.Float[r.x1+(r.x2-r.x1)/2]/(scale*lambda)]; y _ Real.Round[Real.Float[r.y1+(r.y2-r.y1)/2]/(scale*lambda)]; IF x < md.mapXMin THEN md.mapXMin _ x; IF y < md.mapYMin THEN md.mapYMin _ y; IF x > md.mapXMax THEN md.mapXMax _ x; IF y > md.mapYMax THEN md.mapYMax _ y; IF x < 1 THEN x _ 1; IF y < 1 THEN y _ 1; modLoc.mapX_ x; modLoc.mapY_ y; }; InteractiveExtract: PROC [comm: CDSequencer.Command] = { FOR all: CD.InstanceList _ CDOps.InstList[comm.design], all.rest UNTIL all=NIL DO IF all.first.selected THEN { indx: NAT; coreCell: Core.CellType; coreWire: Core.Wire; wireName: Core.ROPE; tesselation: CStitching.Tesselation; TRUSTED {Process.SetPriority[Process.priorityBackground]}; coreCell _ NARROW[Sinix.ExtractCell[obj: all.first.ob, mode: SinixOps.GetExtractMode[comm.design.technology]].result]; wireName _ TerminalIO.RequestRope["\nEnter wire name: "]; indx _ CoreOps.GetWireIndex[coreCell.public, wireName]; coreWire _ coreCell.public[indx]; tesselation _ CornerStitchWire[coreCell, coreWire]; EstablishTopography[tesselation]; IF db THEN { out: IO.STREAM _ TerminalIO.TOS[]; CoreOps.PrintCellType[coreCell, out]; TerminalIO.WriteRope["\n\n"]; }; }; ENDLOOP; TerminalIO.WriteRope["\nJasmine extraction complete.\n"]; }; --InteractiveExtract PrintRect: PROC [tag: Core.ROPE, r: CD.Rect, debug: BOOL] = { IF debug THEN TerminalIO.WriteF["%g: [x1: %g, y1: %g, x2: %g, y2: %g]\n", IO.rope[tag], IO.int[r.x1],IO.int[r.y1],IO.int[r.x2],IO.int[r.y2]]; }; PrintJasmineObjectData: PROC [tile: CStitching.Tile, debug: BOOL] = { GetTypedVar: PROC [ra: REF ANY] RETURNS [tv: AMTypes.TV] = TRUSTED { WITH ra SELECT FROM a: ATOM => tv _ AMBridge.TVForATOM[a]; r: Rope.ROPE => tv _ AMBridge.TVForROPE[r]; ENDCASE => tv _ AMBridge.TVForReferent[ra]; }; tos: IO.STREAM _ TerminalIO.TOS[]; IF debug THEN { TerminalIO.WriteRope["\nJasmine Object: "]; IF tile=NIL THEN TerminalIO.WriteRope[" not found."] ELSE PrintTV.Print[tv: GetTypedVar[tile.value], put: tos]; }; }; PrintModel: PROC [model: SymTab.Ref] = { PrintMacro: PROC = { FOR indices: LIST OF MacroLocation _ locations, indices.rest UNTIL indices=NIL DO [thereIs, val] _ SymTab.Fetch[model, MapConvert[indices.first]]; IF thereIs THEN { macro: JasmineMacro _ NARROW[val]; TerminalIO.WriteRope["\nMap: "]; TerminalIO.WriteRope[MapConvert[indices.first]]; SELECT macro.macroType FROM m1Wire, m2Wire, nDifWire, pDifWire, polyWire => { IF macro.wireAspect=vert THEN TerminalIO.WriteRope[" | "] ELSE TerminalIO.WriteRope[" -- "]; TerminalIO.WriteF[" \t%gK ", IO.real[macro.resistance]]; }; nDifCont, pDifCont, polyCont, Via => { SELECT macro.branch FROM leftT => TerminalIO.WriteRope[" --| "]; rightT=> TerminalIO.WriteRope[" |-- "]; inverseT=> TerminalIO.WriteRope[" L "]; T=> TerminalIO.WriteRope[" T "]; L => TerminalIO.WriteRope[" L "]; reverseL => TerminalIO.WriteRope[" _L "]; inverseL => TerminalIO.WriteRope[" F "]; inverseRevL => TerminalIO.WriteRope[" _F "]; straight => TerminalIO.WriteRope[" * "]; fourWay=> TerminalIO.WriteRope[" + "]; ENDCASE => NULL; TerminalIO.WriteF[" \t%gK ", IO.real[macro.resistance]]; }; nTran, nTranL => { IF macro.xtorAspect=gateTied THEN TerminalIO.WriteRope[" =|= n "] ELSE TerminalIO.WriteRope[" -[n "]; }; pTran, pTranL => { IF macro.xtorAspect=gateTied THEN TerminalIO.WriteRope[" =|= p"] ELSE TerminalIO.WriteRope[" -[p "]; }; ENDCASE => NULL; macroCount _ macroCount.SUCC; }; ENDLOOP; }; val: REF ANY; thereIs: BOOL; macroCount: NAT _ 0; PrintMacro[]; TerminalIO.WriteF["\nMacros: %g, Transistors: %g, Resolution: %g\n\n", IO.int[macroCount], IO.int[tranCount], IO.rope[SELECT resolution FROM low=> "low", medium=>"medium", ENDCASE=>"high"], ]; }; --PrintModel CDSequencer.ImplementCommand[key: $InterJas, proc: InteractiveExtract, queue: doQueue]; CDMenus.CreateEntry[menu: $ProgramMenu, entry: "Extract Jasmine Network", key: $InterJas]; TerminalIO.WriteRope["Interactive Jasmine loaded.\n"]; END... of JasmineImpl ΌJasmineImpl.mesa Copyright c 1986 by Xerox Corporation. All rights resolutionerved. Created by Neil Gunther April 24, 1986 1:16:18 pm PST Last Edited by: Neil Gunther October 8, 1986 12:26:25 pm PDT Jasmine keys for decorating Core ChipnDale keys CD Layers: CD Objects: NOTE: Ordering of LayerObject matches Chipndale keys Operations Change from relative to absolute ("world") coordinates ... sigh!! Avoid tesselation of contact tile by expanding cut rect to match surround dimensions. --*** Bug: Causes Poly & Diff wires to get merged IF tileValue.private=NIL THEN tileValue.private _ $Keep; CStitching.ChangeTile[plane: tesselation, tile: tile, new: tileValue]; mergedWires _ CONS[CStitching.Area[tile], mergedWires]; MergeWireTiles[tile]; FOR mw: LIST OF CStitching.Rect _ mergedWires, mw.rest UNTIL mw=NIL DO mergedRect.r _ CDBasics.Surround[mergedRect.r, mw.first]; ENDLOOP; tileValue.data _ mergedRect; CStitching.ChangeTile[plane: tesselation, tile: tile, new: tileValue]; QuickAndDirty. (Should come from common process parameter source). Self-inductance Represent each segment as Thyme Stray Used fixed values for now Check for overhangs: Is there a tile whose Southern border is more Southerly than that of the starting tile which also abuts its Eastern edge? (i.e. an Eastern overhang). Interactive User Utilities Debugging Utilities Simple diagnostics. Use CSMonitor for WYSIWYG tesselations Thus item appears in Additional Programs Menu Κ*˜™Icodešœ Οmœ8™CK™5K™<—J™šΟk œ˜ Jšœ žœ(˜6Jšœžœžœ˜Jšœžœ˜JšœžœP˜XJšœžœ&˜4Jšœ žœ˜/Jšœžœ˜Jšœ˜Jšœžœ ˜Jšœžœ˜Jšœ˜Jšœ žœ$˜5Jšœ žœJ˜XJšœžœ)˜6Jšœ žœ ˜JšœžœD˜XJšœ ˜ Jšœžœ˜!Jšžœžœžœ˜+Jšœ ˜ Jšœžœ ˜Jšœžœ$˜1Jšœžœ˜Jšœ˜Jšœ˜Jšœ ˜ Jšœžœ˜*Jšœ žœ žœ˜7—K˜•StartOfExpansion[]šΠbl œžœž˜Kšžœε˜μKšžœ˜Kšœžœ˜K˜—Kšžœ ˜ K˜KšΟb œ ™ Kšœžœ5˜NKšœžœ6˜IKšœžœ5˜GKšœžœ7˜Kšœ žœ2˜AK™—š ™Kšžœ žœ˜*KšœΟgžœ˜"—šœ ™ KšΟsœžœ˜Kš’œžœ ˜Kš’œžœ ˜Kš’œžœ ˜Kš’œžœ ˜Kš’œžœ ˜Kš’œžœ˜Kš’œžœ ˜—šœ ™ Kš’œžœ ˜Kš’œžœ ˜Kš’œžœ ˜Kš’œžœ˜Kš’œžœ ˜Kš’œžœ˜K˜—Jš’œ1™5Jšœ žœR˜cKšœžœžœ˜)šœžœžœ˜Kš œ žœžœ žœžœžœžœ˜;Kš œ žœžœ žœžœžœžœ˜9Kšœž˜Kšœ%ž˜(Kšœ˜K˜—Kšœ žœžœ˜#Kšœžœžœ˜5K˜Kšœ žœ˜&Kšœ žœ˜&Kšœ žœ˜'K˜Kšœ žœ&˜3Kšœžœ žœžœ˜&Kš œžœžœžœžœ˜Kšœ žœžœ˜K˜Kšœ žœ˜Kšœžœžœ˜Kš œ žœžœžœžœ˜.K˜Kšœžœžœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœžœžœ˜K˜KšΟc ˜ Kšœžœžœ˜Kšœ žœ˜%head™ šΟnœžœžœ(žœ*˜vK˜Kš€œ#˜2˜š œžœ žœ ˜/Kšœžœ˜šœž œΠks’œž˜*Kšœ’œ ˜Kšœ’œ˜Kšœ’œ˜Kšœ’œ˜Kš’œ˜Kšœ’œ ˜Kšœ’œ ˜Kšžœ˜—Kšœžœ˜Kšœ˜K˜—K˜Kš€œ˜(šœΟi+Πik¦§¦œ˜Ešžœ žœž˜šœ˜Kšžœžœžœžœ˜G—šžœ£Πcs£œ˜KšœA˜A——K˜K™—Kš œ žœžœžœ žœ5˜[Kšœžœ žœ˜Kšœ žœ˜š žœžœžœžœ žœžœž˜EKšœ˜šžœ’œžœ˜+Kšœ˜KšœA™Ašœ˜šœ žœ žœ žœ˜+KšœU™UKšœF˜FKšžœ&˜*—Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜—Kšœz˜zK˜——Kšžœ˜Kšœ¦˜K™—Kš€œ˜4š œ¦c§¦ §¦§¦œ˜‰K˜š€œžœ žœ0˜XKšœžœ˜šœžœž˜0Kš’œ˜Kš’œ˜Kš’œ˜Kšžœ ˜—Kšœžœ˜Jšœ˜K˜K˜—Kš€œ˜%šœ¦+§¦§¦œ˜Ešžœ žœž˜šœ˜Kšžœžœžœžœ˜G—šžœ£¨£œ˜KšœA˜A——K˜—K˜Kšœ7˜7šžœ-žœ˜5Kšœ žœ˜;Kšœžœ žœ=˜Wšœžœ˜!Kšœ5˜5Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜—Kšœ žœ˜Kšœ"˜"Kšœs˜sK˜—Kšœ¦˜K˜—Kšœ˜Kšœ˜Kšœžœ(˜>Kšœžœ&˜8Kšœ*˜*Kšœ‹˜‹Kšœ¦˜K˜—š œž œ*˜J˜Kš œ˜*šœΠisœ˜$K˜š€œžœ)˜Ašœž œož˜ŒKšœ ˜ Kšžœ%˜,—Kšœ¦˜—K˜š€ œžœ˜/šžœ ž˜šœ ˜ šžœžœž˜šœ˜šžœžœžœ˜Kšœ?˜?Kšœ?˜?Kšœ?˜?Kšœ:˜:Kšœ:˜:Kšžœ˜%K˜——šœ˜šžœžœžœ˜Kšœ?˜?Kšœ@˜@Kšžœ˜%K˜—Kšžœ!˜(K˜———šœ ˜ šžœžœž˜šœ˜šžœžœžœ˜Kšœ:˜:Kšœ?˜?Kšœ?˜?Kšœ?˜?Kšžœ˜%Kšœ˜——Kšœ:˜:Kšžœ˜%K˜——šœ ˜ šžœžœž˜šœ˜šžœžœžœ˜Kšœ:˜:Kšœ?˜?Kšœ?˜?Kšœ?˜?Kšžœ˜&Kšœ˜——Kšœ:˜:Kšžœ˜&K˜——šœ ˜ šžœžœž˜šœ˜šžœžœžœ˜KšœA˜AKšœA˜AKšžœ!˜(Kšœ˜——Kšžœ!˜(—Kšœ˜—Kšœ £œ˜"šœ ˜ šžœžœž˜šœ˜šžœžœžœ˜KšœA˜AKšœA˜AKšžœ!˜(Kšœ˜——Kšžœ!˜(—Kšœ˜—šœ ˜ šžœžœž˜šœ˜šžœžœžœ˜KšœA˜AKšœA˜AKšžœ!˜(Kšœ˜——Kšžœ!˜(—Kšœ˜—Kšœ#˜#KšœJ˜JKšœI˜IKšœJ˜JKšœI˜IKšžœž˜—Kšœ¦ ˜—K˜Kšœžœ ˜*Kšœ"žœ˜8šžœžœ ž˜(Kšœ"˜"šžœž˜Kšœ˜Kšžœžœžœ8žœI˜™KšœF˜FKšœ!˜!Kšž˜K˜——Kšžœ˜Kšœ¦˜K˜——Kšœt˜tKšœ˜Kšœ£¦˜K˜—š€œžœ*˜AK˜š  œ˜ Kšœ©œ˜$K˜š€œžœ˜9K˜š€œ˜!Kšœžœ ˜.šžœ žœ˜šœ!˜!šžœ žœžœ˜Kšœ˜Kšœ@˜@K˜——Kšžœžœ˜—K˜—K˜Kšœžœ˜5Kšœ˜šžœžœžœ˜6Kšœ˜Kšœ žœ˜KšœF˜FK˜—Kšœ£˜K˜—š€œžœ˜3KšœΠbvœ,™1š€œ˜!Kšœžœ ˜.šžœ žœ˜šœ0˜0šžœ žœžœ˜Kšœ˜Kšœ@˜@K˜——Kšžœžœ˜—K˜—K˜Kšœžœ˜5Kšœ˜šžœžœžœ˜6Kšœ˜Kšœ žœ˜KšœF˜FKšœžœ(˜:K˜—Kšœ£˜K˜—Kšœ"žœ ˜5Kšœžœ˜*Kšœ žœžœ ˜šžœžœ˜šœ1˜1Kšžœžœžœ™8KšœG™GKšœžœ%™7Kšœ™š žœžœžœ(žœžœž™FKšœ9™9—Kšžœ™Kšœ™KšœG™GK˜Kšœ%˜%Kšœ˜KšœG˜GKšœ˜—šœ!˜!Kšžœžœžœ˜8KšœG˜GK˜K˜——Kšžœžœ˜Kšœ£ ˜—K˜Kšœj˜jKšœ£˜K˜—š  œž œ'žœ˜^K˜Kš€ œ˜ šœ©œ˜$K˜š€ œžœžœžœ˜:šœžœž œ˜Kšœžœ˜!Kšœžœ˜ Kšžœ ˜—K˜—K˜š  œžœžœžœ˜=Kšœ žœ£ ˜K˜Kšœ(˜(šžœΠktœž˜Kšœ˜šœžœžœž˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—šœžœžœž˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—Kšœ˜Kšœ8˜8Kšžœ&˜-—K˜K˜—š œžœžœžœ˜:šœžœž˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—Kšœžœ˜ K˜—K˜š œžœžœžœ˜7K˜š€œžœžœžœ˜8Kšœ"˜"Kšœ˜Kšžœžœ(˜FKšžœ)˜-K˜—K˜KšœB™BKšœžœ ˜Kšœžœ ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜šœž œž˜ Kšœ%˜%Kšœ%˜%Kšœ'˜'Kšœ'˜'Kšœ&˜&Kšžœžœ˜—Kšœžœ˜ K˜K˜—š œžœžœžœ ˜5Kšœ™Jšœžœ˜Kšœ-˜-K˜K˜—šΠbnœžœžœžœ˜˜>Kšœ>˜>Kšžœžœ˜&Kšžœžœ˜&Kšžœžœ˜&Kšžœžœ˜&Kšžœžœžœžœ˜)Kšœ ˜ K˜K˜——™š œžœ ˜8š žœžœ6žœžœž˜Qšžœžœž˜Jšœž˜ Jšœ˜Jšœ˜Jšœžœ˜Jšœ$˜$Kšžœ3˜:Kšœ žœe˜vKšœ9˜9Kšœ7˜7Kšœ!˜!Kšœ3˜3Kšœ!˜!šžœžœ˜ Kšœžœžœžœ˜"Kšœ%˜%Kšœ˜K˜—Kšœ˜—Jšžœ˜Jšœ9˜9—Kšœ¦˜K˜——™š ¬ œžœ žœžœžœ˜=Kšœ&ž™:Kšžœžœ=žœ žœ žœ žœ žœ ˜K˜K˜—š¬€œžœ žœ˜Eš€ œžœžœžœžœžœžœ˜Dšžœžœž˜Kšœžœ ˜'Kšœžœ˜+Kšžœ$˜+—Kšœ˜—K˜Kšœžœžœžœ˜"šžœžœ˜Kšœ+˜+Kšžœžœžœ$˜4Kšžœ6˜:K˜—Kšœ˜K˜—š€ œžœ˜(K˜š€ œžœ˜š žœ žœžœ)žœ žœž˜QKšœA˜Ašžœ žœ˜Kšœžœ˜"Kšœ ˜ Kšœ0˜0šžœžœ˜šœ1˜1Kšžœžœ˜:Kšžœ˜"Kšœ9˜9K˜—šœ&˜&šžœž˜Kšœ'˜'Kšœ'˜'Kšœ(˜(Kšœ ˜ Kšœ"˜"Kšœ*˜*Kšœ)˜)Kšœ-˜-Kšœ)˜)Kšœ&˜&—Kšžœžœ˜Kšœ8˜8K˜—šœ˜Kšžœžœ ˜AKšžœ˜#Kšœ˜—šœ˜Kšžœžœ˜@Kšžœ˜#K˜—Kšžœžœ˜—Kšœžœ˜K˜—Kšžœ˜—K˜K˜—Kšœžœžœ˜ Kšœ žœ˜Kšœ žœ˜Kšœ ˜ Kš œHžœžœžœžœ žœ žœ ˜ΑKšœ£ ˜K˜——˜KšœΟoœ™-KšœW˜WKšœZ˜ZKšœ6˜6K˜K˜—Kšžœ¦˜—…—]΄š