/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: OnRailCheck.java * * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * * 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.erc.wellcheck; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.awt.geom.Rectangle2D; import com.sun.electric.database.geometry.EPoint; import com.sun.electric.database.geometry.PolyBase; import com.sun.electric.tool.erc.ERCWellCheck.StrategyParameter; import com.sun.electric.tool.erc.ERCWellCheck.Transistor; import com.sun.electric.util.CollectionFactory; /** * @author Felix Schmidt * */ public class OnRailCheck implements WellCheckAnalysisStrategy { private Set<Integer> networkExportAvailable; private Set<Integer> networkWithExportCache; private Map<Integer, List<Transistor>> transistors; private List<Transistor> alreadyHit; private StrategyParameter parameter; /** * @param preferences * @param wellCons * @param networkExportAvailable * @param transistors * @param errorLogger * @param cell */ public OnRailCheck(StrategyParameter parameter, Set<Integer> networkExportAvailable, Map<Integer, List<Transistor>> transistors) { super(); this.networkExportAvailable = networkExportAvailable; this.transistors = transistors; this.networkWithExportCache = CollectionFactory.createHashSet(); this.parameter = parameter; } /* * (non-Javadoc) * * @see * com.sun.electric.tool.erc.wellcheck.WellCheckAnalysisStrategy#execute() */ public void execute() { int cacheHits = 0; // System.out.println(wellCons.size()); for (WellCon wc : parameter.getWellCons()) { if (!wc.isOnRail()) { if (networkExportAvailable.contains(wc.getNetNum())) wc.setOnRail(true); else if (networkWithExportCache.contains(wc.getNetNum())) { wc.setOnRail(true); cacheHits++; } else { Set<Integer> startPath = new HashSet<Integer>(); List<Transistor> startTrans = transistors.get(wc.getNetNum()); if (startTrans != null) { if (createTransistorChain(startPath, startTrans.get(0), false)) { wc.setOnRail(true); networkWithExportCache.addAll(startPath); } } } } if (!(wc.isOnRail() || wc.isOnProperRail())) { if (Utils.canBeSubstrateTap(wc.getFun())) { if (parameter.getWellPrefs().mustConnectPWellToGround) { parameter.logError("P-Well contact '" + wc.getNi().getName() + "' not connected to ground", wc); } } else { if (parameter.getWellPrefs().mustConnectNWellToPower) { parameter.logError("N-Well contact '" + wc.getNi().getName() + "' not connected to ground", wc); } } } } } private boolean createTransistorChain(Set<Integer> path, Transistor node, boolean result) { alreadyHit = new LinkedList<Transistor>(); result |= createTransistorRec(path, node, result, node.getDrainNet().get()); if (!result) result |= createTransistorRec(path, node, result, node.getSourceNet().get()); return result; } private boolean createTransistorRec(Set<Integer> path, Transistor node, boolean result, int num) { List<Transistor> transis = new LinkedList<Transistor>(); transis.add(node); alreadyHit.add(node); while (transis.size() > 0) { Transistor transistor = transis.get(0); transis.remove(transistor); Integer neighbor = null; if (transistor.getDrainNet().get() == num) { neighbor = transistor.getSourceNet().get(); } else { neighbor = transistor.getDrainNet().get(); } path.add(neighbor); num = neighbor; result |= networkExportAvailable.contains(neighbor); if (!result) { result |= networkWithExportCache.contains(neighbor); } // cut the line if (result) return result; for (Transistor trans : transistors.get(neighbor)) { if (!alreadyHit.contains(trans)) { transis.add(trans); alreadyHit.add(trans); } } } return result; } }