IntanceToPObj:
PROC [instance: CoreGeometry.Instance]
RETURNS [po: PObj] = {
IF instance.trans.orient=original THEN RETURN [[instance.obj, instance.trans.off]];
po.object ←
SELECT
TRUE
FROM
instance.obj.class=CDRects.bareRectClass => CDRects.CreateRect[CDBasics.OrientedSize[CD.InterestSize[instance.obj], instance.trans.orient], instance.obj.layer],
instance.obj.class.atomicOb => CDAtomicObjects.CreateAtomicOb[instance.obj.class.objectType, CDBasics.OrientedSize[CD.InterestSize[instance.obj], instance.trans.orient], CMosB.cmosB, instance.obj.layer],
ENDCASE => PW.CreateRotation[instance.obj, instance.trans.orient];
po.position ← CDBasics.SubPoints[CDBasics.BaseOfRect[CoreGeometry.BBox[instance]], CDBasics.BaseOfRect[CoreGeometry.BBox[[po.object, []]]]];
};
Translator1: Rope.TranslatorType = {
RETURN [SELECT old FROM '*, '[, '], '., '/ => '$, ENDCASE => old];
};
SimplifyPObj:
PROC [pobjs:
LIST
OF PObj]
RETURNS [news:
LIST
OF PObj ←
NIL]= {
changed: BOOL ← TRUE;
count: NAT ← 0;
seq: REF PObjSeq;
FOR list: LIST OF PObj ← pobjs, list.rest WHILE list#NIL DO count ← count + 1 ENDLOOP;
seq ← NEW [PObjSeq[count]];
FOR i: NAT IN [0 .. count) DO seq[i] ← pobjs.first; pobjs ← pobjs.rest ENDLOOP;
WHILE changed
AND count>0
DO
changed ← FALSE;
FOR i:
NAT
IN [0 .. count-1)
DO
IF seq[i].object#
NIL
THEN
FOR j:
NAT
IN (i .. count)
DO
The following statement does NOT work!!!
IF seq[j].object#
NIL
AND seq[i].object.class=CDRects.bareRectClass
AND seq[j].object.class=CDRects.bareRectClass
AND seq[i].object.layer=seq[j].object.layer
AND Fusable[BBox[seq[i]], BBox[seq[j]]]
THEN {
fused: CD.Rect = CDBasics.Surround[BBox[seq[i]], BBox[seq[j]]];
seq[i] ← [
object: CDRects.CreateRect[CDBasics.SizeOfRect[fused], seq[i].object.layer],
position: CDBasics.BaseOfRect[fused]
];
seq[j].object ← NIL; changed ← TRUE;
}
ENDLOOP;
ENDLOOP;
ENDLOOP;
FOR i:
NAT
IN [0 .. count)
DO
IF seq[i].object#NIL THEN news ← CONS [seq[i], news];
ENDLOOP;
};
ToRoutingCell:
PROC [obj:
CD.Object]
RETURNS [routing:
CD.Object] = {
FiddleName: SymTab.EachPairAction = {
name: ROPE = IF Rope.Find[key, "public."]=0 THEN Rope.Substr[key, 7] ELSE key;
pobjs: REF LIST OF PObj = NARROW [val];
new:
ROPE =
SELECT
TRUE
FROM
Rope.Fetch[name]='[ => Rope.Translate[base: name, translator: Translator1],
Rope.Find[name, "*"]<0 AND Rope.Find[name, "/"]<0 => name,
ENDCASE => Rope.Translate[base: name, translator: Translator2];
IF pobjs^=NIL THEN ERROR; -- there should be at least one piece of geometry per wire.
IF
NOT Rope.Equal[new, name]
THEN
TerminalIO.PutF["** Flat wire %g replaced by %g.\n", IO.rope[key], IO.rope[new]];
pobjs^ ← SimplifyPObj[pobjs^];
[] ← SymTab.Store[nodes, new, val];
};
EachFlatWire: CoreGeometry.EachFlatWireProc = {
EachInstance: CoreGeometry.EachInstanceProc = {
geometry^ ← CONS [IntanceToPObj[CoreGeometry.Transform[trans, instance]], geometry^];
};
name: ROPE ← CoreFlat.WirePathRope[ct, flatWire];
geometry: REF LIST OF PObj ← NARROW [SymTab.Fetch[table, name].val];
IF geometry=NIL THEN {geometry ← NEW [LIST OF PObj ← NIL]; [] ← SymTab.Store[table, name, geometry]};
[] ← CoreGeometry.EnumerateGeometry[SinixRawCMosB.mode.decoration, wire, EachInstance];
};
table: SymTab.Ref ← SymTab.Create[]; -- Table FlatWireRope -> REF LIST OF PObj
nodes: SymTab.Ref ← SymTab.Create[]; -- Table Real names -> REF LIST OF PObj
result: REF = Sinix.Extract[obj, SinixRawCMosB.mode, NIL, NEW [INT ← 40]].result;
ct: Core.CellType;
IF result=NIL OR NOT ISTYPE[result, Core.CellType] THEN ERROR;
ct ← NARROW [result];
[] ← CoreGeometry.EnumerateFlatGeometry[SinixRawCMosB.mode.decoration, ct, Leaf, EachFlatWire];
We change all names that contain *[]/. if any!
[] ← SymTab.Pairs[table, FiddleName];
The final cell
routing ← CDRoutingObjects.CreateRoutingObject[CDRoutingObjects.CreateNodes[nodes], CD.InterestRect[obj]];
TerminalIO.PutF["Object %g translated to routing: %g nodes.\n", IO.rope[PW.Name[obj]], IO.int[SymTab.GetSize[table]]];
};