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: BOOL ← FALSE;
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:
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[
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};
CompareJasmine
ObjectArea:
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