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]; 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 JasmineImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Created by Neil Gunther April 24, 1986 1:16:18 pm PST Last Edited by: Neil Gunther June 20, 1986 10:07:37 pm PDT Jasmine keys for decorating Core ChipnDale keys CD Layers: CD Objects: NOTE: Ordering of LayerObject matches Chipndale keys Operations Relative -> Absolute ("world") coords ... sigh!! To compute the area of angled & straight xtors see: SXCmosBImpl Used fixed values for now Debugging Aids Simple diagnostics. Use CSMonitor for WYSIWYG tesselations See if there exists a tile whose Southern border is more Southerly than that of the starting tile and also abuts the Eastern edge of the starting tile i.e. an Eastern overhang. Item appears in Additional Programs Menu Κ3˜™Icodešœ Οmœ1™