Beispiel #1
0
  /*
   * (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);
  }
Beispiel #2
0
 /**
  * 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());
   }
 }
Beispiel #3
0
 /**
  * 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;
 }
Beispiel #4
0
 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);
   }
 }
Beispiel #5
0
  /**
   * 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();
  }
Beispiel #6
0
  /** 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;
  }
Beispiel #7
0
  /** 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);
        }
      }
    }
  }
Beispiel #8
0
 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);
     }
   }
 }
Beispiel #9
0
  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;
  }
Beispiel #10
0
  /**
   * 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;
  }
Beispiel #11
0
  /**
   * 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();
    }
  }
Beispiel #12
0
  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;
  }
Beispiel #13
0
 static double leafCellYSize(Cell cell) {
   Rectangle2D bounds = cell.getBounds();
   return bounds.getHeight();
 }
Beispiel #14
0
 static double leafCellXSize(Cell cell) {
   Rectangle2D bounds = cell.getBounds();
   return bounds.getWidth();
 }
Beispiel #15
0
 /**
  * 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;
 }
Beispiel #16
0
 /**
  * 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);
 }