📄 mtdrcareatool.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Quick.java * * Copyright (c) 2004 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.drc;import com.sun.electric.technology.*;import com.sun.electric.tool.Consumer;import com.sun.electric.tool.Job;import com.sun.electric.tool.user.ErrorLogger;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.HierarchyEnumerator;import com.sun.electric.database.hierarchy.Nodable;import com.sun.electric.database.geometry.*;import com.sun.electric.database.variable.VarContext;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.network.Network;import com.sun.electric.database.prototype.NodeProto;import java.util.*;import java.awt.geom.AffineTransform;import java.awt.geom.Rectangle2D;import java.awt.geom.Area;/** * User: gg151869 * Date: Dec 11, 2007 */public class MTDRCAreaTool extends MTDRCTool{ /** Miscellanous data for DRC */ private DRC.ReportInfo reportInfo; public MTDRCAreaTool(Cell c, Consumer<MTDRCResult> consumer) { super("Design-Rule Area Check " + c, c, consumer); } @Override boolean checkArea() {return true;} static int checkMinArea(Layer theLayer, Cell topC, DRC.ReportInfo rI, DRCRules areaRules, CellLayersContainer cellLayersC, Job job, String msg) { DRCTemplate minAreaRule = areaRules.getMinValue(theLayer, DRCTemplate.DRCRuleType.MINAREA); DRCTemplate enclosedAreaRule = areaRules.getMinValue(theLayer, DRCTemplate.DRCRuleType.MINENCLOSEDAREA); DRCTemplate spaceRule = areaRules.getSpacingRule(theLayer, null, theLayer, null, true, -1, -1.0, -1.0); // UCONSPA, CONSPA or SPACING if (minAreaRule == null && enclosedAreaRule == null && spaceRule == null) return 0; if (msg != null) { System.out.println("Min Area DRC for " + msg + " in thread " + Thread.currentThread().getName()); } HierarchyEnumerator.Visitor quickArea = new LayerAreaEnumerator(theLayer, minAreaRule, enclosedAreaRule, spaceRule, topC, rI, GeometryHandler.GHMode.ALGO_SWEEP, cellLayersC, job); HierarchyEnumerator.enumerateCell(topC, VarContext.globalContext, quickArea); return rI.errorLogger.getNumErrors() + rI.errorLogger.getNumWarnings(); } @Override public MTDRCResult runTaskInternal(Layer theLayer) { ErrorLogger errorLogger = DRC.getDRCErrorLogger(true, false, ", Layer " + theLayer.getName()); String msg = "Cell " + topCell.getName() + " , layer " + theLayer.getName(); reportInfo = new DRC.ReportInfo(errorLogger, topCell.getTechnology(), false); Date lastAreaGoodDate = DRC.getLastDRCDateBasedOnBits(topCell, false, -1, !reportInfo.inMemory); if (DRC.isCellDRCDateGood(topCell, lastAreaGoodDate)) System.out.println("The cell seems to be MinArea OK. Should I run the code?"); int totalNumErrors = checkMinArea(theLayer, topCell, reportInfo, rules, cellLayersCon, this, msg); HashSet<Cell> goodAreaDRCDate = new HashSet<Cell>(); HashSet<Cell> cleanAreaDRCDate = new HashSet<Cell>(); long endTime = System.currentTimeMillis(); int errorCount = errorLogger.getNumErrors(); int warnCount = errorLogger.getNumWarnings(); System.out.println(errorCount + " errors and " + warnCount + " warnings found in " + msg + " (took " + TextUtils.getElapsedTime(endTime - startTime) + " in thread " + Thread.currentThread().getName() + ")"); long accuEndTime = System.currentTimeMillis() - globalStartTime; System.out.println("Accumulative time " + TextUtils.getElapsedTime(accuEndTime)); if (totalNumErrors == 0) { goodAreaDRCDate.add(topCell); } else { cleanAreaDRCDate.add(topCell); errorLogger.termLogging(true); } return new MTDRCResult(errorCount, warnCount, !checkAbort(), new HashSet<Cell>(), new HashSet<Cell>(), goodAreaDRCDate, cleanAreaDRCDate, null); } /************************************************************************************************************** * LayerAreaEnumerator class **************************************************************************************************************/ public static class GeometryHandlerLayerBucket { GeometryHandler local; boolean merged = false; GeometryHandlerLayerBucket(GeometryHandler.GHMode mode) { local = GeometryHandler.createGeometryHandler(mode, 1); } void addElementLocal(Poly poly, Layer layer) { local.add(layer, poly); } void mergeGeometry(Cell cell, Map<Cell, GeometryHandlerLayerBucket> cellsMap) { if (!merged) { merged = true; for (Iterator<NodeInst> it = cell.getNodes(); it.hasNext();) { NodeInst ni = it.next(); if (!ni.isCellInstance()) continue; // only cell instances AffineTransform trans = ni.transformOut(); Cell protoCell = (Cell) ni.getProto(); GeometryHandlerLayerBucket bucket = cellsMap.get(protoCell); if (bucket != null) // it is null when the layer was not found in the subcell local.addAll(bucket.local, trans); } local.postProcess(true); } else { assert (false); // It should not happen } } } /************************************************************************************************************** * LayerAreaEnumerator class **************************************************************************************************************/ /** * Class that uses local GeometryHandler to calculate the area per cell */ private static class LayerAreaEnumerator extends HierarchyEnumerator.Visitor { private Layer theLayer; private Job job; private Map<Cell,GeometryHandlerLayerBucket> cellsMap; private Layer.Function.Set thisLayerFunction; private GeometryHandler.GHMode mode; private Collection<PrimitiveNode> nodesList; // NodeProto that contains this layer private Collection<ArcProto> arcsList; // ArcProto that contains this layer private CellLayersContainer cellLayersCon; private DRCTemplate minAreaRule, enclosedAreaRule, spacingRule, minAreaEnclosedRule;// private ErrorLogger errorLogger; private Cell topCell; private DRC.ReportInfo reportInfo; LayerAreaEnumerator(Layer layer, DRCTemplate minAreaR, DRCTemplate enclosedAreaR, DRCTemplate spaceR, Cell topC, DRC.ReportInfo rI, GeometryHandler.GHMode m, CellLayersContainer cellLayersC, Job j) { // This is required so the poly arcs will be properly merged with the transistor polys // even though non-electrical layers are retrieved this.minAreaRule = minAreaR; this.enclosedAreaRule = enclosedAreaR; this.spacingRule = spaceR; this.topCell = topC; this.reportInfo = rI; this.theLayer = layer; this.thisLayerFunction = DRC.getMultiLayersSet(theLayer); this.mode = m; cellsMap = new HashMap<Cell,GeometryHandlerLayerBucket>(); nodesList = new ArrayList<PrimitiveNode>(); this.cellLayersCon = cellLayersC; this.job = j; // Store the min value betwen min area and min enclosure to speed up the process minAreaEnclosedRule = minAreaRule; if (enclosedAreaRule != null && (minAreaRule == null || enclosedAreaRule.getValue(0) < minAreaRule.getValue(0))) minAreaEnclosedRule = enclosedAreaRule; // determine list of PrimitiveNodes that have this particular layer for (PrimitiveNode node : topCell.getTechnology().getNodesCollection()) { for (Technology.NodeLayer nLayer : node.getLayers()) { if (thisLayerFunction.contains(nLayer.getLayer().getFunction(), theLayer.getFunctionExtras())) { nodesList.add(node); break; // found } } } arcsList = new ArrayList<ArcProto>(); for (ArcProto ap : topCell.getTechnology().getArcsCollection()) { for (int i = 0; i < ap.getNumArcLayers(); i++) { if (ap.getLayer(i) == theLayer) { arcsList.add(ap); break; // found } } } } public boolean enterCell(HierarchyEnumerator.CellInfo info) { // Checking if the job was aborted by the user if (job.checkAbort()) return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -