📄 techtype.java
字号:
package com.sun.electric.tool.generator.layout;import java.io.Serializable;import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Iterator;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.SizeOffset;import com.sun.electric.technology.Technology;/** The TechType class holds technology dependent information for the layout * generators. Most of the information is available from public static methods. * <p> The TechType class queries the appropriate Technology object to get * references to prototypes commonly used by the layout generators such as the * metal 1 arc proto or the metal 1 pin proto. The Tech class also holds * technology dependant dimensions such as the width of a diffusion contact. * <p> The TechType class serves two purposes. First, it makes it convenient * to access technology dependent information. Second, it hides foundry * specific information that we're not allowed to distribute as open source * software. */public abstract class TechType implements Serializable { private static class ArcPair implements Serializable { private static final long serialVersionUID = 0; private ArcProto arc1, arc2; public ArcPair(ArcProto a1, ArcProto a2) {arc1=a1; arc2=a2;} @Override public boolean equals(Object o) { if (!(o instanceof ArcPair)) return false; ArcPair ap = (ArcPair)o; if (ap.arc1==arc1 && ap.arc2==arc2) return true; if (ap.arc1==arc2 && ap.arc2==arc1) return true; return false; } @Override public int hashCode() {return arc1.hashCode()*arc2.hashCode();} } //----------------------------- public data ---------------------------------- private static final Variable.Key ATTR_X = Variable.newKey("ATTR_X"); private static final Variable.Key ATTR_S = Variable.newKey("ATTR_S"); private static final Variable.Key ATTR_SN = Variable.newKey("ATTR_SN"); private static final Variable.Key ATTR_SP = Variable.newKey("ATTR_SP"); private final Technology generic = Technology.findTechnology("generic"); private final Technology technology; private final TechTypeEnum techEnum; private final PrimitiveNode essentialBounds = generic.findNodeProto("Essential-Bounds"); private final PrimitiveNode facetCenter = generic.findNodeProto("Facet-Center"); private final int nbLay; private final ArcProto[] layers; private final PrimitiveNode[] vias; private final HashMap<ArcPair,PrimitiveNode> viaMap = new HashMap<ArcPair,PrimitiveNode>(); /** layers * * Poly and metal are considered to be routing layers. In contrast * we assume we never want to route in diffusion or well. This * allows us to assign a unique "height" to each of the routing * layers. Layers at the same height can connect directly. Layers * at adjacent heights can connect using vias. * * For now, well and diffusion don't have heights. */ private final ArcProto pdiff, ndiff, p1, m1, m2, m3, m4, m5, m6, m7, m8, m9, ndiff18, pdiff18, ndiff25, pdiff25, ndiff33, pdiff33; /** layer pins */ private final PrimitiveNode ndpin, pdpin, p1pin, m1pin, m2pin, m3pin, m4pin, m5pin, m6pin, m7pin, m8pin, m9pin; /** vias */ private final PrimitiveNode nwm1, pwm1, nwm1Y, pwm1Y, ndm1, pdm1, p1m1, m1m2, m2m3, m3m4, m4m5, m5m6, m6m7, m7m8, m8m9; /** Transistors */ private final PrimitiveNode nmos, pmos, nmos18, pmos18, nmos25, pmos25, nmos33, pmos33; // nvth, pvth, nvtl, pvtl, nnat, pnat; /** special threshold transistor contacts */ private final PrimitiveNode nmos18contact, pmos18contact, nmos25contact, pmos25contact, nmos33contact, pmos33contact; /** Pure layer nodes for Well and Select */ private final PrimitiveNode nwell, pwell; /** Layer nodes are sometimes used to patch notches */ private final PrimitiveNode m1Node, m2Node, m3Node, m4Node, m5Node, m6Node, m7Node, m8Node, m9Node, p1Node, pdNode, ndNode, pselNode, nselNode; /** Transistor layer nodes */ private final PrimitiveNode od18, od25, od33, vth, vtl; //-------------------- Technology dependent dimensions ------------------- protected double // Gilda: gate length depending on foundry gateLength, // Wire offset from center of the poly contact to form a L-shape arc to gate offsetLShapePolyContact, offsetTShapePolyContact, // denote Select spacing rule selectSpace, // surround distance of select from active in transistor selectSurroundDiffInTrans, selectSurroundDiffAlongGateInTrans, // select surround over poly. PP/NP.R.1 in 90nm selectSurround; // RKao my first attempt to embed technology specific dimensions protected double wellSurroundDiff, gateExtendPastMOS, p1Width, p1ToP1Space, gateToGateSpace, gateToDiffContSpace, gateToDiffContSpaceDogBone, selectSurroundDiffInActiveContact, // select surround in active contacts m1MinArea, // min area rules, sq lambda diffCont_m1Width, // width of m1 of min sized diff contact diffContIncr; // when diff cont increases by diffContIncr, // we get an additional cut //----------------------------- private methods ----------------------------- private static void error(boolean pred, String msg) { LayoutLib.error(pred, msg); } private ArcProto getLayer(int n) { return n>(layers.length-1) ? null : layers[n]; } private PrimitiveNode getVia(int n) { return n>(vias.length-1) ? null : vias[n]; } /** * get the PrimitiveNode of a particular type that connects to the * complete set of wires given */ private PrimitiveNode findNode(PrimitiveNode.Function type, ArcProto[] arcs, Technology tech) { for (Iterator<PrimitiveNode> it=tech.getNodes(); it.hasNext();) { PrimitiveNode pn = it.next(); boolean found = true; if (pn.getFunction() == type) { for (int j=0; j<arcs.length; j++) { if (pn.connectsTo(arcs[j]) == null) { found = false; break; } } if (found) return pn; } } return null; } private PrimitiveNode findPin(ArcProto arc) { return arc==null ? null : arc.findPinProto(); } private void putViaMap(ArcProto arc1, ArcProto arc2, PrimitiveNode via) { if (arc1==null || arc2==null || via==null) return; ArcPair ap = new ArcPair(arc1, arc2); error(viaMap.containsKey(ap), "two contacts for same pair of arcs?"); viaMap.put(ap, via); } // initialize map from pair of layers to via that connects them private void initViaMap() { putViaMap(m1, m2, m1m2); putViaMap(m2, m3, m2m3); putViaMap(m3, m4, m3m4); putViaMap(m4, m5, m4m5); putViaMap(m5, m6, m5m6); putViaMap(m6, m7, m6m7); putViaMap(m7, m8, m7m8); putViaMap(m8, m9, m8m9); putViaMap(ndiff, m1, ndm1); putViaMap(pdiff, m1, pdm1); putViaMap(p1, m1, p1m1); } protected TechType(Technology techy, TechTypeEnum techEnum, String[] layerNms) { // This error could happen when there are XML errors while uploading the technologies. error((techy==null), "Null technology in TechType constructor"); // I can't break this into subroutines because most data members are // final. nbLay = layerNms.length; technology = techy; this.techEnum = techEnum; //--------------------------- initialize layers ----------------------- layers = new ArcProto[nbLay]; for (int i=0; i<nbLay; i++) { layers[i] = techy.findArcProto(layerNms[i]); error(layers[i]==null, "No such layer: " + layerNms[i] + " in technology " + techy.getTechName()); } p1 = getLayer(0); m1 = getLayer(1); m2 = getLayer(2); m3 = getLayer(3); m4 = getLayer(4); m5 = getLayer(5); m6 = getLayer(6); m7 = getLayer(7); m8 = getLayer(8); m9 = getLayer(9); pdiff = techy.findArcProto("P-Active"); ndiff = techy.findArcProto("N-Active"); ndiff18 = techy.findArcProto("thick-OD18-N-Active"); pdiff18 = techy.findArcProto("thick-OD18-P-Active"); ndiff25 = techy.findArcProto("thick-OD25-N-Active"); pdiff25 = techy.findArcProto("thick-OD25-P-Active"); ndiff33 = techy.findArcProto("thick-OD33-N-Active"); pdiff33 = techy.findArcProto("thick-OD33-P-Active"); // Layer Nodes m1Node = techy.findNodeProto("Metal-1-Node"); m2Node = techy.findNodeProto("Metal-2-Node"); m3Node = techy.findNodeProto("Metal-3-Node"); m4Node = techy.findNodeProto("Metal-4-Node"); m5Node = techy.findNodeProto("Metal-5-Node"); m6Node = techy.findNodeProto("Metal-6-Node"); m7Node = techy.findNodeProto("Metal-7-Node"); m8Node = techy.findNodeProto("Metal-8-Node"); m9Node = techy.findNodeProto("Metal-9-Node"); p1Node = techy.findNodeProto("Polysilicon-1-Node"); pdNode = techy.findNodeProto("P-Active-Node"); ndNode = techy.findNodeProto("N-Active-Node"); nselNode = techy.findNodeProto("N-Select-Node"); pselNode = techy.findNodeProto("P-Select-Node"); //--------------------------- initialize pins ------------------------- pdpin = findPin(pdiff); ndpin = findPin(ndiff); p1pin = findPin(p1); m1pin = findPin(m1); m2pin = findPin(m2); m3pin = findPin(m3); m4pin = findPin(m4); m5pin = findPin(m5); m6pin = findPin(m6); m7pin = findPin(m7); m8pin = findPin(m8); m9pin = findPin(m9); //--------------------------- initialize vias ------------------------- vias = new PrimitiveNode[nbLay - 1]; for (int i = 0; i < nbLay - 1; i++) { vias[i] = findNode(PrimitiveNode.Function.CONTACT, new ArcProto[] {layers[i], layers[i+1]}, techy); error(vias[i] == null, "No via for layer: " + layerNms[i]); } p1m1 = getVia(0); m1m2 = getVia(1); m2m3 = getVia(2); m3m4 = getVia(3); m4m5 = getVia(4); m5m6 = getVia(5); m6m7 = getVia(6); m7m8 = getVia(7); m8m9 = getVia(8); ndm1 = techy.findNodeProto("Metal-1-N-Active-Con"); pdm1 = techy.findNodeProto("Metal-1-P-Active-Con"); nwm1 = techy.findNodeProto("Metal-1-N-Well-Con"); pwm1 = techy.findNodeProto("Metal-1-P-Well-Con"); nwm1Y = techy.findNodeProto("Y-Metal-1-N-Well-Con"); pwm1Y = techy.findNodeProto("Y-Metal-1-P-Well-Con"); // initialize special threshold transistor contacts nmos18contact = techy.findNodeProto("thick-OD18-Metal-1-N-Active-Con"); pmos18contact = techy.findNodeProto("thick-OD18-Metal-1-P-Active-Con"); nmos25contact = techy.findNodeProto("thick-OD25-Metal-1-N-Active-Con"); pmos25contact = techy.findNodeProto("thick-OD25-Metal-1-P-Active-Con"); nmos33contact = techy.findNodeProto("thick-OD33-Metal-1-N-Active-Con"); pmos33contact = techy.findNodeProto("thick-OD33-Metal-1-P-Active-Con"); initViaMap(); //------------------------ initialize transistors --------------------- nmos = techy.findNodeProto("N-Transistor"); pmos = techy.findNodeProto("P-Transistor"); nmos18 = techy.findNodeProto("OD18-N-Transistor"); pmos18 = techy.findNodeProto("OD18-P-Transistor"); nmos25 = techy.findNodeProto("OD25-N-Transistor"); pmos25 = techy.findNodeProto("OD25-P-Transistor"); nmos33 = techy.findNodeProto("OD33-N-Transistor"); pmos33 = techy.findNodeProto("OD33-P-Transistor"); // transistor layers od18 = techy.findNodeProto("OD18-Node"); od25 = techy.findNodeProto("OD25-Node"); od33 = techy.findNodeProto("OD33-Node"); vth = techy.findNodeProto("VTH-Node"); vtl = techy.findNodeProto("VTL-Node"); //--------------------------- initialize well ------------------------- nwell = techy.findNodeProto("N-Well-Node"); pwell = techy.findNodeProto("P-Well-Node"); } //---------------------------- public classes ----------------------------- /** Hide the differences between technologies. A MosInst's gate is always * vertical. */ public static class MosInst { private final NodeInst mos; private final String leftDiff, rightDiff, topPoly, botPoly; private static void error(boolean pred, String msg) { LayoutLib.error(pred, msg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -