?? gds.java
字號:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: GDS.java * Input/output tool: GDS output * Original C Code written by Sid Penstone, Queens University * Translated to Java by Steven M. Rubin, Sun Microsystems. * * Copyright (c) 2003 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.io.output;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.Export;import com.sun.electric.database.hierarchy.Nodable;import com.sun.electric.database.hierarchy.View;import com.sun.electric.database.prototype.PortOriginal;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.TextUtils;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.VarContext;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.io.GDSLayers;import com.sun.electric.tool.io.IOTool;import com.sun.electric.tool.ncc.basic.NccCellAnnotations;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.math.BigDecimal;import java.util.Calendar;import java.util.Collection;import java.util.Comparator;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.TreeSet;/** * This class writes files in GDS format. */public class GDS extends Geometry{ private static final int GDSVERSION = 3; private static final int BYTEMASK = 0xFF; private static final int DSIZE = 512; /* data block */ private static final int MAXPOINTS = 510; /* maximum points in a polygon */ private static final int EXPORTPRESENTATION= 0; /* centered (was 8 for bottomleft) */ // GDSII bit assignments in STRANS record private static final int STRANS_REFLX = 0x8000;// private static final int STRANS_ABSA = 0x2; // data type codes private static final int DTYP_NONE = 0; // header codes private static final short HDR_HEADER = 0x0002; private static final short HDR_BGNLIB = 0x0102; private static final short HDR_LIBNAME = 0x0206; private static final short HDR_UNITS = 0x0305; private static final short HDR_ENDLIB = 0x0400; private static final short HDR_BGNSTR = 0x0502; private static final short HDR_STRNAME = 0x0606; private static final short HDR_ENDSTR = 0x0700; private static final short HDR_BOUNDARY = 0x0800; private static final short HDR_PATH = 0x0900; private static final short HDR_SREF = 0x0A00;// private static final short HDR_AREF = 0x0B00; private static final short HDR_TEXT = 0x0C00; private static final short HDR_LAYER = 0x0D02; private static final short HDR_DATATYPE = 0x0E02; private static final short HDR_XY = 0x1003; private static final short HDR_ENDEL = 0x1100; private static final short HDR_SNAME = 0x1206; private static final short HDR_TEXTTYPE = 0x1602; private static final short HDR_PRESENTATION= 0x1701; private static final short HDR_STRING = 0x1906; private static final short HDR_STRANS = 0x1A01; private static final short HDR_MAG = 0x1B05; private static final short HDR_ANGLE = 0x1C05;// private static final short HDR_PROPATTR = 0x2B02;// private static final short HDR_PROPVALUE = 0x2C06; // Header byte counts private static final short HDR_N_BGNLIB = 28; private static final short HDR_N_UNITS = 20; private static final short HDR_N_ANGLE = 12; private static final short HDR_N_MAG = 12; // Maximum string sizes private static final int HDR_M_SNAME = 32; //private static final int HDR_M_STRNAME = 32; // replace by preference IOTool.getGDSCellNameMaxLen private static final int HDR_M_ASCII = 256; // contour gathering thresholds for polygon accumulation// private static final double BESTTHRESH = 0.001; /* 1/1000 of a millimeter */// private static final double WORSTTHRESH = 0.1; /* 1/10 of a millimeter */ /** for buffering output data */ private static byte [] dataBufferGDS = new byte[DSIZE]; /** for buffering output data */ private static byte [] emptyBuffer = new byte[DSIZE]; /** Current layer for gds output */ private static GDSLayers currentLayerNumbers; /** Position of next byte in the buffer */ private static int bufferPosition; /** Number data buffers output so far */ private static int blockCount; /** constant for GDS units */ private static double scaleFactor; /** cell naming map */ private Map<Cell,String> cellNames; /** layer number map */ private Map<Layer,GDSLayers> layerNumbers; /** separator string for lib + cell concatanated cell names */ public static final String concatStr = "."; /** Name remapping if NCC annotation */ private Map<String,Set<String>> nameRemapping; /** write pins at Export locations ? */ private final boolean writeExportPins; /** converts bracket to underscores in export names.*/ private final boolean convertBracketsInExports; /** * Main entry point for GDS output. * @param cell the top-level cell to write. * @param context the hierarchical context to the cell. * @param filePath the disk file to create. */ public static GDS writeGDSFile(Cell cell, VarContext context, String filePath) { return writeGDSFile(cell, context, filePath, IOTool.isGDSOutWritesExportPins(), IOTool.getGDSOutputConvertsBracketsInExports()); } /** * Main entry point for GDS output. * @param cell the top-level cell to write. * @param context the hierarchical context to the cell. * @param filePath the disk file to create. * @param writeExportPins write pins at Export locations. * @param convertBracketsInExports converts bracket to underscores in export names. */ public static GDS writeGDSFile(Cell cell, VarContext context, String filePath, boolean writeExportPins, boolean convertBracketsInExports) { if (cell.getView() != View.LAYOUT) { System.out.println("Can only write GDS for layout cells"); return null; } GDS out = new GDS(writeExportPins, convertBracketsInExports); if (out.openBinaryOutputStream(filePath)) return null; BloatVisitor visitor = out.makeBloatVisitor(getMaxHierDepth(cell)); if (out.writeCell(cell, context, visitor)) return null; if (out.closeBinaryOutputStream()) return null; System.out.println(filePath + " written"); // warn if library name was changed String topCellName = cell.getName(); String mangledTopCellName = makeGDSName(topCellName, HDR_M_ASCII); if (!topCellName.equals(mangledTopCellName)) System.out.println("Warning: library name in this file is " + mangledTopCellName + " (special characters were changed)"); return out; } private GDS(boolean writeExportPins, boolean convertBracketsInExports) { this.writeExportPins = writeExportPins; this.convertBracketsInExports = convertBracketsInExports; } protected void start() { initOutput(); outputBeginLibrary(topCell); } protected void done() { outputHeader(HDR_ENDLIB, 0); doneWritingOutput(); } /** Method to write cellGeom */ protected void writeCellGeom(CellGeom cellGeom) { // write this cell Cell cell = cellGeom.cell; outputBeginStruct(cell); boolean renamePins = (cell == topCell && IOTool.getGDSConvertNCCExportsConnectedByParentPins()); boolean colapseGndVddNames = (cell == topCell && IOTool.isGDSColapseVddGndPinNames()); if (renamePins) { // rename pins to allow external LVS programs to virtually connect nets as specified // by the NCC annotation exportsConnectedByParent NccCellAnnotations annotations = NccCellAnnotations.getAnnotations(cell); if (annotations == null) renamePins = false; else nameRemapping = createExportNameMap(annotations, cell); } // write all polys by Layer Set<Layer> layers = cellGeom.polyMap.keySet(); for (Layer layer : layers) { // No technology associated, case when art elements are added in layout // r.getTechnology() == Generic.tech for layer Glyph if (layer == null || layer.getTechnology() == null || layer.getTechnology() == Generic.tech()) continue; if (!selectLayer(layer)) { System.out.println("Skipping " + layer + " in GDS:writeCellGeom"); continue; } List<Object> polyList = cellGeom.polyMap.get(layer); for (Object obj : polyList) { PolyBase poly = (PolyBase)obj; Integer firstLayer = currentLayerNumbers.getFirstLayer(); int layerNum = firstLayer.intValue() & 0xFFFF; int layerType = (firstLayer.intValue() >> 16) & 0xFFFF; writePoly(poly, layerNum, layerType); } } // write all instances for (Nodable no : cellGeom.nodables) { writeNodable(no); } // now write exports if (IOTool.getGDSOutDefaultTextLayer() >= 0) { for(Iterator<PortProto> it = cell.getPorts(); it.hasNext(); ) { Export pp = (Export)it.next(); // find the node at the bottom of this export PortOriginal fp = new PortOriginal(pp.getOriginalPort()); PortInst bottomPort = fp.getBottomPort(); NodeInst bottomNi = bottomPort.getNodeInst(); // find the layer associated with this node PrimitiveNode pNp = (PrimitiveNode)bottomNi.getProto(); Technology.NodeLayer [] nLay = pNp.getLayers(); Layer layer = nLay[0].getLayer().getNonPseudoLayer(); selectLayer(layer);// int textLayer = IOTool.getGDSOutDefaultTextLayer(), textType = 0;// if (currentLayerNumbers.getTextLayer() != -1)// {// textLayer = currentLayerNumbers.getTextLayer() & 0xFFFF;// textType = (currentLayerNumbers.getTextLayer() >> 16) & 0xFFFF;// } int pinLayer = IOTool.getGDSOutDefaultTextLayer(), pinType = 0; if (currentLayerNumbers.getPinLayer() != -1) { pinLayer = currentLayerNumbers.getPinLayer() & 0xFFFF; pinType = (currentLayerNumbers.getPinLayer() >> 16) & 0xFFFF; } // put out a pin if requested if (writeExportPins) { writeExportOnLayer(pp, pinLayer, pinType, renamePins, colapseGndVddNames); // write the text //writeExportOnLayer(pp, textLayer, textType); } } } outputHeader(HDR_ENDSTR, 0); } private Map<String,Set<String>> createExportNameMap(NccCellAnnotations ann, Cell cell) { Map<String,Set<String>> nameMap = new HashMap<String,Set<String>>(); for (Iterator<List<NccCellAnnotations.NamePattern>> it2 = ann.getExportsConnected(); it2.hasNext(); ) { List<NccCellAnnotations.NamePattern> list = it2.next(); // list of all patterns that should be connected Set<String> connectedExports = new TreeSet<String>(new StringComparator()); for (NccCellAnnotations.NamePattern pat : list) { for (Iterator<PortProto> it = cell.getPorts(); it.hasNext(); ) { Export e = (Export)it.next(); String name = e.getName(); if (pat.matches(name)) { connectedExports.add(name); nameMap.put(name, connectedExports); } } } } return nameMap; } private static class StringComparator implements Comparator<String> { /** * Method to sort Objects by their string name. */ public int compare(String s1, String s2) { return s1.compareTo(s2); } public boolean equals(Object obj) { return (this == obj); } } private void writeExportOnLayer(Export pp, int layer, int type, boolean remapNames, boolean colapseGndVddNames) { outputHeader(HDR_TEXT, 0); outputHeader(HDR_LAYER, layer); outputHeader(HDR_TEXTTYPE, type); outputHeader(HDR_PRESENTATION, EXPORTPRESENTATION); // now the orientation NodeInst ni = pp.getOriginalPort().getNodeInst(); int transValue = 0; int angle = ni.getAngle(); if (ni.isXMirrored() != ni.isYMirrored()) transValue |= STRANS_REFLX; if (ni.isYMirrored()) angle = (3600 - angle)%3600; if (ni.isXMirrored()) angle = (1800 - angle)%3600; outputHeader(HDR_STRANS, transValue); // reduce the size of export text by a factor of 2 outputMag(0.5); outputAngle(angle); outputShort((short)12); outputShort(HDR_XY); Poly portPoly = pp.getOriginalPort().getPoly(); outputInt(scaleDBUnit(portPoly.getCenterX())); outputInt(scaleDBUnit(portPoly.getCenterY())); // now the string String str = pp.getName(); if (remapNames) { Set<String> nameSet = nameRemapping.get(str); if (nameSet != null) { str = nameSet.iterator().next(); str = str + ":" + str; //System.out.println("Remapping export "+pp.getName()+" to "+str); } } if (convertBracketsInExports) { // convert brackets to underscores str = str.replaceAll("[\\[\\]]", "_"); } if (colapseGndVddNames) { String tmp = str.toLowerCase(); // Detecting string in lower case and later search for "_" if (tmp.startsWith("vdd_") || tmp.startsWith("gnd_"))
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -