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

📄 libtotech.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
			if (ns.layer == Generic.tech().cellCenterNode) continue;			AffineTransform trans = ns.node.rotateOut();			Rectangle2D nodeBounds = getBoundingBox(ns.node);			// determine the layer			LayerInfo giLayer = null;			if (ns.layer != null && ns.layer != Generic.tech().portNode)			{				String desiredLayer = ns.layer.getName().substring(6);				for(int i=0; i<lis.length; i++)				{					if (desiredLayer.equals(lis[i].name)) { giLayer = lis[i];   break; }				}				if (giLayer == null)				{					System.out.println("Cannot find layer " + desiredLayer);					return null;				}			}			// look at other examples and find samples associated with this			firstEx.studySample = ns;			NodeInfo.LayerDetails multiRule = null;			for(int n=1; n<neList.size(); n++)			{				Example ne = neList.get(n);				// count number of samples associated with the main sample				int total = 0;				for(Sample nso : ne.samples)				{					if (nso.assoc == ns)					{						ne.studySample = nso;						total++;					}				}				if (total == 0)				{					error.markError(ns.node, np, "Still unassociated sample (shouldn't happen)");					return null;				}				// if there are multiple associations, it must be a contact cut				if (total > 1)				{					// make sure the layer is real geometry, not highlight or a port					if (ns.layer == null || ns.layer == Generic.tech().portNode)					{						error.markError(ns.node, np, "Only contact layers may be iterated in examples");						return null;					}					// add the rule					multiRule = getMultiCutRule(ns, neList, np);					if (multiRule != null) break;				}			}			if (multiRule != null)			{				multiRule.layer = giLayer;				nodeLayers[count] = multiRule;				count++;				continue;			}			// associations done for this sample, now analyze them			Point2D [] pointList = null;			int [] pointFactor = null;			Point2D [] points = null;			if (ns.node.getProto() == Artwork.tech().filledPolygonNode ||				ns.node.getProto() == Artwork.tech().closedPolygonNode ||				ns.node.getProto() == Artwork.tech().openedPolygonNode ||				ns.node.getProto() == Artwork.tech().openedDottedPolygonNode ||				ns.node.getProto() == Artwork.tech().openedDashedPolygonNode ||				ns.node.getProto() == Artwork.tech().openedThickerPolygonNode)			{				points = ns.node.getTrace();			}			int trueCount = 0;			int minFactor = 0;			if (points != null)			{				// make sure the arrays hold "count" points				pointList = new Point2D[points.length];				pointFactor = new int[points.length];				for(int i=0; i<points.length; i++)				{					pointList[i] = new Point2D.Double(nodeBounds.getCenterX() + points[i].getX(),						nodeBounds.getCenterY() + points[i].getY());					trans.transform(pointList[i], pointList[i]);				}				trueCount = points.length;			} else			{				double [] angles = null;				if (ns.node.getProto() == Artwork.tech().circleNode || ns.node.getProto() == Artwork.tech().thickCircleNode)				{					angles = ns.node.getArcDegrees();					if (angles[0] == 0 && angles[1] == 0) angles = null;				}//				if (angles == null)//				{//					Variable var2 = ns.node.getVar(Info.MINSIZEBOX_KEY);//					if (var2 != null) minFactor = 2;//				}				// set sample description				if (angles != null)				{					// handle circular arc sample					pointList = new Point2D[3];					pointFactor = new int[3];					pointList[0] = new Point2D.Double(nodeBounds.getCenterX(), nodeBounds.getCenterY());					double dist = nodeBounds.getMaxX() - nodeBounds.getCenterX();					pointList[1] = new Point2D.Double(nodeBounds.getCenterX() + dist * Math.cos(angles[0]),						nodeBounds.getCenterY() + dist * Math.sin(angles[0]));					trans.transform(pointList[1], pointList[1]);					trueCount = 3;				} else if (ns.node.getProto() == Artwork.tech().circleNode || ns.node.getProto() == Artwork.tech().thickCircleNode ||					ns.node.getProto() == Artwork.tech().filledCircleNode)				{					// handle circular sample					pointList = new Point2D[2+minFactor];					pointFactor = new int[2+minFactor];					pointList[0] = new Point2D.Double(nodeBounds.getCenterX(), nodeBounds.getCenterY());					pointList[1] = new Point2D.Double(nodeBounds.getMaxX(), nodeBounds.getCenterY());					trueCount = 2;				} else				{					// rectangular sample: get the bounding box in (pointListx, pointListy)					pointList = new Point2D[2+minFactor];					pointFactor = new int[2+minFactor];					pointList[0] = new Point2D.Double(nodeBounds.getMinX(), nodeBounds.getMinY());					pointList[1] = new Point2D.Double(nodeBounds.getMaxX(), nodeBounds.getMaxY());					trueCount = 2;				}//				if (minFactor > 1)//				{//					pointList[2] = new Point2D.Double(pointList[0].getX(),pointList[0].getY());//					pointList[3] = new Point2D.Double(pointList[1].getX(),pointList[1].getY());//				}			}			double [] pointLeftDist = new double[pointFactor.length];			double [] pointRightDist = new double[pointFactor.length];			double [] pointBottomDist = new double[pointFactor.length];			double [] pointTopDist = new double[pointFactor.length];			double [] centerXDist = new double[pointFactor.length];			double [] centerYDist = new double[pointFactor.length];			double [] pointXRatio = new double[pointFactor.length];			double [] pointYRatio = new double[pointFactor.length];			for(int i=0; i<pointFactor.length; i++)			{				pointLeftDist[i] = pointList[i].getX() - firstEx.lx;				pointRightDist[i] = firstEx.hx - pointList[i].getX();				pointBottomDist[i] = pointList[i].getY() - firstEx.ly;				pointTopDist[i] = firstEx.hy - pointList[i].getY();				centerXDist[i] = pointList[i].getX() - (firstEx.lx+firstEx.hx)/2;				centerYDist[i] = pointList[i].getY() - (firstEx.ly+firstEx.hy)/2;				if (firstEx.hx == firstEx.lx) pointXRatio[i] = 0; else					pointXRatio[i] = (pointList[i].getX() - (firstEx.lx+firstEx.hx)/2) / (firstEx.hx-firstEx.lx);				if (firstEx.hy == firstEx.ly) pointYRatio[i] = 0; else					pointYRatio[i] = (pointList[i].getY() - (firstEx.ly+firstEx.hy)/2) / (firstEx.hy-firstEx.ly);				if (i < trueCount)					pointFactor[i] = TOEDGELEFT | TOEDGERIGHT | TOEDGETOP | TOEDGEBOT | FROMCENTX |						FROMCENTY | RATIOCENTX | RATIOCENTY; else							pointFactor[i] = FROMCENTX | FROMCENTY;			}			Point2D [] pointCoords = new Point2D[pointFactor.length];			for(int n = 1; n<neList.size(); n++)			{				Example ne = neList.get(n);				NodeInst ni = ne.studySample.node;				AffineTransform oTrans = ni.rotateOut();				Rectangle2D oNodeBounds = getBoundingBox(ni);				Point2D [] oPoints = null;				if (ni.getProto() == Artwork.tech().filledPolygonNode ||					ni.getProto() == Artwork.tech().closedPolygonNode ||					ni.getProto() == Artwork.tech().openedPolygonNode ||					ni.getProto() == Artwork.tech().openedDottedPolygonNode ||					ni.getProto() == Artwork.tech().openedDashedPolygonNode ||					ni.getProto() == Artwork.tech().openedThickerPolygonNode)				{					oPoints = ni.getTrace();				}				int newCount = 2;				if (oPoints != null)				{					newCount = oPoints.length;					int numPoints = Math.min(trueCount, newCount);					int bestOffset = 0;					double bestDist = Double.MAX_VALUE;					for(int offset = 0; offset < numPoints; offset++)					{						// determine total distance between points						double dist = 0;						for(int i=0; i<numPoints; i++)						{							double dX = points[i].getX() - oPoints[(i+offset)%numPoints].getX();							double dY = points[i].getY() - oPoints[(i+offset)%numPoints].getY();							dist += Math.hypot(dX, dY);						}						if (dist < bestDist)						{							bestDist = dist;							bestOffset = offset;						}					}					for(int i=0; i<numPoints; i++)					{						pointCoords[i] = new Point2D.Double(oNodeBounds.getCenterX() + oPoints[(i+bestOffset)%numPoints].getX(),							oNodeBounds.getCenterY() + oPoints[(i+bestOffset)%numPoints].getY());						oTrans.transform(pointCoords[i], pointCoords[i]);					}				} else				{					double [] angles = null;					if (ni.getProto() == Artwork.tech().circleNode || ni.getProto() == Artwork.tech().thickCircleNode)					{						angles = ni.getArcDegrees();						if (angles[0] == 0 && angles[1] == 0) angles = null;					}					if (angles != null)					{						pointCoords[0] = new Point2D.Double(oNodeBounds.getCenterX(), oNodeBounds.getCenterY());						double dist = oNodeBounds.getMaxX() - oNodeBounds.getCenterX();						pointCoords[1] = new Point2D.Double(oNodeBounds.getCenterX() + dist * Math.cos(angles[0]),							oNodeBounds.getCenterY() + dist * Math.sin(angles[0]));						oTrans.transform(pointCoords[1], pointCoords[1]);					} else if (ni.getProto() == Artwork.tech().circleNode || ni.getProto() == Artwork.tech().thickCircleNode ||						ni.getProto() == Artwork.tech().filledCircleNode)					{						pointCoords[0] = new Point2D.Double(oNodeBounds.getCenterX(), oNodeBounds.getCenterY());						pointCoords[1] = new Point2D.Double(oNodeBounds.getMaxX(), oNodeBounds.getCenterY());					} else					{						pointCoords[0] = new Point2D.Double(oNodeBounds.getMinX(), oNodeBounds.getMinY());						pointCoords[1] = new Point2D.Double(oNodeBounds.getMaxX(), oNodeBounds.getMaxY());					}				}				if (newCount != trueCount)				{					error.markError(ni, np, "Main example of layer " + Info.getSampleName(ne.studySample.layer) +						" has " + trueCount + " points but this has " + newCount);					return null;				}				for(int i=0; i<trueCount; i++)				{					// see if edges are fixed distance from example edge					if (!DBMath.areEquals(pointLeftDist[i], pointCoords[i].getX() - ne.lx)) pointFactor[i] &= ~TOEDGELEFT;					if (!DBMath.areEquals(pointRightDist[i], ne.hx - pointCoords[i].getX())) pointFactor[i] &= ~TOEDGERIGHT;					if (!DBMath.areEquals(pointBottomDist[i], pointCoords[i].getY() - ne.ly)) pointFactor[i] &= ~TOEDGEBOT;					if (!DBMath.areEquals(pointTopDist[i], ne.hy - pointCoords[i].getY())) pointFactor[i] &= ~TOEDGETOP;					// see if edges are fixed distance from example center					if (!DBMath.areEquals(centerXDist[i], pointCoords[i].getX() - (ne.lx+ne.hx)/2)) pointFactor[i] &= ~FROMCENTX;					if (!DBMath.areEquals(centerYDist[i], pointCoords[i].getY() - (ne.ly+ne.hy)/2)) pointFactor[i] &= ~FROMCENTY;					// see if edges are fixed ratio from example center					double r = 0;					if (ne.hx != ne.lx)						r = (pointCoords[i].getX() - (ne.lx+ne.hx)/2) / (ne.hx-ne.lx);					if (!DBMath.areEquals(r, pointXRatio[i])) pointFactor[i] &= ~RATIOCENTX;					if (ne.hy == ne.ly) r = 0; else						r = (pointCoords[i].getY() - (ne.ly+ne.hy)/2) / (ne.hy-ne.ly);					if (!DBMath.areEquals(r, pointYRatio[i])) pointFactor[i] &= ~RATIOCENTY;				}				// make sure port information is on the primary example				if (ns.layer != Generic.tech().portNode) continue;				// check port angle				Variable var = ns.node.getVar(Info.PORTANGLE_KEY);				Variable var2 = ni.getVar(Info.PORTANGLE_KEY);				if (var == null && var2 != null)				{					System.out.println("Warning: moving port angle to main example of " + np);					ns.node.newVar(Info.PORTANGLE_KEY, var2.getObject());				}				// check port range				var = ns.node.getVar(Info.PORTRANGE_KEY);				var2 = ni.getVar(Info.PORTRANGE_KEY);				if (var == null && var2 != null)				{					System.out.println("Warning: moving port range to main example of " + np);					ns.node.newVar(Info.PORTRANGE_KEY, var2.getObject());				}				// check connectivity				var = ns.node.getVar(Info.CONNECTION_KEY);				var2 = ni.getVar(Info.CONNECTION_KEY);				if (var == null && var2 != null)				{					System.out.println("Warning: moving port connections to main example of " + np);					ns.node.newVar(Info.CONNECTION_KEY, var2.getObject());				}			}			// error check for the highlight layer			if (ns.layer == null)			{				for(int i=0; i<trueCount; i++)					if ((pointFactor[i]&(TOEDGELEFT|TOEDGERIGHT)) == 0 ||						(pointFactor[i]&(TOEDGETOP|TOEDGEBOT)) == 0)				{						error.markError(ns.node, np, "Highlight must be constant distance from edge");					return null;				}			}			// finally, make a rule for this sample			Technology.TechPoint [] newRule = stretchPoints(pointList, pointFactor, ns, np, neList);			if (newRule == null) return null;			// add the rule to the global list			ns.msg = Info.getValueOnNode(ns.node);			if (ns.msg != null && ns.msg.length() == 0) ns.msg = null;			ns.values = newRule;			// stop now if a highlight or port object			if (ns.layer == null || ns.layer == Generic.tech().portNode) continue;			nodeLayers[count] = new NodeInfo.LayerDetails();			nodeLayers[count].layer = giLayer;			nodeLayers[count].ns = ns;			nodeLayers[count].style = getStyle(ns.node);			nodeLayers[count].representation = Technology.NodeLayer.POINTS;			nodeLayers[count].values = fixValues(np, ns.values);			if (nodeLayers[count].values.length == 2)			{				if (nodeLayers[count].style == Poly.Type.CROSSED ||					nodeLayers[count].style == Poly.Type.FILLED ||					nodeLayers[count].style == Poly.Type.CLOSED)				{					nodeLayers[count].representation = Technology.NodeLayer.BOX;//					if (minFactor != 0)//						nodeLayers[count].representation = Technology.NodeLayer.MINBOX;				}			}			count++;		}		if (count != nodeLayers.length)			System.out.println("Warning: Generated only " + count + " of " + nodeLayers.length + " layers for " + np);		return nodeLayers;	}	private NodeInfo.LayerDetails [] makeNodeScaledUniformly(List<Example> neList, Cell np, LayerInfo [] lis)	{		Example firstEx = neList.get(0);		// count 

⌨️ 快捷键说明

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