DIRECTORY
CD, CDAtomicObjects, CDBasics, CDCells, CDCurves, CDDefaultProcs, CDDirectory, CDEvents, CDImports, CDInstances, CDRects, CDRoutingObjects, CDSatellites, CDSymbolicObjects, CDTexts, CMosB, CMosBExtras,
Imager, ImagerColor, ImagerTransformation, List,
Pipal, PipalCD, PipalInt, PipalMos, PipalPaint,
Properties, PW, Real, RefTab, Saguaro;
PipalCDImpl:
CEDAR PROGRAM
IMPORTS CD, CDAtomicObjects, CDBasics, CDCells, CDCurves, CDDefaultProcs, CDDirectory, CDEvents, CDImports, CDInstances, CDRects, CDRoutingObjects, CDSatellites, CDSymbolicObjects, CDTexts, CMosB, CMosBExtras, Imager, ImagerTransformation, List, Pipal, PipalInt, PipalMos, Properties, PW, Real, RefTab, Saguaro
EXPORTS PipalCD
SHARES CDCells, CDCurves, CDImports, CDRects, CDTexts =
BEGIN OPEN PipalCD;
Top-Level Conversion
cdToPProcs: RefTab.Ref ← RefTab.Create[];
pToCDProcs: Pipal.ClassTable ← Pipal.CreateClassTable[];
pToCDInstanceProcs: Pipal.ClassTable ← Pipal.CreateClassTable[];
RegisterCDToPProc:
PROC [class:
CD.ObjectClass, proc: CDToPProc] = {
[] ← RefTab.Store[cdToPProcs, class, NEW [CDToPProc ← proc]];
};
RegisterPToCDProc:
PROC [class: Pipal.Class, proc: PToCDProc] = {
[] ← Pipal.StoreInClassTable[pToCDProcs, class, NEW [PToCDProc ← proc]];
};
RegisterPToCDInstanceProc:
PROC [class: Pipal.Class, proc: PToCDInstanceProc] = {
[] ← Pipal.StoreInClassTable[pToCDInstanceProcs, class, NEW [PToCDInstanceProc ← proc]];
};
CDOP: TYPE = RECORD [cdobj: CD.Object, cdprops: CD.PropList ← NIL];
cdToPObjects: RefTab.Ref ← RefTab.Create[]; -- [CD.Object -> Pipal.Object]
pToCDObjects: RefTab.Ref ← RefTab.Create[];
-- [Pipal.Object -> CDOP]
SomethingWeirdGoingOn:
SIGNAL [] =
CODE;
CheckAndStore:
PROC [obj: Pipal.Object, cdobj:
CD.Object, cdprops:
CD.PropList] = {
IF obj=Pipal.void THEN RETURN;
IF cdobj.class=CDCells.pCellClass AND NARROW [cdobj.specific, CD.CellSpecific].dummyCell THEN RETURN;
IF CDToPRect[cdobj.bbox]#PipalInt.BBox[obj, []] THEN SIGNAL SomethingWeirdGoingOn[];
IF CDRectSize[cdobj.bbox]#PipalInt.ObjectSize[obj] THEN SIGNAL SomethingWeirdGoingOn[];
IF CDToPRect[CD.InterestRect[cdobj]]#PipalInt.AbutBox[obj] THEN SIGNAL SomethingWeirdGoingOn[];
[] ← RefTab.Store[cdToPObjects, cdobj, obj];
[] ← RefTab.Store[pToCDObjects, obj, NEW [CDOP ← [cdobj, cdprops]]];
};
CheckInstance:
PROC [obj: Pipal.Object, cdobj:
CD.Object, cdprops:
CD.PropList, cdtrans:
CD.Transformation, transformation: PipalInt.Transformation] = {
IF obj=Pipal.void THEN RETURN;
IF CDToPRect[CDBasics.MapRect[cdobj.bbox, cdtrans]]#PipalInt.BBox[obj, transformation] THEN SIGNAL SomethingWeirdGoingOn[];
IF CDToPRect[CDBasics.MapRect[CD.InterestRect[cdobj], cdtrans]]#PipalInt.TransformRectangle[transformation, PipalInt.AbutBox[obj]] THEN SIGNAL SomethingWeirdGoingOn[];
};
CDToPObject:
PUBLIC CDToPProc = {
refProc: REF CDToPProc;
IF cdobj=NIL THEN ERROR;
obj ← RefTab.Fetch[cdToPObjects, cdobj].val;
IF obj#NIL THEN RETURN;
refProc ← NARROW [RefTab.Fetch[cdToPProcs, cdobj.class].val];
IF refProc=NIL THEN ERROR;
obj ← (refProc^)[cdobj];
obj ← AddCDProps[cdobj.properties, obj, FALSE];
CheckAndStore[obj, cdobj, NIL];
};
PToCDObject:
PUBLIC PToCDProc = {
cdop: REF CDOP ← NARROW [RefTab.Fetch[pToCDObjects, obj].val];
refProc: REF PToCDProc;
IF cdop#NIL THEN RETURN [cdop.cdobj, cdop.cdprops];
refProc ← NARROW [Pipal.FetchFromClassTable[pToCDProcs, Pipal.ObjectClass[obj]]];
[cdobj, cdprops] ← (IF refProc=NIL THEN PToCDExpand ELSE (refProc^))[obj];
CheckAndStore[obj, cdobj, cdprops];
};
PToCDInstance:
PUBLIC PToCDInstanceProc = {
refProc: REF PToCDInstanceProc ← NARROW [Pipal.FetchFromClassTable[pToCDInstanceProcs, Pipal.ObjectClass[obj]]];
[cdobj, cdprops, cdtrans] ← (IF refProc=NIL THEN PToCDInstanceFromObj ELSE (refProc^))[obj, transformation];
CheckInstance[obj, cdobj, cdprops, cdtrans, transformation];
};
CDToP Conversions Utilities
UnknownProp:
SIGNAL [key:
ATOM, val:
REF] =
CODE;
stupidCDProps: LIST OF REF ← LIST [$layerOfPin, $CDSatellitesGroupId, $CDBringoverLibraryName, $CDSatellitesOGroup, $OwnerDesign, $CDSatellitesComment];
extractProps: LIST OF REF ← LIST [$SinixPropertiesCache, $CMosBExtractProc, $RawCMosBExtractProc, $SinixSatellites, $SinixCMosBExtractProc, $SisyphExtractProc, $SisyphParmNames, $CodeFor, $IconFor, $SinixInstanceCache, $FlattenInstanceCache, $SinixObjectCache];
otherProps:
LIST OF REF ←
LIST [$X, $PinOrder, $InstanceName, $DontFlatten, $Export, $MintDiscardMe];
ProcessSchematicIconProps:
PROC [props:
CD.PropList, obj: Pipal.Object]
RETURNS [
CD.PropList, Pipal.Object] = {
type: PipalMos.SchematicIconType;
codeFor: Pipal.ROPE ← NARROW [Properties.GetProp[props, $CodeFor]];
iconFor: Pipal.ROPE ← NARROW [Properties.GetProp[props, $IconFor]];
IF (codeFor=NIL AND iconFor=NIL) OR (codeFor#NIL AND iconFor#NIL) THEN RETURN [props, obj];
SELECT Properties.GetProp[props, $SisyphExtractProc]
FROM
$SisyphExtractCellIcon => type ← cell;
$SisyphExtractNamedWireIcon => type ← wire;
$SisyphExtractUnNamedWireIcon => type ← unnamedWire;
ENDCASE => RETURN [props, obj];
props ← Properties.PutProp[props, $CodeFor, NIL];
props ← Properties.PutProp[props, $IconFor, NIL];
props ← Properties.PutProp[props, $SisyphExtractProc, NIL];
obj ← PipalMos.CreateSchematicIcon[obj, IF codeFor=NIL THEN iconFor ELSE codeFor, codeFor#NIL, type];
RETURN [props, obj];
};
AddCDProps:
PROC [props:
CD.PropList, obj: Pipal.Object, inst:
BOOL]
RETURNS [new: Pipal.Object] = {
[props, new] ← ProcessSchematicIconProps[props, obj];
WHILE props#
NIL DO
key: REF ← props.first.key;
val: REF ← props.first.val;
IF ISTYPE [key,
ATOM]
THEN SELECT TRUE FROM
key=$SignalName OR key=$Describe => new ← Pipal.CreateAnnotation[new, Pipal.nameProp, NARROW [val, Pipal.ROPE]];
key=$SisyphExpressions => new ← Pipal.CreateAnnotation[new, IF inst THEN $SisyphInstanceExpressions ELSE $SisyphObjectExpressions, NARROW [val, LIST OF Pipal.ROPE]]; -- hack hack hack!
List.Memb[key, stupidCDProps] => {};
List.Memb[key, extractProps] => {};
List.Memb[key, otherProps] => {};
ENDCASE => {
SIGNAL UnknownProp[NARROW [key], val];
otherProps← CONS [key, otherProps];
};
props ← props.rest;
ENDLOOP;
};
CDToPInstance:
PUBLIC PROC [instance:
CD.Instance]
RETURNS [obj: Pipal.Object] = {
properties: CD.PropList ← instance.properties;
SELECT TRUE FROM
Special hack for pins, first!
CDSymbolicObjects.IsSymbolicOb[instance.ob] => {
obj ← PipalMos.CreateMarker[
CDRectSize[CDSymbolicObjects.Denotes[instance]],
CDToPLayer[CDSymbolicObjects.GetLayer[instance]]
];
properties ← Properties.PutProp[properties, $layerOfPin, NIL];
};
Hack for $SisyphExtractProc=$ExtractNull
instance.ob.class.newLayer#
NIL AND instance.ob.layer=
CD.commentLayer
AND Properties.GetProp[properties, $SisyphExtractProc] = $ExtractNull => {
instance ← CDInstances.Copy[instance];
IF NOT instance.ob.class.newLayer[instance, CD.FetchLayer[NIL, $blue]] THEN ERROR;
obj ← CDToPObject[instance.ob];
properties ← Properties.PutProp[properties, $SisyphExtractProc, NIL];
};
ENDCASE => obj ← CDToPObject[instance.ob];
obj ← AddCDProps[properties, Transform[instance.trans, obj], TRUE];
};
Class-Specific CDToP Object Conversions
All the functions in that section assume that the properties of cdobj have been dealt with.
CDToPBox: CDToPProc = {
obj ← PipalMos.CreateBox[CDRectSize[cdobj.bbox], CDToPLayer[cdobj.layer]];
};
CDToPAtomicAnnotation: CDToPProc = {
ov: Pipal.Object ← CDToPOverlay[CDDirectory.Expand1ByDraw[cdobj]];
obj ← Pipal.CreateAnnotation[
ov,
IF PipalMos.ContainsWell[ov] THEN PipalMos.biAtomicProp ELSE PipalMos.atomicProp,
cdobj.class.objectType
];
};
CDToPTransistorAnnotation: CDToPProc = {
obj ← Pipal.CreateAnnotation[
CDToPOverlay[CDDirectory.Expand1ByDraw[cdobj]],
PipalMos.transistorProp,
cdobj.class.objectType
];
};
CDToPOrient: CDToPProc = {
rs: PW.RotationSpecific ← NARROW [cdobj.specific];
obj ← PipalInt.CreateOrient[VAL [ORD [rs.orientation]], CDToPObject[rs.obj]];
};
CDToPRouting: CDToPProc = {
rs: CDRoutingObjects.RoutingSpecific ← NARROW [cdobj.specific];
nodes: Pipal.Objects ← NIL;
FOR i:
NAT IN [0 .. rs.size)
DO
node: CDRoutingObjects.Node ← rs[i];
subs: Pipal.Objects ← NIL;
FOR j:
NAT IN [0 .. node.size)
DO
po: CDRoutingObjects.PlacedObject = node[j];
position: CD.Position = po.position;
subs ← CONS [PipalInt.TransformObject[[[position.x, position.y]], CDToPObject[po.object]], subs];
ENDLOOP;
nodes ← CONS [AddCDProps[node.properties, Pipal.CreateOverlay[subs], TRUE], nodes];
ENDLOOP;
obj ← IRAnnotate[rs.ir, Pipal.CreateOverlay[nodes]];
};
CDXYTile: PipalMos.XYTileProc = {
RETURN [CDToPObject[PW.GetTile[NARROW [data], x, y]]];
};
CDToPTiling: CDToPProc = {
obj ← PipalMos.CreateTiling[PW.GetTilingSize[cdobj].sizeX, PW.GetTilingSize[cdobj].sizeY, CDXYTile, cdobj];
};
CDToPImport: CDToPProc = {
import: CDImports.ImportSpecific = NARROW [cdobj.specific];
IF import.boundOb=NIL THEN ERROR;
obj ← CDToPObject[import.boundOb];
};
CDToPIndirect: CDToPProc = {
obj ← Pipal.CreateAnnotation[
CDToPObject[CDDirectory.Expand1[cdobj].new], PipalMos.indirectProp, NIL
];
};
CDToPAbut: CDToPProc = {
EachInst: PW.EachSubObjectProc = {children ← CONS [CDToPObject[subObject], children]};
children: Pipal.Objects ← NIL;
[] ← PW.EnumerateSubObjects[cdobj, EachInst];
obj ← PipalInt.CreateAbut[cdobj.class=PW.abutXClass, Pipal.Reverse[children]];
};
CDToPText: CDToPProc = {
text: CDTexts.TextSpecific ← NARROW [cdobj.specific];
obj ← PipalMos.CreateText[text.text, text.cdFont.font]
};
ImagerObjectData: TYPE = REF ImagerObjectDataRec;
ImagerObjectDataRec:
TYPE =
RECORD [
cdImagerObject: Imager.Object,
color: ImagerColor.ConstantColor
];
DrawImagerObject:
PROC [self: Imager.Object, context: Imager.Context] = {
iod: ImagerObjectData = NARROW [self.data];
Imager.SetColor[context, iod.color];
Imager.DrawObject[context: context, object: iod.cdImagerObject, interactive: TRUE];
};
CDToPCurve: CDToPProc = {
curve: CDCurves.CurveSpecific ← NARROW [cdobj.specific];
cdImagerObject: Imager.Object ← curve.imagerObject;
iod: ImagerObjectData ←
NEW [ImagerObjectDataRec ← [
cdImagerObject: cdImagerObject, color: PipalMos.FetchLayerColor[CDToPLayer[cdobj.layer]]
]];
obj ← PipalMos.CreatePicture[
CDRectSize[cdobj.bbox],
NEW [Imager.ObjectRep ← [draw: DrawImagerObject, clip: cdImagerObject.clip, data: iod]]
];
};
CDToPPicture: CDToPProc = {
obj ← PipalMos.CreatePicture[CDRectSize[cdobj.bbox], NARROW [cdobj.specific]]
};
CDToPOverlay: CDToPProc = {
cs: CD.CellSpecific = NARROW [cdobj.specific];
GetSatellites:
PROC [from:
REF]
RETURNS [satellites: Pipal.Objects ←
NIL] = {
FOR list:
CD.InstanceList ← CDSatellites.GetSatellites[from], list.rest
WHILE list#
NIL DO
IF NOT RefTab.Store[seen, list.first, $TRUE] THEN ERROR; -- satellite of several!
satellites ← CONS [CDToPInstance[list.first], satellites];
ENDLOOP;
};
CreateStar:
PROC [master: Pipal.Object, satellites: Pipal.Objects, overlayStar:
BOOL]
RETURNS [Pipal.Object] = {
IF satellites=NIL THEN RETURN [master];
RETURN [PipalMos.CreateStar[master, satellites, overlayStar]];
};
seen: RefTab.Ref ← RefTab.Create[];
EachNonText: CDCells.InstEnumerator = {
IF CDTexts.IsText[inst.ob] THEN RETURN;
children ← CONS [CreateStar[CDToPInstance[inst], GetSatellites[inst], FALSE], children];
};
EachText: CDCells.InstEnumerator = {
IF NOT CDTexts.IsText[inst.ob] OR RefTab.Fetch[seen, inst].found THEN RETURN;
children ← CONS [CDToPInstance[inst], children];
};
children: Pipal.Objects ← NIL;
objectSatellites: Pipal.Objects ← GetSatellites[cdobj];
[] ← CDCells.EnumerateInstances[cdobj, EachNonText];
[] ← CDCells.EnumerateInstances[cdobj, EachText];
obj ← Pipal.CreateOverlay[children];
obj ← CreateStar[obj, objectSatellites, TRUE];
IF cs.specifiedIr THEN obj ← IRAnnotate[cs.ir, obj];
};
Class-Specific PToCD Object Conversions
PToCDInstanceFromObj: PToCDInstanceProc = {
[cdobj, cdprops] ← PToCDObject[obj];
cdtrans ← PToCDTrans[transformation];
};
PToCDInstanceInternal:
PROC [obj: Pipal.Object, transformation: PipalInt.Transformation]
RETURNS [cdinst:
CD.Instance] = {
cdobj: CD.Object; cdprops: CD.PropList; cdtrans: CD.Transformation;
[cdobj, cdprops, cdtrans] ← PToCDInstance[obj, transformation];
cdinst ← NEW [CD.InstanceRep ← [ob: cdobj, trans: cdtrans, properties: cdprops]];
};
PToCDAnnotation: PToCDProc = {
annotation: Pipal.Annotation ← NARROW [obj];
SELECT annotation.key
FROM
PipalInt.abutBoxProp => {
refAbutBox: REF PipalInt.Rectangle ← NARROW [annotation.value];
cdobj ←
PW.CreateCell[
LIST [PToCDInstanceInternal[annotation.child, []]],
PToCDRect[refAbutBox^]
];
};
ENDCASE => {
[cdobj, cdprops] ← PToCDObject[annotation.child];
cdprops ← Properties.PutProp[cdprops, annotation.key, annotation.value];
};
};
PToCDBox: PToCDProc = {
box: PipalMos.Box ← NARROW [obj];
cdobj ← CDRects.CreateRect[PToCDVector[box.size], PToCDLayer[box.layer]];
};
PToCDMarker: PToCDProc = {
marker: PipalMos.Marker ← NARROW [obj];
cdobj ← CDRects.CreateRect[PToCDVector[marker.size], PToCDLayer[marker.layer]];
};
PToCDText: PToCDProc = {
text: PipalMos.Text ← NARROW [obj];
trans: Imager.Transformation = text.font.charToClient;
scale: INT ← Real.Round[trans.a];
IF NOT ImagerTransformation.CloseEnough[ImagerTransformation.Scale[scale], trans] THEN SIGNAL SomethingWeirdGoingOn[];
cdobj ← CDTexts.Create[text.contents, CDTexts.MakeFont[PipalMos.GetTextFontName[text], scale]];
};
PToCDPicture: PToCDProc = {
picture: PipalMos.Picture ← NARROW [obj];
cdobj ← CreatePicture[PToCDVector[picture.size], picture.imagerObject];
};
PToCDExpand: PToCDProc = {
instances: CD.InstanceList ← NIL;
EachChild: PipalInt.EachChildProc = {
IF child=Pipal.void THEN RETURN;
instances ← CONS [PToCDInstanceInternal[child, transformation], instances];
};
[] ← PipalInt.Enumerate[obj, EachChild];
cdobj ← PW.CreateCell[instances];
IF cdobj.bbox = [0, 0, 1, 1] THEN cdobj.bbox ← [0, 0, 0, 0];
};
Initialization
CDEvents.RegisterEventProc[$AfterChange, AfterObjectChange];
CDEvents.RegisterEventProc[$AfterCellReplacement, AfterObjectChange];
Attention: wndif, wpdif, wpwellCont, wnwellCont do not appear in that table to avoid problems!
RegisterCDPLayer[CD.errorLayer, PipalMos.errorLayer];
RegisterCDPLayer[CD.commentLayer, PipalMos.commentLayer];
RegisterCDPLayer[CMosBExtras.bond, $Bond];
RegisterCDPLayer[CMosB.ndif, $Ndif];
RegisterCDPLayer[CMosB.pdif, $Pdif];
RegisterCDPLayer[CMosB.pwellCont, $PwellCont];
RegisterCDPLayer[CMosB.nwellCont, $NwellCont];
RegisterCDPLayer[CMosB.pwell, $Pwell];
RegisterCDPLayer[CMosB.nwell, $Nwell];
RegisterCDPLayer[CMosB.pol, $Pol];
RegisterCDPLayer[CMosB.met, $Met];
RegisterCDPLayer[CMosB.met2, $Met2];
RegisterCDPLayer[CMosB.ovg, $Ovg];
RegisterCDPLayer[CMosB.cut, $Cut];
RegisterCDPLayer[CMosB.cut2, $Cut2];
RegisterCDPLayer[
CD.FetchLayer[
NIL, $blue], PipalMos.blueCommentLayer];
RegisterCDToPProc[CDRects.bareRectClass, CDToPBox];
RegisterCDToPProc[CDRects.wellRectClass, CDToPAtomicAnnotation];
RegisterCDToPProc[CDCells.pCellClass, CDToPOverlay];
RegisterCDToPProc[PW.abutXClass, CDToPAbut];
RegisterCDToPProc[PW.abutYClass, CDToPAbut];
RegisterCDToPProc[PW.rotationClass, CDToPOrient];
RegisterCDToPProc[CDRoutingObjects.routingClass, CDToPRouting];
RegisterCDToPProc[PW.tilingClass, CDToPTiling];
RegisterCDToPProc[PW.indirectClass, CDToPIndirect];
RegisterCDToPProc[CDTexts.flipTextClass, CDToPText];
RegisterCDToPProc[CDTexts.rigidTextClass, CDToPText];
RegisterCDToPProc[CDCurves.splineClass, CDToPCurve];
RegisterCDToPProc[CDCurves.lineClass, CDToPCurve];
RegisterCDToPProc[CDCurves.polygonClass, CDToPCurve];
RegisterCDToPProc[CDCurves.filledCurveClass, CDToPCurve];
RegisterCDToPProc[pictureClass, CDToPPicture];
RegisterCDToPProc[CDImports.importsClass, CDToPImport];
All Atomic classes
FOR list:
LIST OF ATOM ←
LIST [$C2SimpleCon, $C2WellSimpleCon, $C2LargeSimpleCon, $C2LargeWellSimpleCon, $C2DifShortCon, $C2Dif
fShortCon, $C2WellDifShortCon, $C2Via, $C2LargeVia], list.rest
WHILE list#
NIL DO
RegisterCDToPProc[CD.FetchObjectClass[list.first, CMosB.cmosB], CDToPAtomicAnnotation];
ENDLOOP;
FOR list:
LIST OF ATOM ←
LIST [$C2Trans, $C2WellTrans, $C2LTrans, $C2LWellTrans], list.rest
WHILE list#
NIL DO
RegisterCDToPProc[CD.FetchObjectClass[list.first, CMosB.cmosB], CDToPTransistorAnnotation];
ENDLOOP;
Pipal.PutClassMethod[Pipal.annotationClass, PipalMos.extractTransistorMethod,
NEW [PipalMos.ExtractTransistorProc ← AnnotationExtractTransistor]];
RegisterPToCDProc[Pipal.annotationClass, PToCDAnnotation];
RegisterPToCDProc[PipalMos.boxClass, PToCDBox];
RegisterPToCDProc[PipalMos.markerClass, PToCDMarker];
RegisterPToCDProc[PipalMos.textClass, PToCDText];
RegisterPToCDProc[PipalMos.pictureClass, PToCDPicture];
RegisterPToCDInstanceProc[PipalMos.boxClass, PToCDInstanceFromObj];
RegisterPToCDInstanceProc[PipalMos.markerClass, PToCDInstanceFromObj];
RegisterPToCDInstanceProc[PipalMos.textClass, PToCDInstanceFromObj];
RegisterPToCDInstanceProc[PipalMos.pictureClass, PToCDInstanceFromObj];