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

📄 libtotech.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
				{					error.markError(null, np, "Need 2 gate (poly) and 2 gated (active) ports on field-effect transistor");					return null;				}				// also make sure that dif1Port is positive and dif2Port is negative				double x1Pos = (nIn.nodePortDetails[dif1Port].values[0].getX().getMultiplier() * nIn.xSize +					nIn.nodePortDetails[dif1Port].values[0].getX().getAdder() +					nIn.nodePortDetails[dif1Port].values[1].getX().getMultiplier() * nIn.xSize +					nIn.nodePortDetails[dif1Port].values[1].getX().getAdder()) / 2;				double x2Pos = (nIn.nodePortDetails[dif2Port].values[0].getX().getMultiplier() * nIn.xSize +					nIn.nodePortDetails[dif2Port].values[0].getX().getAdder() +					nIn.nodePortDetails[dif2Port].values[1].getX().getMultiplier() * nIn.xSize +					nIn.nodePortDetails[dif2Port].values[1].getX().getAdder()) / 2;				double y1Pos = (nIn.nodePortDetails[dif1Port].values[0].getY().getMultiplier() * nIn.ySize +					nIn.nodePortDetails[dif1Port].values[0].getY().getAdder() +					nIn.nodePortDetails[dif1Port].values[1].getY().getMultiplier() * nIn.ySize +					nIn.nodePortDetails[dif1Port].values[1].getY().getAdder()) / 2;				double y2Pos = (nIn.nodePortDetails[dif2Port].values[0].getY().getMultiplier() * nIn.ySize +					nIn.nodePortDetails[dif2Port].values[0].getY().getAdder() +					nIn.nodePortDetails[dif2Port].values[1].getY().getMultiplier() * nIn.ySize +					nIn.nodePortDetails[dif2Port].values[1].getY().getAdder()) / 2;				if (Math.abs(x1Pos-x2Pos) > Math.abs(y1Pos-y2Pos))				{					if (x1Pos < x2Pos)					{						int k = dif1Port;   dif1Port = dif2Port;   dif2Port = k;					}				} else				{					if (y1Pos < y2Pos)					{						int k = dif1Port;   dif1Port = dif2Port;   dif2Port = k;					}				}				// also make sure that pol1Port is negative and pol2Port is positive				x1Pos = (nIn.nodePortDetails[pol1Port].values[0].getX().getMultiplier() * nIn.xSize +					nIn.nodePortDetails[pol1Port].values[0].getX().getAdder() +					nIn.nodePortDetails[pol1Port].values[1].getX().getMultiplier() * nIn.xSize +					nIn.nodePortDetails[pol1Port].values[1].getX().getAdder()) / 2;				x2Pos = (nIn.nodePortDetails[pol2Port].values[0].getX().getMultiplier() * nIn.xSize +					nIn.nodePortDetails[pol2Port].values[0].getX().getAdder() +					nIn.nodePortDetails[pol2Port].values[1].getX().getMultiplier() * nIn.xSize +					nIn.nodePortDetails[pol2Port].values[1].getX().getAdder()) / 2;				y1Pos = (nIn.nodePortDetails[pol1Port].values[0].getY().getMultiplier() * nIn.ySize +					nIn.nodePortDetails[pol1Port].values[0].getY().getAdder() +					nIn.nodePortDetails[pol1Port].values[1].getY().getMultiplier() * nIn.ySize +					nIn.nodePortDetails[pol1Port].values[1].getY().getAdder()) / 2;				y2Pos = (nIn.nodePortDetails[pol2Port].values[0].getY().getMultiplier() * nIn.ySize +					nIn.nodePortDetails[pol2Port].values[0].getY().getAdder() +					nIn.nodePortDetails[pol2Port].values[1].getY().getMultiplier() * nIn.ySize +					nIn.nodePortDetails[pol2Port].values[1].getY().getAdder()) / 2;				if (Math.abs(x1Pos-x2Pos) > Math.abs(y1Pos-y2Pos))				{					if (x1Pos > x2Pos)					{						int k = pol1Port;   pol1Port = pol2Port;   pol2Port = k;					}				} else				{					if (y1Pos > y2Pos)					{						int k = pol1Port;   pol1Port = pol2Port;   pol2Port = k;					}				}				// gather extra ports that go at the end				List<NodeInfo.PortDetails> extras = new ArrayList<NodeInfo.PortDetails>();				for(int j=0; j<ports.size(); j++)				{					if (j != pol1Port && j != dif1Port && j != pol2Port && j != dif2Port)						extras.add(ports.get(j));				}				// rearrange the ports				NodeInfo.PortDetails port0 = nIn.nodePortDetails[pol1Port];				NodeInfo.PortDetails port1 = nIn.nodePortDetails[dif1Port];				NodeInfo.PortDetails port2 = nIn.nodePortDetails[pol2Port];				NodeInfo.PortDetails port3 = nIn.nodePortDetails[dif2Port];				nIn.nodePortDetails[pol1Port=0] = port0;				nIn.nodePortDetails[dif1Port=1] = port1;				nIn.nodePortDetails[pol2Port=2] = port2;				nIn.nodePortDetails[dif2Port=3] = port3;				for(int j=0; j<extras.size(); j++)					nIn.nodePortDetails[j+4] = extras.get(j);				// make sure implant layers are not connected to ports				for(int k=0; k<nIn.nodeLayers.length; k++)				{					NodeInfo.LayerDetails nld = nIn.nodeLayers[k];					if (nld.layer.fun.isSubstrate()) nld.portIndex = -1;				}			}			if (nIn.serp)			{				// finish up serpentine transistors				nIn.specialType = PrimitiveNode.SERPTRANS;				// determine port numbers for serpentine transistors				int polIndex = -1, difIndex = -1;				for(int k=0; k<nIn.nodeLayers.length; k++)				{					NodeInfo.LayerDetails nld = nIn.nodeLayers[k];					if (nld.layer.fun.isPoly())					{						polIndex = k;					} else if (nld.layer.fun.isDiff())					{						if (difIndex >= 0)						{							// figure out which layer is the basic active layer							int funExtraOld = nIn.nodeLayers[difIndex].layer.funExtra;							int funExtraNew = nld.layer.funExtra;							if (funExtraOld == funExtraNew) continue;							if (funExtraOld == 0) continue;						}						difIndex = k;					}				}				if (difIndex < 0 || polIndex < 0)				{					error.markError(null, np, "No diffusion and polysilicon layers in serpentine transistor");					return null;				}				// find width and extension from comparison to poly layer				Sample polNs = nIn.nodeLayers[polIndex].ns;				Rectangle2D polNodeBounds = polNs.node.getBounds();				Sample difNs = nIn.nodeLayers[difIndex].ns;				Rectangle2D difNodeBounds = difNs.node.getBounds();				for(int k=0; k<nIn.nodeLayers.length; k++)				{					NodeInfo.LayerDetails nld = nIn.nodeLayers[k];					Sample ns = nld.ns;					Rectangle2D nodeBounds = ns.node.getBounds();					if (polNodeBounds.getWidth() > polNodeBounds.getHeight())					{						// horizontal layer						nld.lWidth = nodeBounds.getMaxY() - (ns.parent.ly + ns.parent.hy)/2;						nld.rWidth = (ns.parent.ly + ns.parent.hy)/2 - nodeBounds.getMinY();						nld.extendT = difNodeBounds.getMinX() - nodeBounds.getMinX();					} else					{						// vertical layer						nld.lWidth = nodeBounds.getMaxX() - (ns.parent.lx + ns.parent.hx)/2;						nld.rWidth = (ns.parent.lx + ns.parent.hx)/2 - nodeBounds.getMinX();						nld.extendT = difNodeBounds.getMinY() - nodeBounds.getMinY();					}					nld.extendB = nld.extendT;				}				// add in electrical layers for diffusion				NodeInfo.LayerDetails [] addedLayers = new NodeInfo.LayerDetails[nIn.nodeLayers.length+2];				for(int k=0; k<nIn.nodeLayers.length; k++)					addedLayers[k] = nIn.nodeLayers[k];				NodeInfo.LayerDetails diff1 = nIn.nodeLayers[difIndex].duplicate();				NodeInfo.LayerDetails diff2 = nIn.nodeLayers[difIndex].duplicate();				addedLayers[nIn.nodeLayers.length] = diff1;				addedLayers[nIn.nodeLayers.length+1] = diff2;				nIn.nodeLayers = addedLayers;				diff1.inLayers = diff2.inLayers = false;				nIn.nodeLayers[difIndex].inElectricalLayers = false;				diff1.portIndex = dif1Port;				diff2.portIndex = dif2Port;				// compute port extension factors				nIn.specialValues = new double[6];				int layerCount = 0;				for(Sample ns : firstEx.samples)				{					if (ns.values != null && ns.layer != Generic.tech().portNode &&						ns.layer != Generic.tech().cellCenterNode && ns.layer != null)							layerCount++;				}				nIn.specialValues[0] = layerCount+1;				if (nIn.nodePortDetails[dif1Port].values[0].getX().getAdder() >					nIn.nodePortDetails[dif1Port].values[0].getY().getAdder())				{					// vertical diffusion layer: determine polysilicon width					nIn.specialValues[3] = (nIn.ySize * nIn.nodeLayers[polIndex].values[1].getY().getMultiplier() +						nIn.nodeLayers[polIndex].values[1].getY().getAdder()) -						(nIn.ySize * nIn.nodeLayers[polIndex].values[0].getY().getMultiplier() +						nIn.nodeLayers[polIndex].values[0].getY().getAdder());					// determine diffusion port rule					nIn.specialValues[1] = (nIn.xSize * nIn.nodePortDetails[dif1Port].values[0].getX().getMultiplier() +						nIn.nodePortDetails[dif1Port].values[0].getX().getAdder()) -						(nIn.xSize * nIn.nodeLayers[difIndex].values[0].getX().getMultiplier() +						nIn.nodeLayers[difIndex].values[0].getX().getAdder());					nIn.specialValues[2] = (nIn.ySize * nIn.nodePortDetails[dif1Port].values[0].getY().getMultiplier() +						nIn.nodePortDetails[dif1Port].values[0].getY().getAdder()) -						(nIn.ySize * nIn.nodeLayers[polIndex].values[1].getY().getMultiplier() +						nIn.nodeLayers[polIndex].values[1].getY().getAdder());					// determine polysilicon port rule					nIn.specialValues[4] = (nIn.ySize * nIn.nodePortDetails[pol1Port].values[0].getY().getMultiplier() +						nIn.nodePortDetails[pol1Port].values[0].getY().getAdder()) -						(nIn.ySize * nIn.nodeLayers[polIndex].values[0].getY().getMultiplier() +						nIn.nodeLayers[polIndex].values[0].getY().getAdder());					nIn.specialValues[5] = (nIn.xSize * nIn.nodeLayers[difIndex].values[0].getX().getMultiplier() +						nIn.nodeLayers[difIndex].values[0].getX().getAdder()) -						(nIn.xSize * nIn.nodePortDetails[pol1Port].values[1].getX().getMultiplier() +						nIn.nodePortDetails[pol1Port].values[1].getX().getAdder());					// setup electrical layers for diffusion					diff1.values[0].getY().setMultiplier(0);					diff1.values[0].getY().setAdder(0);					diff1.rWidth = 0;					diff2.values[1].getY().setMultiplier(0);					diff2.values[1].getY().setAdder(0);					diff2.lWidth = 0;				} else				{					// horizontal diffusion layer: determine polysilicon width					nIn.specialValues[3] = (nIn.xSize * nIn.nodeLayers[polIndex].values[1].getX().getMultiplier() +						nIn.nodeLayers[polIndex].values[1].getX().getAdder()) -						(nIn.xSize * nIn.nodeLayers[polIndex].values[0].getX().getMultiplier() +						nIn.nodeLayers[polIndex].values[0].getX().getAdder());					// determine diffusion port rule					nIn.specialValues[1] = (nIn.ySize * nIn.nodePortDetails[dif1Port].values[0].getY().getMultiplier() +						nIn.nodePortDetails[dif1Port].values[0].getY().getAdder()) -						(nIn.ySize * nIn.nodeLayers[difIndex].values[0].getY().getMultiplier() +						nIn.nodeLayers[difIndex].values[0].getY().getAdder());					nIn.specialValues[2] = (nIn.xSize * nIn.nodeLayers[polIndex].values[0].getX().getMultiplier() +						nIn.nodeLayers[polIndex].values[0].getX().getAdder()) -						(nIn.xSize * nIn.nodePortDetails[dif1Port].values[1].getX().getMultiplier() +						nIn.nodePortDetails[dif1Port].values[1].getX().getAdder());					// determine polysilicon port rule					nIn.specialValues[4] = (nIn.xSize * nIn.nodePortDetails[pol1Port].values[0].getX().getMultiplier() +						nIn.nodePortDetails[pol1Port].values[0].getX().getAdder()) -						(nIn.xSize * nIn.nodeLayers[polIndex].values[0].getX().getMultiplier() +						nIn.nodeLayers[polIndex].values[0].getX().getAdder());					nIn.specialValues[5] = (nIn.ySize * nIn.nodeLayers[difIndex].values[0].getY().getMultiplier() +						nIn.nodeLayers[difIndex].values[0].getY().getAdder()) -						(nIn.ySize * nIn.nodePortDetails[pol1Port].values[1].getY().getMultiplier() +						nIn.nodePortDetails[pol1Port].values[1].getY().getAdder());					// setup electrical layers for diffusion					diff1.values[0].getX().setMultiplier(0);					diff1.values[0].getX().setAdder(0);					diff1.rWidth = 0;					diff2.values[1].getX().setMultiplier(0);					diff2.values[1].getX().setAdder(0);					diff2.lWidth = 0;				}			}			// extract width offset information from highlight box			double lX = 0, hX = 0, lY = 0, hY = 0;			boolean found = false;			for(Sample ns : firstEx.samples)			{				if (ns.layer != null) continue;				found = true;				if (ns.values != null)				{					boolean err = false;					if (ns.values[0].getX().getMultiplier() == -0.5)		// left edge offset					{						lX = ns.values[0].getX().getAdder();					} else if (ns.values[0].getX().getMultiplier() == 0.5)					{						lX = nIn.xSize + ns.values[0].getX().getAdder();					} else err = true;					if (ns.values[0].getY().getMultiplier() == -0.5)		// bottom edge offset					{						lY = ns.values[0].getY().getAdder();					} else if (ns.values[0].getY().getMultiplier() == 0.5)					{						lY = nIn.ySize + ns.values[0].getY().getAdder();;					} else err = true;					if (ns.values[1].getX().getMultiplier() == 0.5)		// right edge offset					{						hX = -ns.values[1].getX().getAdder();					} else if (ns.values[1].getX().getMultiplier() == -0.5)					{						hX = nIn.xSize - ns.values[1].getX().getAdder();					} else err = true;					if (ns.values[1].getY().getMultiplier() == 0.5)		// top edge offset					{						hY = -ns.values[1].getY().getAdder();					} else if (ns.values[1].getY().getMultiplier() == -0.5)					{						hY = nIn.ySize - ns.values[1].getY().getAdder();					} else err = true;					if (err)					{						error.markError(ns.node, np, "Highlighting cannot scale from center");						return null;					}				} else				{					error.markError(ns.node, np, "No rule found for highlight");					return null;				}			}			if (!found)			{				error.markError(null, np, "No highlight found");				return null;			}			if (lX != 0 || hX != 0 || lY != 0 || hY != 0)			{				nList[nodeIndex].so = new SizeOffset(lX, hX, lY, hY);			}//			// get grab point information//			for(ns = neList.firstSample; ns != NOSAMPLE; ns = ns.nextSample)//				if (ns.layer == Generic.tech.cellCenterNode) break;//			if (ns != NOSAMPLE)//			{//				us_tecnode_grab[us_tecnode_grabcount++] = nodeindex+1;//				us_tecnode_grab[us_tecnode_grabcount++] = (ns.node.geom.lowx +//					ns.node.geom.highx - neList.lx - neList.hx)/2 *//					el_curlib.lambda[tech.techindex] / lambda;//				us_tecnode_grab[us_tecnode_grabcount++] = (ns.node.geom.lowy +//					ns.node.geom.highy - neList.ly - neList.hy)/2 *//					el_curlib.lambda[tech.techindex] / lambda;//				us_tecflags |= HASGRAB;//			}			// advance the fill pointer			nodeIndex++;		}		return nList;	}	private NodeInfo.LayerDetails [] makePrimitiveNodeLayers(List<Example> neList, Cell np, LayerInfo [] lis)	{		// if there is only one example: make sample scale with edge		Example firstEx = neList.get(0);		if (neList.size() <= 1)		{			return makeNodeScaledUniformly(neList, np, lis);		}		// count the number of real layers in the node		int count = 0;		for(Sample ns : firstEx.samples)		{			if (ns.layer != null && ns.layer != Generic.tech().portNode) count++;		}		NodeInfo.LayerDetails [] nodeLayers = new NodeInfo.LayerDetails[count];		count = 0;		// look at every sample "ns" in the main example "neList"		for(Sample ns : firstEx.samples)		{			// ignore grab point specification

⌨️ 快捷键说明

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