<> <> <> <> <<>> DIRECTORY AMBridge, AMTypes, CD, CDBasics, CDSequencer, CDMenus, CDOps, CMosB, Core, CoreClasses, CoreFlat, CoreOps, CDOrient, CoreProperties, CStitching, IO, Jasmine, NewCoreClasses, PrintTV, Process, Rope, Sinix, SinixCMos, TerminalIO; JasmineImpl: CEDAR PROGRAM IMPORTS AMBridge, CD, CDBasics, CDSequencer, CDMenus, CDOps, CMosB, CoreClasses, CoreFlat, CoreOps, CDOrient, CoreProperties, CStitching, IO, PrintTV, Process, Rope, Sinix, SinixCMos, TerminalIO EXPORTS Jasmine = BEGIN OPEN Jasmine; JasmineParams: TYPE = REF JasmineParamsRec; JasmineParamsRec: TYPE = RECORD[ apData: PACKED ARRAY JasmineObject OF EffectiveAP _ ALL[NEW[APRec]] ]; EffectiveAP: TYPE = REF APRec; APRec: TYPE = RECORD[ effPerim: INT _ 0, effArea: INT _ 0 ]; <> resistorProp: 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 ]; Error: SIGNAL [msg: ROPE] = CODE; none: REF INT = NEW[INT]; spaceTile: REF = NIL; --diagnostics db: BOOL _ FALSE; <> 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-- => IF layer#cut THEN 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]; < Absolute ("world") coords ... sigh!!>> wireRect _ CDOrient.MapRect[ itemInCell: [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 [xtorInst: CD.Instance] = { data _ NEW[LayersInTileRec]; layer _ SELECT xtorInst.ob.class.objectType FROM CDNXtor => nXtor, CDPXtor => pXtor, CDNXtorL => nXtorL, ENDCASE => pXtorL; data.primary[layer] _ TRUE; }; InsertPseudoTransistor: 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]; -- recast IF basic.class=CoreClasses.transistorCellClass THEN { inst: CD.Instance _ NARROW[CoreProperties.GetCellInstanceProp[instance, instanceProp]]; pseudoXtor: 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]; CStitching.ChangeEnumerateArea[plane: tesselation, rect: pseudoXtor, eachRect: InsertPseudoTransistor, data: data, skip: none]; }; }; --AddTransistorGeometry data: LayersInTile; layer: LayerObject; wireGeometryProp: ATOM = SinixCMos.extractBMode.wireGeometryProp; instanceProp: ATOM = SinixCMos.extractBMode.instanceProp; tesselation _ CStitching.NewTesselation[]; CoreFlat.EnumerateAtomicWireLeaves[root: root, rootWire: wire, eachInternalWire: AddWireGeometry, eachWireInstance: AddTransistorGeometry]; }; --CornerStitchWire EstablishTopography: PUBLIC PROC [tesselation: CStitching.Tesselation] = { jasmineParams: JasmineParams _ NEW[JasmineParamsRec]; DefineJasmineObjects: CStitching.TileProc --PROC [tile: REF Tile, data: REF]-- = { tLayer: LayersInTile = NARROW[tile.value]; tileData: JasmineObjectInLayer _ NEW[JasmineObjectRec]; ElectJasmineObject: PROC [nomination, elected: JasmineObject] = { RelArea: TYPE = {smallerThan, largerThan, equalTo}; CompareJasmineObjectArea: 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 => [0, 0, 32, 32], nTran, pTran => [0, 0, 64, 64], nTranL, pTranL => [0, 0, 112, 144], ENDCASE => [0, 0, INT.FIRST, INT.FIRST]; }; tileData.object _ SELECT CompareJasmineObjectArea[CDBasics.SizeOfRect[CStitching.Area[tile]], CDBasics.SizeOfRect[CDStandardArea[elected]]] FROM smallerThan, equalTo => elected, ENDCASE => tileData.object _ nomination; }; --ElectJasmineObject DiscriminateObjectsFromLayers: 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 => tileData.object _ m1Wire; }; tLayer.secondary[met2] => { SELECT TRUE FROM tLayer.secondary[ndif] => ElectJasmineObject[m2Wire, nDifCont]; tLayer.secondary[poly] => ElectJasmineObject[m2Wire, polyCont]; ENDCASE => tileData.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 => tileData.object _ m1Wire; }; tLayer.secondary[met2] => ElectJasmineObject[m1Wire, Via]; ENDCASE => tileData.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 => tileData.object _ m2Wire; }; tLayer.secondary[met1] => ElectJasmineObject[m2Wire, Via]; ENDCASE => tileData.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 => tileData.object _ nDifWire; }; ENDCASE => tileData.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 => tileData.object _ pDifWire; }; ENDCASE => tileData.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 => tileData.object _ polyWire; }; ENDCASE => tileData.object _ polyWire; }; via => tileData.object _ Via; nXtor => tileData.object _ nTran; nXtorL => tileData.object _ nTranL; pXtor => tileData.object _ pTran; pXtorL => tileData.object _ pTranL; ENDCASE => NULL; }; --DiscriminateObjectsFromLayers ComputeWireAP: PROC = { p: CD.Position _ CDBasics.SizeOfRect[CStitching.Area[tile]]; tileData.area _ (p.x*p.y)/(lambda*lambda); tileData.perim _ 2*(p.x+p.y)/lambda; jasmineParams.apData[tileData.object].effArea _ jasmineParams.apData[tileData.object].effArea + tileData.area; jasmineParams.apData[tileData.object].effPerim _ jasmineParams.apData[tileData.object].effPerim + tileData.perim; }; --ComputeWireAP FOR layer: LayerObject IN LayerObject DO wire: Core.Wire = tLayer.coreWire; IF tLayer.primary[layer] THEN { DiscriminateObjectsFromLayers[layer]; ComputeWireAP[]; IF wire#NIL AND CoreProperties.GetWireProp[from: wire, prop: modelProp]=NIL THEN CoreProperties.PutWireProp[on: wire, prop: modelProp, value: tileData]; CStitching.ChangeTile[plane: tesselation, tile: tile, new: tileData]; PrintJasmineObjectData[tile, db]; EXIT; }; ENDLOOP; }; --DefineJasmineObjects CStitching.EnumerateArea[plane: tesselation, rect: CStitching.all, eachTile: DefineJasmineObjects, skip: spaceTile]; }; --EstablishTopography <> 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]; }; }; TraceAdjacent: PROC [startingTile: CStitching.Tile] = { 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]; PrintAdj: PROC [adj: CStitching.Tile] = { PrintRect[" Adj", CStitching.Area[adj], db]; }; PrintRect["Start", CStitching.Area[startingTile], db]; --trace down Eastern edge tEast _ CStitching.NE[startingTile]; WHILE CStitching.SEdge[tEast]>=s DO IF tEast.value#spaceTile THEN PrintAdj[tEast]; TRUSTED {tEast _ LOOPHOLE[tEast.wS]}; ENDLOOP; <> IF tEast.value#spaceTile THEN PrintAdj[tEast]; --trace left, along Southern edge TRUSTED {tSouth _ LOOPHOLE[startingTile.wS]}; WHILE CStitching.WEdge[tSouth]>=w DO IF tSouth.value#spaceTile THEN PrintAdj[tSouth]; tSouth _ tSouth.sW; ENDLOOP; IF tSouth.value#spaceTile THEN PrintAdj[tSouth]; --trace up Western edge tWest _ CStitching.SW[startingTile]; WHILE CStitching.NEdge[tWest]<=n DO IF tWest.value#spaceTile THEN PrintAdj[tWest]; tWest _ tWest.eN; ENDLOOP; IF tWest.value#spaceTile THEN PrintAdj[tWest]; --trace right, along Northern edge to starting point TRUSTED {tNorth _ LOOPHOLE[startingTile.eN]; WHILE CStitching.EEdge[tNorth]<=e DO IF tNorth.value#spaceTile THEN PrintAdj[tNorth]; tNorth _ LOOPHOLE[tNorth.nE]; ENDLOOP}; IF tNorth.value#spaceTile THEN PrintAdj[tNorth]; }; --TraceAdjacent InteractiveExtract: PROC [comm: CDSequencer.Command] = { tech: Sinix.Mode; SELECT comm.design.technology.key FROM $cmos => tech _ SinixCMos.extractAMode; $cmosB => tech _ SinixCMos.extractBMode; ENDCASE => { TerminalIO.WriteRope[Rope.Cat["The technology ", comm.design.technology.name, " is not implemented in Jasmine.\n"]]; RETURN; }; 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: tech].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]; --CoreOps.PrintWire[coreWire, out]; TerminalIO.WriteRope["\n\n"]; }; }; ENDLOOP; TerminalIO.WriteRope["\nJasmine extraction complete.\n"]; }; --InteractiveExtract <> 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