📄 xmlrules.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: XMLRules.java * Written by Gilda Garreton, Sun Microsystems. * * Copyright (c) 2005 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.technology;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.Geometric;import java.util.*;import java.io.Serializable;public class XMLRules implements DRCRules, Serializable{ /** Hash map to store rules per matrix index */ public HashMap<XMLRules.XMLRule, XMLRules.XMLRule>[] matrix; /** To remeber the technology */ private Technology tech; public XMLRules (Technology t) { this.tech = t; int numLayers = tech.getNumLayers(); int uTSize = (numLayers * numLayers + numLayers) / 2 + numLayers + tech.getNumNodes(); this.matrix = new HashMap[uTSize]; } /** * Method to determine the technology associated with this rules set. * @return the technology associated with this rules set. */ public Technology getTechnology() { return tech; } /** * Method to determine the index in the upper-left triangle array for two layers/nodes. In this type of rules, * the index starts after primitive nodes and single layers rules. * @param index1 the first layer/node index. * @param index2 the second layer/node index. * @return the index in the array that corresponds to these two layers/nodes. */ public int getRuleIndex(int index1, int index2) { if (index1 > index2) { int temp = index1; index1 = index2; index2 = temp; } int pIndex = (index1+1) * (index1/2) + (index1&1) * ((index1+1)/2); pIndex = index2 + (tech.getNumLayers()) * index1 - pIndex; return tech.getNumLayers() + tech.getNumNodes() + pIndex; } /** * Method to find the edge spacing rule between two layer. * @param layer1 the first layer. * @param layer2 the second layer. * @return the edge rule distance between the layers. * Returns null if there is no edge spacing rule. */ public DRCTemplate getEdgeRule(Layer layer1, Layer layer2) { return null; } /** * Method to tell UI if multiple wide rules are allowed * @param index * @return true if multiple wide riles are allowed. */ public boolean doesAllowMultipleWideRules(int index) { return true; } /** Method to get total number of rules stored */ public int getNumberOfRules() { // This function is better not to be cached int numberOfRules = 0; for (HashMap<XMLRules.XMLRule, XMLRules.XMLRule> map : matrix) { if (map != null) numberOfRules++; } return numberOfRules; } /** * To retrieve those nodes whose have rules * @return Array of Strings */ public String[] getNodesWithRules() { String[] nodesWithRules = new String[tech.getNumNodes()]; int j = 0; for(Iterator<PrimitiveNode> it = tech.getNodes(); it.hasNext(); ) { PrimitiveNode np = it.next(); nodesWithRules[j++] = np.getName(); } return nodesWithRules; } /** * Method to retrieve different spacing rules depending on spacingCase. * Type can be SPACING (normal values), SPACINGW (wide values), * SPACINGE (edge values) and CUTSPA (multi cuts) * @param index * @param spacingCase * @param wideRules * @return list of rules subdivided in UCONSPA and CONSPA */ public List<DRCTemplate> getSpacingRules(int index, DRCTemplate.DRCRuleType spacingCase, boolean wideRules) { List<DRCTemplate> list = new ArrayList<DRCTemplate>(2); switch (spacingCase) { case SPACING: // normal rules { double maxLimit = 0; int multi = -1; if (wideRules) { multi = 0; maxLimit = Double.MAX_VALUE; } list = getRuleForRange(index, DRCTemplate.DRCRuleType.CONSPA, -1, multi, maxLimit, list); list = getRuleForRange(index, DRCTemplate.DRCRuleType.UCONSPA, -1, multi, maxLimit, list); } break; case UCONSPA2D: // multi contact rule {// list = getRuleForRange(index, DRCTemplate.DRCRuleType.CONSPA, 1, -1, 0, list); list = getRuleForRange(index, DRCTemplate.DRCRuleType.UCONSPA2D, 1, -1, 0, list); } break; default: } return (list); } /** * * @param index * @param newRules * @param spacingCase SPACING for normal case, SPACINGW for wide case, CUTSPA for multi cuts * @param wideRules */ public void setSpacingRules(int index, List<DRCTemplate> newRules, DRCTemplate.DRCRuleType spacingCase, boolean wideRules) { List<DRCTemplate> list = new ArrayList<DRCTemplate>(0); HashMap<XMLRules.XMLRule,XMLRules.XMLRule> map = matrix[index]; // delete old rules for (DRCTemplate rule : newRules) { // Invalid data if (rule.getValue(0) <= 0 || rule.ruleName == null || rule.ruleName.equals("")) continue; // first remove any possible rule in the map switch (spacingCase) { case SPACING: // normal rules { double maxLimit = 0; int multi = -1; if (wideRules) // wide rules { multi = 0; maxLimit = Double.MAX_VALUE; } list = getRuleForRange(index, rule.ruleType, -1, multi, maxLimit, list); } break; case UCONSPA2D: // multi contact rule { list = getRuleForRange(index, rule.ruleType, 1, -1, 0, list); } break; default: } // No the most efficient algorithm for (DRCTemplate tmp : list) map.remove(tmp); } for (DRCTemplate rule : newRules) { // Invalid data if (rule.getValue(0) <= 0 || rule.ruleName == null || rule.ruleName.equals("")) continue; addRule(index, rule); } } /** * Method to retrieve simple layer or node rules * @param index the index of the layer or node * @param type the rule type. * @return the requested rule. */ public XMLRule getRule(int index, DRCTemplate.DRCRuleType type) { return (getRule(index, type, 0, 0, -1, null, null)); } /** * Method to retrieve specific SURROUND rules stored per node that involve two layers * @param index the combined index of the two layers involved * @param type * @param nodeName list containing the name of the primitive * @return DRCTemplate containing the rule */ public XMLRule getRule(int index, DRCTemplate.DRCRuleType type, String nodeName) { List<String> nameList = new ArrayList<String>(1); nameList.add(nodeName); return (getRule(index, type, 0, 0, -1, nameList, null)); } /** * Method to get the minimum <type> rule for a Layer * where <type> is the rule type. E.g. MinWidth or Area * @param layer the Layer to examine. * @param type rule type * @return the minimum width rule for the layer. * Returns null if there is no minimum width rule. */ public DRCTemplate getMinValue(Layer layer, DRCTemplate.DRCRuleType type) { int index = layer.getIndex(); if (index < 0) return null; return (getRule(index, type)); } /** * Method to set the minimum <type> rule for a Layer * where <type> is the rule type. E.g. MinWidth or Area * @param layer the Layer to examine. * @param name the rule name * @param value the new rule value * @param type rule type */ public void setMinValue(Layer layer, String name, double value, DRCTemplate.DRCRuleType type) { int index = layer.getIndex(); if (value <= 0) { System.out.println("Error: zero value in XMLRules:setMinValue"); return; } XMLRule oldRule = getRule(index, type); HashMap<XMLRules.XMLRule,XMLRules.XMLRule> map = matrix[index]; // Remove old rule first map.remove(oldRule); XMLRule r = new XMLRule(name, new double[]{value}, type, 0, 0, -1, DRCTemplate.DRCMode.ALL.mode()); addXMLRule(index, r); } /** * Method similar to getRuleForRange() but only search based on range of widths * @param index * @param type * @param multiCut -1 if don't care, 0 if no cuts, 1 if cuts * @param minW * @param maxW * @param list * @return List of DRC rules */ private List<DRCTemplate> getRuleForRange(int index, DRCTemplate.DRCRuleType type, int multiCut, double minW, double maxW, List<DRCTemplate> list) { HashMap<XMLRules.XMLRule,XMLRules.XMLRule> map = matrix[index]; if (list == null) list = new ArrayList<DRCTemplate>(2); if (map == null) return (list); for (XMLRule rule : map.values()) { if (rule.ruleType == type) { // discard rules that are not valid for this particular tech mode (ST or TSMC)// if (rule.when != DRCTemplate.DRCMode.ALL.mode() && (rule.when&techMode) != techMode)// continue; if (rule.multiCuts != -1 && rule.multiCuts != multiCut) continue; // Cuts don't match if (rule.maxWidth <= maxW && rule.maxWidth > minW) list.add(rule); } } return (list); } /** * Method to retrieve a rule based on type and max wide size * (valid for metal only) */ private XMLRule getRule(int index, DRCTemplate.DRCRuleType type, double wideS, double length, int multiCut, List<String> possibleNodeNames, List<String> layerNamesInOrder) { HashMap<XMLRules.XMLRule,XMLRules.XMLRule> map = matrix[index]; if (map == null) return (null); XMLRule maxR = null; boolean searchFor = (wideS > 0); for (XMLRule rule : map.values()) { if (rule.ruleType == type) { // Needs multiCut values if (rule.multiCuts != -1 && rule.multiCuts != multiCut) continue; // Cuts don't match // in case of spacing rules, we might need to match special names if (rule.nodeName != null && possibleNodeNames != null && !possibleNodeNames.contains(rule.nodeName)) continue; // No combination found // names in order do not match if (layerNamesInOrder != null && (!rule.name1.equals(layerNamesInOrder.get(0)) || !rule.name2.equals(layerNamesInOrder.get(1)))) continue; // First found is valid// if (!searchFor) return (rule);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -