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

📄 layoutcell.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
				// figure out the new location of the other nodeinst				Point2D ptD = new Point2D.Double();				trans.transform(ono.getAnchorCenter(), ptD);				dx = ptD.getX();   dy = ptD.getY();				dx = dx - ono.getAnchorCenterX() - othX;				dy = dy - ono.getAnchorCenterY() - othY;				// ignore null motion on nodes that have already been examined				if (dx != 0 || dy != 0 || !dOrient.equals(Orientation.IDENT))				{                    rigidModified.add(ai);					if (Layout.DEBUG) System.out.println("    Moving "+ono+" at other end by ("+dx+","+dy+")");                    alterNodeInst(ono, dx, dy, dOrient);				}			}			// move the arcinst			if (Layout.DEBUG) System.out.println("    Altering arc, head moves to "+newPts[ArcInst.HEADEND]+" tail moves to "+newPts[ArcInst.TAILEND]);			doMoveArcInst(ai, newPts[ArcInst.HEADEND], newPts[ArcInst.TAILEND], AI_RIGID);		}		// re-scan rigid arcs and recursively modify arcs on other nodes		for(Connection thisEnd : rigidArcs)		{            ArcInst ai = thisEnd.getArc();			if (!ai.isLinked()) continue;			// only want arcinst that was just explored            if (!rigidModified.contains(ai)) continue;			// get the other nodeinst			NodeInst ono = ai.getPortInst(1 - thisEnd.getEndIndex()).getNodeInst();			if (Layout.DEBUG) System.out.println("  " + ni + " re-examining " + ai + " to other "+ono);			modNodeArcs(ono, dOrient);		}	}	/**	 * Method to modify the flexible arcs connected to a NodeInst.	 * @param ni the NodeInst being examined.	 * @param dOrient the change in the node Orientation.	 * @return true if any nodes that have exports move.	 * This indicates that instances of the current cell must be examined for ArcInst motion.	 */	private void modFlex(NodeInst ni, Orientation dOrient)	{		// build a list of the flexible arcs on this nodeinst		List<Connection> flexArcs = new ArrayList<Connection>();		for(Iterator<Connection> it = getConnections(ni); it.hasNext(); )//		for(Iterator<Connection> it = ni.getConnections(); it.hasNext(); )		{			Connection con = it.next();			ArcInst ai = con.getArc();			// ignore if arcinst is not flexible//			if (getChangeClock(ai) == AI_RIGID.intValue()) continue;			if (Layout.isRigid(ai)) continue;			// ignore arcs that connect two ports on the same node			if (ai.getHeadPortInst().getNodeInst() == ai.getTailPortInst().getNodeInst()) continue;			// include in the list to be considered here            flexArcs.add(con);		}		if (flexArcs.size() == 0) return;		// look at all of the flexible arcs on this nodeinst//        long startTime = System.currentTimeMillis();		for(Connection thisEnd : flexArcs)		{            ArcInst ai = thisEnd.getArc();			if (!ai.isLinked()) continue;			if (Layout.DEBUG) System.out.println("  Modifying fixed-angle "+ai);			// if flexible arcinst has been changed, verify its connectivity			if (arcMoved(ai))//			if (getChangeClock(ai) >= AI_FLEX.intValue())			{				if (Layout.DEBUG) System.out.println("   Arc already changed");				ensureArcInst(ai, AI_FLEX);				continue;			}			// figure where each end of the arcinst is            int thisEndIndex = thisEnd.getEndIndex();            int thatEndIndex = 1 - thisEndIndex;            EPoint thisLocation = thisEnd.getLocation();            EPoint thatLocation = ai.getLocation(thatEndIndex);			// if nodeinst motion stays within port area, ignore the arcinst			if (ai.isSlidable() && ai.stillInPort(thisEndIndex, thisLocation, true))				continue;			// create the two points that will be the new ends of this arc			Point2D [] newPts = new Point2D.Double[2];            for (int i = 0; i < 2; i++) {                newPts[i] = new Point2D.Double();                AffineTransform trans = transformByPort(ai.getPortInst(i));                trans.transform(ai.getLocation(i), newPts[i]);                newPts[i].setLocation(DBMath.round(newPts[i].getX()),                    DBMath.round(newPts[i].getY()));            }			// make sure the arc end is still in the port			Poly poly = thisEnd.getPortInst().getPoly();			if (!poly.isInside(newPts[thisEndIndex]))			{				Rectangle2D bbox = poly.getBounds2D();				if (newPts[thisEndIndex].getY() >= bbox.getMinY() && newPts[thisEndIndex].getY() <= bbox.getMaxY())				{					// extend arc horizontally to fit in port					if (newPts[thisEndIndex].getX() < bbox.getMinX())					{						newPts[thisEndIndex].setLocation(bbox.getMinX(), newPts[thisEndIndex].getY());					} else if (newPts[thisEndIndex].getX() > bbox.getMaxX())					{						newPts[thisEndIndex].setLocation(bbox.getMaxX(), newPts[thisEndIndex].getY());					}				} else if (newPts[thisEndIndex].getX() >= bbox.getMinX() && newPts[thisEndIndex].getX() <= bbox.getMaxX())				{					// extend arc vertically to fit in port					if (newPts[thisEndIndex].getY() < bbox.getMinY())					{						newPts[thisEndIndex].setLocation(newPts[thisEndIndex].getX(), bbox.getMinY());					} else if (newPts[thisEndIndex].getY() > bbox.getMaxY())					{						newPts[thisEndIndex].setLocation(newPts[thisEndIndex].getX(), bbox.getMaxY());					}				} else				{					// extend arc arbitrarily to fit in port					Point2D pt = poly.closestPoint(newPts[thisEndIndex]);					newPts[thisEndIndex].setLocation(pt);				}			}			// get other end of arcinst and its position			NodeInst ono = ai.getPortInst(thatEndIndex).getNodeInst();//			newPts[thatEndIndex].setLocation(thatLocation);			// see if other nodeinst has changed			boolean mangle = true;            if (movedNodes.contains(ono)) mangle = false;			if (!ai.isFixedAngle()) mangle = false; else			{				if (ono.isLocked()) mangle = false; else				{					if (ono.isCellInstance())					{						if (ono.getParent().isInstancesLocked()) mangle = false;					} else					{						if (User.isDisallowModificationLockedPrims() &&							((PrimitiveNode)ono.getProto()).isLockedPrim()) mangle = false;					}				}            }			if (mangle)			{				// other nodeinst untouched, mangle it				double dx = newPts[thisEndIndex].getX() - thisLocation.getX();				double dy = newPts[thisEndIndex].getY() - thisLocation.getY();				double odx = newPts[thatEndIndex].getX() - thatLocation.getX();				double ody = newPts[thatEndIndex].getY() - thatLocation.getY();				if (DBMath.doublesEqual(thisLocation.getX(), thatLocation.getX()))				{					// null arcinst must not be explicitly horizontal					if (!DBMath.doublesEqual(thisLocation.getY(), thatLocation.getY()) ||						ai.getAngle() == 900 || ai.getAngle() == 2700)					{						// vertical arcinst: see if it really moved in X						if (dx == odx) dx = odx = 0;						// move horizontal, shrink vertical						newPts[thatEndIndex].setLocation(newPts[thatEndIndex].getX() + dx-odx, newPts[thatEndIndex].getY());						// see if next nodeinst need not be moved						if (!DBMath.doublesEqual(dx, odx) && ai.isSlidable() && ai.stillInPort(thatEndIndex, newPts[thatEndIndex], true))							dx = odx = 0;						// if other node already moved, don't move it any more						if (movedNodes.contains(ono)) dx = odx = 0;						if (dx != odx)						{							double xAmount = DBMath.round(dx-odx);							if (Layout.DEBUG) System.out.println("  Moving "+ono+" by ("+xAmount+",0)");							alterNodeInst(ono, xAmount, 0, Orientation.IDENT);						}						if (Layout.DEBUG) System.out.println("  Moving vertical arc so head=("+newPts[ArcInst.HEADEND].getX()+","+newPts[ArcInst.HEADEND].getY()+							") and tail=("+newPts[ArcInst.TAILEND].getX()+","+newPts[ArcInst.TAILEND].getY()+")");						doMoveArcInst(ai, newPts[ArcInst.HEADEND], newPts[ArcInst.TAILEND], AI_FLEX);						if (!DBMath.doublesEqual(dx, odx))							modNodeArcs(ono, Orientation.IDENT);						continue;					}				}				if (DBMath.doublesEqual(thisLocation.getY(), thatLocation.getY()))				{					// horizontal arcinst: see if it really moved in Y					if (DBMath.doublesEqual(dy, ody)) dy = ody = 0;					// shrink horizontal, move vertical					newPts[thatEndIndex].setLocation(newPts[thatEndIndex].getX(), newPts[thatEndIndex].getY() + dy-ody);					// see if next nodeinst need not be moved					if (!DBMath.doublesEqual(dy, ody) && ai.isSlidable() &&						ai.stillInPort(thatEndIndex, newPts[thatEndIndex], true))							dy = ody = 0;					// if other node already moved, don't move it any more					if (movedNodes.contains(ono)) dx = odx = 0;					if (!DBMath.doublesEqual(dy, ody))					{						if (Layout.DEBUG) System.out.println("  Moving "+ono+" by (0,"+(dy-ody)+")");						alterNodeInst(ono, 0, dy-ody, Orientation.IDENT);					}					if (Layout.DEBUG) System.out.println("  Moving horizontal arc so head=("+newPts[ArcInst.HEADEND].getX()+","+newPts[ArcInst.HEADEND].getY()+						") and tail=("+newPts[ArcInst.TAILEND].getX()+","+newPts[ArcInst.TAILEND].getY()+")");					doMoveArcInst(ai, newPts[ArcInst.HEADEND], newPts[ArcInst.TAILEND], AI_FLEX);					if (!DBMath.doublesEqual(dy, ody))					{						modNodeArcs(ono, Orientation.IDENT);					}					continue;				}				/***** THIS CODE HANDLES ALL-ANGLE RIGIDITY WITH THE FIXED-ANGLE CONSTRAINT *****/				// special code to handle nonorthogonal fixed-angles				nonOrthogFixAng(ai, thisEnd, thisEndIndex, thatEndIndex, ono, newPts);				dx = newPts[thatEndIndex].getX() - thatLocation.getX();				dy = newPts[thatEndIndex].getY() - thatLocation.getY();				// change the arc				updateArc(ai, newPts[ArcInst.HEADEND], newPts[ArcInst.TAILEND], AI_FLEX);				// if other node already moved, don't move it any more				if (movedNodes.contains(ono)) dx = dy = 0;				if (dx != 0 || dy != 0)				{					if (Layout.DEBUG) System.out.println("  Moving "+ono+" by ("+dx+","+dy+")");					alterNodeInst(ono, dx, dy, Orientation.IDENT);					modNodeArcs(ono, Orientation.IDENT);				}				continue;			}			// other node has changed or arc is funny, just use its position			if (Layout.DEBUG) System.out.println("  Moving nonmanhattan arc so head=("+newPts[ArcInst.HEADEND].getX()+","+newPts[ArcInst.HEADEND].getY()+				") and tail=("+newPts[ArcInst.TAILEND].getX()+","+newPts[ArcInst.TAILEND].getY()+")");			doMoveArcInst(ai, newPts[ArcInst.HEADEND], newPts[ArcInst.TAILEND], AI_FLEX);		}//        long stopTime = System.currentTimeMillis();//        System.out.println("Moving in modFlex took " + (stopTime - startTime));	}	/**	 * Method to determine the motion of a nonorthogonal ArcInst given that one end has moved.	 * The end that is "thisEnd" has moved to (ax[thisEndIndex],ay[thisEndIndex]), so this method	 * must determine the coordinates of the other end and set (ax[thatEndIndex],ay[thatEndIndex]).	 * @param ai the nonorthogonal ArcInst that is adjusting.	 * @param thisEnd the Connection at one end of the ArcInst.	 * @param thisEndIndex the index (0 or 1) of "thisEnd" of the ArcInst.	 * @param thatEnd the Connection at the other end of the ArcInst.	 * @param thatEndIndex the index (0 or 1) of "thatEnd" of the ArcInst.	 * @param ono the node at the other end ("thatEnd").	 * @param newPts an array of 2 points that defines the coordinates of the two ends (0: head, 1: tail).	 */	private void nonOrthogFixAng(ArcInst ai, Connection thisEnd, int thisEndIndex, int thatEndIndex,		NodeInst ono, Point2D [] newPts)	{		// look for longest other arc on "ono" to determine proper end position		double bestDist = Double.NEGATIVE_INFINITY;		ArcInst bestAI = null;		for(Iterator<Connection> it = getConnections(ai.getPortInst(thatEndIndex)); it.hasNext(); )//		for(Iterator<Connection> it = ai.getPortInst(thatEndIndex).getConnections(); it.hasNext(); )		{			Connection con = it.next();			ArcInst oai = con.getArc();			if (oai == ai) continue;            double length = oai.getGridLength();			if (length <= bestDist) continue;			bestDist = length;			bestAI = oai;		}		// if no other arcs, allow that end to move the same as this end		if (bestAI == null)		{			newPts[thatEndIndex].setLocation(				newPts[thatEndIndex].getX() + newPts[thisEndIndex].getX() - thisEnd.getLocation().getX(),				newPts[thatEndIndex].getY() + newPts[thisEndIndex].getY() - thisEnd.getLocation().getY());			return;		}		// compute intersection of arc "bestai" with new moved arc "ai"		Point2D inter = DBMath.intersect(newPts[thisEndIndex], ai.getAngle(),			bestAI.getHeadLocation(), bestAI.getAngle());		if (inter == null)		{			newPts[thatEndIndex].setLocation(				newPts[thatEndIndex].getX() + newPts[thisEndIndex].getX() - thisEnd.getLocation().getX(),				newPts[thatEndIndex].getY() + newPts[thisEndIndex].getY() - thisEnd.getLocation().getY());			return;		}		newPts[thatEndIndex].setLocation(inter);	}	/**	 * Method to ensure that an ArcInst is still connected properly at each end.	 * If it is not, the ArcInst must be jogged or adjusted.	 * @param ai the ArcInst to check.	 * @param arctyp the nature of the arc: 0 for rigid, 1 for flexible.	 */	private void ensureArcInst(ArcInst ai, Integer arctyp)	{		// if nothing is outside port, quit		Point2D headPoint = ai.getHeadLocation();		boolean inside0 = ai.headStillInPort(headPoint, true);		Point2D tailPoint = ai.getTailLocation();		boolean inside1 = ai.tailStillInPort(tailPoint, true);		if (inside0 && inside1) return;		// get area of the ports		Poly headPoly = ai.getHeadPortInst().getPoly();		Poly tailPoly = ai.getTailPortInst().getPoly();		// if arcinst is not fixed-angle, run it directly to the port centers		if (!ai.isFixedAngle())		{			double fx = headPoly.getCenterX();   double fy = headPoly.getCenterY();			double tx = tailPoly.getCenterX();   double ty = tailPoly.getCenterY();			doMoveArcInst(ai, new Point2D.Double(fx, fy), new Point2D.Double(tx, ty), arctyp);			return;		}		// get bounding boxes of polygons		Rectangle2D headBounds = headPoly.getBounds2D();		Rectangle2D tailBounds = tailPoly.getBounds2D();		double lx0 = headBounds.getMinX();   double hx0 = headBounds.getMaxX();		double ly0 = headBounds.getMinY();   double hy0 = headBounds.getMaxY();		double lx1 = tailBounds.getMinX();   double hx1 = tailBounds.getMaxX();		double ly1 = tailBounds.getMinY();   double hy1 = tailBounds.getMaxY();		// if manhattan path runs between the ports, adjust the arcinst		if (lx0 <= hx1 && lx1 <= hx0)		{			// arcinst runs vertically			double tx = (Math.max(lx0,lx1) + Math.min(hx0,hx1)) / 2;			double fx = tx;			double fy = (ly0+hy0) / 2;   double ty = (ly1+hy1) / 2;			Point2D fPt = headPoly.closestPoint(new Point2D.Double(fx, fy));			Point2D tPt = tailPoly.closestPoint(new Point2D.Double(tx, ty));			doMoveArcInst(ai, fPt, tPt, arctyp);			return;		}		if (ly0 <= hy1 && ly1 <= hy0)		{			// arcinst runs horizontally			double ty = (Math.max(ly0,ly1) + Math.min(hy0,hy1)) / 2;			double fy = ty;			double fx = (lx0+hx0) / 2;   double tx = (lx1+hx1) / 2;			Point2D fPt = headPoly.closestPoint(new Point2D.Double(fx, fy));			Point2D tPt = tailPoly.closestPoint(new Point2D.Double(tx, ty));			doMoveArcInst(ai, fPt, tPt, arctyp);			return;		}		// give up and jog the arcinst		double fx = headPoly.getCenterX();   double fy = headPoly.getCenterY();		double tx = tailPoly.getCenterX();   double ty = tailPoly.getCenterY();		doMoveArcInst(ai, new Point2D.Double(fx, fy), new Point2D.Double(tx, ty), arctyp);	}	/**	 * Method to update the coordinates of the ends of an ArcInst.	 * @param ai the ArcInst to adjust	 * @param headPt the new coordinates of the head of the ArcInst.	 * @param tailPt the new coordinates of the tail of the ArcInst.	 * @param arctyp the nature of the arc: 0 for rigid, 1 for flexible.	 */	private void updateArc(ArcInst ai, Point2D headPt, Point2D tailPt, Integer arctyp)	{		// set the proper arcinst position//		Point2D oldHeadPt = ai.getHeadLocation();

⌨️ 快捷键说明

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