📄 mimicstitch.java
字号:
mimicInteractive, matchPorts, matchPortWidth, matchArcCount, matchNodeType, matchNodeSize, noOtherArcsThisDir, notAlreadyConnected, this); return true; } } /** * Method to do mimic stitching. * It can be used during batch processing to mimic directly. * @param ai1 the arc connected to the first port of the connection to mimic. * @param end1 the end of "ai1" that defines the first port of the connection to mimic. * @param ai2 the arc connected to the second port of the connection to mimic. * @param end2 the end of "ai2" that defines the second port of the connection to mimic. * @param oWidth the width of the arc to run. * @param oProto the type of arc to run. * @param prefX the preferred X position of the mimic (if there is a choice). * @param prefY the preferred Y position of the mimic (if there is a choice). * @param forced true if this was an explicitly requested mimic. * @param method the type of job that is running (CHANGE or EXAMINE). * @param mimicInteractive true to run interactively. * @param matchPorts true to require port types to match. * @param matchPortWidth true to require port widths to match. * @param matchArcCount true to require the number of arcs to match. * @param matchNodeType true to require the node types to match. * @param matchNodeSize true to require the node sizes to match. * @param noOtherArcsThisDir true to require that no other arcs exist in the same direction. * @param notAlreadyConnected true to require that the connection not already be made with other arcs. * @param theJob the job that is running this mimic operation */ public static void mimicOneArc(ArcInst ai1, int end1, ArcInst ai2, int end2, double oWidth, ArcProto oProto, double prefX, double prefY, boolean forced, Job.Type method, boolean mimicInteractive, boolean matchPorts, boolean matchPortWidth, boolean matchArcCount, boolean matchNodeType, boolean matchNodeSize, boolean noOtherArcsThisDir, boolean notAlreadyConnected, Job theJob) { if (forced) System.out.println("Mimicing last arc..."); buildLikelySituations(); PortInst [] endPi = new PortInst[2]; Connection conn1 = ai1.getConnection(end1); Connection conn2 = ai2.getConnection(end2); endPi[0] = conn1.getPortInst(); endPi[1] = conn2.getPortInst(); Point2D [] endPts = new Point2D[2]; endPts[0] = conn1.getLocation(); endPts[1] = conn2.getLocation(); Cell cell = endPi[0].getNodeInst().getParent(); Netlist netlist = cell.acquireUserNetlist(); if (netlist == null) { System.out.println("Sorry, a deadlock aborted mimic-routing (network information unavailable). Please try again"); return; } int busWidth = netlist.getBusWidth(ai1); // make list of possible arc connections List<PossibleArc> possibleArcs = new ArrayList<PossibleArc>(); // count the number of other arcs on the ends int con1 = endPi[0].getNodeInst().getNumConnections() + endPi[1].getNodeInst().getNumConnections() - 2; // precompute polygon information about every port in the cell HashMap<PortInst,Poly> cachedPortPoly = new HashMap<PortInst,Poly>(); for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); for(Iterator<PortInst> pIt = ni.getPortInsts(); pIt.hasNext(); ) { PortInst pi = pIt.next(); if (oProto != null) { if (!pi.getPortProto().connectsTo(oProto)) continue; } cachedPortPoly.put(pi, pi.getPoly()); } } if (cachedPortPoly.size() == 0) return; // search from both ends for(int end=0; end<2; end++) { PortInst pi0 = endPi[end]; PortInst pi1 = endPi[1-end]; NodeInst node0 = pi0.getNodeInst(); NodeInst node1 = pi1.getNodeInst(); PortProto port0 = pi0.getPortProto(); PortProto port1 = pi1.getPortProto(); Point2D pt0 = endPts[end]; Point2D pt1 = endPts[1-end]; double dist = pt0.distance(pt1); double distX = pt1.getX() - pt0.getX(); double distY = pt1.getY() - pt0.getY(); int angle = 0; if (dist != 0) angle = DBMath.figureAngle(pt0, pt1); boolean useFAngle = false; double angleRadians = 0; if ((angle%900) != 0) { angleRadians = DBMath.figureAngleRadians(pt0, pt1); useFAngle = true; } Poly port0Poly = pi0.getPoly(); double end0Offx = pt0.getX() - port0Poly.getCenterX(); double end0Offy = pt0.getY() - port0Poly.getCenterY(); double node0Wid = node0.getLambdaBaseXSize(); double node0Hei = node0.getLambdaBaseYSize();// SizeOffset so0 = node0.getSizeOffset();// double node0Wid = node0.getXSize() - so0.getLowXOffset() - so0.getHighXOffset();// double node0Hei = node0.getYSize() - so0.getLowYOffset() - so0.getHighYOffset(); double node1Wid = node1.getLambdaBaseXSize(); double node1Hei = node1.getLambdaBaseYSize();// SizeOffset so1 = node1.getSizeOffset();// double node1Wid = node1.getXSize() - so1.getLowXOffset() - so1.getHighXOffset();// double node1Hei = node1.getYSize() - so1.getLowYOffset() - so1.getHighYOffset(); // now search every node in the cell for(Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); Rectangle2D bounds = ni.getBounds(); if (theJob != null && theJob.checkAbort()) { System.out.println("Mimic Arc Job aborted"); return; } // now look for another node that matches the situation for(Iterator<NodeInst> oIt = cell.getNodes(); oIt.hasNext(); ) { NodeInst oNi = oIt.next(); Rectangle2D oBounds = oNi.getBounds(); // ensure that intra-node wirings stay that way if (node0 == node1) { if (ni != oNi) continue; } else { if (ni == oNi) continue; } // make sure the distances are sensible if (distX > 0) { if (bounds.getMaxX() + distX < oBounds.getMinX()) continue; if (bounds.getMinX() + distX > oBounds.getMaxX()) continue; } else { if (bounds.getMinX() + distX > oBounds.getMaxX()) continue; if (bounds.getMaxX() + distX < oBounds.getMinX()) continue; } if (distY > 0) { if (bounds.getMaxY() + distY < oBounds.getMinY()) continue; if (bounds.getMinY() + distY > oBounds.getMaxY()) continue; } else { if (bounds.getMinY() + distY > oBounds.getMaxY()) continue; if (bounds.getMaxY() + distY < oBounds.getMinY()) continue; } // compare each port for(Iterator<PortInst> pIt = ni.getPortInsts(); pIt.hasNext(); ) { PortInst pi = pIt.next(); PortProto pp = pi.getPortProto(); // if this port is not cached, it cannot connect, so ignore it Poly poly = cachedPortPoly.get(pi); if (poly == null) continue; double x0 = poly.getCenterX(); double y0 = poly.getCenterY(); x0 += end0Offx; y0 += end0Offy; double wantX1 = x0; double wantY1 = y0; if (dist != 0) { if (useFAngle) { wantX1 = x0 + Math.cos(angleRadians) * dist; wantY1 = y0 + Math.sin(angleRadians) * dist; } else { wantX1 = x0 + DBMath.cos(angle) * dist; wantY1 = y0 + DBMath.sin(angle) * dist; } } Point2D xy0 = new Point2D.Double(x0, y0); Point2D want1 = new Point2D.Double(wantX1, wantY1); for(Iterator<PortInst> oPIt = oNi.getPortInsts(); oPIt.hasNext(); ) { PortInst oPi = oPIt.next(); PortProto oPp = oPi.getPortProto(); if (ni == oNi && pp == oPp) continue; // if this port is not cached, it cannot connect, so ignore it Poly thisPoly = cachedPortPoly.get(oPi); if (thisPoly == null) continue; // don't replicate what is already done if (pi == pi0 && oPi == pi1) continue; // see if they are the same distance apart boolean ptInPoly = thisPoly.isInside(want1); if (!ptInPoly) continue; // figure out the wiring situation here int situation = 0; // if there is a network that already connects these, ignore if (netlist.sameNetwork(ni, pp, oNi, oPp)) { situation |= LIKELYALREADYCONNECTED; } // see if there are already wires going in this direction int desiredAngle = -1; if (x0 != wantX1 || y0 != wantY1) desiredAngle = DBMath.figureAngle(xy0, want1); for(Iterator<Connection> pII = ni.getConnections(); pII.hasNext(); ) { Connection con = pII.next(); PortInst aPi = con.getPortInst(); if (aPi.getPortProto() != pp) continue; ArcInst oAi = con.getArc(); if (desiredAngle < 0) { if (oAi.getHeadLocation().getX() == oAi.getTailLocation().getX() && oAi.getHeadLocation().getY() == oAi.getTailLocation().getY()) { situation |= LIKELYARCSSAMEDIR; break; } } else { if (oAi.getHeadLocation().getX() == oAi.getTailLocation().getX() && oAi.getHeadLocation().getY() == oAi.getTailLocation().getY()) continue; int thisend = 0; if (oAi.getTailPortInst() == aPi) thisend = 1; int existingAngle = DBMath.figureAngle(oAi.getLocation(thisend), oAi.getLocation(1-thisend)); if (existingAngle == desiredAngle) { situation |= LIKELYARCSSAMEDIR; break; } } } desiredAngle = -1; if (x0 != wantX1 || y0 != wantY1) desiredAngle = DBMath.figureAngle(want1, xy0); for(Iterator<Connection> pII = oNi.getConnections(); pII.hasNext(); ) { Connection con = pII.next(); PortInst aPi = con.getPortInst(); if (aPi.getPortProto() != oPp) continue; ArcInst oAi = con.getArc(); if (desiredAngle < 0) { if (oAi.getHeadLocation().getX() == oAi.getTailLocation().getX() && oAi.getHeadLocation().getY() == oAi.getTailLocation().getY()) { situation |= LIKELYARCSSAMEDIR; break; } } else { if (oAi.getHeadLocation().getX() == oAi.getTailLocation().getX() && oAi.getHeadLocation().getY() == oAi.getTailLocation().getY()) continue; int thisend = 0; if (oAi.getTailPortInst() == aPi) thisend = 1; int existingAngle = DBMath.figureAngle(oAi.getLocation(thisend), oAi.getLocation(1-thisend)); if (existingAngle == desiredAngle) { situation |= LIKELYARCSSAMEDIR; break; } } } if (pp instanceof Export && oPp instanceof Export) { int e0Wid = netlist.getBusWidth((Export)pp); int e1Wid = netlist.getBusWidth((Export)oPp); if (e0Wid != busWidth || e1Wid != busWidth) situation |= LIKELYDIFFPORTWIDTH; } else { if (busWidth != 1) situation |= LIKELYDIFFPORTWIDTH; } int con2 = ni.getNumConnections() + oNi.getNumConnections(); if (con1 != con2) situation |= LIKELYDIFFARCCOUNT; if (ni.getProto() != node0.getProto() || oNi.getProto() != node1.getProto()) { situation |= LIKELYDIFFNODETYPE; } else { if (pp != port0 || oPp != port1) situation |= LIKELYDIFFPORT; } double wid = ni.getLambdaBaseXSize(); double hei = ni.getLambdaBaseYSize();// SizeOffset so = ni.getSizeOffset();// double wid = ni.getXSize() - so.getLowXOffset() - so.getHighXOffset();// double hei = ni.getYSize() - so.getLowYOffset() - so.getHighYOffset(); if (wid != node0Wid || hei != node0Hei) situation |= LIKELYDIFFNODESIZE; wid = oNi.getLambdaBaseXSize(); hei = oNi.getLambdaBaseYSize();// so = oNi.getSizeOffset();// wid = oNi.getXSize() - so.getLowXOffset() - so.getHighXOffset();// hei = oNi.getYSize() - so.getLowYOffset() - so.getHighYOffset(); if (wid != node1Wid || hei != node1Hei) situation |= LIKELYDIFFNODESIZE; // see if this combination has already been considered PossibleArc found = null; for(PossibleArc pa : possibleArcs) { if (pa.ni1 == ni && pa.pp1 == pp && pa.ni2 == oNi && pa.pp2 == oPp) { found = pa; break; } if (pa.ni2 == ni && pa.pp2 == pp && pa.ni1 == oNi && pa.pp1 == oPp) { found = pa; break; } } if (found != null) { if (found.situation == situation) continue; int foundIndex = -1; for(int k=0; k<situations.length; k++) { if (found.situation == situations[k]) break; if (situation == situations[k]) { foundIndex = k; break; } } if (foundIndex >= 0 && found.situation == situations[foundIndex]) continue; } if (found == null) { found = new PossibleArc(); possibleArcs.add(found); } found.ni1 = ni; found.pp1 = pp; found.ni2 = oNi; found.pp2 = oPp; found.situation = situation; } } } } } // now create the mimiced arcs processPossibilities(cell, possibleArcs, prefX, prefY, method, forced, mimicInteractive, matchPorts, matchPortWidth, matchArcCount, matchNodeType, matchNodeSize, noOtherArcsThisDir, notAlreadyConnected); } private static void processPossibilities(Cell cell, List<PossibleArc> possibleArcs, double prefX, double prefY, Job.Type method, boolean forced, boolean mimicInteractive, boolean matchPorts, boolean matchPortWidth, boolean matchArcCount, boolean matchNodeType, boolean matchNodeSize, boolean noOtherArcsThisDir, boolean notAlreadyConnected) { if (mimicInteractive) { // do this in a separate thread so that this examine job can finish MimicInteractive task = new MimicInteractive(cell, possibleArcs, prefX, prefY); SwingUtilities.invokeLater(task); return; } // not interactive: follow rules in the Preferences int ifIgnorePorts = 0, ifIgnorePortWidth = 0, ifIgnoreArcCount = 0, ifIgnoreNodeType = 0; int ifIgnoreNodeSize = 0, ifIgnoreOtherSameDir = 0, ifAlreadyConnected = 0; int count = 0; boolean deletion = false; for(int j=0; j<situations.length; j++) { // see if this situation is possible List<Route> allRoutes = new ArrayList<Route>(); List<ArcInst> allKills = new ArrayList<ArcInst>(); int total = 0; for(PossibleArc pa : possibleArcs) { if (pa.ai != null) deletion = true; if (pa.situation != situations[j]) continue; total++; if (pa.ai != null) { // plan an arc deletion allKills.add(pa.ai); } else { // plan an arc creation Poly portPoly1 = pa.ni1.getShapeOfPort(pa.pp1); Poly portPoly2 = pa.ni2.getShapeOfPort(pa.pp2); Point2D bend = new Point2D.Double((portPoly1.getCenterX() + portPoly2.getCenterX()) / 2 + prefX, (portPoly1.getCenterY() + portPoly2.getCenterY()) / 2 + prefY); PortInst pi1 = pa.ni1.findPortInstFromProto(pa.pp1); PortInst pi2 = pa.ni2.findPortInstFromProto(pa.pp2); Route route = router.planRoute(pa.ni1.getParent(), pi1, pi2, bend, null, true, true); if (route.size() == 0) { System.out.println("Problem creating arc");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -