📄 parasitictool.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ParasiticTool.java * Written by: Gilda Garreton, Sun Microsystems. * * 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.extract;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.PolyBase;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.network.Network;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.Pref;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.Geometric;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.topology.RTBounds;import com.sun.electric.database.variable.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.Tool;import com.sun.electric.tool.simulation.Simulation;import com.sun.electric.tool.user.ErrorLogger;import java.awt.geom.AffineTransform;import java.awt.geom.Rectangle2D;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;/** * Class to implement parasitic extraction. */public class ParasiticTool extends Tool { /** The Parasitic Extraction tool */ private static ParasiticTool tool = new ParasiticTool(); private static ErrorLogger errorLogger = ErrorLogger.newInstance("Parasitics Extraction");; private ParasiticTool() { super("parasitic");} /** * Method to initialize the Parasitics tool. */ public void init() { } /** * Method to retrieve singlenton associated to parasitic tool */ public static ParasiticTool getParasiticTool() { return tool; } public static ErrorLogger getParasiticErrorLogger() { return errorLogger; } public static double getAreaScale(double scale) { return scale*scale/1000000; } // area in square microns public static double getPerimScale(double scale) { return scale/1000; } // perim in microns public void netwokParasitic(Network network, Cell cell) { new AnalyzeParasitic(network, cell); } public static List<Object> calculateParasistic(ParasiticGenerator tool, Cell cell, VarContext context) { errorLogger.clearLogs(cell);// Netlist netList = cell.getNetlist(false); if (context == null) context = VarContext.globalContext; ParasiticVisitor visitor = new ParasiticVisitor(tool, context); HierarchyEnumerator.enumerateCell(cell, context, visitor);// HierarchyEnumerator.enumerateCell(cell, context, netList, visitor); List<Object> list = visitor.getParasitics(); return list; } private static class ParasiticVisitor extends HierarchyEnumerator.Visitor { private Map<Network,NetPBucket> netMap; //private Netlist netList; private List<Object> transAndRCList = new ArrayList<Object>(); private ParasiticGenerator tool; private VarContext context; public List<Object> getParasitics() { List<Object> list = new ArrayList<Object>(transAndRCList); for (Network net : netMap.keySet()) { Object value = netMap.get(net); if (value != null) list.add(value); } return list; } public HierarchyEnumerator.CellInfo newCellInfo() { return new ParasiticCellInfo(); } public ParasiticVisitor(ParasiticGenerator tool, VarContext context) { //this.netList = netList; this.tool = tool; netMap = new HashMap<Network,NetPBucket>();// netMap = new HashMap(netList.getNumNetworks()); this.context = context; } /** * @param info */ public void exitCell(HierarchyEnumerator.CellInfo info) { // Done with root cell if (info.getParentInfo() == null) { for (Network net : netMap.keySet()) { NetPBucket bucket = netMap.get(net); bucket.postProcess(false); } } } private NetPBucket getNetParasiticsBucket(Network net, HierarchyEnumerator.CellInfo info) { NetPBucket parasiticNet = netMap.get(net); int numRemoveParents = context.getNumLevels(); if (parasiticNet == null) { String name = info.getUniqueNetNameProxy(net, "/").toString(numRemoveParents); parasiticNet = new NetPBucket(name); netMap.put(net, parasiticNet); } return parasiticNet; } public boolean enterCell(HierarchyEnumerator.CellInfo info) { ParasiticCellInfo iinfo = (ParasiticCellInfo)info; iinfo.extInit(); int numRemoveParents = context.getNumLevels(); for(Iterator<ArcInst> aIt = info.getCell().getArcs(); aIt.hasNext(); ) { ArcInst ai = aIt.next(); // don't count non-electrical arcs if (ai.getProto().getFunction() == ArcProto.Function.NONELEC) continue; Network net = info.getNetlist().getNetwork(ai, 0); // netList.getNetwork(ai, 0); if (net == null) continue; PortInst tailP = ai.getTailPortInst(); PortInst headP = ai.getHeadPortInst();// Network net1 = netList.getNetwork(tailP);// Network net2 = netList.getNetwork(headP);// if (net1 != net) net2 = net1; NetPBucket parasiticNet = getNetParasiticsBucket(net, info); if (parasiticNet == null) continue; String netName = info.getUniqueNetNameProxy(net, "/").toString(numRemoveParents); String net1Name = netName+"_"+tailP.getNodeInst().getName(); String net2Name = netName+"_"+headP.getNodeInst().getName(); boolean isDiffArc = ai.isDiffusionArc(); // check arc function Technology tech = ai.getProto().getTechnology(); Poly [] arcInstPolyList = tech.getShapeOfArc(ai); int tot = arcInstPolyList.length; for(int j=0; j<tot; j++) { Poly poly = arcInstPolyList[j]; if (poly.getStyle().isText()) continue; if (poly.isPseudoLayer()) continue; Layer layer = poly.getLayer(); if (layer.getTechnology() != Technology.getCurrent()) continue;// if (layer.isPseudoLayer()) continue; if (isDiffArc || layer.getCapacitance() > 0.0) //if (layer.isDiffusionLayer() || (!isDiffArc && layer.getCapacitance() > 0.0)) parasiticNet.addCapacitance(layer, poly); if (layer.getResistance() > 0.0) parasiticNet.modifyResistance(layer, poly, new String[] {net1Name, net2Name}, true); } } return (true); } /** * * @param no * @param info * @return */ public boolean visitNodeInst(Nodable no, HierarchyEnumerator.CellInfo info) { NodeInst ni = no.getNodeInst(); if (ni.isCellInstance()) return true; // hierarchical // Its like pins, facet-center if (NodeInst.isSpecialNode(ni)) return (false); // initialize to examine the polygons on this node Technology tech = ni.getProto().getTechnology(); AffineTransform trans = ni.rotateOut(); ExtractedPBucket parasitic = tool.createBucket(ni, (ParasiticCellInfo)info); if (parasitic != null) transAndRCList.add(parasitic); int numRemoveParents = context.getNumLevels(); PrimitiveNode.Function function = ni.getFunction(); // In case of contacts, the area is substracted. boolean add = function != PrimitiveNode.Function.CONTACT; Poly [] polyList = tech.getShapeOfNode(ni, true, true, null); int tot = polyList.length; for(int i=0; i<tot; i++) { Poly poly = polyList[i]; if (poly.isPseudoLayer()) continue; // make sure this layer connects electrically to the desired port PortProto pp = poly.getPort(); if (pp == null) continue; Network net = info.getNetlist().getNetwork(ni, pp, 0); // netList.getNetwork(ni, pp, 0); // don't bother with layers without capacity Layer layer = poly.getLayer(); if (layer.getTechnology() != Technology.getCurrent()) continue; if (!layer.isDiffusionLayer() && net == null) continue; // only this case skipping for now, schematic case// if (!layer.isDiffusionLayer() &&// layer.getCapacitance() == 0.0 && layer.getResistance() == 0.0) continue; NetPBucket parasiticNet = getNetParasiticsBucket(net, info); if (parasiticNet == null) continue; boolean isDiffLayer = layer.isDiffusionLayer(); if (function.isTransistor() && isDiffLayer) parasiticNet.addTransistor(parasitic); // get the area of this polygon poly.transform(trans); // leave out the gate capacitance of transistors boolean gateLayer = (layer.getFunction() == Layer.Function.GATE); if (isDiffLayer || !gateLayer && layer.getCapacitance() > 0.0) // diffusion might have zero capacitances ) parasiticNet.addCapacitance(layer, poly); // Doesn't include gates if user set that if (gateLayer && !tech.isGateIncluded()) continue; String netName = info.getUniqueNetNameProxy(net, "/").toString(numRemoveParents) + "_" + ni.getName(); if (layer.getResistance() > 0.0) parasiticNet.modifyResistance(layer, poly, new String[] {netName, netName}, add); } return (true); } } /****** inner class to store information ****/ private static class ParasiticBucket { public Poly poly; /** Face area perpendicular to euclidean distance */ public double area; /** Width of cross section */ public double length; protected ParasiticBucket(Poly p, double a, double l) { poly = p; area = a; length = l; } } private static class ParasiticValue {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -