CDConvertTechnologies.mesa (a package to convert technologies of ChipNDale designs)
Copyright © 1983, 1985, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, June 24, 1983 5:03 pm
Last edited by: Christian Jacobi, December 12, 1986 9:47:21 am PST
DIRECTORY
CD,
CDAtomicObjects,
CDBasics,
CDCells,
CDCellsInteractions,
CDCommandOps,
CDCleanUp,
CDDirectory,
CDImports,
CDOps,
CDCurves,
CDProperties,
CDRects,
CDSequencer,
CDSymbolicObjects,
CDTexts,
CDViewer,
RefTab,
Rope,
TerminalIO;
CDConvertTechnologies:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDAtomicObjects, CDCellsInteractions, CDCleanUp, CDCells, CDCommandOps, CDDirectory, CDImports, CDOps, CDCurves, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CDViewer, RefTab, TerminalIO =
BEGIN
--MUST BE SETUP USING INTERPRETER
fromTechnologyKey: ATOM←NIL;
toTechnologyKey: ATOM←NIL;
layerConversion: RefTab.Ref; -- layerkey => layerkey
classConversion: RefTab.Ref; -- object class key => key for atomic objects
classPosOffsets: RefTab.Ref; -- old object class key => CD.Position [offset in old coord system]
classSizeOffsets: RefTab.Ref; -- old object class key => CD.Position [offset in old coord system]
--must be protected
correspondKey: REF INT;
design: CD.Design;
newDesign: CD.Design;
lambda: CD.Number;
newLambda: CD.Number;
oldTech: CD.Technology;
newTech: CD.Technology;
TRect:
PROC [rect:
CD.Rect]
RETURNS [r:
CD.Rect] = {
r ← [x1: rect.x1*newLambda/lambda, x2: rect.x2*newLambda/lambda, y1: rect.y1*newLambda/lambda, y2: rect.y2*newLambda/lambda]
};
TPos:
PROC [pos:
CD.Position]
RETURNS [p:
CD.Position] = {
p ← [pos.x*newLambda/lambda, pos.y*newLambda/lambda]
};
TNum:
PROC [n:
CD.Number]
RETURNS [
CD.Number] = {
RETURN [n*newLambda/lambda]
};
SizeOffset:
PROC [oldOb:
CD.Object]
RETURNS [s:
CD.Position←[0, 0]] = {
IF classSizeOffsets#
NIL
THEN
WITH RefTab.Fetch[classSizeOffsets, oldOb.class.objectType].val
SELECT
FROM
p: REF CD.Position => s ← p^;
ENDCASE => NULL;
};
MustOffsetOrigin:
PROC [oldOb:
CD.Object]
RETURNS [off:
CD.Position ← [0, 0]] = {
--off in old coord system
IF classPosOffsets#
NIL
THEN
WITH RefTab.Fetch[classPosOffsets, oldOb.class.objectType].val
SELECT
FROM
p: REF CD.Position => off ← p^;
ENDCASE => NULL;
};
OriginPos:
PROC [i:
CD.Instance, point:
CD.Position ← [0, 0]]
RETURNS [p:
CD.Position] = {
--point in origin coordinates of object i.ob is returned in world coordinates
RETURN [CDBasics.MapPoint[
pointInCell: point,
cellInWorld: i.trans
]]
};
CorrespondingLayer:
PROC [layer:
CD.Layer]
RETURNS [l:
CD.Layer] = {
key: ATOM ← CD.LayerKey[layer];
WITH RefTab.Fetch[layerConversion, key].val
SELECT
FROM
a: ATOM => l ← CD.FetchLayer[newTech, a];
ENDCASE => {
IF CD.LayerTechnology[layer]=NIL THEN RETURN [layer];
l ← CD.FetchLayer[newTech, CD.LayerKey[layer]]
}
};
TransferAny:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object←
NIL] = {
WITH CDProperties.GetProp[ob, correspondKey]
SELECT
FROM
ob1: CD.Object => RETURN [ob1];
ENDCASE => NULL;
IF CDAtomicObjects.IsAtomicOb[ob] THEN new ← TransferAtomicObject[ob]
ELSE IF CDCells.IsCell[ob] THEN new ← TransferCell[ob]
ELSE IF ob.class.wireTyped THEN new ← TransferWire[ob]
ELSE IF CDSymbolicObjects.IsMark[ob] THEN new ← CDSymbolicObjects.CreateMark[]
ELSE IF CDTexts.IsText[ob] THEN new ← TransferText[ob]
ELSE IF CDImports.IsImport[ob] THEN new ← TransferImport[ob]
ELSE IF CDCurves.IsPolygon[ob] THEN new ← TransferPolygon[ob]
ELSE IF CDCurves.IsLine[ob] THEN new ← TransferLine[ob]
ELSE IF CDCurves.IsSpline[ob] THEN new ← TransferSpline[ob]
ELSE IF CDCurves.IsFilledCurve[ob] THEN new ← TransferFilledCurve[ob];
IF new=NIL THEN new ← TransferHard[ob];
IF new=NIL THEN TerminalIO.PutRope["unknown object type\n"]
};
GetAtomKey:
PROC [a:
ATOM]
RETURNS [
ATOM] = {
WITH RefTab.Fetch[classConversion, a].val
SELECT
FROM
aa: ATOM => RETURN [aa];
ENDCASE => RETURN [NIL];
};
TransferAtomicObject:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object←
NIL] = {
newKey: ATOM ← GetAtomKey[ob.class.objectType];
sz: CD.Position ← CD.InterestSize[ob];
sz ← TPos[CDBasics.AddPoints[sz, SizeOffset[ob]]];
IF newKey#
NIL
THEN {
new ← CDAtomicObjects.CreateAtomicOb[newKey, sz, newTech, CorrespondingLayer[ob.layer]];
}
};
TransferHard:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object←
NIL] = {
ob1: CD.Object ← CDDirectory.Expand[ob, design, NIL].new;
IF ob1=NIL OR ob1=ob THEN ob1 ← CDDirectory.ExpandByDraw[ob];
IF ob1#
NIL
THEN {
new ← TransferWithChildrenCheck[ob1];
CDProperties.PutProp[ob, correspondKey, CDProperties.GetProp[ob1, correspondKey]];
}
};
TransferWire:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] = {
new ← CDRects.CreateRect[TPos[CD.InterestSize[ob]], CorrespondingLayer[ob.layer]]
};
TransferText:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] = {
tp: CDTexts.TextSpecific ← NARROW[ob.specific];
font: CDTexts.CDFont;
font ← CDTexts.MakeFont[name: tp.cdFont.supposedName, scale: TNum[tp.cdFont.scaleI]];
new ← CDTexts.Create[text: tp.text, font: font, layer: CorrespondingLayer[ob.layer], flip: CDTexts.IsFlipText[ob]];
};
TransferImport:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] = {
--dirty
ip: CDImports.ImportSpecific ← NARROW[ob.specific];
newIp: CDImports.ImportSpecific ← NEW[CDImports.ImportRep←[ir: TRect[ip.ir], objectName: ip.objectName, designName: ip.designName]];
new ← NEW[CD.ObjectRep←ob^];
new.properties ← NIL;
new.specific ← newIp;
new.bbox ← TRect[new.bbox];
[] ← CDDirectory.Include[newDesign, new, CDDirectory.Name[ob]]
};
TransferPosList:
PROC [ob:
CD.Object]
RETURNS [newPl:
LIST
OF
CD.Position←
NIL, w:
CD.Number] = {
pp: CDCurves.CurveSpecific ← NARROW[ob.specific];
FOR pl:
LIST
OF
CD.Position ← pp.points, pl.rest
WHILE pl#
NIL
DO
newPl ← CONS[TPos[pl.first], newPl];
ENDLOOP;
w ← pp.w
};
TransferPolygon:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] = {
newPl: LIST OF CD.Position; w: CD.Number;
[newPl, w] ← TransferPosList[ob];
new ← CDCurves.CreatePolygon[newPl, CorrespondingLayer[ob.layer]].ob;
};
TransferLine:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] = {
newPl: LIST OF CD.Position; w: CD.Number;
[newPl, w] ← TransferPosList[ob];
new ← CDCurves.CreateLine[newPl, w, CorrespondingLayer[ob.layer]].ob;
};
TransferSpline:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] = {
newPl: LIST OF CD.Position; w: CD.Number;
[newPl, w] ← TransferPosList[ob];
new ← CDCurves.CreateSpline[newPl, w, CorrespondingLayer[ob.layer]].ob;
};
TransferFilledCurve:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] = {
newPl: LIST OF CD.Position; w: CD.Number;
[newPl, w] ← TransferPosList[ob];
new ← CDCurves.CreateFilledCurve[newPl, CorrespondingLayer[ob.layer]].ob;
};
TransferCell:
PROC [ob:
CD.Object]
RETURNS [new:
CD.Object] = {
EachInst: CDCells.InstEnumerator = {
newChild: CD.Object;
copy: CD.Instance;
position: CD.Position ← TPos[OriginPos[inst, MustOffsetOrigin[inst.ob]]];
newChild ← TransferAny[inst.ob];
IF newChild#
NIL
THEN {
copy ← CDCells.IncludeOb[design: NIL, cell: new, ob: newChild, trans: [position, inst.trans.orient], mode: dontResize].newInst;
CDProperties.AppendProps[winner: copy.properties, looser: inst.properties, putOnto: copy];
}
};
cp: CD.CellSpecific ← NARROW[ob.specific];
new ← CDCells.CreateEmptyCell[];
[] ← CDCells.EnumerateInstances[ob, EachInst];
IF cp.specifiedIr THEN CDCells.SetInterestRect[NIL, new, TRect[cp.ir]];
[] ← CDCells.ResizeCell[NIL, new];
CDProperties.AppendProps[winner: new.properties, looser: ob.properties, putOnto: new];
[] ← CDDirectory.Include[newDesign, new, CDDirectory.Name[ob]];
[] ← CDCells.SetSimplificationTreshhold[new];
};
ReallyTransfer:
PROC [ob:
CD.Object]
RETURNS [ob1:
CD.Object] = {
--all children of ob are already transfereed
ob1 ← TransferAny[ob]
};
TransferWithChildrenCheck:
PROC [ob:
CD.Object]
RETURNS [ob1
: CD.Object] = {
EachChild:
PROC [me:
CD.Object, x:
REF] = {
[] ← TransferWithChildrenCheck[me];
};
WITH CDProperties.GetProp[ob, correspondKey]
SELECT
FROM
obx: CD.Object => ob1 ← obx;
ENDCASE => {
CDDirectory.EnumerateChildObjects[ob, EachChild, NIL];
ob1 ← ReallyTransfer[ob];
CDProperties.PutProp[ob, correspondKey, ob1]
};
};
Transfer:
PROC [from:
CD.Design, tech:
CD.Technology]
RETURNS [nD:
CD.Design] = {
EachDirEl:
PROC [name: Rope.
ROPE, ob:
CD.Object]
RETURNS [quit:
BOOL←
FALSE] = {
[] ← TransferWithChildrenCheck[ob];
};
dummyOb, newDummyOb: CD.Object;
design ← from;
correspondKey ← NEW[INT];
oldTech ← from.technology;
newTech ← tech;
newDesign ← nD ← CDOps.CreateDesign[tech];
dummyOb ← CDCellsInteractions.MakeTopInstance[from].ob;
lambda ← oldTech.lambda;
newLambda ← newTech.lambda;
[] ← CDDirectory.Enumerate[design: from, action: EachDirEl];
newDummyOb ← TransferWithChildrenCheck[dummyOb];
[] ← CDCells.IncludeOb[design: newDesign, ob: newDummyOb];
CDCleanUp.RemoveProperties[from, correspondKey];
};
ProtectedTransferComm:
PROC [comm: CDSequencer.Command] = {
t: CD.Technology; d: CD.Design;
TerminalIO.PutRope["transfer technology\n"];
IF comm.design.technology.key#fromTechnologyKey
THEN {
TerminalIO.PutRope["not right ""from"" technology set up\n"];
ERROR ABORTED
};
t ← CD.FetchTechnology[toTechnologyKey];
IF t=
NIL
THEN {
TerminalIO.PutRope["the ""to"" technology is not loaded\n"];
ERROR ABORTED
};
[] ← CDCleanUp.CleanUp[comm.design];
d ← Transfer[comm.design, t];
[] ← CDViewer.CreateViewer[d];
};
TransferComm:
PROC [comm: CDSequencer.Command] = {
TerminalIO.PutRope["transfer technology\n"];
TerminalIO.PutRope["Has not been checked for this release\n"];
[] ← CDCommandOps.DoWithResource[
proc: ProtectedTransferComm,
comm: comm,
resource: $CDTransferTecnology
];
};
CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "convert technology", proc: TransferComm, key: $CDConvertTechnologiesX, doc: "MUST set up technologies with command file first"];
END.