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

📄 connectivity.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
				}			}		}		return touchingPi;	}	private static class Centerline	{		Point2D start, end;		EPoint startUnscaled, endUnscaled;		boolean startHub, endHub;		double width;		boolean handled;		int angle;		Centerline(double width, Point2D start, Point2D end)		{			this.width = width;			this.start = start;			this.startUnscaled = new EPoint(start.getX() / SCALEFACTOR, start.getY() / SCALEFACTOR);			this.endUnscaled = new EPoint(end.getX() / SCALEFACTOR, end.getY() / SCALEFACTOR);			this.end = end;			startHub = endHub = false;			if (start.equals(end)) angle = -1; else				angle = GenMath.figureAngle(end, start);		}		void setStart(double x, double y)		{			start.setLocation(x, y);			startUnscaled = new EPoint(x / SCALEFACTOR, y / SCALEFACTOR);		}		void setEnd(double x, double y)		{			end.setLocation(x, y);			endUnscaled = new EPoint(x / SCALEFACTOR, y / SCALEFACTOR);		}		public String toString()		{			return "CENTERLINE from (" + TextUtils.formatDouble(start.getX()/SCALEFACTOR) + "," +				TextUtils.formatDouble(start.getY()/SCALEFACTOR) + ") to (" +				TextUtils.formatDouble(end.getX()/SCALEFACTOR) + "," +				TextUtils.formatDouble(end.getY()/SCALEFACTOR) + ") wid=" +				TextUtils.formatDouble(width/SCALEFACTOR) + ", len=" +				TextUtils.formatDouble((start.distance(end)/SCALEFACTOR));		}	}	/**	 * Method to return the port and location to use for one end of a Centerline.	 * @param cl the Centerline to connect	 * @param loc1 it's location (values returned through this object!)	 * @param layer the layer associated with the Centerline.	 * @param ap the type of arc to create.	 * @param startSide true to	 * @param newCell the Cell in which to find ports.	 * @return the PortInst on the Centerline.	 */	private PortInst locatePortOnCenterline(Centerline cl, Point2D loc1, Layer layer, ArcProto ap, boolean startSide, Cell newCell)	{		PortInst piRet = null;		boolean isHub = cl.endHub;		EPoint startPoint = cl.endUnscaled;		if (startSide)		{			isHub = cl.startHub;			startPoint = cl.startUnscaled;		}		if (!isHub)		{			List<PortInst> possiblePorts = findPortInstsTouchingPoint(startPoint, layer, newCell, ap);			for(PortInst pi : possiblePorts)			{				Poly portPoly = pi.getPoly();				Point2D [] points = portPoly.getPoints();				if (points.length == 1)				{					Point2D iPt = GenMath.intersect(cl.startUnscaled, cl.angle, points[0], (cl.angle+900)%3600);					if (iPt != null)					{						loc1.setLocation(iPt.getX(), iPt.getY());						piRet = pi;						break;					}				} else				{					if (portPoly.contains(startPoint))					{						loc1.setLocation(startPoint);						piRet = pi;						break;					}					for(int i=0; i<points.length; i++)					{						int last = i-1;						if (last < 0) last = points.length-1;						Point2D portLineFrom = points[last];						Point2D portLineTo = points[i];						Point2D interPt = null;						if (portLineFrom.equals(portLineTo))						{							interPt = GenMath.intersect(cl.startUnscaled, cl.angle, portLineFrom, (cl.angle+900)%3600);						} else						{							int angPortLine = GenMath.figureAngle(portLineFrom, portLineTo);							interPt = GenMath.intersect(portLineFrom, angPortLine, cl.startUnscaled, cl.angle);							if (interPt != null)							{								if (interPt.getX() < Math.min(portLineFrom.getX(), portLineTo.getX()) ||									interPt.getX() > Math.max(portLineFrom.getX(), portLineTo.getX()) ||									interPt.getY() < Math.min(portLineFrom.getY(), portLineTo.getY()) ||									interPt.getY() > Math.max(portLineFrom.getY(), portLineTo.getY())) interPt = null;							}						}						if (interPt == null) continue;						loc1.setLocation(interPt.getX(), interPt.getY());						if (!portPoly.contains(loc1)) continue;						piRet = pi;						break;					}					if (piRet != null) break;				}			}		}		if (piRet == null)		{			// shrink the end inward by half-width			PrimitiveNode pin = ap.findPinProto();			int ang = GenMath.figureAngle(cl.start, cl.end);			double xOff = GenMath.cos(ang) * cl.width/2;			double yOff = GenMath.sin(ang) * cl.width/2;			if (startSide)			{				if (!isHub && cl.start.distance(cl.end) > cl.width)					cl.setStart(cl.start.getX() + xOff, cl.start.getY() + yOff);				NodeInst ni = wantNodeAt(cl.startUnscaled, pin, cl.width / SCALEFACTOR, newCell);				loc1.setLocation(cl.startUnscaled.getX(), cl.startUnscaled.getY());				piRet = ni.getOnlyPortInst();			} else			{				if (!isHub && cl.start.distance(cl.end) > cl.width)					cl.setEnd(cl.end.getX() - xOff, cl.end.getY() - yOff);				NodeInst ni = wantNodeAt(cl.endUnscaled, pin, cl.width / SCALEFACTOR, newCell);				loc1.setLocation(cl.endUnscaled.getX(), cl.endUnscaled.getY());				piRet = ni.getOnlyPortInst();			}		}		return piRet;	}	private List<PortInst> findPortInstsTouchingPoint(Point2D pt, Layer layer, Cell newCell, ArcProto ap)	{		List<PortInst> touchingNodes = new ArrayList<PortInst>();		boolean mightCreateExports = false;		Rectangle2D checkBounds = new Rectangle2D.Double(pt.getX(), pt.getY(), 0, 0);		for(Iterator<RTBounds> it = newCell.searchIterator(checkBounds); it.hasNext(); )		{			RTBounds geom = it.next();			if (!(geom instanceof NodeInst)) continue;			NodeInst ni = (NodeInst)geom;			if (ni.isCellInstance())			{				boolean found = false;				for(Iterator<PortInst> pIt = ni.getPortInsts(); pIt.hasNext(); )				{					PortInst pi = pIt.next();					Poly portPoly = pi.getPoly();					if (portPoly.contains(pt))					{						touchingNodes.add(pi);						found = true;						break;					}				}				if (found) continue;				// remember that a cell was found...might have to create exports on it				mightCreateExports = true;				continue;			}			// for pins, must be centered over the desired point			if (ni.getFunction() == PrimitiveNode.Function.PIN)			{				if (!ni.getOnlyPortInst().getPortProto().connectsTo(ap)) continue;				if (ni.getAnchorCenter().equals(pt))				{					touchingNodes.add(ni.getOnlyPortInst());				}			} else			{				// nonpins can have any touching and connecting layer				Poly [] polys = tech.getShapeOfNode(ni, true, true, null);				AffineTransform trans = ni.rotateOut();				for(int i=0; i<polys.length; i++)				{					Poly oPoly = polys[i];					Layer oLayer = geometricLayer(oPoly.getLayer());					if (layer != oLayer) continue;					oPoly.transform(trans);					// do the polys touch?					if (oPoly.contains(pt))					{						PortInst touchingPi = findPortInstClosestToPoly(ni, (PrimitivePort)oPoly.getPort(), pt);						if (touchingPi == null)						{                            addErrorLog(newCell, "Can't find port for "+ni+" and "+oPoly.getPort(),                                new EPoint(pt.getX(), pt.getY()));                            continue;						}						touchingNodes.add(touchingPi);						break;					}				}			}		}		// if no ports were found but there were cells, should create new exports in the cells		if (touchingNodes.size() == 0 && mightCreateExports)		{			// can we create an export on the cell?			PortInst pi = makePort(newCell, layer, pt);			if (pi != null)				touchingNodes.add(pi);		}		return touchingNodes;	}	/**	 * Method to connect to a given location and layer.	 * @param cell the cell in which this location/layer exists.	 * @param layer the layer on which to connect.	 * @param pt the location in the Cell for the connection.	 * @return a PortInst on a node in the Cell (null if it cannot be found).	 */	private PortInst makePort(Cell cell, Layer layer, Point2D pt)	{		Rectangle2D checkBounds = new Rectangle2D.Double(pt.getX(), pt.getY(), 0, 0);		for(Iterator<RTBounds> it = cell.searchIterator(checkBounds); it.hasNext(); )		{			RTBounds geom = it.next();			if (!(geom instanceof NodeInst)) continue;			NodeInst subNi = (NodeInst)geom;			PortInst foundPi = null;			if (subNi.isCellInstance())			{				AffineTransform transIn = subNi.rotateIn(subNi.translateIn());				Point2D inside = new Point2D.Double();				transIn.transform(pt, inside);				Cell subCell = (Cell)subNi.getProto();				PortInst pi = makePort(subCell, layer, inside);				if (pi != null)				{					// already exported?					for(Iterator<Export> eIt = pi.getNodeInst().getExports(); eIt.hasNext(); )					{						Export e = eIt.next();						if (e.getOriginalPort() == pi)						{							foundPi = subNi.findPortInstFromProto(e);							return foundPi;						}					}					// if not already exported, make the export now					if (foundPi == null)					{						Netlist nl = subCell.acquireUserNetlist();						Network net = nl.getNetwork(pi);						String exportName = null;						for(Iterator<String> nIt = net.getExportedNames(); nIt.hasNext(); )						{							String eName = nIt.next();							if (exportName == null || exportName.length() < eName.length()) exportName = eName;						}						if (exportName == null) exportName = "E";						exportName = ElectricObject.uniqueObjectName(exportName, subCell, PortProto.class, true);						Export e = Export.newInstance(subCell, pi, exportName);						foundPi = subNi.findPortInstFromProto(e);						return foundPi;					}				}			} else			{				Technology tech = subNi.getProto().getTechnology();				AffineTransform trans = subNi.rotateOut();				Poly [] polyList = tech.getShapeOfNode(subNi, true, true, null);				for(int i=0; i<polyList.length; i++)				{					Poly poly = polyList[i];					if (poly.getPort() == null) continue;					if (geometricLayer(poly.getLayer()) != layer) continue;					poly.transform(trans);					if (poly.contains(pt))					{						// found polygon that touches the point.  Make the export						foundPi = findPortInstClosestToPoly(subNi, (PrimitivePort)poly.getPort(), pt);						return foundPi;					}				}			}		}		return null;	}	/********************************************** VIA/CONTACT EXTRACTION **********************************************/	private static class PossibleVia	{		PrimitiveNode pNp;		int rotation;		double minWidth, minHeight;		double largestShrink;		Technology.NodeLayer cutNodeLayer;		Layer [] layers;		double [] shrinkL, shrinkR, shrinkT, shrinkB;		PossibleVia(PrimitiveNode pNp, int numLayers)		{			this.pNp = pNp;			layers = new Layer[numLayers];			shrinkL = new double[numLayers];			shrinkR = new double[numLayers];			shrinkT = new double[numLayers];			shrinkB = new double[numLayers];		}	}	/**	 * Method to scan the geometric information for possible contacts and vias.	 * Any vias found are created in the new cell and removed from the geometric information.     * @param merge     * @param originalMerge     * @param newCell     * @return False if the job was aborted     */    private boolean extractVias(PolyMerge merge, PolyMerge originalMerge, Cell newCell)	{		// make a list of all via/cut layers in the technology and count the number of vias/cuts		int totalCuts = 0;		List<Layer> layers = new ArrayList<Layer>();		for (Layer layer : allCutLayers.keySet())		{			layers.add(layer);			List<PolyBase> cutList = allCutLayers.get(layer);			totalCuts += cutList.size();		}		// initialize list of nodes that have been created		List<NodeInst> contactNodes = new ArrayList<NodeInst>();		// examine all vias/cuts for possible contacts		int soFar = 0;

⌨️ 快捷键说明

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