📄 schematic.java
字号:
return; } } // check all pins if (np.getFunction() == PrimitiveNode.Function.PIN) { // may be stranded if there are no exports or arcs if (!ni.hasExports() && !ni.hasConnections()) { // see if the pin has displayable variables on it boolean found = false; for(Iterator<Variable> it = ni.getVariables(); it.hasNext(); ) { Variable var = it.next(); if (var.isDisplay()) { found = true; break; } } if (!found) { errorLogger.logError("Stranded pin (not connected or exported)", geom, cell, null, eg.getSortKey()); return; } } if (ni.isInlinePin()) { errorLogger.logError("Unnecessary pin (between 2 arcs)", geom, cell, null, eg.getSortKey()); return; } Point2D pinLoc = ni.invisiblePinWithOffsetText(false); if (pinLoc != null) { List<Geometric> geomList = new ArrayList<Geometric>(); List<EPoint> ptList = new ArrayList<EPoint>(); geomList.add(geom); ptList.add(new EPoint(ni.getAnchorCenterX(), ni.getAnchorCenterY())); ptList.add(new EPoint(pinLoc.getX(), pinLoc.getY())); errorLogger.logError("Invisible pin has text in different location", geomList, null, ptList, null, null, cell, eg.getSortKey()); return; } } // check parameters if (np instanceof Cell) { Cell instCell = (Cell)np; Cell contentsCell = instCell.contentsView(); if (contentsCell == null) contentsCell = instCell; // ensure that this node matches the parameter list for(Iterator<Variable> it = ni.getDefinedParameters(); it.hasNext(); ) { Variable var = it.next(); assert ni.isParam(var.getKey()); Variable foundVar = contentsCell.getParameter(var.getKey()); if (foundVar == null) { // this node's parameter is no longer on the cell: delete from instance String trueVarName = var.getTrueName(); errorLogger.logError("Parameter '" + trueVarName + "' on " + ni + " is invalid", geom, cell, null, eg.getSortKey()); } else { // this node's parameter is still on the cell: make sure units are OK if (var.getUnit() != foundVar.getUnit()) { String trueVarName = var.getTrueName(); errorLogger.logError("Parameter '" + trueVarName + "' on " + ni + " had incorrect units (now fixed)", geom, cell, null, eg.getSortKey()); addVariable(ni, var.withUnit(foundVar.getUnit())); } // make sure visibility is OK if (foundVar.isInterior()) { if (var.isDisplay()) { String trueVarName = var.getTrueName(); errorLogger.logError("Parameter '" + trueVarName + "' on " + ni + " should not be visible (now fixed)", geom, cell, null, eg.getSortKey()); addVariable(ni, var.withDisplay(false)); } } else { if (!var.isDisplay()) { String trueVarName = var.getTrueName(); errorLogger.logError("Parameter '" + trueVarName + "' on " + ni + " should be visible (now fixed)", geom, cell, null, eg.getSortKey()); addVariable(ni, var.withDisplay(true)); } } } } // make sure instance name isn't the same as a network in the cell String nodeName = ni.getName(); for(Iterator<Network> it = netlist.getNetworks(); it.hasNext(); ) { Network net = it.next(); if (net.hasName(nodeName)) { errorLogger.logError("Node " + ni + " is named '" + nodeName + "' which conflicts with a network name in this cell", geom, cell, null, eg.getSortKey()); break; } } } // check all exports for proper icon/schematics characteristics match Cell parentCell = ni.getParent(); for(Iterator<Cell> cIt = parentCell.getCellGroup().getCells(); cIt.hasNext(); ) { Cell iconCell = cIt.next(); if (iconCell.getView() != View.ICON) continue; for(Iterator<Export> it = ni.getExports(); it.hasNext(); ) { Export e = it.next(); Export iconExport = e.getEquivalentPort(iconCell); if (iconExport == null) continue; if (e.getCharacteristic() != iconExport.getCharacteristic()) { errorLogger.logError("Export '" + e.getName() + "' on " + ni + " is " + e.getCharacteristic().getFullName() + " but export in icon cell " + iconCell.describe(false) + " is " + iconExport.getCharacteristic().getFullName(), geom, cell, null, eg.getSortKey()); } } } // check for port overlap checkPortOverlap(netlist, ni, eg); } else { ArcInst ai = (ArcInst)geom; // check for being floating if it does not have a visible name on it boolean checkDangle = false; if (Artwork.isArtworkArc(ai.getProto())) return; // ignore artwork arcs Name arcName = ai.getNameKey(); if (arcName == null || arcName.isTempname()) checkDangle = true; if (checkDangle) { // do not check for dangle when busses are on named networks if (ai.getProto() == Schematics.tech().bus_arc) { Name name = netlist.getBusName(ai); if (name != null && !name.isTempname()) checkDangle = false; } } if (checkDangle) { // check to see if this arc is floating for(int i=0; i<2; i++) { NodeInst ni = ai.getPortInst(i).getNodeInst(); // OK if not a pin if (ni.getProto().getFunction() != PrimitiveNode.Function.PIN) continue; // OK if it has exports on it if (ni.hasExports()) continue; // OK if it connects to more than 1 arc if (ni.getNumConnections() != 1) continue; // the arc dangles errorLogger.logError("Arc dangles", geom, cell, null, eg.getSortKey()); return; } } // check to see if its width is sensible int signals = netlist.getBusWidth(ai); if (signals < 1) signals = 1; for(int i=0; i<2; i++) { PortInst pi = ai.getPortInst(i); NodeInst ni = pi.getNodeInst(); if (!ni.isCellInstance()) continue; Cell subNp = (Cell)ni.getProto(); PortProto pp = pi.getPortProto(); Cell np = subNp.contentsView(); if (np != null) { pp = ((Export)pi.getPortProto()).getEquivalent(); if (pp == null || pp == pi.getPortProto()) { List<Geometric> geomList = new ArrayList<Geometric>(); geomList.add(geom); geomList.add(ni); errorLogger.logError("Arc " + ai.describe(true) + " connects to " + pi.getPortProto() + " of " + ni + ", but there is no equivalent port in " + np, geomList, null, cell, eg.getSortKey()); continue; } } int portWidth = netlist.getBusWidth((Export)pp); if (portWidth < 1) portWidth = 1; int nodeSize = ni.getNameKey().busWidth(); if (nodeSize <= 0) nodeSize = 1; if (signals != portWidth && signals != portWidth*nodeSize) { List<Geometric> geomList = new ArrayList<Geometric>(); geomList.add(geom); geomList.add(ni); errorLogger.logError("Arc " + ai.describe(true) + " (" + signals + " wide) connects to " + pp + " of " + ni + " (" + portWidth + " wide)", geomList, null, cell, eg.getSortKey()); } } } } /** * Method to check whether any port on a node overlaps others without connecting. */ private static void checkPortOverlap(Netlist netlist, NodeInst ni, ErrorGrouper eg) { if (ni.getProto().getTechnology() == Generic.tech() || ni.getProto().getTechnology() == Artwork.tech()) return; Cell cell = ni.getParent(); for(Iterator<PortInst> it = ni.getPortInsts(); it.hasNext(); ) { PortInst pi = it.next(); Network net = netlist.getNetwork(pi); Rectangle2D bounds = pi.getPoly().getBounds2D(); for(Iterator<RTBounds> sIt = cell.searchIterator(bounds); sIt.hasNext(); ) { Geometric oGeom = (Geometric)sIt.next(); if (!(oGeom instanceof NodeInst)) continue; NodeInst oNi = (NodeInst)oGeom; if (ni == oNi) continue; if (ni.getNodeIndex() > oNi.getNodeIndex()) continue; if (oNi.getProto().getTechnology() == Generic.tech() || oNi.getProto().getTechnology() == Artwork.tech()) continue; // see if ports touch for(Iterator<PortInst> pIt = oNi.getPortInsts(); pIt.hasNext(); ) { PortInst oPi = pIt.next(); Rectangle2D oBounds = oPi.getPoly().getBounds2D(); if (bounds.getMaxX() < oBounds.getMinX()) continue; if (bounds.getMinX() > oBounds.getMaxX()) continue; if (bounds.getMaxY() < oBounds.getMinY()) continue; if (bounds.getMinY() > oBounds.getMaxY()) continue; // see if they are connected if (net == netlist.getNetwork(oPi)) continue; // report the error List<Geometric> geomList = new ArrayList<Geometric>(); geomList.add(ni); geomList.add(oNi); errorLogger.logError("Nodes '" + ni + "' '" + oNi + "' have touching ports that are not connected", geomList, null, cell, eg.getSortKey()); return; } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -