-- ChipExpandAtomic.mesa -- A package to expand atomic Chipmonk cell geometries, -- such as transistors and contacts, for circuit extraction. -- last modified by E. McCreight, November 5, 1982 11:22 AM -- written by E. McCreight, March 17, 1982 10:28 AM DIRECTORY ChipDRC, ChipExpand, ChipNetDefs, ppdefs; ChipExpandAtomic: PROGRAM IMPORTS ChipDRC, ChipExpand, ChipNetDefs EXPORTS ChipExpand SHARES ChipExpand = BEGIN OPEN ppdefs, ChipNetDefs, ChipDRC, ChipExpand; -- Procedures copied from Chipmonk and changed slightly -- for design rule checking and circuit extraction. The main -- difference here is that pol and dif are not allowed -- to overlap at all. exXstr0: PUBLIC drProc = BEGIN p: LONG POINTER TO xstr object = LOOPHOLE[ob]; IF p.l=pdif THEN pr.orArea[x-p.surround+p.wExt, y-p.surround, x+p.size[0]+p.surround-p.wExt, y+p.size[1]+p.surround, nwel, @pr.r]; IF x > pr.r.x2 OR y > pr.r.y2 OR x + p.size[0] < pr.r.x1 OR y + p.size[1] < pr.r.y1 THEN RETURN; -- IF p.lExt>0 THEN BEGIN -- make 0-length source/drain terminals anyway joinTo ← @xstrInst.map[drain]; pr.orArea[x + p.wExt, y, x + p.width + p.wExt, y + p.lExt, p.l, @pr.r]; -- "drain" dif joinTo ← @xstrInst.map[source]; pr.orArea[x + p.wExt, y + p.length + p.lExt, x + p.width + p.wExt, y + p.size[1], p.l, @pr.r]; -- "source" dif END; joinTo ← @xstrInst.map[gate]; pr.orArea[x, y + p.lExt, x + p.size[0], y + p.length + p.lExt, pol, @pr.r]; -- gate IF doingDRC THEN BEGIN ExtractorFeature.p[x+p.wExt, y+p.lExt, x+p.width+p.wExt, y + p.length + p.lExt, (IF p.l=dif THEN nGate ELSE pGate)]; IF p.wExt<polyGateOverlap THEN BEGIN ExtractorFeature.p[x-polyGateOverlap+p.wExt, y+p.lExt, x, y + p.length + p.lExt, polyRequired]; ExtractorFeature.p[x+p.size[0], y+p.lExt, x+p.size[0]+polyGateOverlap-p.wExt, y + p.length + p.lExt, polyRequired]; END; IF p.lExt<minTransistorDiffusionWidth THEN BEGIN ExtractorFeature.p[x+p.wExt, y-minTransistorDiffusionWidth+p.lExt, x+p.width+p.wExt, y, (IF p.l=dif THEN nPlusRequired ELSE pPlusRequired)]; ExtractorFeature.p[x+p.wExt, y + p.size[1], x+p.width+p.wExt, y + p.length + p.lExt+minTransistorDiffusionWidth, (IF p.l=dif THEN nPlusRequired ELSE pPlusRequired)]; END; ExtractorFeature[x+p.wExt-depletionOverlap, y+p.lExt-depletionOverlap, x+p.width+p.wExt+depletionOverlap, y + p.length + p.lExt+depletionOverlap, (IF p.impl THEN nDepletionRequired ELSE nDepletionForbidden)]; END; IF p.impl THEN pr.orArea[x+p.wExt-depletionOverlap, y+p.lExt-depletionOverlap, x + p.size[0]-p.wExt+depletionOverlap, y + p.size[1]-p.lExt+depletionOverlap, imp, @pr.r]; END; exAXstr0: PUBLIC drProc = BEGIN p: LONG POINTER TO xstr object = LOOPHOLE[ob]; ele: locNum; hPoly, vPoly, nDrain, eDrain, wSource, sSource: Rect; IF x > pr.r.x2 OR y > pr.r.y2 OR x + p.size[0] < pr.r.x1 OR y + p.size[1] < pr.r.y1 THEN RETURN; ele ← 2*p.lExt+p.length; -- length and two length extensions -- The transistor makes a 90-degree bend, going eastward and -- then southward. The diffusion on the outer side of the angle, -- that is, on the northeast side, is arbitrarily called the drain. hPoly ← [x1: x, y1: y+p.lExt, x2: x+p.size[0]-p.lExt, y2: y+p.length+p.lExt]; vPoly ← [x1: x+p.size[0]-p.length-p.lExt, y1: hPoly.y2, x2: hPoly.x2, y2: y+p.size[1]]; nDrain ← [x1: x+p.wExt, y1: y, x2: x+p.size[0], y2: hPoly.y1]; eDrain ← [x1: vPoly.x2, y1: nDrain.y2, x2: nDrain.x2, y2: y+p.size[1]-p.wExt]; wSource ← [ x1: x+p.size[0]-ele, y1: hPoly.y2, x2: vPoly.x1, y2: y+p.size[1]-p.wExt]; sSource ← [x1: x+MIN[p.wExt, p.size[0]-ele], y1: hPoly.y2, x2: wSource.x1, y2: y+MIN[ele, p.size[1]-p.wExt]]; -- We are willing to put out 0-width wires here -- so that other conductors can join onto them, -- and so that design rule checking can work. joinTo ← @xstrInst.map[drain]; pr.orArea[nDrain.x1, nDrain.y1, nDrain.x2, nDrain.y2, dif, @pr.r]; -- north "drain" dif pr.orArea[eDrain.x1, eDrain.y1, eDrain.x2, eDrain.y2, dif, @pr.r]; -- east "drain" dif joinTo ← @xstrInst.map[source]; pr.orArea[wSource.x1, wSource.y1, wSource.x2, wSource.y2, dif, @pr.r]; -- west "source" dif IF sSource.x1<sSource.x2 THEN pr.orArea[sSource.x1, sSource.y1, sSource.x2, sSource.y2, dif,@pr.r]; -- south "source" dif joinTo ← @xstrInst.map[gate]; pr.orArea[hPoly.x1, hPoly.y1, hPoly.x2, hPoly.y2, pol, @pr.r]; -- horizontal gate IF vPoly.y1<vPoly.y2 THEN pr.orArea[vPoly.x1, vPoly.y1, vPoly.x2, vPoly.y2, pol, @pr.r]; -- vertical gate IF doingDRC THEN BEGIN reqLev: ExtractLevel ← IF p.l=dif THEN nPlusRequired ELSE pPlusRequired; ExtractorFeature.p[sSource.x1, hPoly.y1, hPoly.x2, hPoly.y2, (IF p.l=dif THEN nGate ELSE pGate)]; -- horizontal ExtractorFeature.p[vPoly.x1, vPoly.y1, vPoly.x2, wSource.y2, (IF p.l=dif THEN nGate ELSE pGate)]; -- vertical IF sSource.x1-hPoly.x1<polyGateOverlap THEN ExtractorFeature.p[ sSource.x1-polyGateOverlap, hPoly.y1, hPoly.x1, hPoly.y2, polyRequired]; -- horizontal IF vPoly.y2-wSource.y2<polyGateOverlap THEN ExtractorFeature.p[vPoly.x1, vPoly.y2, vPoly.x2, wSource.y2+polyGateOverlap, polyRequired]; -- vertical IF p.lExt<minTransistorDiffusionWidth THEN BEGIN ExtractorFeature.p[ nDrain.x1, nDrain.y2-minTransistorDiffusionWidth, eDrain.x1+minTransistorDiffusionWidth, nDrain.y1, reqLev]; -- north drain ExtractorFeature.p[ eDrain.x2, eDrain.y1, eDrain.x1+minTransistorDiffusionWidth, eDrain.y2, reqLev]; -- east drain END; IF wSource.x2-wSource.x1<minTransistorDiffusionWidth THEN ExtractorFeature.p[ wSource.x2-minTransistorDiffusionWidth, wSource.y1, wSource.x1, MAX[wSource.y2, wSource.y1+minTransistorDiffusionWidth], reqLev]; -- west source IF sSource.x1<sSource.x2 AND sSource.y2-sSource.y1<minTransistorDiffusionWidth THEN ExtractorFeature.p[ sSource.x1, sSource.y2, sSource.x2, sSource.y1+minTransistorDiffusionWidth, reqLev]; -- south source END; IF p.impl THEN BEGIN pr.orArea[nDrain.x1-depletionOverlap, hPoly.y1-depletionOverlap, hPoly.x2+depletionOverlap, hPoly.y2+depletionOverlap, imp, @pr.r]; pr.orArea[vPoly.x1-depletionOverlap, vPoly.y1-depletionOverlap, vPoly.x2+depletionOverlap, eDrain.y2+depletionOverlap, imp, @pr.r]; END ELSE IF doingDRC THEN BEGIN ExtractorFeature.p[ sSource.x1-depletionOverlap, hPoly.y1-depletionOverlap, hPoly.x2+depletionOverlap, hPoly.y2+depletionOverlap, nDepletionForbidden]; -- horizontal ExtractorFeature.p[ vPoly.x1-depletionOverlap, vPoly.y1-depletionOverlap, vPoly.x2+depletionOverlap, wSource.y2+depletionOverlap, nDepletionForbidden]; -- vertical END; END; -- of exAXstr0 exPu0: PUBLIC drProc = BEGIN p: LONG POINTER TO xstr object = LOOPHOLE[ob]; xx, yy: INTEGER; id: NormalNetIdPtr; xstrInst.map[gate] ← xstrInst.map[source] ← NewNet[initRefs: 2]; id ← GetNormalNetId[@xstrInst.map[gate]]; id.source ← NearestCellInstance[xstrInst]; id.couldBeLogo ← FALSE; IF x > pr.r.x2 OR y > pr.r.y2 OR x + p.size[0] < pr.r.x1 OR y + p.size[1] < pr.r.y1 THEN RETURN; xx ← x + p.wExt; yy ← y + p.lExt; -- IF p.lExt>0 THEN BEGIN joinTo ← @xstrInst.map[drain]; pr.orArea[xx, y, xx + p.width, y + p.lExt, dif, @pr.r]; -- "drain" dif END; joinTo ← @xstrInst.map[gate]; pr.orArea[x, yy, x + p.size[0], yy + p.length, pol, @pr.r]; pr.orArea[x, y, x + p.size[0], yy + p.length + p.lExt, imp, @pr.r]; xx ← x + p.size[0]/2 - butconSX/2; yy ← y + p.size[1]; joinTo ← @xstrInst.map[source]; pr.orArea[xx, y+p.lExt+p.length, xx + butconSX, yy, dif, @pr.r]; -- "source" dif joinTo ← @xstrInst.map[gate]; pr.orArea[xx, yy - butconSY, xx + butconSX, yy, met, @pr.r]; xx ← xx + butconSX/4; yy ← yy - butconSX/4; pr.saveArea[xx, yy - butconSX, xx + butconSX/2, yy, cut, @pr.r]; END; exBC0: PUBLIC drProc = BEGIN p: LONG POINTER TO cont object = LOOPHOLE[ob]; IF x > pr.r.x2 OR y > pr.r.y2 OR x + p.size[0] < pr.r.x1 OR y + p.size[1] < pr.r.y1 THEN RETURN; pr.orArea[x, y, x + p.size[0], y + p.size[1], met, @pr.r]; pr.orArea[x, y, x + p.size[0], y + p.size[1]/2, pol, @pr.r]; pr.orArea[x, y + p.size[1]/2, x + p.size[0], y + p.size[1], dif, @pr.r]; pr.saveArea[ x + p.magicN, y + p.magicN, x - p.magicN + p.size[0], y + p.magicN + p.size[0], cut, @pr.r]; END; exBuC0: PUBLIC drProc = BEGIN p: LONG POINTER TO cont object = LOOPHOLE[ob]; IF x > pr.r.x2 OR y > pr.r.y2 OR x + p.size[0] < pr.r.x1 OR y + p.size[1] < pr.r.y1 THEN RETURN; pr.orArea[x+p.wExt,y,x+p.size[0]-p.wExt+p.magicN,y+p.size[1], pol, @pr.r]; pr.orArea[x,y+p.lExt,x+p.size[0],y+p.size[1]-p.lExt, dif, @pr.r]; pr.saveArea[x,y,x+p.size[0],y+p.size[1],bur,@pr.r]; END; END. -- of ChipExpandAtomic