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];