📄 generatevhdl.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Generate.java * Generate VHDL from a circuit * 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.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.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.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.PrimitivePort;import com.sun.electric.technology.technologies.Schematics;import com.sun.electric.tool.simulation.Simulation;import com.sun.electric.tool.user.CompileVHDL;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 is the VHDL generation facility. */public class GenerateVHDL extends Topology{ /** special codes during VHDL generation */ /** ordinary block */ private static final int BLOCKNORMAL = 0; /** a MOS transistor */ private static final int BLOCKMOSTRAN = 1; /** a buffer */ private static final int BLOCKBUFFER = 2; /** an and, or, xor */ private static final int BLOCKPOSLOGIC = 3; /** an inverter */ private static final int BLOCKINVERTER = 4; /** a nand */ private static final int BLOCKNAND = 5; /** a nor */ private static final int BLOCKNOR = 6; /** an xnor */ private static final int BLOCKXNOR = 7; /** a settable D flip-flop */ private static final int BLOCKFLOPDS = 8; /** a resettable D flip-flop */ private static final int BLOCKFLOPDR = 9; /** a settable T flip-flop */ private static final int BLOCKFLOPTS = 10; /** a resettable T flip-flop */ private static final int BLOCKFLOPTR = 11; /** a general flip-flop */ private static final int BLOCKFLOP = 12; private static final String NORMALCONTINUATIONSTRING = " "; private static final String COMMENTCONTINUATIONSTRING = "-- "; /** * Method to convert a cell to a list of strings with VHDL in them. * @param cell the Cell to convert. * @return a list of strings with VHDL in them (null on error). */ public static List<String> convertCell(Cell cell) { // cannot make VHDL for cell with no ports if (cell.getNumPorts() == 0) { System.out.println("Cannot convert " + cell.describe(false) + " to VHDL: it has no ports"); return null; } GenerateVHDL out = new GenerateVHDL(); out.openStringsOutputStream(); out.setOutputWidth(80, false); out.setContinuationString(NORMALCONTINUATIONSTRING); // generate the VHDL if (out.writeCell(cell, null)) return null; // return the array of strings with VHDL return out.closeStringsOutputStream(); } /** * Method to start the output. * Writes the header. */ protected void start() { setContinuationString(COMMENTCONTINUATIONSTRING); writeWidthLimited("-- VHDL automatically generated by the Electric VLSI Design System, version " + Version.getVersion() + "\n"); setContinuationString(NORMALCONTINUATIONSTRING); } protected void done() {} /** * Method to write one level of hierarchy. */ protected void writeCellTopology(Cell cell, CellNetInfo cni, VarContext context, Topology.MyCellInfo info) { // write the header writeWidthLimited("\n"); setContinuationString(COMMENTCONTINUATIONSTRING); writeWidthLimited("-------------------- Cell " + cell.describe(false) + " --------------------\n"); setContinuationString(NORMALCONTINUATIONSTRING); Netlist nl = cni.getNetList(); // write the entity section String properCellName = getSafeCellName(cell.getName()); writeWidthLimited("entity " + addString(properCellName, null) + " is port(" + addPortList(cni) + ");\n"); writeWidthLimited(" end " + addString(properCellName, null) + ";\n"); // write the "architecture" line writeWidthLimited("\n"); writeWidthLimited("architecture " + addString(properCellName, null) + "_BODY of " + addString(properCellName, null) + " is\n"); // find all negated arcs int instNum = 1; Map<ArcInst,Integer> negatedHeads = new HashMap<ArcInst,Integer>(); Map<ArcInst,Integer> negatedTails = new HashMap<ArcInst,Integer>(); for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); ) { ArcInst ai = it.next(); if (ai.getHead().isNegated()) negatedHeads.put(ai, new Integer(instNum++)); if (ai.getTail().isNegated()) negatedTails.put(ai, new Integer(instNum++)); } // write prototypes for each node; gather information for NAND, NOR, and XNOR Set<Integer> multiInputNAND = new HashSet<Integer>(); Set<Integer> multiInputNOR = new HashSet<Integer>(); Set<Integer> multiInputNXOR = new HashSet<Integer>(); boolean gotInverters = false; Set<String> cellNamesWritten = new HashSet<String>(); for(Iterator<Nodable> it = nl.getNodables(); it.hasNext(); ) { Nodable no = it.next(); AnalyzePrimitive ap = new AnalyzePrimitive(no, negatedHeads, negatedTails); String pt = ap.getPrimName(); if (pt == null) continue; int special = ap.getSpecial(); // write only once per prototype if (special == BLOCKINVERTER) { gotInverters = true; continue; } if (special == BLOCKNAND) { multiInputNAND.add(new Integer(TextUtils.atoi(pt.substring(4)))); continue; } if (special == BLOCKNOR) { multiInputNOR.add(new Integer(TextUtils.atoi(pt.substring(3)))); continue; } if (special == BLOCKXNOR) { multiInputNXOR.add(new Integer(TextUtils.atoi(pt.substring(4)))); continue; } // ignore component with no ports if (no.getProto().getNumPorts() == 0) continue; pt = getSafeCellName(pt); if (cellNamesWritten.contains(pt)) continue; cellNamesWritten.add(pt); if (no.isCellInstance()) { String parameterizedName = parameterizedName(no, context); CellNetInfo subCni = getCellNetInfo(parameterizedName); if (subCni == null) { System.out.println("ERROR: no subcell information for: " + parameterizedName); continue; } writeWidthLimited(" component " + addString(pt, null) + " port(" + addPortList(subCni) + ");\n"); } else { writeWidthLimited(" component " + addString(pt, null) + " port(" + addPortListPrim(no, special) + ");\n"); } writeWidthLimited(" end component;\n"); } // write prototype for multi-input NAND, NOR, and XNOR for(Integer i : multiInputNAND) { String compName = "nand" + i; cellNamesWritten.add(compName); writeWidthLimited(" component " + compName + " port("); for(int j=1; j<=i.intValue(); j++) { if (j > 1) writeWidthLimited(", "); writeWidthLimited("a" + j); } writeWidthLimited(": in BIT; y: out BIT);\n"); writeWidthLimited(" end component;\n"); } for(Integer i : multiInputNOR) { String compName = "nor" + i; cellNamesWritten.add(compName); writeWidthLimited(" component " + compName + " port("); for(int j=1; j<=i.intValue(); j++) { if (j > 1) writeWidthLimited(", "); writeWidthLimited("a" + j); } writeWidthLimited(": in BIT; y: out BIT);\n"); writeWidthLimited(" end component;\n"); } for(Integer i : multiInputNXOR) { String compName = "xnor" + i; cellNamesWritten.add(compName); writeWidthLimited(" component " + compName + " port("); for(int j=1; j<=i.intValue(); j++) { if (j > 1) writeWidthLimited(", "); writeWidthLimited("a" + j); } writeWidthLimited(": in BIT; y: out BIT);\n"); writeWidthLimited(" end component;\n"); } // write inverter prototype if applicable if (negatedHeads.size() > 0 || negatedTails.size() > 0) gotInverters = true; if (gotInverters) { cellNamesWritten.add("inverter"); writeWidthLimited(" component inverter port(a: in BIT; y: out BIT);\n"); writeWidthLimited(" end component;\n"); } // write internal signals that were used SignalNameLine snl = new SignalNameLine(); for(Iterator<CellSignal> it = cni.getCellSignals(); it.hasNext(); ) { CellSignal cs = it.next(); if (cs.getExport() != null) continue; if (!cs.getNetwork().getArcs().hasNext()) continue; String sigName = addString(cs.getName(), cell); snl.addSignalName(sigName); } for(ArcInst ai : negatedHeads.keySet()) { Integer index = negatedHeads.get(ai); String sigName = "PINV" + index.intValue(); snl.addSignalName(sigName); } for(ArcInst ai : negatedTails.keySet()) { Integer index = negatedTails.get(ai); String sigName = "PINV" + index.intValue(); snl.addSignalName(sigName); } snl.finish(); // write the instances writeWidthLimited("\n"); writeWidthLimited("begin\n"); for(Iterator<Nodable> it = nl.getNodables(); it.hasNext(); ) { Nodable no = it.next(); // ignore component with no ports if (no.getProto().getNumPorts() == 0) continue; int special = BLOCKNORMAL; String pt = no.getProto().getName(); if (!no.isCellInstance()) { AnalyzePrimitive ap = new AnalyzePrimitive(no, negatedHeads, negatedTails); pt = ap.getPrimName(); if (pt == null) continue; special = ap.getSpecial(); } String instname = getSafeCellName(no.getName()); writeWidthLimited(" " + addString(instname, null)); // make sure the instance name doesn't conflict with a prototype name if (cellNamesWritten.contains(instname)) writeWidthLimited("NV"); if (no.isCellInstance()) { String parameterizedName = parameterizedName(no, context); CellNetInfo subCni = getCellNetInfo(parameterizedName); if (subCni == null) { System.out.println("STILL NO SUBCELL INFORMATION FOR "+parameterizedName); continue; } writeWidthLimited(": " + addString(getSafeCellName(pt), null) + " port map(" + addRealPortsCell(subCni, no, negatedHeads, negatedTails, nl) + ");\n"); } else { writeWidthLimited(": " + addString(getSafeCellName(pt), null) + " port map(" + addRealPortsPrim(no, special, negatedHeads, negatedTails, nl) + ");\n"); } } // write pseudo-nodes for all negated arcs for(ArcInst ai : negatedHeads.keySet()) { Integer index = negatedHeads.get(ai); writeWidthLimited(" PSEUDO_INVERT" + index.intValue() + ": inverter port map("); Network net = nl.getNetwork(ai, 0); if (ai.getHeadPortInst().getPortProto().getBasePort().getCharacteristic() == PortCharacteristic.OUT) { writeWidthLimited("PINV" + index.intValue() + ", " + addString(net.describe(false), cell)); } else { writeWidthLimited(addString(net.describe(false), cell) + ", PINV" + index.intValue()); } writeWidthLimited(");\n"); } for(ArcInst ai : negatedTails.keySet()) { Integer index = negatedTails.get(ai); writeWidthLimited(" PSEUDO_INVERT" + index.intValue() + ": inverter port map("); Network net = nl.getNetwork(ai, 0); if (ai.getTailPortInst().getPortProto().getBasePort().getCharacteristic() == PortCharacteristic.OUT) { writeWidthLimited("PINV" + index.intValue() + ", " + addString(net.describe(false), cell)); } else { writeWidthLimited(addString(net.describe(false), cell) + ", PINV" + index.intValue()); } writeWidthLimited(");\n"); } // finish the cell writeWidthLimited("end " + addString(properCellName, null) + "_BODY;\n"); } /****************************** METHODS TO WRITE LIST OF CELL PARAMETERS ******************************/ /** * Method to write actual signals that connect to a cell instance. * @param cni signal information for the cell being instantiated. * @param no the instance node. * @param negatedHeads map of arcs with negated head ends. * @param negatedTails map of arcs with negated tail ends. * @param nl the Netlist for the Cell containing the instance. * @return a string with the connection signals. */ private String addRealPortsCell(CellNetInfo cni, Nodable no, Map<ArcInst,Integer> negatedHeads, Map<ArcInst,Integer> negatedTails, Netlist nl) { Cell subCell = (Cell)no.getProto(); Netlist subNL = cni.getNetList(); boolean first = false; StringBuffer infstr = new StringBuffer(); for(int pass = 0; pass < 5; pass++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -