<> <> <> <> <<>> 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] = { <<--*** Bug: Causes Poly & Diff wires to get merged>> 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