📄 stitchfilljob.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: StitchFillJob.java * * Copyright (c) 2008 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool.generator.layout.fill;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.user.CellChangeJobs;import com.sun.electric.tool.user.ExportChanges;import com.sun.electric.tool.user.ui.WindowFrame;import com.sun.electric.tool.routing.*;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.hierarchy.View;import com.sun.electric.database.topology.*;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.geometry.Orientation;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortCharacteristic;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.network.Network;import com.sun.electric.database.network.Netlist;import com.sun.electric.technology.Layer;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.Technology;import com.sun.electric.technology.PrimitiveNode;import java.util.*;import java.awt.geom.Rectangle2D;import java.awt.geom.Area;import java.awt.geom.Point2D;/** * Fill Generator working on unconnected arcs * User: Gilda Garreton * Date: Nov 4, 2008 */public class StitchFillJob extends Job{ private Cell topCell; private Library outLibrary; private List<Cell> generatedCells = new ArrayList<Cell>();// private static final boolean doFill = false; public StitchFillJob(Cell cell, Library lib, boolean doItNow) { super("Fill generator job", null, Type.CHANGE, null, null, Priority.USER); this.topCell = cell; this.outLibrary = lib; if (doItNow) // call from regressions { try { if (doIt()) terminateOK(); } catch (JobException e) { e.printStackTrace(); } } else startJob(); // queue the job } public boolean doIt() throws JobException { Point2D center = new Point2D.Double(0, 0); // Get cells from EditWindows if (topCell == null) { Technology tech = null; List<NodeInst> fillCells = new ArrayList<NodeInst>(); List<Geometric> fillGeoms = new ArrayList<Geometric>(); String fillCellName = "NewFill{lay}"; Library lib = Library.getCurrent(); if (lib == null) { System.out.println("No current library available."); return false; } Cell oldCell = lib.findNodeProto(fillCellName); // Delete previous version if (oldCell != null) oldCell.kill(); Cell newCell = Cell.makeInstance(lib, fillCellName); for (Iterator<WindowFrame> itW = WindowFrame.getWindows(); itW.hasNext();) { WindowFrame w = itW.next(); Cell c = w.getContent().getCell(); if (c == null) { System.out.println("No cell in window '" + w.getTitle() + "'"); continue; } if (c.getView() != View.LAYOUT) { System.out.println("Cell '" + c + "' is not a layout cell"); continue; } Technology t = c.getTechnology(); if (tech == null) tech = t; else if (tech != t) System.out.println("Mixing technologies in fill generator: " + tech.getTechName() + " " + t.getTechName()); NodeInst ni = NodeInst.makeInstance(c, center, c.getDefWidth(), c.getDefHeight(), newCell); fillCells.add(ni); fillGeoms.add(ni); } // actual fill gen doTheJob(newCell, fillCellName, fillCells, fillGeoms, null, false, this); return true; // done at this point } String[] instructions = topCell.getTextViewContents(); if (instructions == null) { System.out.println("No fill instructions found."); return false; } for (String line : instructions) { if (line.startsWith("//")) continue; // commented line StringTokenizer parse = new StringTokenizer(line, ":", false); int count = 0; String fillCellName = null, rest = null; while (parse.hasMoreTokens()) { assert(count < 2); String value = parse.nextToken(); switch (count) { case 0: fillCellName = value; break; default: rest = value; break; } count++; } if (fillCellName == null) continue; // no parsing matching // getting possible options like "w" or "2x4" int index = fillCellName.indexOf("("); boolean wideOption = false; List<TileInfo> tileList = new ArrayList<TileInfo>(); if (index != -1) { // Getting options like (W) String options = fillCellName.substring(index); fillCellName = fillCellName.substring(0, index); parse = new StringTokenizer(options, "(), ", false); while (parse.hasMoreTokens()) { String option = parse.nextToken(); String lowerCase = option.toLowerCase(); // wide option where exports are added in lowest layer if (lowerCase.equals("w")) { wideOption = true; fillCellName += "W"; } else if (lowerCase.contains("x")) { index = lowerCase.indexOf("x"); String str = lowerCase.substring(0, index); int x = Integer.valueOf(str); str = lowerCase.substring(index+1, lowerCase.length()); int y = Integer.valueOf(str); // tile information TileInfo tile = new TileInfo(x, y); tileList.add(tile); } } }// Library lib = topCell.getLibrary(); // extracting fill subcells parse = new StringTokenizer(rest, " ,", false); String newName = fillCellName+"{lay}"; Cell oldCell = outLibrary.findNodeProto(newName); // Delete previous version if (oldCell != null) { oldCell.kill(); } Cell newCell = Cell.makeInstance(outLibrary, newName); Technology tech = null; List<NodeInst> fillCells = new ArrayList<NodeInst>(); List<Geometric> fillGeoms = new ArrayList<Geometric>(); while (parse.hasMoreTokens()) { String fillCell = parse.nextToken(); index = fillCell.indexOf("("); // options like (I) boolean instanceFlag = false; if (index != -1) { instanceFlag = fillCell.toLowerCase().indexOf("(i") != -1; // only (I) option for now fillCell = fillCell.substring(0, index); } Cell c = topCell.getLibrary().findNodeProto(fillCell); // +"{lay}"); if (c == null) { System.out.println("Cell '" + fillCell + "' does not exist"); continue; } if (c.getView() != View.LAYOUT) { System.out.println("Cell '" + c + "' is not a layout cell"); continue; } Technology t = c.getTechnology(); if (tech == null) tech = t; else if (tech != t) System.out.println("Mixing technologies in fill generator: " + tech.getTechName() + " " + t.getTechName()); NodeInst ni = NodeInst.makeInstance(c, center, c.getDefWidth(), c.getDefHeight(), newCell); if (!instanceFlag) fillCells.add(ni); fillGeoms.add(ni); } newCell.setTechnology(tech); generatedCells.add(newCell); // actual fill gen doTheJob(newCell, fillCellName, fillCells, fillGeoms, tileList, wideOption, this); } return true; } public List<Cell> getGeneratedCells() {return generatedCells;} /** * Method that executes the different functions to get the tool working * @param newCell * @param fillCellName * @param fillCells * @param fillGeoms * @param tileList * @param wideOption * @param job */ private static void doTheJob(Cell newCell, String fillCellName, List<NodeInst> fillCells, List<Geometric> fillGeoms, List<TileInfo> tileList, boolean wideOption, Job job) { // Re-exporting ExportChanges.reExportNodes(newCell, fillGeoms, false, true, false, true);// if (!doFill) return; // Flatting subcells new CellChangeJobs.ExtractCellInstances(newCell, fillCells, Integer.MAX_VALUE, true, true); // generation of master fill generateFill(newCell, wideOption); // tiles generation. Flat generation for now generateTiles(newCell, fillCellName, tileList, job); } /** * Class to store tile information */ private class TileInfo { int x, y; // size in x and y axes TileInfo(int a, int b) { x = a; y = b; } } /** * Method to generate tiles of a given cell according to the description provided. * The function will use the auto stitch tool so no hierarchy is expected. * @param template Cell to use as template * @param fillCellName Root name of the template cell * @param tileList List of dimensions to create * @param job Job running the task */ private static void generateTiles(Cell template, String fillCellName, List<TileInfo> tileList, Job job) { if (tileList == null) return; // nothing to tile // tiles generation. Flat generation for now for (TileInfo info : tileList) { String newTileName = fillCellName + info.x + "x" + info.y + "{lay}"; Cell newTile = Cell.makeInstance(template.getLibrary(), newTileName); // generate the array List<NodeInst> niList = new ArrayList<NodeInst>(); Rectangle2D rect = template.getBounds(); double width = rect.getWidth(); double height = rect.getHeight(); double xPos = 0, yPos; for (int i = 0; i < info.x; i++) { yPos = 0; for (int j = 0; j < info.y; j++) { NodeInst newNi = NodeInst.makeInstance(template, new Point2D.Double(xPos, yPos), width, height, newTile, Orientation.IDENT, null, 0); niList.add(newNi); yPos += height; } xPos += width; } AutoStitch.runAutoStitch(newTile, niList, null, job, null, null, true, true, true); } } /** * Main class to auto-stitch metal layers found in given cell * @param theCell Cell with the metal layer information * @param wideOption True if exports in the lowest layer will be added * @return True if auto-stitch ran without errors */ private static boolean generateFill(Cell theCell, boolean wideOption) { InteractiveRouter router = new SimpleWirer();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -