📄 sue.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Sue.java * Input/output tool: Sue input * Written 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.input;import com.sun.electric.database.geometry.EGraphics;import com.sun.electric.database.geometry.EPoint;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.prototype.NodeProto;import com.sun.electric.database.prototype.PortCharacteristic;import com.sun.electric.database.prototype.PortOriginal;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.database.text.Name;import com.sun.electric.database.text.TextUtils;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.topology.PortInst;import com.sun.electric.database.topology.RTBounds;import com.sun.electric.database.variable.CodeExpression;import com.sun.electric.database.variable.EvalJavaBsh;import com.sun.electric.database.variable.MutableTextDescriptor;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;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.Job;import com.sun.electric.tool.io.IOTool;import com.sun.electric.tool.io.output.Spice;import java.awt.geom.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStreamReader;import java.io.LineNumberReader;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;/** * This class reads files in Sue files. */public class Sue extends Input{ /*************** SUE EQUIVALENCES ***************/ private static class SueExtraWire { private String portName; private double xOffset; private double yOffset; private SueExtraWire(String portName, double xOffset, double yOffset) { this.portName = portName; this.xOffset = xOffset; this.yOffset = yOffset; } }; private SueExtraWire [] transistorWires = { new SueExtraWire("d", 3, 0), new SueExtraWire("s", -3, 0), new SueExtraWire("g", 0, 4.5) }; private SueExtraWire [] transistor4Wires = { new SueExtraWire("d", 3, 0), new SueExtraWire("s", -3, 0), new SueExtraWire("b", -0.25, -2.5), new SueExtraWire("g", 0, 4.5) }; private SueExtraWire [] resistorWires = { new SueExtraWire("a", -3, 0), new SueExtraWire("b", 3, 0) }; private SueExtraWire [] capacitorWires = { new SueExtraWire("a", 0, 1.75), new SueExtraWire("b", 0, -1.75) }; private SueExtraWire [] twoPortWires = { new SueExtraWire("a", -11.25, 3.625), new SueExtraWire("b", -11.25, -3.625), new SueExtraWire("x", 11.25, 3.625), new SueExtraWire("y", 11.25, -3.625) }; private static class SueEquiv { private String sueName; private NodeProto intProto; private boolean netateOutput; private int rotation; private boolean transpose; private double xOffset; private double yOffset; private PrimitiveNode.Function detailFunct; private SueExtraWire [] extraWires; private SueEquiv(String sueName, NodeProto intProto, boolean netateOutput, int rotation, boolean transpose, double xOffset, double yOffset, PrimitiveNode.Function detailFunct, SueExtraWire [] extraWires) { this.sueName = sueName; this.intProto = intProto; this.netateOutput = netateOutput; this.rotation = rotation; this.transpose = transpose; this.xOffset = xOffset; this.yOffset = yOffset; this.detailFunct = detailFunct; this.extraWires = extraWires; } }; private SueEquiv [] sueEquivs = { // name primitive NEG ANG X Y FUNCTION EXTRA-WIRES new SueEquiv("pmos10", Schematics.tech().transistorNode, false, 900,false, -2, 0, PrimitiveNode.Function.TRAPMOS, transistorWires), new SueEquiv("nmos10", Schematics.tech().transistorNode, false, 900,false, -2, 0, PrimitiveNode.Function.TRANMOS, transistorWires), new SueEquiv("pmos4", Schematics.tech().transistorNode, false, 900,false, -2, 0, PrimitiveNode.Function.TRAPMOS, transistorWires), new SueEquiv("nmos4", Schematics.tech().transistorNode, false, 900,false, -2, 0, PrimitiveNode.Function.TRANMOS, transistorWires), new SueEquiv("pmos", Schematics.tech().transistorNode, false, 900,false, -2, 0, PrimitiveNode.Function.TRAPMOS, transistorWires), new SueEquiv("nmos", Schematics.tech().transistorNode, false, 900,false, -2, 0, PrimitiveNode.Function.TRANMOS, transistorWires), new SueEquiv("capacitor", Schematics.tech().capacitorNode, false, 0,false, 0, 0, null, capacitorWires), new SueEquiv("resistor", Schematics.tech().resistorNode, false, 900,false, 0, 0, null, resistorWires), new SueEquiv("inductor", Schematics.tech().inductorNode, false, 0,false, 0, 0, null, null), new SueEquiv("cccs", Schematics.tech().twoportNode, false, 0,false, 1.25,-6.875, PrimitiveNode.Function.CCCS, twoPortWires), new SueEquiv("ccvs", Schematics.tech().twoportNode, false, 0,false, 1.25,-6.875, PrimitiveNode.Function.CCVS, twoPortWires), new SueEquiv("vcvs", Schematics.tech().twoportNode, false, 0,false, 1.25,-6.875, PrimitiveNode.Function.VCVS, twoPortWires), new SueEquiv("vccs", Schematics.tech().twoportNode, false, 0,false, -1.875,-5, PrimitiveNode.Function.VCCS, null) }; private SueEquiv [] sueEquivs4 = { // name primitive NEG ANG X Y FUNCTION EXTRA-WIRES new SueEquiv("pmos10", Schematics.tech().transistor4Node, false, 0,true, -2, 0, PrimitiveNode.Function.TRAPMOS, transistor4Wires), new SueEquiv("nmos10", Schematics.tech().transistor4Node, false, 900,false, -2, 0, PrimitiveNode.Function.TRANMOS, transistor4Wires), new SueEquiv("pmos4", Schematics.tech().transistor4Node, false, 0,true, -2, 0, PrimitiveNode.Function.TRAPMOS, transistor4Wires), new SueEquiv("nmos4", Schematics.tech().transistor4Node, false, 900,false, -2, 0, PrimitiveNode.Function.TRANMOS, transistor4Wires), new SueEquiv("pmos", Schematics.tech().transistor4Node, false, 0,true, -2, 0, PrimitiveNode.Function.TRAPMOS, transistor4Wires), new SueEquiv("nmos", Schematics.tech().transistor4Node, false, 900,false, -2, 0, PrimitiveNode.Function.TRANMOS, transistor4Wires), new SueEquiv("capacitor", Schematics.tech().capacitorNode, false, 0,false, 0, 0, null, capacitorWires), new SueEquiv("resistor", Schematics.tech().resistorNode, false, 900,false, 0, 0, null, resistorWires), new SueEquiv("inductor", Schematics.tech().inductorNode, false, 0,false, 0, 0, null, null), new SueEquiv("cccs", Schematics.tech().twoportNode, false, 0,false, 1.25,-6.875, PrimitiveNode.Function.CCCS, twoPortWires), new SueEquiv("ccvs", Schematics.tech().twoportNode, false, 0,false, 1.25,-6.875, PrimitiveNode.Function.CCVS, twoPortWires), new SueEquiv("vcvs", Schematics.tech().twoportNode, false, 0,false, 1.25,-6.875, PrimitiveNode.Function.VCVS, twoPortWires), new SueEquiv("vccs", Schematics.tech().twoportNode, false, 0,false, -1.875,-5, PrimitiveNode.Function.VCCS, null) }; /*************** SUE WIRES ***************/ private static class SueWire { private Point2D [] pt; private PortInst [] pi; private ArcProto proto; private SueWire() { pt = new Point2D[2]; pi = new PortInst[2]; } }; /*************** SUE NETWORKS ***************/ private static class SueNet { private Point2D pt; private String label; }; private String sueLastLine; private String lastLineRead; private List<String> sueDirectories; /** * Method to import a library from disk. * @param lib the library to fill * @return the created library (null on error). */ protected Library importALibrary(Library lib) { // determine the cell name String cellName = lib.getName(); // initialize the number of directories that need to be searched sueDirectories = new ArrayList<String>(); // determine the current directory String topDirName = TextUtils.getFilePath(lib.getLibFile()); sueDirectories.add(topDirName); // find all subdirectories that start with "suelib_" and include them in the search File topDir = new File(topDirName); String [] fileList = topDir.list(); for(int i=0; i<fileList.length; i++) { if (!fileList[i].startsWith("suelib_")) continue; String dirName = topDirName + fileList[i]; if (!dirName.endsWith("/")) dirName += "/"; File subDir = new File(dirName); if (subDir.isDirectory()) sueDirectories.add(dirName); } // see if the current directory is inside of a SUELIB int lastSep = topDirName.lastIndexOf('/'); if (lastSep >= 0 && topDirName.substring(lastSep+1).startsWith("suelib_")) { String upDirName = topDirName.substring(0, lastSep); File upperDir = new File(upDirName); String [] upFileList = upperDir.list(); for(int i=0; i<upFileList.length; i++) { if (!upFileList[i].startsWith("suelib_")) continue; String dirName = upDirName + upFileList[i]; File subDir = new File(dirName); if (subDir.isDirectory()) sueDirectories.add(dirName); } } // read the file try { Cell topCell = readFile(lib, cellName, lineReader); if (topCell == null) return null; Job.getUserInterface().setCurrentCell(lib, topCell); } catch (IOException e) { System.out.println("ERROR reading Sue libraries"); } return lib; } /** * Method to read the SUE file. */ private Cell readFile(Library lib, String cellName, LineNumberReader lr) throws IOException { boolean placeIcon = false; List<SueWire> sueWires = new ArrayList<SueWire>(); List<SueNet> sueNets = new ArrayList<SueNet>(); Cell cell = null; Cell schemCell = null; Cell iconCell = null; lastLineRead = null; Point2D iconPt = null; List<String> argumentKey = new ArrayList<String>(); List<String> argumentValue = new ArrayList<String>(); Set<NodeInst> invertNodeOutput = new HashSet<NodeInst>(); Map<String,List<NodeInst>> duplicateNames = new HashMap<String,List<NodeInst>>(); for(;;) { // get the next line of text List<String> keywords = getNextLine(lr); if (keywords == null) break; int count = keywords.size(); if (count == 0) continue; String keyword0 = keywords.get(0); // handle "proc" for defining views if (keyword0.equalsIgnoreCase("proc")) { // write any wires from the last proc if (cell != null) { placeWires(sueWires, sueNets, cell, invertNodeOutput); placeNets(sueNets, cell); sueWires = new ArrayList<SueWire>(); sueNets = new ArrayList<SueNet>(); } if (count < 2) { System.out.println("Cell " + cellName + ", line " + lr.getLineNumber() + ": 'proc' is missing arguments: " + lastLineRead); continue; } String keyword1 = keywords.get(1); if (keyword1.startsWith("SCHEMATIC_")) { // create the schematic cell String subCellName = keyword1.substring(10); if (subCellName.equalsIgnoreCase("[get_file_name]")) subCellName = cellName; subCellName += "{sch}"; schemCell = cell = Cell.makeInstance(lib, subCellName); placeIcon = false; } else if (keyword1.startsWith("ICON_")) { // create the icon cell String subCellName = keyword1.substring(5); if (subCellName.equalsIgnoreCase("[get_file_name]")) subCellName = cellName; subCellName += "{ic}"; iconCell = cell = Cell.makeInstance(lib, subCellName); } else { System.out.println("Cell " + cellName + ", line " + lr.getLineNumber() + ": unknown 'proc' statement: " + lastLineRead); } continue; } // handle "make" for defining components if (keyword0.equalsIgnoreCase("make")) { if (count < 2) { System.out.println("Cell " + cellName + ", line " + lr.getLineNumber() + ": 'make' is missing arguments: " + lastLineRead); continue; } // extract parameters ParseParameters parP = new ParseParameters(keywords, 2); // ignore self-references String keyword1 = keywords.get(1); if (keyword1.equalsIgnoreCase(cellName)) { if (parP.pt != null) { // queue icon placement iconPt = parP.pt; placeIcon = true; } continue; } // special case for network names: queue them if (keyword1.equalsIgnoreCase("name_net_m") || keyword1.equalsIgnoreCase("name_net_s") || keyword1.equalsIgnoreCase("name_net")) { if (parP.theName != null) { SueNet sn = new SueNet(); sn.pt = parP.pt; sn.label = parP.theName; sueNets.add(sn); } continue; } // first check for special names NodeProto proto = null; double xOff = 0, yOff = 0; PortCharacteristic type = PortCharacteristic.UNKNOWN; double xShrink = 0, yShrink = 0; boolean invertOutput = false; int rotation = 0; boolean transpose = false; PrimitiveNode.Function detailFunct = null; SueExtraWire [] extraWires = null; if (keyword1.equalsIgnoreCase("inout")) { proto = Schematics.tech().offpageNode; AffineTransform trans = Orientation.fromC(parP.rot, parP.trn).pureRotate(); Point2D offPt = new Point2D.Double(2, 0); trans.transform(offPt, offPt); xOff = offPt.getX(); yOff = offPt.getY(); type = PortCharacteristic.BIDIR; } else if (keyword1.equalsIgnoreCase("input")) { proto = Schematics.tech().offpageNode; AffineTransform trans = Orientation.fromC(parP.rot, parP.trn).pureRotate(); Point2D offPt = new Point2D.Double(-2, 0); trans.transform(offPt, offPt); xOff = offPt.getX(); yOff = offPt.getY(); type = PortCharacteristic.IN; } else if (keyword1.equalsIgnoreCase("output")) { proto = Schematics.tech().offpageNode; AffineTransform trans = Orientation.fromC(parP.rot, parP.trn).pureRotate(); Point2D offPt = new Point2D.Double(2, 0); trans.transform(offPt, offPt); xOff = offPt.getX(); yOff = offPt.getY(); type = PortCharacteristic.OUT; } else if (keyword1.equalsIgnoreCase("rename_net")) { proto = Schematics.tech().wirePinNode; } else if (keyword1.equalsIgnoreCase("global")) { Name busName = Name.findName(parP.theName); int busWidth = busName.busWidth(); if (busWidth > 1) proto = Schematics.tech().busPinNode; else { proto = Schematics.tech().wirePinNode; if (parP.theName.equalsIgnoreCase("gnd")) { AffineTransform trans = Orientation.fromC(parP.rot, parP.trn).pureRotate(); Point2D offPt = new Point2D.Double(0, -2); trans.transform(offPt, offPt); xOff = offPt.getX(); yOff = offPt.getY(); proto = Schematics.tech().groundNode; type = PortCharacteristic.GND; } if (parP.theName.equalsIgnoreCase("vdd")) { proto = Schematics.tech().powerNode; type = PortCharacteristic.PWR; } } } else if (keyword1.equalsIgnoreCase("join_net")) { proto = Schematics.tech().wireConNode; xShrink = -2; AffineTransform trans = Orientation.fromC(parP.rot, parP.trn).pureRotate(); Point2D offPt = new Point2D.Double(1.25, 0); trans.transform(offPt, offPt); xOff = offPt.getX(); yOff = offPt.getY(); } // now check for internal associations to known primitives if (proto == null) { SueEquiv [] curEquivs = sueEquivs; if (IOTool.isSueUses4PortTransistors()) curEquivs = sueEquivs4; int i = 0; for( ; i < curEquivs.length; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -