JasmineImpl.mesa
Copyright © 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
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
];
Jasmine keys for decorating Core
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];
ChipnDale keys
CDTechnology: CD.Technology = CMosB.cmosB;
lambda: CD.Number = CMosB.lambda;
CD Layers:
CDCut: ATOM = $cut;
CDMetal1: ATOM = $met;
CDMetal2: ATOM = $met2;
CDNDif: ATOM = $ndif;
CDOGlass: ATOM = $ovg;
CDPDif: ATOM = $pdif;
CDPoly: ATOM = $pol;
CDVia: ATOM = $cut2;
CD Objects:
CDRect:  ATOM = $Rect;
CDCell:  ATOM = $Cell;
CDNXtor:  ATOM = $C2Trans;
CDPXtor:  ATOM = $C2WellTrans;
CDNXtorL: ATOM = $C2LTrans;
CDPXtorL: ATOM = $CLWellTrans;
NOTE: Ordering of LayerObject matches Chipndale keys
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: BOOLFALSE;
Operations
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];
Relative -> 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: BOOLTRUE]-- = {
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[
To compute the area of angled & straight xtors see: SXCmosBImpl
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] = {
Used fixed values for now
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
Debugging Aids
PrintRect: PROC [tag: Core.ROPE, r: CD.Rect, debug: BOOL] = {
Simple diagnostics. Use CSMonitor for WYSIWYG tesselations
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;
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.
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
Item appears in Additional Programs Menu
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