IF result=
NIL
THEN {
EachInstance: CDCells.InstEnumerator = {
IF NOT ISTYPE[inst.ob.specific, CD.RectSpecific] THEN ERROR;
SELECT inst.ob.layer
FROM
CMosB.bur => {
IF gateFound THEN ERROR;
gateFound ← TRUE;
gateLayout ← [inst.ob, inst.trans];
};
CMosB.ndif => {
SELECT
FALSE
FROM
ch1Found => {ch1Found ← TRUE; ch1Layout ← [inst.ob, inst.trans]};
ch2Found => {ch2Found ← TRUE; ch2Layout ← [inst.ob, inst.trans]};
ch3Found => {ch3Found ← TRUE; ch3Layout ← [inst.ob, inst.trans]};
ENDCASE => ERROR;
};
ENDCASE => ERROR;
};
Decorate:
PROC [port:
INT, instance: CoreGeometry.Instance] = {
wire: Core.Wire = cellType.public[port];
CoreGeometry.PutPins[mode.decoration, wire, LIST[instance]];
CoreGeometry.PutGeometry[mode.decoration, wire, LIST[instance]];
};
cellType: Core.CellType;
gateFound, ch1Found, ch2Found, ch3Found: BOOL ← FALSE;
gateLayout, ch1Layout, ch2Layout, ch3Layout: CoreGeometry.Instance;
mappedCh1, mappedCh2, mappedCh3: CD.Rect;
leftC, midC, rightC: CoreGeometry.Instance;
leftMC, midMC, rightMC: CD.Rect;
length, width: INT ← 0;
[] ← CDCells.EnumerateInstances[obj, EachInstance];
mappedCh1 ← CDBasics.MapRect[ch1Layout.obj.bbox, ch1Layout.trans];
mappedCh2 ← CDBasics.MapRect[ch2Layout.obj.bbox, ch2Layout.trans];
mappedCh3 ← CDBasics.MapRect[ch3Layout.obj.bbox, ch3Layout.trans];
IF mappedCh1.y1 # mappedCh2.y1 OR mappedCh2.y1 # mappedCh3.y1 OR
mappedCh1.y2 # mappedCh2.y2 OR mappedCh2.y2 # mappedCh3.y2
THEN ERROR;
SELECT
TRUE
FROM
mappedCh1.x2 = mappedCh2.x1 AND mappedCh2.x2 = mappedCh3.x1 => {
leftC ← ch1Layout; midC ← ch2Layout; rightC ← ch3Layout;
leftMC ← mappedCh1; midMC ← mappedCh2; rightMC ← mappedCh3
};
mappedCh1.x2 = mappedCh3.x1 AND mappedCh3.x2 = mappedCh2.x1 => {
leftC ← ch1Layout; midC ← ch3Layout; rightC ← ch2Layout;
leftMC ← mappedCh1; midMC ← mappedCh3; rightMC ← mappedCh2
};
mappedCh2.x2 = mappedCh1.x1 AND mappedCh1.x2 = mappedCh3.x1 => {
leftC ← ch2Layout; midC ← ch1Layout; rightC ← ch3Layout;
leftMC ← mappedCh2; midMC ← mappedCh1; rightMC ← mappedCh3
};
mappedCh2.x2 = mappedCh3.x1 AND mappedCh3.x2 = mappedCh1.x1 => {
leftC ← ch2Layout; midC ← ch3Layout; rightC ← ch1Layout;
leftMC ← mappedCh2; midMC ← mappedCh3; rightMC ← mappedCh1
};
mappedCh3.x2 = mappedCh1.x1 AND mappedCh1.x2 = mappedCh2.x1 => {
leftC ← ch3Layout; midC ← ch1Layout; rightC ← ch2Layout;
leftMC ← mappedCh3; midMC ← mappedCh1; rightMC ← mappedCh2
};
mappedCh3.x2 = mappedCh2.x1 AND mappedCh2.x2 = mappedCh2.x1 => {
leftC ← ch3Layout; midC ← ch2Layout; rightC ← ch1Layout;
leftMC ← mappedCh3; midMC ← mappedCh2; rightMC ← mappedCh1
};
ENDCASE => ERROR; --rectangles do not abut
ch1Layout ← leftC;
ch2Layout ← midC;
ch3Layout ← rightC;
mappedCh1 ← leftMC;
mappedCh2 ← midMC;
mappedCh3 ← rightMC;
length ← (mappedCh2.x2 - mappedCh2.x1)/CMosB.lambda;
width ← (mappedCh2.y2 - mappedCh2.y1)/CMosB.lambda;
cellType ← CoreClasses.CreateUnspecified[
public: CoreOps.CreateWire[LIST[CoreOps.CreateWire[name: "r1"], CoreOps.CreateWire[name: "r2"]]],
props: CoreProperties.Props[[CoreOps.nameProp, Sinix.NameFromSatellites[obj, properties]], [$ResistorLength, NEW[INT ← length]], [$ResistorWidth, NEW[INT ← width]]]];
Decorate[0, ch1Layout];
Decorate[1, ch3Layout];
CoreProperties.PutCellTypeProp[cellType, StructureColor.ColorerProp, resistorColorer];
CoreProperties.PutCellTypeProp[cellType, $CoreStructureColorer, resistorColorer]; -- hack, eliminates load dependency on StructuralComparison
CoreGeometry.PutObject[mode.decoration, cellType, obj];
result ← cellType;
SinixImpl.AddInCache[obj, mode, userData, result];
};