📄 techtolib.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: TechToLib.java * Technology Editor, conversion of technologies to libraries * Written by Steven M. Rubin, 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.tool.user.tecEdit;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.geometry.EGraphics;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.id.CellId;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.DRCRules;import com.sun.electric.technology.DRCTemplate;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.PrimitivePort;import com.sun.electric.technology.SizeOffset;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Artwork;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.Job;import com.sun.electric.tool.erc.ERC;import com.sun.electric.tool.user.User;import com.sun.electric.tool.user.ui.TopLevel;import java.awt.Color;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import javax.swing.JOptionPane;/** * This class generates technology libraries from technologys. */public class TechToLib{ /** * Method to convert the current technology into a library. */ public static void makeLibFromTech() { List<Technology> techs = new ArrayList<Technology>(); for(Iterator<Technology> it = Technology.getTechnologies(); it.hasNext(); ) { Technology tech = it.next();// if (tech.isNonStandard()) continue; techs.add(tech); } String [] techChoices = new String[techs.size()]; for(int i=0; i<techs.size(); i++) techChoices[i] = techs.get(i).getTechName(); String chosen = (String)JOptionPane.showInputDialog(TopLevel.getCurrentJFrame(), "Technology to Edit", "Choose a technology to edit", JOptionPane.QUESTION_MESSAGE, null, techChoices, Technology.getCurrent().getTechName()); if (chosen == null) return; Technology tech = Technology.findTechnology(chosen); Library already = Library.findLibrary(tech.getTechName()); if (already != null) { JOptionPane.showMessageDialog(TopLevel.getCurrentJFrame(), "There is already a library called '" + tech.getTechName() + "'. Delete it first.", "Cannot Convert Technology", JOptionPane.ERROR_MESSAGE); System.out.println(); return; } new LibFromTechJob(tech, false); } /** * Class to create a technology-library from a technology (in a Job). */ private static class LibFromTechJob extends Job { private Technology tech; private String libraryName; private boolean doItNow; private LibFromTechJob(Technology tech, boolean doItNow) { super("Make Technology Library from Technology", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.tech = tech; this.doItNow = doItNow; if (!doItNow) startJob(); } public String getLibraryName() { return libraryName; } public boolean doIt() { Library lib = makeLibFromTech(tech); if (lib == null) return false; // switch to the library and show a cell User.setCurrentLibrary(lib); if (!doItNow) fieldVariableChanged("libraryName"); libraryName = lib.getName(); return true; } } /** * Method to convert technology "tech" into a library and return that library. * Returns NOLIBRARY on error */ public static Library makeLibFromTech(Technology tech) { Library lib = Library.newInstance(tech.getTechName(), null); if (lib == null) { System.out.println("Cannot create library " + tech.getTechName()); return null; } System.out.println("Created library " + tech.getTechName() + "..."); // create the miscellaneous info cell (called "factors") Cell fNp = Cell.newInstance(lib, "factors"); if (fNp == null) return null; fNp.setInTechnologyLibrary(); // compute the number of layers (ignoring pseudo-layers) int layerTotal = 0; for(Iterator<Layer> it = tech.getLayers(); it.hasNext(); ) { Layer layer = it.next(); if (!layer.isPseudoLayer()) layerTotal++; } // build the general information cell GeneralInfo gi = new GeneralInfo(); gi.shortName = tech.getTechShortName(); if (gi.shortName == null) gi.shortName = tech.getTechName(); gi.nonElectrical = tech.isNonElectrical(); gi.scale = tech.getScale(); gi.scaleRelevant = tech.isScaleRelevant(); gi.resolution = tech.getResolution(); gi.defaultFoundry = tech.getPrefFoundry(); gi.defaultNumMetals = tech.getNumMetals(); gi.description = tech.getTechDesc(); gi.minRes = tech.getMinResistanceSetting().getDoubleFactoryValue(); gi.minCap = tech.getMinCapacitanceSetting().getDoubleFactoryValue(); gi.maxSeriesResistance = tech.getMaxSeriesResistance(); gi.gateShrinkage = tech.getGateLengthSubtraction(); gi.includeGateInResistance = tech.isGateIncluded(); gi.includeGround = tech.isGroundNetIncluded(); gi.gateCapacitance = tech.getGateCapacitanceSetting().getDoubleFactoryValue(); gi.wireRatio = tech.getWireRatioSetting().getDoubleFactoryValue(); gi.diffAlpha = tech.getDiffAlphaSetting().getDoubleFactoryValue(); Color [] wholeMap = tech.getColorMap(); int numLayers = tech.getNumTransparentLayers(); gi.transparentColors = new Color[numLayers]; for(int i=0; i<numLayers; i++) gi.transparentColors[i] = wholeMap[1<<i]; gi.spiceLevel1Header = tech.getSpiceHeaderLevel1(); gi.spiceLevel2Header = tech.getSpiceHeaderLevel2(); gi.spiceLevel3Header = tech.getSpiceHeaderLevel3(); DRCRules drcRules = tech.getFactoryDesignRules(); if (drcRules != null) { int rulesSize = layerTotal*(layerTotal + 1)/2; gi.conDist = new double[rulesSize]; gi.unConDist = new double[rulesSize]; Arrays.fill(gi.conDist, -1); Arrays.fill(gi.unConDist, -1); int ruleIndex = 0; for (int i1 = 0; i1 < layerTotal; i1++) { for (int i2 = i1; i2 < layerTotal; i2++) { for (DRCTemplate t: drcRules.getSpacingRules(drcRules.getRuleIndex(i1, i2), DRCTemplate.DRCRuleType.SPACING, false)) { if (t.ruleType == DRCTemplate.DRCRuleType.CONSPA) gi.conDist[ruleIndex] = t.getValue(0); else if (t.ruleType == DRCTemplate.DRCRuleType.UCONSPA) gi.unConDist[ruleIndex] = t.getValue(0); } ruleIndex++; } } } gi.generate(fNp); // create the layer node names Map<Layer,Cell> layerCells = new HashMap<Layer,Cell>(); // create the layer nodes System.out.println("Creating the layers..."); ArrayList<String> layerSequence = new ArrayList<String>(); LayerInfo [] lList = new LayerInfo[layerTotal]; Map<Layer,String> gdsLayers = tech.getGDSLayers(); int layIndex = 0; for(Iterator<Layer> it = tech.getLayers(); it.hasNext(); ) { Layer layer = it.next(); if (layer.isPseudoLayer()) continue; EGraphics desc = layer.getGraphics(); String fName = "layer-" + layer.getName() + "{lay}"; // make sure the layer doesn't exist if (lib.findNodeProto(fName) != null) { System.out.println("Warning: already a cell '" + fName + "'. Creating a new version"); } Cell lNp = Cell.newInstance(lib, fName); if (lNp == null) return null; lNp.setTechnology(Artwork.tech()); lNp.setInTechnologyLibrary(); layerCells.put(layer, lNp); LayerInfo li = new LayerInfo(); lList[layIndex++] = li; li.name = layer.getName(); li.fun = layer.getFunction(); li.funExtra = layer.getFunctionExtras(); li.pseudo = layer.isPseudoLayer(); li.desc = desc; if (li.pseudo) { String masterName = layer.getNonPseudoLayer().getName(); for(int j=0; j<layIndex; j++) { if (lList[j].name.equals(masterName)) { lList[j].myPseudo = li; break; } } continue; } // compute foreign file formats li.cif = (String)layer.getCIFLayerSetting().getFactoryValue(); li.dxf = (String)layer.getDXFLayerSetting().getFactoryValue(); li.skill = (String)layer.getSkillLayerSetting().getFactoryValue(); String gdsLayer = gdsLayers.get(layer); if (gdsLayer != null) li.gds = gdsLayer; // compute the SPICE information li.spiRes = layer.getResistanceSetting().getDoubleFactoryValue(); li.spiCap = layer.getCapacitanceSetting().getDoubleFactoryValue(); li.spiECap = layer.getEdgeCapacitanceSetting().getDoubleFactoryValue(); // compute the 3D information li.height3d = layer.getDistance(); li.thick3d = layer.getThickness(); // build the layer cell li.generate(lNp); layerSequence.add(lNp.getName().substring(6)); } if (layIndex != layerTotal) { System.out.println("INTERNAL ERROR: "); } // save the layer sequence String[] layerSequenceArray = layerSequence.toArray(new String[layerSequence.size()]); lib.newVar(Info.LAYERSEQUENCE_KEY, layerSequenceArray); // create the arc cells System.out.println("Creating the arcs..."); int arcTotal = 0; for(Iterator<ArcProto> it = tech.getArcs(); it.hasNext(); ) if (!it.next().isNotUsed()) arcTotal++; ArcInfo[] aList = new ArcInfo[arcTotal]; String [] arcSequence = new String[arcTotal]; int arcCount = 0; Map<ArcProto,Cell> arcCells = new HashMap<ArcProto,Cell>(); for(Iterator<ArcProto> it = tech.getArcs(); it.hasNext(); ) { ArcProto ap = it.next(); if (ap.isNotUsed()) continue; ArcInfo aIn = makeArcInfo(ap, lList); aList[arcCount] = aIn; arcSequence[arcCount] = ap.getName(); arcCount++; String fName = "arc-" + ap.getName() + "{lay}"; // make sure the arc doesn't exist if (lib.findNodeProto(fName) != null) { System.out.println("Warning: already a cell '" + fName + "'. Creating a new version"); } Cell aNp = Cell.makeInstance(lib, fName); if (aNp == null) return null; aNp.setTechnology(Artwork.tech()); aNp.setInTechnologyLibrary(); arcCells.put(ap, aNp); aIn.generate(aNp); // now create the arc layers double wid = ap.getDefaultLambdaBaseWidth(); double widX4 = wid * 4; if (widX4 <= 0) widX4 = 10; Poly [] polys = ap.getShapeOfDummyArc(widX4); double xOff = wid*2 + DBMath.gridToLambda(ap.getMaxLayerGridExtend());// double xOff = wid*2 + wid/2 + ap.getLambdaElibWidthOffset()/2; for(int i=0; i<polys.length; i++) { Poly poly = polys[i]; Layer arcLayer = poly.getLayer().getNonPseudoLayer(); if (arcLayer == null) continue; EGraphics arcDesc = arcLayer.getGraphics(); // scale the arc geometry appropriately Point2D [] points = poly.getPoints(); for(int k=0; k<points.length; k++) poly.setPoint(k, points[k].getX() - xOff - 20, points[k].getY() - 5); // create the node to describe this layer NodeInst ni = placeGeometry(poly, aNp); if (ni == null) continue; // get graphics for this layer Manipulate.setPatch(ni, arcDesc); Cell layerCell = layerCells.get(arcLayer); if (layerCell != null) ni.newVar(Info.LAYER_KEY, layerCell.getId()); ni.newVar(Info.OPTION_KEY, new Integer(Info.LAYERPATCH)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -