📄 edif.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: EDIF.java * Input/output tool: EDIF netlist generator * Original C Code written by Steven M. Rubin, B G West and Glen M. Lawson * Translated to Java by Steven M. Rubin, 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.io.output;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.geometry.Orientation;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.hierarchy.Nodable;import com.sun.electric.database.hierarchy.View;import com.sun.electric.database.network.Global;import com.sun.electric.database.network.Netlist;import com.sun.electric.database.network.Network;import com.sun.electric.database.prototype.NodeProto;import com.sun.electric.database.prototype.PortCharacteristic;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.text.Version;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.Connection;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.variable.DisplayedText;import com.sun.electric.database.variable.ElectricObject;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Artwork;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.technology.technologies.Schematics;import com.sun.electric.tool.io.IOTool;import com.sun.electric.tool.user.User;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.text.DecimalFormat;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * This is the netlister for EDIF. */public class EDIF extends Topology{ /** true to add extra "ripping" cells where arcs and busses meet */ private static final boolean ADD_RIPPERS = true; private static class EGraphic { private String text; EGraphic(String text) { this.text = text; } String getText() { return text; } } private static final EGraphic EGUNKNOWN = new EGraphic("UNKNOWN"); private static final EGraphic EGART = new EGraphic("ARTWORK"); private static final EGraphic EGWIRE = new EGraphic("WIRE"); private static final EGraphic EGBUS = new EGraphic("BUS"); private EGraphic egraphic = EGUNKNOWN; private EGraphic egraphic_override = EGUNKNOWN; // for bus rippers private static class BusRipper { private NodeInst ni; private Network net; private int busWidth; private int busIndex; private int splitterIndex; private String busName; private static HashMap<Cell,List<BusRipper>> rippersPerCell = null; private BusRipper(NodeInst ni, Network net, int busWidth, int busIndex, int splitterIndex, String busName) { this.ni = ni; this.net = net; this.busWidth = busWidth; this.busIndex = busIndex; this.splitterIndex = splitterIndex; this.busName = busName; } public int getBusWidth() { return busWidth; } public int getBusIndex() { return busIndex; } public int getSplitterIndex() { return splitterIndex; } public static void makeBusRipper(NodeInst ni, Network net, int busWidth, int busIndex, int splitterIndex, String busName) { BusRipper br = new BusRipper(ni, net, busWidth, busIndex, splitterIndex, busName); // add to lists Cell cell = ni.getParent(); if (rippersPerCell == null) rippersPerCell = new HashMap<Cell,List<BusRipper>>(); List<BusRipper> rippersInCell = rippersPerCell.get(cell); if (rippersInCell == null) { rippersInCell = new ArrayList<BusRipper>(); rippersPerCell.put(cell, rippersInCell); } rippersInCell.add(br); } public static BusRipper findBusRipper(NodeInst ni, Network net) { if (rippersPerCell == null) return null; List<BusRipper> rippersInCell = rippersPerCell.get(ni.getParent()); if (rippersInCell == null) return null; for(BusRipper br : rippersInCell) { if (br.ni == ni && br.net == net) return br; } return null; } public static List<BusRipper> getRippersOnBus(Cell cell, String busName) { List<BusRipper> ripperList = new ArrayList<BusRipper>(); if (rippersPerCell == null) return ripperList; List<BusRipper> rippersInCell = rippersPerCell.get(cell); if (rippersInCell == null) return ripperList; for(BusRipper br : rippersInCell) { if (br.busName.equals(busName)) ripperList.add(br); } return ripperList; } public static void done() { rippersPerCell = null; } } // settings that may later be changed by preferences private static final String primitivesLibName = "ELECTRIC_PRIMS"; private int scale = 20; EDIFEquiv equivs; private final HashMap<Library,LibToWrite> libsToWrite; // key is Library, Value is LibToWrite private final List<Library> libsToWriteOrder; // list of libraries to write, in order private static class LibToWrite { private final List<CellToWrite> cellsToWrite; private LibToWrite(Library l) { cellsToWrite = new ArrayList<CellToWrite>(); } private void add(CellToWrite c) { cellsToWrite.add(c); } private Iterator<CellToWrite> getCells() { return cellsToWrite.iterator(); } } private static class CellToWrite { private final Cell cell; private final CellNetInfo cni; private final VarContext context; private CellToWrite(Cell cell, CellNetInfo cni, VarContext context) { this.cell = cell; this.cni = cni; this.context = context; } } /** * The main entry point for EDIF deck writing. * @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 void writeEDIFFile(Cell cell, VarContext context, String filePath) { EDIF out = new EDIF(); if (out.openTextOutputStream(filePath)) return; if (out.writeCell(cell, context)) return; if (out.closeTextOutputStream()) return; System.out.println(filePath + " written"); } /** * Creates a new instance of the EDIF netlister. */ EDIF() { libsToWrite = new HashMap<Library,LibToWrite>(); libsToWriteOrder = new ArrayList<Library>(); equivs = new EDIFEquiv(); } protected void start() { // If this is a layout representation, then create the footprint if (topCell.getView() == View.LAYOUT) { // default routing grid is 6.6u = 660 centimicrons int rgrid = 660; // calculate the actual routing grid in microns double route = rgrid / 100;// String iname = name + ".foot";// io_fileout = xcreate(iname, io_filetypeedif, "EDIF File", &truename);// if (io_fileout == NULL)// {// if (truename != 0) ttyputerr(_("Cannot write %s"), iname);// return(TRUE);// } // write the header System.out.println("Writing footprint for cell " + makeToken(topCell.getName())); printWriter.println("(footprint " + TextUtils.formatDouble(route) + "e-06"); printWriter.println(" (unknownLayoutRep"); // get standard cell dimensions Rectangle2D cellBounds = topCell.getBounds(); double width = cellBounds.getWidth() / rgrid; double height = cellBounds.getHeight() / rgrid; printWriter.println(" (" + makeToken(topCell.getName()) + " standard (" + TextUtils.formatDouble(height) + " " + TextUtils.formatDouble(width) + ")"); printWriter.println(")))"); return; } // write the header String header = "Electric VLSI Design System"; if (User.isIncludeDateAndVersionInOutput()) { header += ", version " + Version.getVersion(); } writeHeader(topCell, header, "EDIF Writer", topCell.getLibrary().getName()); // write out all primitives used in the library blockOpen("library"); blockPutIdentifier(primitivesLibName); blockPut("edifLevel", "0"); blockOpen("technology"); blockOpen("numberDefinition"); if (IOTool.isEDIFUseSchematicView()) { writeScale(Technology.getCurrent()); } blockClose("numberDefinition"); if (IOTool.isEDIFUseSchematicView()) { writeFigureGroup(EGART); writeFigureGroup(EGWIRE); writeFigureGroup(EGBUS); } blockClose("technology"); HashMap<Object,PrimitiveNode> primsFound = new HashMap<Object,PrimitiveNode>(); writeAllPrims(topCell, primsFound); blockClose("library"); // TODO (DONE) initialize rippers library if (ADD_RIPPERS) { // figure out how many bus rippers are needed HashSet<Integer> rippers = new HashSet<Integer>(); countRippers(topCell, rippers); if (rippers.size() > 0) { blockOpen("library"); blockPutIdentifier("cdsRipLib"); blockPut("edifLevel", "0"); blockOpen("technology"); blockOpen("numberDefinition"); if (IOTool.isEDIFUseSchematicView()) writeScale(Technology.getCurrent()); blockClose("numberDefinition"); blockClose("technology"); } for(Integer width : rippers) { blockOpen("cell"); blockPutIdentifier("ripper_" + width.intValue()); blockPut("cellType", "RIPPER"); blockOpen("view"); blockPutIdentifier("symbol"); blockPut("viewType", IOTool.isEDIFUseSchematicView() ? "SCHEMATIC" : "NETLIST"); blockOpen("interface"); blockOpen("port"); blockOpen("array"); blockPutIdentifier("dst_0"); blockPutIdentifier(width.toString()); blockClose("array"); blockClose("port"); blockOpen("port"); blockOpen("array"); blockPutIdentifier("src"); blockPutIdentifier(width.toString()); blockClose("array"); blockClose("port"); blockOpen("joined"); blockPut("portRef", "dst_0"); blockPut("portRef", "src"); blockClose("joined"); blockOpen("symbol"); blockOpen("figure"); blockPutIdentifier("wire"); blockOpen("circle"); blockOpen("pt"); blockPutIdentifier("-5"); blockPutIdentifier("0"); blockClose("pt"); blockOpen("pt"); blockPutIdentifier("5"); blockPutIdentifier("0"); blockClose("pt"); blockClose("circle"); blockClose("figure"); blockOpen("portImplementation"); blockPutIdentifier("dst_0"); blockOpen("connectLocation"); blockOpen("figure"); blockPutIdentifier("pin"); blockOpen("dot"); writePoint(0, 0); blockClose("dot"); blockClose("figure"); blockClose("connectLocation"); blockClose("portImplementation"); blockOpen("portImplementation"); blockPutIdentifier("src"); blockOpen("connectLocation"); blockOpen("figure"); blockPutIdentifier("pin"); blockOpen("dot"); writePoint(0, 0); blockClose("dot"); blockClose("figure"); blockClose("connectLocation"); blockClose("portImplementation"); blockClose("symbol"); blockClose("interface"); blockClose("view"); blockClose("cell"); } if (rippers.size() > 0) { blockClose("library"); } } // external libs // organize by library List<String> libs = new ArrayList<String>(); for (EDIFEquiv.NodeEquivalence e : equivs.getNodeEquivs()) { if (libs.contains(e.externalLib)) continue; libs.add(e.externalLib); } for (String lib : libs) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -