?? gds.java
字號(hào):
if (annotations.size() > 0) { String [] anArr = new String[annotations.size()]; for(int i=0; i<annotations.size(); i++) anArr[i] = annotations.get(i); TextDescriptor td = TextDescriptor.getCellTextDescriptor().withInterior(true).withDispPart(TextDescriptor.DispPos.NAMEVALUE); this.cell.newVar(NccCellAnnotations.NCC_ANNOTATION_KEY, anArr, td); } } if (IOTool.isGDSInSimplifyCells()) simplifyNodes(this.cell); builtCells.add(this.cell); } /** Method to see if existing primitive nodes could be merged and define more complex nodes * such as contacts */ private void simplifyNodes(Cell cell) { Map<Layer, List<NodeInst>> map = new HashMap<Layer, List<NodeInst>>(); for (Iterator<NodeInst> itNi = cell.getNodes(); itNi.hasNext();) { NodeInst ni = itNi.next(); if (!(ni.getProto() instanceof PrimitiveNode)) continue; // not primitive PrimitiveNode pn = (PrimitiveNode)ni.getProto(); if (pn.getFunction() != PrimitiveNode.Function.NODE) continue; // not pure layer node. Layer layer = pn.getLayerIterator().next(); // they are supposed to have only 1 List<NodeInst> list = map.get(layer); if (list == null) // first time { list = new ArrayList<NodeInst>(); map.put(layer, list); } list.add(ni); } Technology tech = cell.getTechnology(); Set<NodeInst> toDelete = new HashSet<NodeInst>(); Set<NodeInst> viaToDelete = new HashSet<NodeInst>(); List<Geometric> geomList = new ArrayList<Geometric>(); for (Iterator<PrimitiveNode> itPn = tech.getNodes(); itPn.hasNext();) { PrimitiveNode pn = itPn.next(); boolean allFound = true; if (pn.getFunction() != PrimitiveNode.Function.CONTACT) continue; // only dealing with metal contacts for now. Layer m1Layer = null, m2Layer = null; Layer viaLayer = null; SizeOffset so = pn.getProtoSizeOffset(); for (Iterator<Layer> itLa = pn.getLayerIterator(); itLa.hasNext();) { Layer l = itLa.next(); if (map.get(l) == null) { allFound = false; break; } if (l.getFunction().isMetal()) { if (m1Layer == null) m1Layer = l; else m2Layer = l; } else if (l.getFunction().isContact()) viaLayer = l; } if (!allFound) continue; // not all layers for this particular node found if (viaLayer == null) continue; // not metal contact assert(m1Layer != null); List<NodeInst> list = map.get(m1Layer); assert(list != null); Layer.Function.Set thisLayer = new Layer.Function.Set(viaLayer.getFunction()); List<NodeInst> viasList = map.get(viaLayer); for (NodeInst ni : list) { Poly[] polys = tech.getShapeOfNode(ni, true, false, null); assert(polys.length == 1); // it must be only 1 Poly m1P = polys[0]; List<NodeInst> nList = map.get(m2Layer); if (nList == null) continue; // nothing found in m2Layer for (NodeInst n : nList) { Poly[] otherPolys = tech.getShapeOfNode(n, true, false, null); assert(otherPolys.length == 1); // it must be only 1 Poly m2P = otherPolys[0]; if (!m2P.getBounds2D().equals(m1P.getBounds2D())) continue; // no match ImmutableNodeInst d = ni.getD(); String name = ni.getName(); int atIndex = name.indexOf('@'); if (atIndex < 0) name += "tmp"; else name = name.substring(0, atIndex) + "tmp" + name.substring(atIndex); NodeInst newNi = NodeInst.makeInstance(pn, d.anchor, m2P.getBounds2D().getWidth() + so.getLowXOffset() + so.getHighXOffset(), m2P.getBounds2D().getHeight() + so.getLowYOffset() + so.getHighYOffset(), ni.getParent(), ni.getOrient(), name, 0); if (newNi == null) continue; // Searching for vias to delete assert(viasList != null); Poly[] viaPolys = tech.getShapeOfNode(newNi, true, false, thisLayer); boolean found = false; // Can be more than 1 due to MxN cuts viaToDelete.clear(); for (int i = 0; i < viaPolys.length; i++) { Poly poly = viaPolys[i]; Rectangle2D bb = poly.getBounds2D(); bb.setRect(ERectangle.fromLambda(bb)); found = false; for (NodeInst viaNi : viasList) { Poly[] thisViaList = tech.getShapeOfNode(viaNi, true, false, thisLayer); assert(thisViaList.length == 1); // hack to get rid of the resolution issue Poly p = thisViaList[0]; Rectangle2D b = p.getBounds2D(); b.setRect(ERectangle.fromLambda(b)); if (thisViaList[0].polySame(poly)) { viaToDelete.add(viaNi); assert(!found); found = true; } } if (!found) { break; // fail to find all nodes } } if (!found) // rolling back new node { newNi.kill(); } else { if (SHOWPROGRESS) System.out.println("Adding " + newNi.getName()); toDelete.clear(); geomList.clear(); toDelete.add(ni); toDelete.add(n); toDelete.addAll(viaToDelete); String message = toDelete.size() + " nodes were replaced for more complex primitives in cell '" + cell.getName() + "'"; geomList.add(newNi); errorLogger.logWarning(message, geomList, null, null, null, null, cell, -1); // Deleting now replaced pure primitives cell.killNodes(toDelete); } } } } } private void nameInstances(boolean countOff) { Map<String,GenMath.MutableInteger> maxSuffixes = new HashMap<String,GenMath.MutableInteger>(); Set<String> userNames = new HashSet<String>(); int count = 0; for (MakeInstance mi: insts) { if (countOff && ((++count % 2000) == 0)) System.out.println(" Named " + count + " instances"); if (mi.nodeName != null) { if (!validGdsNodeName(mi.nodeName)) { System.out.println(" Warning: Node name '" + mi.nodeName + "' in cell " + cell.describe(false) + " is bad (" + Name.checkName(mi.nodeName.toString()) + ")...ignoring the name"); } else if (!userNames.contains(mi.nodeName.toString())) { userNames.add(mi.nodeName.toString()); continue; } } Name baseName; if (mi.proto instanceof Cell) { baseName = ((Cell)mi.proto).getBasename(); } else { PrimitiveNode np = (PrimitiveNode)mi.proto; baseName = np.getTechnology().getPrimitiveFunction(np, 0).getBasename(); } String basenameString = baseName.toString(); GenMath.MutableInteger maxSuffix = maxSuffixes.get(basenameString); if (maxSuffix == null) { maxSuffix = new GenMath.MutableInteger(-1); maxSuffixes.put(basenameString, maxSuffix); } maxSuffix.increment(); mi.nodeName = baseName.findSuffixed(maxSuffix.intValue()); } } private boolean validGdsNodeName(Name name) { return name.isValid() && !name.hasEmptySubnames() && !name.isBus() || !name.isTempname(); } private static void buildInstances() { Set<Cell> builtCells = new HashSet<Cell>(); for(CellBuilder cellBuilder : allBuilders.values()) cellBuilder.makeInstances(builtCells); } } /** * Class to save instance array information. */ private static class MakeInstanceArray { private NodeProto proto; private int nCols, nRows; private Orientation orient; private Point2D startLoc, rowOffset, colOffset; private MakeInstanceArray(NodeProto proto, int nCols, int nRows, Orientation orient, Point2D startLoc, Point2D rowOffset, Point2D colOffset) { this.proto = proto; this.nCols = nCols; this.nRows = nRows; this.orient = orient; this.startLoc = startLoc; this.rowOffset = rowOffset; this.colOffset = colOffset; } /** * Method to instantiate an array of cell instances. * @param parent the Cell in which to create the geometry. */ private void instantiate(CellBuilder theCell, Cell parent, Map<NodeProto,List<EPoint>> massiveMerge) { int arraySimplification = IOTool.getGDSArraySimplification(); if (Technology.HANDLEBROKENOUTLINES) { NodeInst subNi = null; Cell subCell = (Cell)proto; int numArcs = subCell.getNumArcs(); int numNodes = subCell.getNumNodes(); int numExports = subCell.getNumPorts(); if (numArcs == 0 && numExports == 0 && numNodes == 1) { subNi = subCell.getNode(0); if (subNi.getProto().getFunction() != PrimitiveNode.Function.NODE) subNi = null; } if (subNi != null && subNi.getTrace() != null) subNi = null; if (subNi != null) { if (arraySimplification > 0) { List<EPoint> points = buildArray(); if (arraySimplification == 2) { // add the array's geometry the layer's outline List<EPoint> soFar = massiveMerge.get(subNi.getProto()); if (soFar == null) { soFar = new ArrayList<EPoint>(); massiveMerge.put(subNi.getProto(), soFar); } if (soFar.size() > 0) soFar.add(null); for(EPoint ep : points) soFar.add(ep); } else { // place a pure-layer node that embodies the array buildComplexNode(points, subNi.getProto(), parent); } return; } else { // remember that array simplification would have helped arraySimplificationUseful = true; } } } // generate an array double ptcX = startLoc.getX(); double ptcY = startLoc.getY(); for (int ic = 0; ic < nCols; ic++) { double ptX = ptcX; double ptY = ptcY; for (int ir = 0; ir < nRows; ir++) { // create the node if (IOTool.isGDSInInstantiatesArrays() || (ir == 0 && ic == 0) || (ir == (nRows-1) && ic == (nCols-1))) { Point2D loc = new Point2D.Double(ptX, ptY); NodeInst ni = NodeInst.makeInstance(proto, loc, proto.getDefWidth(), proto.getDefHeight(), parent, orient, null, 0); if (ni != null) { if (IOTool.isGDSInExpandsCells() && ni.isCellInstance()) ni.setExpanded(); } } // add the row displacement ptX += rowOffset.getX(); ptY += rowOffset.getY(); } // add displacement ptcX += colOffset.getX(); ptcY += colOffset.getY(); } } private List<EPoint> buildArray() { List<EPoint> points = new ArrayList<EPoint>(); Rectangle2D bounds = ((Cell)proto).getBounds(); Rectangle2D boundCopy = new Rectangle2D.Double(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight()); DBMath.transformRect(boundCopy, orient.pureRotate()); double ptcX = startLoc.getX(); double ptcY = startLoc.getY(); for (int ic = 0; ic < nCols; ic++) { double ptX = ptcX; double ptY = ptcY; for (int ir = 0; ir < nRows; ir++) { points.add(new EPoint(ptX+boundCopy.getMinX(), ptY+boundCopy.getMinY())); points.add(new EPoint(ptX+boundCopy.getMaxX(), ptY+boundCopy.getMinY())); points.add(new EPoint(ptX+boundCopy.getMaxX(), ptY+boundCopy.getMaxY())); points.add(new EPoint(ptX+boundCopy.getMinX(), ptY+boundCopy.getMaxY())); // insert a "break" marker to start a new polygon if (ic < nCols-1 || ir < nRows-1) points.add(null); // add the row displacement ptX += rowOffset.getX(); ptY += rowOffset.getY(); } // add displacement ptcX += colOffset.getX(); ptcY += colOffset.getY(); } return points; } } private static class MakeInstance implements Comparable<MakeInstance> { private NodeProto proto; private Point2D loc; private Orientation orient; private double wid, hei; private EPoint[] points; // trace private String exportName; // export private Name nodeName; // text private String origNodeName; // original text with invalid name private MakeInstance(NodeProto proto, Point2D loc, Orientation orient, double wid, double hei, EPoint[] points, String exportName, Name nodeName) { this.proto = proto; this.loc = loc; this.orient = orient; this.wid = DBMath.round(wid); this.hei = DBMath.round(hei); this.points = points; this.exportName = exportName; if (nodeName != null && NodeInst.checkNameKey(nodeName, null)) { // If name is not valid, a new one will be automatically created. origNodeName = nodeName.toString(); // remember the name for error reporting nodeName = null; } this.nodeName = nodeName; } public int compareTo(MakeInstance that) { return TextUtils.STRING_NUMBER_ORDER.compare(this.nodeName.toString(), that.nodeName.toString()); } /** * Method to instantiate a node/export in a Cell. * @param parent the Cell in which to create the geometry. * @param exportUnify a map that shows how renamed exports connect. * @return true if the export had to be renamed. */ private boolean instantiate(Cell parent, Map<String,String> exportUnify) { String name = nodeName.toString(); NodeInst ni = NodeInst.makeInstance(proto, loc, wid, hei, parent, orient, name, 0); String errorMsg = null; if (ni == null) return false; if (ni.getNameKey() != nodeName) { errorMsg = "GDS name '" + name + "' renamed to '" + ni.getName() + "'";
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -