⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stdcellparams.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
		NodeProto diffNode =			mosLeft instanceof FoldedPmos ? tech.pdNode() : tech.ndNode();		double prevX = LayoutLib.roundCenterX(prevPort);		double thisX = LayoutLib.roundCenterX(thisPort);		double dist = thisX - prevX;		// If they overlap perfectly or if they're so far apart there's no		// select notch then no notches of any kind are possible.		if (dist == 0 || (dist >= selectOverhangsDiffCont * 2 + tech.getSelectSpacingRule()))			return;		// Fill a notch with diffusion.		//		// I can't fill notches using a diffusion arc because the span in		// the Y coordinate of the port of the diffusion contact may not		// include the center of such an arc. This occurs for MOS		// transistors with a single contact cut.		//		// I therefore fill the notch using a diffusion node.		double mosY = mosLeft.getMosCenterY();        double mosRightY = mosRight.getMosCenterY();        // if they are not aligned along Y, the extra select node might not cover top transistor.        if (!DBMath.areEquals(mosY, mosRightY))        {            double activePlusSelect = diffWid/2 + tech.getSelectSurroundDiffInTrans();            double topY = -activePlusSelect, bottomY = activePlusSelect;            double sign = 1;            if (mosY > mosRightY)            {                topY += mosY; bottomY += mosRightY; sign = -1;            }            else            {                topY += mosRightY; bottomY += mosY;            }            double diff = DBMath.round(topY - bottomY);            if (DBMath.isGreaterThan(diff, 0))            {                // round diff to multiple of min precision otherwise diff/2 (or node center will generate DRC errors)//                double minRe = f.getTechnology().getResolution()*2;                double minRe = getGridResolution()*2;                if (minRe > 0 && DBMath.hasRemainder(diff, minRe))                {                    diff += getGridResolution(); // to ceil correctlu otherwise it could leave a notch                    diff = ((int)(Math.ceil(diff/minRe))) * minRe;                }                diffWid += diff;                mosY += DBMath.round(sign * diff/2);            }        }        double a = mosLeft.getDiffContWidth();        double b = mosLeft.getGateWidth();        Rectangle2D diffNodeBnd = LayoutLib.calculateNodeInst(diffNode, thisX-dist/2, mosY,                dist, diffWid);        if (fillDiffNotch)        {            NodeInst dFill = LayoutLib.newNodeInst(diffNode, diffNodeBnd, 0, f);            double contY = LayoutLib.roundCenterY(thisPort); // contact is always on grid            LayoutLib.newArcInst(diffArc, DEF_SIZE, thisPort, thisX, contY,                                 dFill.getOnlyPortInst(),                                 LayoutLib.roundCenterX(dFill.getOnlyPortInst()),                                 contY);            // Never place wide arcs directly onto the FoldedMos            // diffusion-metal1 contacts because they become bad width hints.            if (dist < m1OverhangsDiffCont * 2 + m1Space) {                // m1 is 1 lambda narrower than diffusion contact width                double m1Wid = mosLeft.getDiffContWidth() - 1;                NodeInst mFill =                    LayoutLib.newNodeInst(tech.m1Node(), thisX-dist/2, contY,	dist,                                          m1Wid, 0, f);                LayoutLib.newArcInst(tech.m1(), DEF_SIZE, thisPort, mFill.getOnlyPortInst());            }        }        // Rounding values to avoid out-of-grid values        double roundedPosY = DBMath.round(diffNodeBnd.getY() - diffNodeBnd.getHeight()/2);        Rectangle2D selectRec = new Rectangle2D.Double(diffNodeBnd.getX() - dist/2, roundedPosY,                diffNodeBnd.getWidth(), diffNodeBnd.getHeight());        double selectDiff = (a - b);//        if (DBMath.isGreaterThan(selectDiff, 0))		    addSelAroundDiff(diffNode, selectRec, selectDiff, f);	}	private static FoldedMos getRightMos(Object a) {		if (a instanceof FoldedMos)  return (FoldedMos) a;		error(!(a instanceof FoldedMos[]), "not FoldedMos or FoldedMos[]");		FoldedMos[] moss = (FoldedMos[]) a;		return moss[moss.length - 1];	}	private static String trkMsg(Object key, Cell schem) {		return "Track assignment for export: "			+ key			+ " in Cell: "			+ schem.getName()			+ ".\n    ";	}	//----------------------------- public constants --------------------------	/** This class allows the user to specify which source/drains	 * wireVddGnd() should connect to power or ground.  Most users will	 * be happy with the predefined instances: ODD or EVEN. */	public interface SelectSrcDrn {		public boolean connectThisOne(int mosNdx, int srcDrnNdx);	}	public static final SelectSrcDrn EVEN = new SelectSrcDrn() {		public boolean connectThisOne(int mosNdx, int srcDrnNdx) {			return srcDrnNdx % 2 == 0;		}	};	public static final SelectSrcDrn ODD = new SelectSrcDrn() {		public boolean connectThisOne(int mosNdx, int srcDrnNdx) {			return srcDrnNdx % 2 == 1;		}	};	//------------------------ public methods --------------------------------------	//------------------------------------------------------------------------------	// Allow user to customize standard cell characteristics	//	/** Attach the well ties to special busses rather than to Vdd and Gnd. */	public void setDoubleStrapGate(boolean val) {		doubleStrapGate = val;	}	/** GasP generators use exhaustive search for gate placement */	public void setExhaustivePlace(boolean val) {		exhaustivePlace = val;	}	/** Set number of permuations GasP placer should try before giving	 * up. */	public void setNbPlacerPerms(int i) {		nbPlacerPerms = i;	}	/** Units of lambda */	public void setNmosWellHeight(double h) {		nmosWellHeight = h;		init();	}	/** Units of lambda */	public void setPmosWellHeight(double h) {		pmosWellHeight = h;		init();	}	/** Set the maximum width of a each MOS finger. Units of lambda */	public void setMaxMosWidth(double wid) {		maxMosWidth = wid;	}    /** Set the starting offset from 0 of the pmos tracks */    public void setPmosTrackOffset(double offset) {        pmosTrackOffset = offset;        init();    }    /** Set the starting offset from 0 of the nmos tracks */    public void setNmosTrackOffset(double offset) {        nmosTrackOffset = offset;        init();    }    /** Set the track width */    public void setTrackWidth(double width) {        trackWidth = width;        init();    }    /** Set the width of the Vdd track */    public void setVddWidth(double width) {        vddWidth = width;        init();    }    /** Set the width of the Gnd track */    public void setGndWidth(double width) {        gndWidth = width;        init();    }    public void setM1TrackWidth(double width) {        m1TrackWidth = width;    }    public double getM1TrackWidth() { return m1TrackWidth; }    public void setM2TrackWidth(double width) {        m2TrackWidth = width;    }    public double getM2TrackWidth() { return m2TrackWidth; }    public double getDRCRingSpacing() { return drcRingSpace; }    public double getM1TrackAboveVDD() {        double trackX;        if (is90nm()) {            // vddTop + m1_m1_sp + m1_wid/2 + m1_xcon_extension            trackX = getVddY() + getVddWidth()/2 + 2.4 + getM1TrackWidth()/2 + 2.8;        } else {            // vddTop + m1_m1_sp + m1_wid/2            trackX = getVddY() + getVddWidth()/2 + 3 + 2;        }        return trackX;    }    public double getM1TrackBelowGnd() {        double trackX;        double gndBot = getGndY() - getGndWidth()/2;        if (is90nm()) {            // gndBot - m1_m1_sp - m1_wid/2 - m1_xcon_extension            trackX = gndBot - 2.4 - getM1TrackWidth()/2 - 2.8;        } else {            // gndBot - m1_m1_sp - m1_wid/2            trackX = gndBot - getM1TrackWidth() - 2;        }        return trackX;    }    public double getWellOverhangDiff() {        if (is90nm()) return 8;        else return 6;    }    public double getGridResolution() { return gridResolution; }    /** Get the fold pitch for folded transistor, given the number of series transistors */    public double getFoldPitch(int nbSeries) {        if (is90nm())            return (8 + (nbSeries - 1) * (3 + 2));        else            return (8 + (nbSeries - 1) * (3 + 2));    }	/** Turn on Network Consistency Checking after each gate is generated.	 *<p> This just checks topology and ignores sizes. */	public void enableNCC(String libName) {		schemLib = Library.findLibrary(libName);		error(schemLib==null, "Please open the PurpleFour Library");	}	public void setVddExportName(String vddNm) {vddExportName=vddNm;}	public String getVddExportName() {return vddExportName;}	public void setGndExportName(String gndNm) {gndExportName=gndNm;}	public String getGndExportName() {return gndExportName;}	public void setVddExportRole(PortCharacteristic vddRole) {		vddExportRole = vddRole;	}	public PortCharacteristic getVddExportRole() {		return vddExportRole;	}	public void setGndExportRole(PortCharacteristic gndRole) {		gndExportRole = gndRole;	}	public PortCharacteristic getGndExportRole() {		return gndExportRole;	}	//------------------------------------------------------------------------------	// Utilities for gate generators	public StdCellParams(TechType.TechTypeEnum techEnum) {        if      (techEnum == TechType.TechTypeEnum.CMOS90) initCMOS90();        else if (techEnum == TechType.TechTypeEnum.MOCMOS || techEnum == TechType.TechTypeEnum.TSMC180) initMoCMOS();        else {            error(true, "Standard Cell Params does not understand technology "+techEnum);        }        this.tech = techEnum.getTechType();    }    void setOutputLibrary(Library lib) {        this.layoutLib = lib;    }    Library getOutputLibrary() { return layoutLib; }    public TechType getTechType() { return tech; }        public double getNmosWellHeight() {		return nmosWellHeight;	}	public double getPmosWellHeight() {		return pmosWellHeight;	}	public boolean getDoubleStrapGate() {		return doubleStrapGate;	}	public boolean getExhaustivePlace() {		return exhaustivePlace;	}	public int getNbPlacerPerms() {		return nbPlacerPerms;	}	public double getCellBot() {		return -nmosWellHeight;	}	public double getCellTop() {		return pmosWellHeight;	}	public double getGndY() {		return gndY;	}	public void setGndY(double y) {		gndY = y;		init();	}	public double getVddY() {		return vddY;	}	public void setVddY(double y) {		vddY = y;		init();	}	public double getGndWidth() {		return gndWidth;	}	public double getVddWidth() {		return vddWidth;	}	/** Gets the Y coordinate of the ith available track. Available	 * tracks exclude Vdd, Gnd, and reserved tracks. */	public double getTrackY(int i) {		error(i==0, "StdCellParams.getTrackY: 0 is an illegal track index");		return i>0			? pmosTracks.get(i - 1).doubleValue()			: nmosTracks.get(-i - 1).doubleValue();	}	/** A physical track number enumerates all tracks regardless of	 * whether the track is blocked. The value 0 is illegal. Tracks 1	 * and higher are PMOS tracks. Tracks -1 and lower are NMOS	 * tracks */	public double getPhysTrackY(int i) {		error(i==0, "StdCellParams.getPhysTrackY: 0 is illegal track index");		return i>0		    ? trackPitch/2 + (i-1)*trackPitch		    : -trackPitch/2 + (i+1)*trackPitch;	}	/*	public HashMap physTracksToYCoords(HashMap physTracks) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -