📄 tegas.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Tegas.java * Original C Code written by T.J.Goodman, University of Canterbury, N.Z. * 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.hierarchy.Cell;import com.sun.electric.database.hierarchy.Export;import com.sun.electric.database.hierarchy.Nodable;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.PortCharacteristic;import com.sun.electric.database.prototype.PortProto;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.variable.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.PrimitivePort;import com.sun.electric.tool.simulation.Simulation;import com.sun.electric.tool.user.User;import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Set;import java.util.TreeSet;/** * This is the netlister for Tegas. */public class Tegas extends Topology{ private static final int MAXLENGTH = 80; private static final int MAXNAMECHARS = 12; private HashMap<Nodable,Integer> nodeNames; private HashMap<ArcInst,Integer> implicitInverters; private Netlist netList; /** * The main entry point for Tegas 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 writeTegasFile(Cell cell, VarContext context, String filePath) { Tegas out = new Tegas(); 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 Tegas netlister. */ Tegas() { } protected void start() { // parameters to the output-line-length limit and how to break long lines setOutputWidth(MAXLENGTH, true); writeWidthLimited("/* GENERATED BY THE ELECTRIC VLSI DESIGN SYSTEM */\n\n"); writeWidthLimited("COMPILE ;\n\n"); // get library name, check validity String libname = getLibraryName(topCell); int length = libname.length(); if (length > 12) { System.out.println("Library name exceeds 12 characters, The name used for the"); System.out.println("TDL directory will be truncated to :- " + convertName(libname)); } // check library name String str1 = convertName(libname); if (isReservedWord(str1)) { System.out.println(str1 + " IS A RESERVED WORD, RENAME LIBRARY AND RE-RUN"); return; } // write "directory line" to file writeWidthLimited("DIRECTORY: " + str1 + " ;\n\n"); writeWidthLimited("OPTIONS: REPLACE ;\n\n"); } protected void done() { writeWidthLimited(" END COMPILE;\n\n "); } /** * Method to write cellGeom */ protected void writeCellTopology(Cell cell, CellNetInfo cni, VarContext context, Topology.MyCellInfo info) { // MODULE writeWidthLimited("MODULE: "); writeWidthLimited(convertName(cell.describe(false))); writeWidthLimited(";\n\n"); netList = cni.getNetList(); // INPUTS if (cell.getNumPorts() > 0) { StringBuffer infstr = new StringBuffer(); infstr.append("INPUTS:\n"); for(Iterator<CellSignal> it = cni.getCellSignals(); it.hasNext(); ) { CellSignal cs = it.next(); if (!cs.isExported()) continue; Export e = cs.getExport(); if (e.getCharacteristic() != PortCharacteristic.IN) continue; if (isReservedWord(convertName(e.getName()))) { System.out.println("ERROR: " + convertName(e.getName()) + " IS A RESERVED WORD"); } infstr.append(" " + convertName(e.getName()) + "\n"); } infstr.append(";\n\n"); writeWidthLimited(infstr.toString()); // OUTPUTS infstr = new StringBuffer(); infstr.append("OUTPUTS:\n"); for(Iterator<CellSignal> it = cni.getCellSignals(); it.hasNext(); ) { CellSignal cs = it.next(); if (!cs.isExported()) continue; Export e = cs.getExport(); if (e.getCharacteristic() == PortCharacteristic.OUT) { infstr.append(" " + convertName(e.getName()) + "\n"); } else if (e.getCharacteristic() != PortCharacteristic.IN) { System.out.println("EXPORT " + e.getName() + " MUST BE EITHER INPUT OR OUTPUT"); } } infstr.append(";\n\n"); writeWidthLimited(infstr.toString()); } // USE Set<String> instanceDeclarations = new TreeSet<String>(); Set<String> gateDeclarations = new TreeSet<String>(); for(Iterator<Nodable> it = netList.getNodables(); it.hasNext(); ) { Nodable no = it.next(); if (no.isCellInstance()) { // This case can either be for an existing user defined module in this // directory or for a module from the MASTER directory Cell subCell = (Cell)no.getProto(); String instName = getNodeProtoName(no); instanceDeclarations.add(instName + " = " + instName + "///" + getLibraryName(subCell)); continue; } NodeInst ni = (NodeInst)no; PrimitiveNode.Function fun = ni.getFunction(); if (fun == PrimitiveNode.Function.GATEAND || fun == PrimitiveNode.Function.GATEOR || fun == PrimitiveNode.Function.GATEXOR) { // Count number of inputs String gateName = getGateName(ni); int gateWidth = getGateWidth(ni); gateDeclarations.add(gateWidth + "-" + gateName + " = " + gateName + "(" + gateWidth + ",1)"); continue; } if (fun == PrimitiveNode.Function.SOURCE || fun.isResistor() || // == PrimitiveNode.Function.RESIST || fun.isCapacitor() || // == PrimitiveNode.Function.CAPAC || fun == PrimitiveNode.Function.DIODE || fun == PrimitiveNode.Function.INDUCT || fun == PrimitiveNode.Function.METER) { System.out.println("CANNOT HANDLE " + ni.getProto().describe(true) + " NODES"); continue; } } int numDecls = instanceDeclarations.size() + gateDeclarations.size(); if (numDecls > 0) writeWidthLimited("USE:\n\n"); int countDecls = 1; for(String decl : instanceDeclarations) { if (countDecls < numDecls) decl += ","; else decl += ";"; countDecls++; writeWidthLimited(" " + decl + "\n"); } for(String decl : gateDeclarations) { if (countDecls < numDecls) decl += ","; else decl += ";"; countDecls++; writeWidthLimited(" " + decl + "\n"); } if (numDecls > 0) writeWidthLimited("\n"); // DEFINE writeWidthLimited("DEFINE:\n"); // count no. of inverters (negated arcs not attached to logic primitives) implicitInverters = new HashMap<ArcInst,Integer>(); int count = 1; for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); ) { ArcInst ai = it.next(); for(int i=0; i<2; i++) { if (!ai.isNegated(i)) continue; if (ai.getPortInst(i).getPortProto().getCharacteristic() == PortCharacteristic.OUT) { PrimitiveNode.Function fun = ai.getPortInst(i).getNodeInst().getFunction(); if (fun == PrimitiveNode.Function.GATEAND || fun == PrimitiveNode.Function.GATEOR || fun == PrimitiveNode.Function.GATEXOR || fun == PrimitiveNode.Function.BUFFER) continue; } implicitInverters.put(ai, new Integer(count)); count++; } } // name every node nodeNames = new HashMap<Nodable,Integer>(); for(Iterator<Nodable> it = netList.getNodables(); it.hasNext(); ) { Nodable no = it.next(); PrimitiveNode.Function fun = getNodableFunction(no); if (fun.isTransistor() || fun == PrimitiveNode.Function.GATEXOR || fun == PrimitiveNode.Function.GATEAND || fun == PrimitiveNode.Function.GATEOR || fun == PrimitiveNode.Function.BUFFER || fun.isFlipFlop() || no.isCellInstance()) { nodeNames.put(no, new Integer(count++)); continue; } } // write the nodes boolean wrotePower = false, wroteGround = false; for(Iterator<Nodable> it = netList.getNodables(); it.hasNext(); ) { Nodable no = it.next(); PrimitiveNode.Function fun = getNodableFunction(no); if (fun == PrimitiveNode.Function.PIN || fun == PrimitiveNode.Function.ART) continue; if (fun == PrimitiveNode.Function.CONPOWER) { if (wrotePower) continue; wrotePower = true; writeWidthLimited(getNameOfPower((NodeInst)no)); continue; } if (fun == PrimitiveNode.Function.CONGROUND) { if (wroteGround) continue; wroteGround = true; writeWidthLimited(getNameOfPower((NodeInst)no)); continue; } // handle nodeinst descriptions if (fun.isTransistor() || fun == PrimitiveNode.Function.GATEXOR || fun == PrimitiveNode.Function.GATEAND || fun == PrimitiveNode.Function.GATEOR || fun == PrimitiveNode.Function.BUFFER || fun.isFlipFlop() || no.isCellInstance()) { String str1 = getOutputSignals(no, context, cni) + " = " + getNodeProtoName(no) + getInputSignals(no, context, cni) + getGateDelay(no) + ";\n"; writeWidthLimited(str1); continue; } System.out.println("NODETYPE " + no.getProto() + " NOT SUPPORTED"); } // end module writeWidthLimited(" END MODULE;\n\n"); } /****************************** MAIN BLOCKS ******************************/ /** * Method to write the output signals for a Nodable. * @param no the Nodable to write. * @param context the NodeInst's context down the hierarchy. * @param cni the CellNetInfo for the node's parent cell. * @return the output signals for the Nodable. */ private String getOutputSignals(Nodable no, VarContext context, CellNetInfo cni) { int nodeNumber = -1; Integer nodeNum = nodeNames.get(no); if (nodeNum != null) nodeNumber = nodeNum.intValue(); StringBuffer infstr = new StringBuffer(); infstr.append("U" + nodeNumber + "("); PrimitiveNode.Function fun = getNodableFunction(no); boolean needComma = false; if (no.isCellInstance()) { CellNetInfo subCni = getCellNetInfo(parameterizedName(no, context)); for(Iterator<CellSignal> it = subCni.getCellSignals(); it.hasNext(); ) { CellSignal subCs = it.next(); if (!subCs.isExported()) continue; Export e = subCs.getExport(); if (e.getCharacteristic() == PortCharacteristic.IN) continue; if (needComma) infstr.append(","); else needComma = true; Network net = netList.getNetwork(no, e, subCs.getExportIndex()); CellSignal cs = cni.getCellSignal(net); infstr.append(convertName(cs.getName())); } } else { NodeInst ni = (NodeInst)no; for(Iterator<PortProto> it = no.getProto().getPorts(); it.hasNext(); ) { PortProto pp = it.next(); if (fun.isTransistor()) { if (pp.getName().equals("g")) continue; } else { if (pp.getCharacteristic() == PortCharacteristic.IN) continue; } for(Iterator<Connection> aIt = ni.getConnections(); aIt.hasNext(); ) { Connection con = aIt.next(); PortInst pi = con.getPortInst(); if (pi.getPortProto() != pp) continue; ArcInst ai = con.getArc(); if (needComma) infstr.append(","); else needComma = true; String nodeName = getConnectionName(con); infstr.append(nodeName); // if arc on port not negated or a description for an inverter for a negated // arc already exists simply write the source name of this port/arc inst. if (con.isNegated() && implicitInverters.get(ai) != null) { // if the negation is at this end (ie nearest this node) write an inverter // with the port name of the output as inverter input and the net name of the // arc as inverter output. The source name is the net name of the arc writeInverter(con, nodeName, "U" + nodeNumber + "." + convertName(pp.getName())); } } } } infstr.append(")"); return infstr.toString(); } /** * Method to write the input signals for a Nodable. * @param no the Nodable to write. * @param context the NodeInst's context down the hierarchy. * @param cni the CellNetInfo for the node's parent cell. * @return the input signals for the Nodable. */ private String getInputSignals(Nodable no, VarContext context, CellNetInfo cni) { PrimitiveNode.Function fun = getNodableFunction(no); if (fun.isFlipFlop()) return getFlipFlopInputSignals((NodeInst)no); if (no.getProto().getNumPorts() == 0) return ""; StringBuffer infstr = new StringBuffer(); infstr.append("("); boolean first = true; if (no.isCellInstance()) { CellNetInfo subCni = getCellNetInfo(parameterizedName(no, context)); for(Iterator<CellSignal> it = subCni.getCellSignals(); it.hasNext(); ) { CellSignal subCs = it.next(); if (!subCs.isExported()) continue; Export e = subCs.getExport(); if (e.getCharacteristic() == PortCharacteristic.OUT) continue; if (first) first = false; else infstr.append(","); Network net = netList.getNetwork(no, e, subCs.getExportIndex()); CellSignal cs = cni.getCellSignal(net); infstr.append(convertName(cs.getName())); } } else { NodeInst ni = (NodeInst)no; for(Iterator<PortProto> it = no.getProto().getPorts(); it.hasNext(); ) { PrimitivePort pp = (PrimitivePort)it.next(); if (pp.getCharacteristic() != PortCharacteristic.IN) continue; // The transistor "s" port is treated as an inport by electric but is used // as an outport by TDL if (fun.isTransistor() && pp.getName().startsWith("s")) continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -