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

📄 foldedmos.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	 * This constructor is responsible for positioning the internal pieces on	 * the 0.5 lambda grid. Most significant to the user is the positioning of	 * the MOS transistors when gateWidth is less than the width of a minimum	 * sized diffusion contact. In that case this constructor assumes the user	 * will place the edges of the diffusion contact on grid and moves the MOS	 * transistors slightly up or down to get the MOS transistor on the same	 * grid.	 * 	 * @param type	 *            'N' or 'P' for NMOS or PMOS	 * @param x	 *            the middle of the left most diffusion contact	 * @param y	 *            the "middle" of the FoldedMos. If gateWidth is less than the	 *            width of the minimum sized diffusion contact this will be the	 *            middle of the diffusion contact. Otherwise this is the middle	 *            of the MOS transistor.	 * @param nbFolds	 *            the number of folds. Each "fold" consists of a left diffusion	 *            contact, nbSeries transistors stacked in series, and a right	 *            diffusion contact. Adjacent folds share diffusion contacts.	 * @param nbSeries	 *            the number of transistors stacked in series for each fold	 * @param gateWidth	 *            the width of each gate	 * @param gateSpace	 *            allows the user to specify the space between diffusion	 *            contacts and gates and between adjacent gates. null means use	 *            the minimum spacing required by the design rules.	 * @param justifyDiffCont	 *            FoldedMos always makes diffusion contacts a multiple of 5	 *            lambda wide. If the gateWidth is not a multiple of 5 lambda	 *            wide then this argument specifies how the diffusion contact	 *            should be positioned within the diffusion. The choices are	 *            'T', or 'B' to move the contact to the top or bottom.	 *            Centering the contact was eliminated because if the transistor	 *            width was .5 + an integer then the diffusion contact edges	 *            would not be on the same .5 lambda grid as any of the edges of	 *            the transistor thereby leading to CIF resolution errors.	 * @param f	 *            the facet that will contain this FoldedMos	 * @param tech	 */	FoldedMos(char type, double x, double y, int nbFolds, int nbSeries,			  double gateWidth, GateSpace gateSpace, char justifyDiffCont,			  Cell f, TechType tech) {		error(type != 'P' && type != 'N',				"FoldedMos: type must be 'P' or 'N': " + type);		this.tech = tech;		this.gateWidth= gateWidth;		physWidth= Math.max(tech.getDiffContWidth(), gateWidth);		diffVias= new PortInst[nbFolds + 1];		moss= new MosInst[nbFolds * nbSeries];		internalDiffs= new PortInst[nbFolds * (nbSeries - 1)];		if (gateSpace == null)			gateSpace= useMinSp;		PrimitiveNode diffCont= isPmos() ? tech.pdm1() : tech.ndm1();		ArcProto diff= isPmos() ? tech.pdiff() : tech.ndiff();		NodeProto difNod= isPmos() ? tech.pdNode() : tech.ndNode();		// double foldPitch = 8 + (nbSeries - 1) * (3 + 2);		int diffNdx= 0, mosNdx= 0, internalDiffNdx= 0;		// Contact only needs to be multiple of 5 lambda high. Because		// diffusion contact is always justified up or down and because it		// is always an integral number of lambdas high, it's edges and		// center are on the same .5 lambda grid as the transistor edges.		double difConIncr= tech.getDiffContIncr();		difContWid= Math.max(tech.getDiffContWidth(),				((int) (gateWidth / difConIncr)) * difConIncr);		double difContSlop= Math.max(0, (gateWidth - difContWid) / 2);		double difContY= y;		switch (justifyDiffCont) {		case 'T':			difContY+= difContSlop;			break;		case 'B':			difContY-= difContSlop;			break;		default:			error(true, "FoldedMos: justifyDiffCont must be 'T', or 'B'");		}		// If the MOS width is less than the minimum width of a diffusion		// contact then the diffusion contact determines the boundary of		// the transistor. In this case the user will place the top and		// bottom of the diffusion contact on a 0.5 lambda grid.		// Therefore we need to shift the MOS transistor so that its edges		// are also on a 0.5 lambda grid. I will do this by shifting the		// MOS transistor down until its bottom edge is on grid.		mosY= y;		if (gateWidth < tech.getDiffContWidth()) {			double mosBotY= y - gateWidth / 2;			double misAlign= Math.IEEEremainder(mosBotY, 0.5);			mosY-= misAlign;		}		double extraDiffPolySpace = 			gateWidth >= tech.getDiffContWidth() ? (			    0.			) : (				tech.getGateToDiffContSpaceDogBone() - tech.getGateToDiffContSpace()			);		double viaToMosPitch = tech.getDiffContWidth()/2 + 		                       tech.getGateToDiffContSpace() +		                       tech.getGateLength()/2;		double mosToMosPitch = tech.getGateLength() + tech.getGateToGateSpace();		PortInst prevPort= null;		for (int i= 0;; i++) {			// put down diffusion contact			PortInst newPort = 				LayoutLib.newNodeInst(diffCont, x, difContY,				                      LayoutLib.DEF_SIZE, 				                      difContWid, 0, f).getOnlyPortInst();						// Add redundant diffusion as a hint of the metal-1 wire size to 			// use to connect to this diffusion contact. Diffusion contact is			// always on grid.			LayoutLib.newArcInst(diff, tech.getDiffCont_m1Width(), newPort,					             newPort);						addM1ForMinArea(newPort, difContWid, justifyDiffCont);						diffVias[diffNdx++]= newPort;			// connect to previous port			if (prevPort != null) {				newDiffArc(diff, difContY, prevPort, newPort);			}			prevPort= newPort;			if (i >= nbFolds)				break; // exit after inserting last diff contact			// series transistors			for (int j= 0; j < nbSeries; j++) {				double extraSp= gateSpace.getExtraSpace(						j == 0 ? extraDiffPolySpace : 0, i, nbFolds, j,						nbSeries);				if (j == 0 && extraSp != 0) {					// Fill diff notch from center of diff contact to left end					// of MOS. Round up diff node width to multiple of lambda					// or else center will be off .5 lambda grid.					double w= Math.ceil(extraSp);					NodeInst dn= LayoutLib.newNodeInst(difNod, x + w / 2, mosY,							w, gateWidth, 0, f);					newDiffArc(diff, difContY, prevPort, dn.getOnlyPortInst());				}				x+= (j == 0 ? viaToMosPitch : mosToMosPitch) + extraSp;				MosInst m= isPmos() ? tech.newPmosInst(x, mosY, gateWidth, 						tech.getGateLength(), f) : tech.newNmosInst(x, mosY,						gateWidth, tech.getGateLength(), f);				moss[mosNdx++]= m;				newDiffArc(diff, difContY, prevPort, m.leftDiff());				prevPort= m.rightDiff();				if (j != 0) {					internalDiffs[internalDiffNdx++]= m.leftDiff();				}			}			double extraSp= gateSpace.getExtraSpace(extraDiffPolySpace, i,					nbFolds, nbSeries, nbSeries);			x+= viaToMosPitch + extraSp;			if (extraSp != 0) {				// fill diff notch from right end of MOS to center of diff cont				double w= Math.ceil(extraSp);				NodeInst dn= LayoutLib.newNodeInst(difNod, x - w / 2, mosY, w,						gateWidth, 0, f);				newDiffArc(diff, difContY, prevPort, dn.getOnlyPortInst());			}		}	}	// ----------------------------- public methods ------------------------------	/** return the width of each transistor's gate */	public double getGateWidth() {		return gateWidth;	}	/**	 * when the gate is narrower than the diffusion contact return the diffusion	 * contact width, otherwise return the gate width	 */	public double getPhysWidth() {		return physWidth;	}	/**	 * Get the Y coordinate of the centers of the MOS transistors. This may be	 * different from the Y coordinate passed into the constructor. When the MOS	 * transistor is narrower than the diffusion contact the MOS transistor must	 * be been shifted up or down to get its edges on grid	 */	public double getMosCenterY() {		return mosY;	}	/**	 * The diffusion contact's width increases with the gateWidth but is only	 * large enough to surround the diffusion contact cuts	 */	public double getDiffContWidth() {		return difContWid;	}	public int nbSrcDrns() {		return diffVias.length;	}	public PortInst getSrcDrn(int col) {		return diffVias[col];	}	public int nbGates() {		return moss.length;	}	public PortInst getGate(int mosNdx, char pos) {		error(pos != 'T' && pos != 'B', "pos must be 'T' or 'B': " + pos);		return pos == 'T' ? moss[mosNdx].topPoly() : moss[mosNdx].botPoly();	}	public int nbInternalSrcDrns() {		return internalDiffs.length;	}	/**	 * "Internal diffusions" are the diffusions between two series transistors.	 * The user may wish to connect these with "generic:Uinversal" arcs in order	 * to fool Electric's NCC into paralleling transistor stacks of series	 * transistors.	 */	public PortInst getInternalSrcDrn(int col) {		return internalDiffs[col];	}}

⌨️ 快捷键说明

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