📄 stitchfilljob.java
字号:
List<PinsArcPair> l = new ArrayList<PinsArcPair>(); // It could be multiple areas disconnected. List<PolyBase> list = PolyBase.getPointsInArea(area, bottomLayer, false, false); if (list == null) continue; // no matching export on bottom level for (PolyBase b : list) { Rectangle2D resultBnd = b.getBounds2D(); EPoint insert = new EPoint(resultBnd.getCenterX(), resultBnd.getCenterY()); PinsArcPair split; // looking for the first arc where the center is contained. for (ArcInst ai : arcs) { Rectangle2D bnd = ai.getBounds(); if (bnd.contains(insert.getX(), insert.getY())) { split = new PinsArcPair(ai, insert, null); l.add(split); break; } } } newExports.put(rootName, l); } for (Map.Entry<String,List<PinsArcPair>> e : newExports.entrySet()) { List<PinsArcPair> pairs = e.getValue(); for (PinsArcPair pair : pairs) { SplitContainter split = splitArcAtPoint(pair.topArc, pair.insert); Export.newInstance(theCell, split.splitPin.getPortInst(0), e.getKey(), PortCharacteristic.UNKNOWN); } } } // Delete after dealing with the wide option // At least one connection was done otherwise it will keep the original exports. // Option is mostly for debugging purposes. if (topLayers[0] != null || topLayers[1] != null) theCell.killExports(toDelete); // make sure at least one export on a network is the root name netlist = theCell.getNetlist(); for (Iterator<Network> itN = netlist.getNetworks(); itN.hasNext(); ) { Network net = itN.next(); if (!net.isExported()) continue; String name = net.getName(); String rootName = extractRootName(name); if (!name.equals(rootName)) { Export exp = net.getExports().next(); exp.rename(rootName); } } return true; } private static ArcInst getArcInstOverlappingWithArea(Rectangle2D resultBnd, List<ArcInst> at, boolean horizontal, boolean topLayer) { Area topArea = new Area(resultBnd); for (ArcInst ai : at) { Rectangle2D r = ai.getBounds(); // test if the current ai inserts with the given area // and it is fully contained along the axis the arc is aligned if (r.intersects(resultBnd)) { Area rArea = new Area(r); rArea.intersect(topArea); Rectangle2D rect = rArea.getBounds2D(); boolean validArc; if (horizontal && topLayer || !horizontal && !topLayer) // top arc is aligned along Y or bottom arc along Y { validArc = DBMath.areEquals(rect.getWidth(), r.getWidth()); } else // top arc is aligned along X { validArc = DBMath.areEquals(rect.getHeight(), r.getHeight()); } if (validArc) { // found return ai; } } } return null; } /** * Method to get Network from a given network root name * @param netlist Netlist containing the network information * @param rootName Root name of the network * @return Network */ private static List<Network> getNetworkFromName(Netlist netlist, String rootName) { List<Network> list = new ArrayList<Network>(); for (Iterator<Network> it = netlist.getNetworks(); it.hasNext();) { Network net = it.next(); if (net.getName().startsWith(rootName)) list.add(net); } return list; } /** * Method to determine if Layer is aligned horizontally * @param layer Given Layer * @param evenHorizontal True if even layers are horizontal * @return True of layer is horizontal */ private static boolean isLayerHorizontal(Layer layer, boolean evenHorizontal) { int metalNumber = layer.getFunction().getLevel(); return (evenHorizontal && metalNumber%2==0) || (!evenHorizontal && metalNumber%2==1); } /** * Method to collect arcs in a given layer with a given export name from an iterator * @param itAi Arcs iterator * @param horizontal Variable to determine if the arc mus be aligned horizontally * @param layer Given layer * @param exportName Given export name. If null, any export name is valid * @param netlist Given Netlist to find exports * @return List of ArcInsts */ private static List<ArcInst> getArcsInGivenLayer(Iterator<ArcInst> itAi, boolean horizontal, Layer layer, String exportName, Netlist netlist) { List<ArcInst> arcs = new ArrayList<ArcInst>(); for (; itAi.hasNext();) { ArcInst ai = itAi.next(); // Checking arc orientation with respect to layer // If the orientation is not correct, then ignore it if (!isArcAligned(ai, horizontal)) continue; Layer l = ai.getProto().getLayer(0); if (l != layer) continue; if (exportName != null) { Network jNet = netlist.getNetwork(ai, 0); Iterator<Export> itE = jNet.getExports(); if (!itE.hasNext()) { if (Job.getDebug()) System.out.println("AFG: No export name associated to ArcInst '" + ai.getName() + "'"); continue; // no export } Export exp = itE.next(); // first is enough String expName = extractRootName(exp.getName()); if (!expName.equals(exportName)) continue; // no match } arcs.add(ai); } return arcs; } /** * Method to check whether a given arc is properly oriented with respect to the expected input * @param ai the given ArcInst * @param horizontal True if the arc must be horizontal * @return True if the arc is aligned with the given direction */ private static boolean isArcAligned(ArcInst ai, boolean horizontal) { EPoint head = ai.getHeadLocation(); EPoint tail = ai.getTailLocation(); if (horizontal) return (DBMath.areEquals(head.getY(), tail.getY())); return (DBMath.areEquals(head.getX(), tail.getX())); } /** * Method to extract the export root name from a given name * @param name String containing the export name * @return String containing the root name of the export */ private static String extractRootName(String name) { int index = name.indexOf("_"); if (index != -1) // remove any character after _ name = name.substring(0, index); return name; } /** * Methot to extrac root name of the export in a given arc * @param ai arc with the export * @param netlist Given network to search in * @return Non-null string with the root name. Null if no export was found. */ private static String getExportRootName(ArcInst ai, Netlist netlist) { Network jNet = netlist.getNetwork(ai, 0); // Picking only 1 export and considering the root name` // Assuming at 1 export per arc if (jNet == null) return null; assert(jNet != null); Iterator<String> exportNames = jNet.getExportedNames(); if (!exportNames.hasNext()) return null; // no export return extractRootName(exportNames.next()); } /** * Method to split an arc at a given point * @param ai arc to split * @param insert point to split at * @return SplitContainter representing the split pin and new arcs */ private static SplitContainter splitArcAtPoint(ArcInst ai, EPoint insert) { // create the break pins ArcProto ap = ai.getProto(); NodeProto np = ap.findPinProto(); if (np == null) return null; NodeInst ni = NodeInst.makeInstance(np, insert, np.getDefWidth(), np.getDefHeight(), ai.getParent()); if (ni == null) { System.out.println("Cannot create pin " + np.describe(true)); return null; } SplitContainter container = new SplitContainter(); container.splitPin = ni; // get location of connection to these pins PortInst pi = ni.getOnlyPortInst(); // now save the arc information and delete it PortInst headPort = ai.getHeadPortInst(); PortInst tailPort = ai.getTailPortInst(); Point2D headPt = ai.getHeadLocation(); Point2D tailPt = ai.getTailLocation(); double width = ai.getLambdaBaseWidth();// String arcName = ai.getName(); // create the new arcs ArcInst newAi1 = ArcInst.makeInstanceBase(ap, width, headPort, pi, headPt, insert, null); ArcInst newAi2 = ArcInst.makeInstanceBase(ap, width, pi, tailPort, insert, tailPt, null); newAi1.setHeadNegated(ai.isHeadNegated()); newAi1.setHeadExtended(ai.isHeadExtended()); newAi1.setHeadArrowed(ai.isHeadArrowed()); newAi1.setTailNegated(ai.isTailNegated()); newAi1.setTailExtended(ai.isTailExtended()); newAi1.setTailArrowed(ai.isTailArrowed()); newAi2.setHeadNegated(ai.isHeadNegated()); newAi2.setHeadExtended(ai.isHeadExtended()); newAi2.setHeadArrowed(ai.isHeadArrowed()); newAi2.setTailNegated(ai.isTailNegated()); newAi2.setTailExtended(ai.isTailExtended()); newAi2.setTailArrowed(ai.isTailArrowed()); // Determining which arc is left/top if (isLeftTop(headPt, tailPt)) { container.leftArc = newAi1; container.rightArc = newAi2; } else { container.leftArc = newAi2; container.rightArc = newAi1; } ai.kill();// if (arcName != null)// {// if (headPt.distance(insert) > tailPt.distance(insert))// {// newAi1.setName(arcName);// newAi1.copyTextDescriptorFrom(ai, ArcInst.ARC_NAME);// } else// {// newAi2.setName(arcName);// newAi2.copyTextDescriptorFrom(ai, ArcInst.ARC_NAME);// }// } return container; } /** * Internal class to keep potential connections */ private static class PinsArcPair { private ArcInst topArc; private EPoint insert; private Rectangle2D cut; PinsArcPair(ArcInst topA, EPoint point, Rectangle2D c) { topArc = topA; insert = point; cut = c; } } private static boolean isLeftTop(Point2D p1, Point2D p2) { if (DBMath.areEquals(p1.getX(), p2.getX())) { return (!DBMath.isGreaterThan(p1.getY(), p2.getY())); } else if (DBMath.areEquals(p1.getY(), p2.getY())) { return (!DBMath.isGreaterThan(p1.getX(), p2.getX())); } else System.out.println("Case not considered in FillJob:isLeftTop");// assert(false); // not considered yet return false; } /** * Class to store temp info */ private static class SplitContainter { NodeInst splitPin; ArcInst leftArc, rightArc; // to keep track of new arcs after the original one was split } /** * To sort PinsArcPair */ private static final PinsArcPairSort pinsArcSort = new PinsArcPairSort(); /** * Comparator class for sorting PinsArcPair by their insertion point */ private static class PinsArcPairSort implements Comparator<PinsArcPair> { /** * Method to compare two PinsArcPair objects by their insertion point. * @param l1 one PinsArcPair. * @param l2 another PinsArcPair. * @return an integer indicating their sorting order. */ public int compare(PinsArcPair l1, PinsArcPair l2) { EPoint p1 = l1.insert; EPoint p2 = l2.insert; return (isLeftTop(p2, p1)?1:-1); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -