/* * (non-Javadoc) * * @see com.sun.electric.tool.routing.AbstractRoutingBaseClass#testRouter() */ @Override public void testRouter() throws Exception { Cell cell = this.loadCell("placementTests", "PlacementTest4"); TstUserInterface testUI = (TstUserInterface) Job.getUserInterface(); testUI.setCurrentCell(cell); River router = new River(); List<ArcInst> allArcs = new ArrayList<ArcInst>(); for (Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); ) allArcs.add(it.next()); router.river(cell, allArcs); }
/** * Method to add a Parameter to this NodeInst. Overridden in IconNodeInst * * @param param the Variable to delete. */ public void addParameter(Variable param) { if (!isParam(param.getKey())) { throw new IllegalArgumentException("Parameter " + param + " is not defined on " + getProto()); } Cell icon = (Cell) getProto(); Variable iconParam = icon.getParameter(param.getKey()); param = composeInstParam(iconParam, param); if (setD(getD().withParam(param), true)) // check for side-effects of the change { checkPossibleVariableEffects(param.getKey()); } }
/** * Method to return the Parameter on this IconNodeInst with the given key. If the Parameter is not * found on this IconNodeInst, it is also searched for on the default var owner. * * @param key the key of the parameter * @return the Parameter with that key, that may exist either on this IconNodeInst or the default * owner. Returns null if none found. */ @Override public Variable getParameter(Variable.Key key) { if (!(key instanceof Variable.AttrKey)) { return null; } Variable instParam = getD().getDefinedParameter((Variable.AttrKey) key); if (instParam != null) { return instParam; } Cell icon = (Cell) getProto(); Variable iconParam = icon.getParameter(key); return iconParam != null ? composeInstParam(iconParam, null) : null; }
private void undo(Cell cell) { if (!CVS.isDELIB(cell.getLibrary())) return; File libraryFile = TextUtils.getFile(cell.getLibrary().getLibFile()); if (libraryFile == null) return; String libfile = libraryFile.getPath(); // get cell directory if not already added before // check cell files File cellFile = new File(libfile, DELIB.getCellFile(cell)); if (undo(cellFile)) { State state = CVSLibrary.getState(cell); if (state == State.ADDED) CVSLibrary.setState(cell, State.UNKNOWN); if (state == State.REMOVED) CVSLibrary.setState(cell, State.NONE); } }
/** * Method to return an Iterator over all Parameters on this IconNodeInst. This may also include * any parameters on the defaultVarOwner object that are not on this object. * * @return an Iterator over all Parameters on this IconNodeInst. */ @Override public Iterator<Variable> getParameters() { Cell icon = (Cell) getProto(); if (!icon.hasParameters()) { return ArrayIterator.emptyIterator(); } ArrayList<Variable> params = new ArrayList<Variable>(); // get all parameters on this object for (Iterator<Variable> it = icon.getParameters(); it.hasNext(); ) { Variable iconParam = it.next(); Variable instVar = getD().getDefinedParameter((Variable.AttrKey) iconParam.getKey()); params.add(composeInstParam(iconParam, instVar)); } return params.iterator(); }
/** Method to parse the arc cell in "np" and return an ArcInfo object that describes it. */ static ArcInfo parseCell(Cell np) { // create and initialize the GRAPHICS structure ArcInfo aIn = new ArcInfo(); aIn.name = np.getName().substring(4); // look at all nodes in the arc description cell for (Iterator<NodeInst> it = np.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); Variable var = ni.getVar(OPTION_KEY); if (var == null) continue; String str = getValueOnNode(ni); switch (((Integer) var.getObject()).intValue()) { case ARCFUNCTION: aIn.func = ArcProto.Function.UNKNOWN; List<ArcProto.Function> allFuncs = ArcProto.Function.getFunctions(); for (ArcProto.Function fun : allFuncs) { if (fun.toString().equalsIgnoreCase(str)) { aIn.func = fun; break; } } break; case ARCINC: aIn.angInc = TextUtils.atoi(str); break; case ARCFIXANG: aIn.fixAng = str.equalsIgnoreCase("yes"); break; case ARCWIPESPINS: aIn.wipes = str.equalsIgnoreCase("yes"); break; case ARCNOEXTEND: aIn.noExtend = str.equalsIgnoreCase("no"); break; case ARCANTENNARATIO: aIn.antennaRatio = TextUtils.atof(str); break; case ARCWIDTHOFFSET: aIn.widthOffset = TextUtils.atof(str); break; } } return aIn; }
/** Method to compact an Arc technology-edit cell */ static void compactCell(Cell cell) { // compute bounds of arc contents Rectangle2D nonSpecBounds = null; for (Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getProto() == Generic.tech().cellCenterNode) continue; // ignore the special text nodes boolean special = false; for (int i = 0; i < arcTextTable.length; i++) if (arcTextTable[i].ni == ni) special = true; if (special) continue; // compute overall bounds Rectangle2D bounds = ni.getBounds(); if (nonSpecBounds == null) nonSpecBounds = bounds; else Rectangle2D.union(nonSpecBounds, bounds, nonSpecBounds); } // now rearrange the geometry if (nonSpecBounds != null) { double xOff = -nonSpecBounds.getCenterX(); double yOff = -nonSpecBounds.getMaxY(); if (xOff != 0 || yOff != 0) { for (Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); ) { NodeInst ni = it.next(); if (ni.getProto() == Generic.tech().cellCenterNode) continue; // ignore the special text nodes boolean special = false; for (int i = 0; i < arcTextTable.length; i++) if (arcTextTable[i].ni == ni) special = true; if (special) continue; // center the geometry ni.move(xOff, yOff); } } } }
private void generate(StringBuffer buf, Cell cell, String useDir) { if (!CVS.isDELIB(cell.getLibrary())) return; File libraryFile = TextUtils.getFile(cell.getLibrary().getLibFile()); if (libraryFile == null) return; String libfile = libraryFile.getPath(); // get cell directory if not already added before File celldirFile = new File(libfile, DELIB.getCellSubDir(cell.getId())); String celldir = celldirFile.getPath(); if (!addedCellDirs.containsKey(celldir) && !libfile.equals(celldir)) { if (celldirFile.exists()) add(buf, celldir, useDir); addedCellDirs.put(celldir, null); } // check cell files File cellFile = new File(libfile, DELIB.getCellFile(cell)); add(buf, cellFile.getPath(), useDir); // check that header is added or in cvs, or library is going to be added if (add) { File headerFile = new File(libfile, DELIB.getHeaderFile()); if (!libs.contains(cell.getLibrary()) && !CVS.isFileInCVS(headerFile)) { add(buf, headerFile.getPath(), useDir); } } }
public Cell makeVddGndM3Cell(Cell layCell, TechType tech) { Library layLib = layCell.getLibrary(); CellName nm = layCell.getCellName(); String m3Nm = nm.getName() + "_m3{lay}"; Cell m3Cell = Cell.newInstance(layLib, m3Nm); Rectangle2D bounds = layCell.findEssentialBounds(); double minX = bounds.getMinX(); double minY = bounds.getMinY(); double maxX = bounds.getMaxX(); double maxY = bounds.getMaxY(); LayoutLib.newNodeInst(tech.essentialBounds(), minX, minY, DEF_SIZE, DEF_SIZE, 0, m3Cell); LayoutLib.newNodeInst(tech.essentialBounds(), maxX, maxY, DEF_SIZE, DEF_SIZE, 180, m3Cell); for (Integer x : xCoords) { PortInst p1 = LayoutLib.newNodeInst(tech.m3pin(), x, minY, DEF_SIZE, DEF_SIZE, 180, m3Cell) .getOnlyPortInst(); PortInst p2 = LayoutLib.newNodeInst(tech.m3pin(), x, maxY, DEF_SIZE, DEF_SIZE, 180, m3Cell) .getOnlyPortInst(); LayoutLib.newArcInst(tech.m3(), vddGndWidth, p1, p2); } return m3Cell; }
/** * Method to call a series of routines which convert the hierarchical network description into a * flattened database representation. The actual simulation must take place on the flattened * network. Returns true on error. */ boolean flattenNetwork(Cell cell) { /* * create a "dummy" level to use as a mixed signal destination for plotting and * screen display. This level should be bypassed for structure checking and general * simulation, however, so in the following code, references to "als.cellRoot" * have been changed to als.cellRoot.next (pointing to mainCell). * Peter Gallant July 16, 1990 */ als.cellRoot = new ALS.Connect(); als.cellRoot.instName = "[MIXED_SIGNAL_LEVEL]"; als.cellRoot.modelName = als.cellRoot.instName; als.cellRoot.exList = new ArrayList<ALS.ALSExport>(); als.cellRoot.parent = null; als.cellRoot.child = null; als.cellRoot.next = null; ALS.Connect tempRoot = als.cellRoot; // get upper-case version of main proto String mainName = cell.getName().toUpperCase(); als.cellRoot = new ALS.Connect(); als.cellRoot.instName = mainName; als.cellRoot.modelName = als.cellRoot.instName; als.cellRoot.exList = new ArrayList<ALS.ALSExport>(); als.cellRoot.parent = null; als.cellRoot.child = null; als.cellRoot.next = null; // these lines link the mixed level as the head followed by mainCell PJG tempRoot.next = als.cellRoot; // shouldn't this be null? ... smr tempRoot.child = als.cellRoot; als.cellRoot = tempRoot; // this code checks to see if model mainCell is present in the netlist PJG ALS.Model modHead = findModel(mainName); if (modHead == null) return true; for (ALS.ALSExport exHead : modHead.exList) { findXRefEntry(als.cellRoot.next, (String) exHead.nodeName); } if (flattenModel(als.cellRoot.next)) return true; for (ALS.Node nodeHead : als.nodeList) { if (nodeHead.load < 1) nodeHead.load = 1; } return false; }
/** * Add or Remove libs and cells from CVS. * * @param libs * @param cells * @param add true to add to cvs, false to remove from cvs * @param undo true to undo add/remove (boolean add ignored in this case). */ public static void addremove(List<Library> libs, List<Cell> cells, boolean add, boolean undo) { if (libs == null) libs = new ArrayList<Library>(); if (cells == null) cells = new ArrayList<Cell>(); // make sure cells are part of a DELIB CVSLibrary.LibsCells bad = CVSLibrary.notFromDELIB(cells); if (bad.cells.size() > 0) { CVS.showError( "Error: the following Cells are not part of a DELIB library and cannot be acted upon individually", "CVS Add/Remove Error", bad.libs, bad.cells); return; } bad = CVSLibrary.getModified(libs, cells); if (bad.libs.size() > 0 || bad.cells.size() > 0) { CVS.showError( "Error: the following Libraries or Cells must be saved first", "CVS " + (add ? "Add" : "Remove") + " Error", bad.libs, bad.cells); return; } // delib cells must have library added first List<Library> assertLibsInCVS = new ArrayList<Library>(); for (Cell cell : cells) { Library lib = cell.getLibrary(); if (libs.contains(lib) || assertLibsInCVS.contains(lib)) continue; assertLibsInCVS.add(lib); } bad = CVSLibrary.getNotInCVS(assertLibsInCVS, null); if (bad.libs.size() > 0) { CVS.showError( "Error: cannot add DELIB cells if cell's DELIB library is not in cvs", "CVS " + (add ? "Add" : "Remove") + " Error", bad.libs, bad.cells); return; } // optimize a little, remove cells from cells list if cell's lib in libs list CVSLibrary.LibsCells good = CVSLibrary.consolidate(libs, cells); if (!undo) { // when job generates files to add/remove, it will do the check to see if they are in // cvs or not. Don't do it here because we may specify lib to add unadded cells. /* if (add) { good = CVSLibrary.getNotInCVS(libs, cells); } else { good = CVSLibrary.getInCVS(libs, cells); } */ // issue final warning for Remove if (!add) { StringBuffer list = new StringBuffer( "Warning! CVS Remove will delete disk files for these Libraries and Cells!!!"); for (Library lib : good.libs) list.append("\n " + lib.getName()); for (Cell cell : good.cells) list.append("\n " + cell.libDescribe()); if (!Job.getUserInterface().confirmMessage(list.toString())) return; } (new AddRemoveJob(good.libs, good.cells, add)).startJob(); } else { (new UndoAddRemoveJob(good.libs, good.cells)).startJob(); } }
public static Cell makePart(double sz, StdCellParams stdCell) { TechType tech = stdCell.getTechType(); sz = stdCell.roundSize(sz); String nm = "nms1" + (stdCell.getDoubleStrapGate() ? "_strap" : ""); sz = stdCell.checkMinStrength(sz, 1, nm); // Space needed at top of MOS well. // We need more space if we're double strapping poly. double outsideSpace = stdCell.getDoubleStrapGate() ? (2 + 5 + 1.5 // p1_nd_sp + p1m1_wid + p1_p1_sp/2 ) : (wellOverhangDiff); double spaceAvail = nmosTop - (stdCell.getCellBot() + outsideSpace); double totWid = sz * 3; FoldsAndWidth fw = stdCell.calcFoldsAndWidth(spaceAvail, totWid, 1); error(fw == null, "can't make Nms1 this small: " + sz); Cell nms1 = stdCell.findPart(nm, sz); if (nms1 != null) return nms1; nms1 = stdCell.newPart(nm, sz); // leave vertical m1 track for g double gX = 1.5 + 2; // m1_m1_sp/2 + m1_wid/2 LayoutLib.newExport(nms1, "g", PortCharacteristic.IN, tech.m1(), 4, gX, gY); // gnd port overlaps leftmost MOS diffusion contacts double mosX = gX + 2 + 3 + 2; // m1_wid/2 + m1_m1_sp + m1_wid/2 double nmosY = nmosTop - fw.physWid / 2; FoldedMos nmos = new FoldedNmos(mosX, nmosY, fw.nbFolds, 1, fw.gateWid, nms1, tech); // output d m1_wid/2 + m1_m1_sp + m1_wid/2 double dX = StdCellParams.getRightDiffX(nmos) + 2 + 3 + 2; LayoutLib.newExport(nms1, "d", PortCharacteristic.OUT, tech.m1(), 4, dX, dY); // create gnd export and connect to MOS source/drains stdCell.wireVddGnd(nmos, StdCellParams.EVEN, nms1); // connect up input g TrackRouter g = new TrackRouterH(tech.m1(), 3, gY, tech, nms1); g.connect(nms1.findExport("g")); for (int i = 0; i < nmos.nbGates(); i++) g.connect(nmos.getGate(i, 'T')); if (stdCell.getDoubleStrapGate()) { // Connect gates using metal1 along bottom of cell double gndBot = stdCell.getGndY() - stdCell.getGndWidth() / 2; double inLoFromGnd = gndBot - 3 - 2; // -m1_m1_sp -m1_wid/2 double nmosBot = nmosY - fw.physWid / 2; double inLoFromMos = nmosBot - 2 - 2.5; // -nd_p1_sp -p1m1_wid/2 double inLoY = Math.min(inLoFromGnd, inLoFromMos); TrackRouter inLo = new TrackRouterH(tech.m1(), 3, inLoY, tech, nms1); inLo.connect(nms1.findExport("g")); for (int i = 0; i < nmos.nbGates(); i++) { inLo.connect(nmos.getGate(i, 'B')); } } // connect up output d TrackRouter d = new TrackRouterH(tech.m2(), 4, dY, tech, nms1); d.connect(nms1.findExport("d")); for (int i = 1; i < nmos.nbSrcDrns(); i += 2) { d.connect(nmos.getSrcDrn(i)); } // add wells double wellMinX = 0; double wellMaxX = dX + 2 + 1.5; // m1_wid/2 + m1m1_space/2 stdCell.addNmosWell(wellMinX, wellMaxX, nms1); // add essential bounds stdCell.addNstackEssentialBounds(wellMinX, wellMaxX, nms1); // perform Network Consistency Check stdCell.doNCC(nms1, nm + "{sch}"); return nms1; }
static double leafCellYSize(Cell cell) { Rectangle2D bounds = cell.getBounds(); return bounds.getHeight(); }
static double leafCellXSize(Cell cell) { Rectangle2D bounds = cell.getBounds(); return bounds.getWidth(); }
/** * Method to return the prototype of this Nodable. * * @return the prototype of this Nodable. */ public NodeProto getProto() { Cell iconCell = IconNodeInst.this.getProto(); Cell mainSchematics = iconCell.getCellGroup().getMainSchematics(); return mainSchematics != null ? mainSchematics : iconCell; }
/** * Method to return true if the Variable on this NodeInst with given key is a parameter. * Parameters are those Variables that have values on instances which are passed down the * hierarchy into the contents. * * @param varKey key to test * @return true if the Variable with given key is a parameter. */ @Override public boolean isParam(Variable.Key varKey) { Cell icon = (Cell) getProto(); return icon.isParam(varKey); }