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

📄 autostitch.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
					PortProto rPp = mPp;					while (rNi.isCellInstance())					{						AffineTransform temp = rNi.translateOut();						temp.preConcatenate(trans);						Export e = (Export)rPp;						rNi = e.getOriginalPort().getNodeInst();						rPp = e.getOriginalPort().getPortProto();						trans = rNi.rotateOut();						trans.preConcatenate(temp);					}					// see how much geometry is on this node					Poly [] polys = shapeOfNode(rNi);					int tot = polys.length;					if (tot == 0)					{						// not a geometric primitive: look for ports that touch						Poly oPoly = oNi.getShapeOfPort(mPp);						if (comparePoly(oNi, mPp, oPoly, oNet, ni, pp, poly, net, ap, stayInside, top, limitBound))							return true;					} else					{						// a geometric primitive: look for ports on layers that touch						Netlist subNetlist = rNi.getParent().getUserNetlist();						for(int j=0; j<tot; j++)						{							Poly oPoly = polys[j];							// only want electrically connected polygons							if (oPoly.getPort() == null) continue;							// only want polygons connected to correct part of nodeinst							if (!subNetlist.portsConnected(rNi, rPp, oPoly.getPort())) continue;							// if the polygon layer is pseudo, substitute real layer							if (ni.getProto() != Generic.tech().simProbeNode)							{								Layer oLayer = oPoly.getLayer();								if (oLayer != null) oLayer = oLayer.getNonPseudoLayer();								Layer apLayer = arcLayers.get(ap);								if (!oLayer.getTechnology().sameLayer(oLayer, apLayer)) continue;							}							// transform the polygon and pass it on to the next test							oPoly.transform(trans);							if (comparePoly(oNi, mPp, oPoly, oNet, ni, pp, poly, net, ap, stayInside, top, limitBound))								return true;						}					}				}			}		} else		{			// primitive node: check its layers			AffineTransform trans = oNi.rotateOut();			// determine target point			double ox = poly.getCenterX();			double oy = poly.getCenterY();			// look at all polygons on nodeinst oNi			Poly [] polys = shapeOfNode(oNi);			int tot = polys.length;			if (tot == 0)			{				// not a geometric primitive: look for ports that touch				PortProto bestPp = null;				double bestDist = 0;				for(Iterator<PortProto> pIt = oNi.getProto().getPorts(); pIt.hasNext(); )				{					PortProto rPp = pIt.next();					// compute best distance to the other node					Poly portPoly = oNi.getShapeOfPort(rPp);					double dist = Math.abs(portPoly.getCenterX()-ox) + Math.abs(portPoly.getCenterY()-oy);					if (bestPp == null)					{						bestDist = dist;						bestPp = rPp;					}					if (dist > bestDist) continue;					bestPp = rPp;   bestDist = dist;				}				if (bestPp != null)				{					PortProto rPp = bestPp;					Network oNet = top.getPortNetwork(oNi.findPortInstFromProto(bestPp));					if (net == null || oNet != net)					{						// port must be able to connect to the arc						if (rPp.getBasePort().connectsTo(ap))						{							// transformed the polygon and pass it on to the next test							Poly oPoly = oNi.getShapeOfPort(rPp);							if (comparePoly(oNi, rPp, oPoly, oNet, ni, pp, poly, net, ap, stayInside, top, limitBound))								return true;						}					}				}			} else			{				// a geometric primitive: look for ports on layers that touch				for(int j=0; j<tot; j++)				{					Poly oPoly = polys[j];					// only want electrically connected polygons					if (oPoly.getPort() == null) continue;					// if the polygon layer is pseudo, substitute real layer					Layer oLayer = oPoly.getLayer();					if (oLayer != null) oLayer = oLayer.getNonPseudoLayer();					// this must be the smallest layer on the arc					Layer apLayer = arcLayers.get(ap);					if (!apLayer.getTechnology().sameLayer(apLayer, oLayer)) continue;					// do not stitch where there is already an electrical connection					PortInst oPi = oNi.findPortInstFromProto(oPoly.getPort());					Network oNet = top.getPortNetwork(oPi);					if (net != null && oNet == net) continue;					// search all ports for the closest connected to this layer					PortProto bestPp = null;					double bestDist = 0;					for(Iterator<PortProto> pIt = oNi.getProto().getPorts(); pIt.hasNext(); )					{						PortProto rPp = pIt.next();						if (!top.portsConnected(oNi, rPp, oPoly.getPort())) continue;						// compute best distance to the other node						Poly portPoly = oNi.getShapeOfPort(rPp);						double dist = Math.abs(ox-portPoly.getCenterX()) + Math.abs(oy-portPoly.getCenterY());						if (bestPp == null) bestDist = dist;						if (dist > bestDist) continue;						bestPp = rPp;   bestDist = dist;					}					if (bestPp == null) continue;					PortProto rPp = bestPp;					// port must be able to connect to the arc					if (!rPp.getBasePort().connectsTo(ap)) continue;					// transformed the polygon and pass it on to the next test					oPoly.transform(trans);					if (comparePoly(oNi, rPp, oPoly, oNet, ni, pp, poly, net, ap, stayInside, top, limitBound))						return true;				}			}		}		return false;	}	/**	 * Method to compare two polygons.  If these polygons touch	 * or overlap then the two nodes should be connected.	 * @param oNi the NodeInst responsible for the first polygon.	 * @param opp the PortProto responsible for the first polygon.	 * @param oPoly the first polygon.	 * @param oNet the Network responsible for the first polygon.	 * @param ni the NodeInst responsible for the second polygon.	 * @param pp the PortProto responsible for the second polygon.	 * @param poly the second polygon.	 * @param net the Network responsible for the second polygon.	 * @param ap the type of arc to use when stitching the nodes.	 * @param stayInside is the area in which to route (null to route arbitrarily).	 * @param top the netlist for the Cell with the polygons.	 * @param limitBound if not null, only consider connections that occur in this area.	 * @return true if the connection is made.	 */	private boolean comparePoly(NodeInst oNi, PortProto opp, Poly oPoly, Network oNet,		NodeInst ni, PortProto pp, Poly poly, Network net,		ArcProto ap, PolyMerge stayInside, Topology top, Rectangle2D limitBound)	{		// find the bounding boxes of the polygons		if (poly.separation(oPoly) >= DBMath.getEpsilon()) return false;		// be sure the closest ports are being used		Poly portPoly = ni.getShapeOfPort(pp);		Point2D portCenter = new Point2D.Double(portPoly.getCenterX(), portPoly.getCenterY());		Poly oPortPoly = oNi.getShapeOfPort(opp);		Point2D oPortCenter = new Point2D.Double(oPortPoly.getCenterX(), oPortPoly.getCenterY());		if (USEQTREE && stayInside == null)		{			if (ni.isCellInstance() || oNi.isCellInstance())			{				Rectangle2D polyBounds = portPoly.getBounds2D();				Rectangle2D oPolyBounds = oPortPoly.getBounds2D();				// quit now if bounding boxes don't intersect				if ((polyBounds.getMinX() > oPolyBounds.getMaxX() || oPolyBounds.getMinX() > polyBounds.getMaxX()) &&					(polyBounds.getMinY() > oPolyBounds.getMaxY() || oPolyBounds.getMinY() > polyBounds.getMaxY())) return false;			}		}		double dist = portCenter.distance(oPortCenter);		for(Iterator<PortProto> it = oNi.getProto().getPorts(); it.hasNext(); )		{			PortProto tPp = it.next();			if (tPp == opp) continue;			if (!top.portsConnected(oNi, tPp, opp)) continue;			portPoly = oNi.getShapeOfPort(tPp);			Point2D tPortCenter = new Point2D.Double(portPoly.getCenterX(), portPoly.getCenterY());			double tDist = portCenter.distance(tPortCenter);			if (tDist >= dist) continue;			dist = tDist;			opp = tPp;			oPortCenter.setLocation(tPortCenter);		}		for(Iterator<PortProto> it = ni.getProto().getPorts(); it.hasNext(); )		{			PortProto tPp = it.next();			if (tPp == pp) continue;			if (!top.portsConnected(ni, tPp, pp)) continue;			portPoly = ni.getShapeOfPort(tPp);			Point2D tPortCenter = new Point2D.Double(portPoly.getCenterX(), portPoly.getCenterY());			double tDist = oPortCenter.distance(tPortCenter);			if (tDist >= dist) continue;			dist = tDist;			pp = tPp;			portCenter.setLocation(tPortCenter);		}		// reject connection if it is out of the limit bounds		if (limitBound != null)		{			if (!DBMath.pointInRect(portCenter, limitBound) && !DBMath.pointInRect(oPortCenter, limitBound))				return false;		}		// find some dummy position to help run the arc		double x = (oPortCenter.getX() + portCenter.getX()) / 2;		double y = (oPortCenter.getY() + portCenter.getY()) / 2;		// run the wire		PortInst pi = ni.findPortInstFromProto(pp);		PortInst opi = oNi.findPortInstFromProto(opp);		return connectObjects(pi, net, opi, oNet, ni.getParent(), new Point2D.Double(x,y), stayInside, top);	}	/**	 * Method to connect two objects if they touch.	 * @param eobj1 the first object (either an ArcInst or a PortInst).	 * @param net1 the network on which the first object resides.	 * @param eobj2 the second object (either an ArcInst or a PortInst).	 * @param net2 the network on which the second object resides.	 * @param cell the Cell in which these objects reside.	 * @param ctr bend point suggestion when making "L" connection.	 * @param stayInside is the area in which to route (null to route arbitrarily).	 * @param top the topology of the cell.	 * @return true if a connection is made.	 */	private boolean connectObjects(ElectricObject eobj1, Network net1, ElectricObject eobj2, Network net2,		Cell cell, Point2D ctr, PolyMerge stayInside, Topology top)	{		// run the wire		NodeInst ni1 = null;		if (eobj1 instanceof NodeInst) ni1 = (NodeInst)eobj1; else			if (eobj1 instanceof PortInst) ni1 = ((PortInst)eobj1).getNodeInst();		NodeInst ni2 = null;		if (eobj2 instanceof NodeInst) ni2 = (NodeInst)eobj2; else			if (eobj2 instanceof PortInst) ni2 = ((PortInst)eobj2).getNodeInst();		Route route = router.planRoute(cell, eobj1, eobj2, ctr, stayInside, true, true);		if (route.size() == 0) return false;//		// see if this caused an arc to be deleted//		boolean deletedArc = false;//        for (RouteElement e : route)//            if (e.getAction() == RouteElement.RouteElementAction.deleteArc) { deletedArc = true;  break; }        allRoutes.add(route);		top.connect(net1, net2);		// if either ni or oNi is a pin primitive, see if it is a candidate for clean-up		if (ni1 != null)		{			if (ni1.getFunction() == PrimitiveNode.Function.PIN &&				!ni1.hasExports() && !ni1.hasConnections())			{				possibleInlinePins.add(ni1);			}		}		if (ni2 != null)		{			if (ni2.getFunction() == PrimitiveNode.Function.PIN &&				!ni2.hasExports() && !ni2.hasConnections())			{				possibleInlinePins.add(ni2);			}		}		return true;	}	/****************************************** EXPORT-CREATION STITCHING ******************************************/	/**	 * Method to check an object for possible stitching to neighboring objects with export creation.	 * Actual stitching is not done, but necessary exports are created.	 * @param geom the object to check for stitching.	 */	private void checkExportCreationStitching(Geometric geom)	{		Cell cell = geom.getParent();		NodeInst ni = null;		if (geom instanceof NodeInst) ni = (NodeInst)geom;		// make a list of other geometrics that touch or overlap this one (copy it because the main list will change)		List<Geometric> geomsInArea = new ArrayList<Geometric>();		Rectangle2D geomBounds = geom.getBounds();		double epsilon = DBMath.getEpsilon();		Rectangle2D searchBounds = new Rectangle2D.Double(geomBounds.getMinX()-epsilon, geomBounds.getMinY()-epsilon,			geomBounds.getWidth()+epsilon*2, geomBounds.getHeight()+epsilon*2);		for(Iterator<RTBounds> it = cell.searchIterator(searchBounds); it.hasNext(); )		{			Geometric oGeom = (Geometric)it.next();			if (oGeom != geom) geomsInArea.add(oGeom);		}		for(Geometric oGeom : geomsInArea)		{			// find another node in this area			if (oGeom instanceof ArcInst)			{				// other geometric is an ArcInst				ArcInst oAi = (ArcInst)oGeom;				if (ni == null) continue;				// compare node "ni" against arc "oAi"				if (ni.isCellInstance())					compareNodeInstWithArcMakeExport(ni, oAi);			} else			{				// other geometric a NodeInst				NodeInst oNi = (NodeInst)oGeom;				if (!oNi.isCellInstance())				{					PrimitiveNode pnp = (PrimitiveNode)oNi.getProto();					if (pnp.getTechnology() == Generic.tech()) continue;					if (pnp.getFunction() == PrimitiveNode.Function.NODE) continue;				}				if (ni == null)				{					// compare arc "geom" against node "oNi"					if (oNi.isCellInstance())						compareNodeInstWithArcMakeExport(oNi, (ArcInst)geom);					continue;				}				// compare node "ni" against node "oNi"				if (oNi.isCellInstance() && ni.isCellInstance())				{					compareTwoNodesMakeExport(ni, oNi);				}			}		}	}	/**	 * Method to compare a node instance and an arc to see if they touch and should be connected and an export created.	 * @param ni the NodeInst to compare.	 * @param ai the ArcInst to compare.	 */	private void compareNodeInstWithArcMakeExport(NodeInst ni, ArcInst ai)	{		// get the 

⌨️ 快捷键说明

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