SinixAmorph.mesa
Barth, July 25, 1989 2:44:42 pm PDT
Last Edited by: Gasbarro June 23, 1989 5:32:06 pm PDT
DIRECTORY CD, CDBasics, CDCells, CMosB, Core, CoreClasses, CoreGeometry, CoreOps, CoreProperties, Sinix, SinixImpl, StructureColor;
SinixAmorph: CEDAR PROGRAM
IMPORTS CDBasics, CDCells, CMosB, CoreClasses, CoreGeometry, CoreOps, CoreProperties, Sinix, SinixImpl
SHARES SinixImpl
= BEGIN
ExtractAmorphTransistor: PUBLIC Sinix.ExtractProc = {
result ← SinixImpl.SearchObjectCache[obj, mode, userData];
IF result=NIL THEN {
EachInstance: CDCells.InstEnumerator = {
IF NOT ISTYPE[inst.ob.specific, CD.RectSpecific] THEN ERROR;
SELECT inst.ob.layer FROM
CMosB.pol, CMosB.pwell => {
IF gateFound THEN ERROR;
gateFound ← TRUE;
gateLayout ← [inst.ob, inst.trans];
};
CMosB.pwellCont => {
IF islandFound THEN ERROR;
islandFound ← TRUE;
islandLayout ← [inst.ob, inst.trans];
};
CMosB.ndif => {
IF ch1Found THEN {
IF ch2Found THEN ERROR;
ch2Found ← TRUE;
ch2Layout ← [inst.ob, inst.trans];
}
ELSE {
ch1Found ← TRUE;
ch1Layout ← [inst.ob, inst.trans];
};
};
ENDCASE => ERROR;
};
Decorate: PROC [port: CoreClasses.TransistorPort, instance: CoreGeometry.Instance] = {
wire: Core.Wire = cellType.public[ORD [port]];
CoreGeometry.PutPins[mode.decoration, wire, LIST[instance]];
CoreGeometry.PutGeometry[mode.decoration, wire, LIST[instance]];
};
cellType: Core.CellType;
gateFound, ch1Found, ch2Found, islandFound: BOOLFALSE;
gateLayout, ch1Layout, ch2Layout, islandLayout: CoreGeometry.Instance;
mappedCh1, mappedCh2: 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];
IF mappedCh1.y1 # mappedCh2.y1 OR mappedCh1.y2 # mappedCh2.y2 THEN ERROR;
IF mappedCh1.x2 > mappedCh2.x1 THEN {
tRect: CD.Rect ← mappedCh2;
tInstance: CoreGeometry.Instance ← ch2Layout;
mappedCh2 ← mappedCh1;
mappedCh1 ← tRect;
ch2Layout ← ch1Layout;
ch1Layout ← tInstance;
};
length ← (mappedCh2.x1 - mappedCh1.x2)/CMosB.lambda;
width ← (mappedCh2.y2 - mappedCh2.y1)/CMosB.lambda;
cellType ← CoreClasses.CreateTransistor[
type: nE, length: length, width: width,
props: CoreProperties.Props[[CoreOps.nameProp, Sinix.NameFromSatellites[obj, properties]], [$SinixAmorphType, IF gateLayout.obj.layer=CMosB.pol THEN $LowVoltage ELSE $HighVoltage]]];
Decorate[gate, gateLayout];
Decorate[ch1, ch1Layout];
Decorate[ch2, ch2Layout];
CoreGeometry.PutObject[mode.decoration, cellType, obj];
result ← cellType;
SinixImpl.AddInCache[obj, mode, userData, result];
};
};
ExtractAmorphResistor: PUBLIC Sinix.ExtractProc = {
result ← SinixImpl.SearchObjectCache[obj, mode, userData];
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 => {
IF ch1Found THEN {
IF ch2Found THEN ERROR;
ch2Found ← TRUE;
ch2Layout ← [inst.ob, inst.trans];
}
ELSE {
ch1Found ← TRUE;
ch1Layout ← [inst.ob, inst.trans];
};
};
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: BOOLFALSE;
gateLayout, ch1Layout, ch2Layout: CoreGeometry.Instance;
mappedCh1, mappedCh2: 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];
IF mappedCh1.y1 # mappedCh2.y1 OR mappedCh1.y2 # mappedCh2.y2 THEN ERROR;
IF mappedCh1.x2 > mappedCh2.x1 THEN {
tRect: CD.Rect ← mappedCh2;
tInstance: CoreGeometry.Instance ← ch2Layout;
mappedCh2 ← mappedCh1;
mappedCh1 ← tRect;
ch2Layout ← ch1Layout;
ch1Layout ← tInstance;
};
length ← (mappedCh2.x1 - mappedCh1.x2)/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, ch2Layout];
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];
};
};
ExtractPolyResistor: PUBLIC Sinix.ExtractProc = {
result ← SinixImpl.SearchObjectCache[obj, mode, userData];
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: BOOLFALSE;
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];
};
};
resistorColorer: StructureColor.Colorer ← NEW[StructureColor.ColorerPrivate ← [
CellTypeColor: ResistorColor,
ColorPorts: ResistorPortColor]];
ResistorColor: PROC [ct: Core.CellType] RETURNS [StructureColor.Color] = {
RETURN[LOOPHOLE[resistorColorer]];
};
ResistorPortColor: PROC [ct: Core.CellType, SetColor: PROC [Core.Wire, StructureColor.Color]] = {
IF ct.public.size#2 THEN ERROR;
IF ct.public[0].size#0 THEN ERROR;
SetColor[ct.public[0], 1];
IF ct.public[1].size#0 THEN ERROR;
SetColor[ct.public[1], 1];
};
Sinix.RegisterExtractProc[$ExtractAmorphTransistor, ExtractAmorphTransistor];
Sinix.RegisterExtractProc[$ExtractAmorphResistor, ExtractAmorphResistor];
Sinix.RegisterExtractProc[$ExtractPolyResistor, ExtractPolyResistor];
END.