Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: CompileVerilogStruct.java
* Compile Structural Verilog to a netlist
*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*
* 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.user;
import com.sun.electric.database.EditingPreferences;
import com.sun.electric.database.geometry.EPoint;
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.View;
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.topology.ArcInst;
import com.sun.electric.database.topology.NodeInst;
import com.sun.electric.database.topology.PortInst;
import com.sun.electric.technology.ArcProto;
import com.sun.electric.technology.PrimitiveNode;
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.JobException;
import com.sun.electric.util.TextUtils;
import com.sun.electric.util.math.DBMath;
import com.sun.electric.util.math.Orientation;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
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.Map;
import java.util.Set;
/**
* This is the structural Verilog compiler.
*/
public class CompileVerilogStruct
{
private List allModules;
private int errorCount;
private boolean verbose;
private boolean hasErrors;
private VModule curModule;
private List tList;
private int tokenIndex;
/********** Modules *************************************************/
/**
* Class to define a Verilog Module (or Primitive)
*/
public class VModule
{
/** name of entity */ private String name;
/** true if cell in Verilog */ private boolean defined;
/** true if a primitive */ private boolean primitive;
/** cell of this module */ private Cell cell;
/** list of ports */ private List ports;
/** list of internal wires */ private List wires;
/** list of instances */ private List instances;
/** list of assignments */ private Map assignments;
/** networks in the module */ private Map> allNetworks;
VModule(String name, boolean defined, boolean primitive)
{
this.name = name;
this.defined = defined;
cell = null;
if (!defined)
{
// find the cell
for(Library lib : Library.getVisibleLibraries())
{
for(Iterator it = lib.getCells(); it.hasNext(); )
{
Cell libCell = it.next();
if (libCell.getName().equals(name))
{
for(Iterator gIt = libCell.getCellGroup().getCells(); gIt.hasNext(); )
{
Cell rightOne = gIt.next();
if (rightOne.getView() == View.LAYOUT)
{
cell = rightOne;
break;
}
}
if (cell == null)
{
cell = libCell;
break;
}
}
}
if (cell != null) break;
}
}
ports = new ArrayList();
wires = new ArrayList();
instances = new ArrayList();
allNetworks = new HashMap>();
assignments = new HashMap();
allModules.add(this);
}
/**
* Method to tell whether this VModule is a Verilog Module or Primitive.
* @return true if it is a Primitive.
*/
public boolean isPrimitive() { return primitive; }
/**
* Method to return the name of this VModule.
* @return the Verilog module name.
*/
public String getName() { return name; }
/**
* Method to return a List of Instances inside of this Verilog Module.
* @return a List of VInstance objects inside of this VModule.
*/
public List getInstances() { return instances; }
/**
* Method to return a List of exports inside of this Verilog Module.
* @return a list of VExport objects inside of this VModule.
*/
public List getPorts() { return ports; }
/**
* Method to return the Electric Cell associated with this VModule.
* @return the Cell (null if none found).
*/
public Cell getCell() { return cell; }
};
/********** Exports on Modules **********************************/
private static final int MODE_UNKNOWN = 0;
private static final int MODE_IN = 1;
private static final int MODE_OUT = 2;
private static final int MODE_INOUT = 3;
/**
* Class to define ports on Verilog Modules.
* These are "formal ports", defined in the module header.
*/
public static class VExport
{
/** name of port */ private String name;
/** mode of port */ private int mode;
/** range of port */ private int firstIndex, secondIndex;
public VExport(String name)
{
this.name = name;
mode = MODE_UNKNOWN;
firstIndex = secondIndex = -1;
}
/**
* Method to return the name of this module port.
* @return the name of this VExport.
*/
public String getName() { return name; }
/**
* Method to tell whether this port is bussed.
* @return true if there are multiple signals on this VExport.
*/
public boolean isBus() { return firstIndex >= 0; }
};
/********** Instances **********************************************/
/**
* Class to define an instance or transistor, found inside of a Verilog module.
*/
public static class VInstance
{
private VModule module;
private PrimitiveNode.Function fun;
private String instanceName;
private Map ports;
/**
* Constructor for a cell instance.
* @param module the parent module.
* @param instanceName the name of the cell instance.
*/
public VInstance(VModule module, String instanceName)
{
this.module = module;
this.fun = null;
this.instanceName = instanceName;
ports = new HashMap();
}
/**
* Constructor for a transistor.
* @param fun the transistor type.
* @param instanceName the name of the transistor instance.
*/
public VInstance(PrimitiveNode.Function fun, String instanceName)
{
this.module = null;
this.fun = fun;
this.instanceName = instanceName;
ports = new HashMap();
}
/**
* Method to add a new port on this VInstance.
* @param lp the local port ("actual port") found on the instance.
* @param signalNames a list of signal names for that port.
*/
public void addConnection(VPort lp, String[] signalNames)
{
ports.put(lp, signalNames);
}
/**
* Method to return the sub-module that defines this instance.
* @return a sub-VModule that is the prototype of this VInstance.
* (null if this is a transistor).
*/
public VModule getModule() { return module; }
/**
* Method to return the transistor function that defines this instance.
* @return a PrimitiveNode.Function description of the transistor.
* (null if this is a cell instance).
*/
public PrimitiveNode.Function getFunction() { return fun; }
}
/********** Ports on Instances **********************************/
/**
* Class to define a port on a VInstance.
*/
public static class VPort
{
/** Instance */ private VInstance in;
/** name of port */ private String portName;
/** true if part of a bus */ private boolean onBus;
public VPort(VInstance in, String portName, boolean onBus)
{
this.in = in;
this.portName = portName;
this.onBus = onBus;
}
}
/**
* The constructor compiles the Verilog in disk file.
* @param f the disk file.
* @param verbose true to give progress while compiling.
*/
public CompileVerilogStruct(File f, boolean verbose)
{
this.verbose = verbose;
try
{
InputStreamReader is = new InputStreamReader(new FileInputStream(f));
LineNumberReader lineReader = new LineNumberReader(is);
List stringList = new ArrayList();
for(;;)
{
String line = lineReader.readLine();
if (line == null) break;
stringList.add(line);
}
String [] strings = new String[stringList.size()];
for(int i=0; i getModules() { return allModules; }
private void processVerilog(String [] strings)
{
if (verbose)
{
Job.getUserInterface().startProgressDialog("Compiling Verilog", null);
Job.getUserInterface().setProgressNote("Scanning...");
}
allModules = new ArrayList();
tList = new ArrayList();
errorCount = 0;
hasErrors = false;
doScanner(strings);
if (verbose)
{
Job.getUserInterface().setProgressNote("Parsing...");
Job.getUserInterface().setProgressValue(0);
}
doParser();
if (verbose)
Job.getUserInterface().stopProgressDialog();
// make network list
for(VModule module : allModules)
{
// remove assigned wire names
for(int i=0; i portsOnNet = module.allNetworks.get(assignedName);
if (portsOnNet == null) module.allNetworks.put(assignedName, portsOnNet = new ArrayList());
portsOnNet.add(lp);
}
}
}
}
// dumpData();
}
// private void dumpData()
// {
// // write what was found
// for(VModule vm : allModules)
// {
// System.out.println();
// System.out.print("++++ MODULE "+vm.name+"(");
// boolean first = true;
// for(VExport fp : vm.ports)
// {
// if (!first) System.out.print(", ");
// first = false;
// System.out.print(fp.name);
// if (fp.firstIndex != -1 && fp.secondIndex != -1)
// System.out.print("[" + fp.firstIndex + ":" + fp.secondIndex + "]");
// switch (fp.mode)
// {
// case MODE_IN: System.out.print(" input"); break;
// case MODE_OUT: System.out.print(" output"); break;
// case MODE_INOUT: System.out.print(" inout"); break;
// }
// }
// System.out.println(")");
// if (!vm.defined)
// {
// if (vm.cell == null) System.out.println(" CELL NOT FOUND"); else
// System.out.println(" CELL IS "+vm.cell.describe(false));
// }
// for(VInstance in : vm.instances)
// {
// System.out.print(" INSTANCE "+in.instanceName+" OF CELL "+in.module.name+"(");
// first = true;
// for(VPort lp : in.ports.keySet())
// {
// if (!first) System.out.print(", ");
// first = false;
// String[] netNames = in.ports.get(lp);
// if (netNames.length == 1) System.out.print(lp.portName+"="+netNames[0]); else
// {
// System.out.print("[");
// for(int i=0; i ports = vm.allNetworks.get(netName);
// for(VPort lp : ports)
// System.out.print(" " + lp.in.instanceName+":"+lp.portName);
// System.out.println();
// }
// }
// }
/**
* Method to report whether the Verilog compile was successful.
* @return true if there were errors.
*/
public boolean hasErrors() { return hasErrors; };
/******************************** THE VERILOG SCANNER ********************************/
private static class TokenType
{
private String name, str;
private TokenType(String name, String str)
{
this.name = name;
this.str = str;
}
public String getName() { return name; }
public String getChar() { return str; }
public static final TokenType LEFTPAREN = new TokenType("Left Parenthesis", "(");
public static final TokenType RIGHTPAREN = new TokenType("Right Parenthesis", ")");
public static final TokenType LEFTBRACKET = new TokenType("Left Bracket", "[");
public static final TokenType RIGHTBRACKET = new TokenType("Right Bracket", "]");
public static final TokenType LEFTBRACE = new TokenType("Left Brace", "{");
public static final TokenType RIGHTBRACE = new TokenType("Right Brace", "}");
public static final TokenType SLASH = new TokenType("Forward Slash", "/");
public static final TokenType COMMA = new TokenType("Comma", ",");
public static final TokenType MINUS = new TokenType("Minus", "-");
public static final TokenType PERIOD = new TokenType("Period", ".");
public static final TokenType APOSTROPHE = new TokenType("Apostrophe", "'");
public static final TokenType QUESTION = new TokenType("Question", "?");
public static final TokenType HASH = new TokenType("Hash", "#");
public static final TokenType COLON = new TokenType("Colon", ":");
public static final TokenType ATSIGN = new TokenType("At Sign", "@");
public static final TokenType EQUALS = new TokenType("Equals", "=");
public static final TokenType SEMICOLON = new TokenType("Semicolon", ";");
public static final TokenType DOUBLEDOT = new TokenType("DotDot", "..");
public static final TokenType VARASSIGN = new TokenType("Assign", "=>");
public static final TokenType UNKNOWN = new TokenType("Unknown", "");
public static final TokenType IDENTIFIER = new TokenType("Identifier", "");
public static final TokenType KEYWORD = new TokenType("Keyword", "");
public static final TokenType DECIMAL = new TokenType("Decimal Number", "");
public static final TokenType CHAR = new TokenType("Character", "");
public static final TokenType STRING = new TokenType("String", "");
}
private class TokenList
{
/** token number */ private TokenType type;
/** NULL if delimiter,
* pointer to global name space if identifier,
* pointer to keyword table if keyword,
* pointer to string if decimal literal,
* pointer to string if based literal,
* value of character if character literal,
* pointer to string if string literal,
* pointer to string if bit string literal */ private Object pointer;
/** TRUE if space before next token */ private boolean space;
/** line number token occurred */ private int lineNum;
private TokenList(TokenType type, Object pointer, int lineNum, boolean space)
{
this.type = type;
this.pointer = pointer;
this.lineNum = lineNum;
this.space = true;
tList.add(this);
}
public int makeErrorLine(StringBuffer buffer)
{
int index = tList.indexOf(this);
int lineNumber = this.lineNum;
// back up to start of line
while (index > 0 && tList.get(index-1).lineNum == lineNumber) index--;
// form line in buffer
int pointer = 0;
for(int i=index; i= tList.size()) return null;
TokenList token = tList.get(tokenIndex++);
return token;
}
private TokenList peekNextToken()
{
if (tokenIndex >= tList.size()) return null;
return tList.get(tokenIndex);
}
private TokenType getTokenType(TokenList token)
{
if (token == null) return TokenType.UNKNOWN;
return token.type;
}
private TokenList needNextToken(TokenType type)
{
TokenList token = getNextToken();
if (token == null)
{
reportErrorMsg(null, "End of file encountered");
return null;
}
if (token.type != type)
{
reportErrorMsg(token, "Expecting a " + type.getName());
parseToSemicolon();
return null;
}
return token;
}
/********** Keywords ******************************************/
private static class VKeyword
{
/** string defining keyword */ private String name;
private static List theKeywords = new ArrayList();
VKeyword(String name)
{
this.name = name;
theKeywords.add(this);
}
public static VKeyword findKeyword(String tString)
{
for(VKeyword vk : theKeywords)
{
if (vk.name.equals(tString)) return vk;
}
return null;
}
public static final VKeyword ALWAYS = new VKeyword("always");
public static final VKeyword ANALOG = new VKeyword("analog");
public static final VKeyword ASSIGN = new VKeyword("assign");
public static final VKeyword BEGIN = new VKeyword("begin");
public static final VKeyword ELECTRICAL = new VKeyword("electrical");
public static final VKeyword ELSE = new VKeyword("else");
public static final VKeyword END = new VKeyword("end");
public static final VKeyword ENDMODULE = new VKeyword("endmodule");
public static final VKeyword ENDPRIMITIVE = new VKeyword("endprimitive");
public static final VKeyword ENDSPECIFY = new VKeyword("endspecify");
public static final VKeyword ENDTABLE = new VKeyword("endtable");
public static final VKeyword IF = new VKeyword("if");
public static final VKeyword INITIAL = new VKeyword("initial");
public static final VKeyword INOUT = new VKeyword("inout");
public static final VKeyword INPUT = new VKeyword("input");
public static final VKeyword LOGIC = new VKeyword("logic");
public static final VKeyword MODULE = new VKeyword("module");
public static final VKeyword OUTPUT = new VKeyword("output");
public static final VKeyword PARAMETER = new VKeyword("parameter");
public static final VKeyword PRIMITIVE = new VKeyword("primitive");
public static final VKeyword REAL = new VKeyword("real");
public static final VKeyword REG = new VKeyword("reg");
public static final VKeyword SPECIFY = new VKeyword("specify");
public static final VKeyword SUPPLY = new VKeyword("supply");
public static final VKeyword SUPPLY0 = new VKeyword("supply0");
public static final VKeyword SUPPLY1 = new VKeyword("supply1");
public static final VKeyword TABLE = new VKeyword("table");
public static final VKeyword TRANIF0 = new VKeyword("tranif0");
public static final VKeyword TRANIF1 = new VKeyword("tranif1");
public static final VKeyword WIRE = new VKeyword("wire");
};
/**
* Method to do lexical scanning of input Verilog and create token list.
*/
private void doScanner(String [] strings)
{
String buf = "";
int bufPos = 0;
int lineNum = 0;
boolean space = false;
for(;;)
{
if (bufPos >= buf.length())
{
if (lineNum >= strings.length) return;
buf = strings[lineNum++];
if (verbose && (lineNum%100) == 0)
Job.getUserInterface().setProgressValue( lineNum * 100 / strings.length);
bufPos = 0;
space = true;
} else
{
if (Character.isWhitespace(buf.charAt(bufPos))) space = true; else
space = false;
}
while (bufPos < buf.length() && Character.isWhitespace(buf.charAt(bufPos))) bufPos++;
if (bufPos >= buf.length()) continue;
char c = buf.charAt(bufPos);
if (Character.isLetter(c))
{
// could be identifier (keyword) or bit string literal
int end = bufPos;
for(; end < buf.length(); end++)
{
char eChar = buf.charAt(end);
if (!Character.isLetterOrDigit(eChar) && eChar != '_') break;
}
// got alphanumeric from c to end - 1
VKeyword key = VKeyword.findKeyword(buf.substring(bufPos, end));
if (key != null)
{
new TokenList(TokenType.KEYWORD, key, lineNum, space);
} else
{
String ident = buf.substring(bufPos, end);
new TokenList(TokenType.IDENTIFIER, ident, lineNum, space);
}
bufPos = end;
} else if (TextUtils.isDigit(c))
{
// could be decimal or based literal
int end = bufPos+1;
for(; end < buf.length(); end++)
{
char eChar = buf.charAt(end);
if (!TextUtils.isDigit(eChar) && eChar != '_') break;
}
// got numeric from c to end - 1
new TokenList(TokenType.DECIMAL, buf.substring(bufPos, end), lineNum, space);
bufPos = end;
} else
{
switch (c)
{
case '\\':
// backslash starts a quoted identifier
int end = bufPos + 1;
while (end < buf.length() && buf.charAt(end) != '\n')
{
if (Character.isWhitespace(buf.charAt(end))) break;
end++;
}
// identifier from c + 1 to end - 1
String ident = buf.substring(bufPos + 1, end);
new TokenList(TokenType.IDENTIFIER, ident, lineNum, space);
bufPos = end;
break;
case '/':
// got a slash...look for "//" comment
end = bufPos + 1;
if (end < buf.length() && buf.charAt(end) == '/')
{
// single-line comment: skip to end of line
while (end < buf.length() && buf.charAt(end) != '\n')
end++;
if (end < buf.length() && buf.charAt(end) == '\n') end++;
bufPos = end;
break;
}
if (end < buf.length() && buf.charAt(end) == '*')
{
// multi-line comment: skip to terminator
bufPos = end + 1;
for(;;)
{
if (bufPos < buf.length()-1 && buf.charAt(bufPos) == '*' && buf.charAt(bufPos+1) == '/')
{
bufPos += 2;
break;
}
bufPos++;
if (bufPos >= buf.length()-1)
{
if (lineNum >= strings.length) return;
buf = strings[lineNum++];
if (verbose && (lineNum%100) == 0)
Job.getUserInterface().setProgressValue( lineNum * 100 / strings.length);
bufPos = 0;
space = true;
}
}
break;
}
// not a comment: put the token back
new TokenList(TokenType.SLASH, null, lineNum, space);
bufPos++;
break;
case '"':
// got a start of a string
end = bufPos + 1;
while (end < buf.length() && buf.charAt(end) != '\n')
{
if (buf.charAt(end) == '"')
{
if (end+1 < buf.length() && buf.charAt(end+1) == '"') end++; else
break;
}
end++;
}
// string from c + 1 to end - 1
String newString = buf.substring(bufPos + 1, end);
newString.replaceAll("\"\"", "\"");
new TokenList(TokenType.STRING, newString, lineNum, space);
if (buf.charAt(end) == '"') end++;
bufPos = end;
break;
case '`':
// single-line command: skip to end of line
end = bufPos + 1;
while (end < buf.length() && buf.charAt(end) != '\n')
end++;
if (end < buf.length() && buf.charAt(end) == '\n') end++;
bufPos = end;
break;
case '\'':
// character literal
if (bufPos+2 < buf.length() && buf.charAt(bufPos+2) == '\'')
{
new TokenList(TokenType.CHAR, new Character(buf.charAt(bufPos+1)), lineNum, space);
bufPos += 3;
} else
{
if (tList.size() > 0 && bufPos < buf.length()-1)
{
TokenList prevTL = tList.get(tList.size()-1);
char nextC = buf.charAt(bufPos+1);
if (prevTL.type == TokenType.DECIMAL && Character.toLowerCase(nextC) == 'b')
{
if (bufPos+1 < buf.length()-1)
{
nextC = buf.charAt(bufPos+2);
String sym = null;
if (nextC == '1') sym = "vdd"; else
if (nextC == '0') sym = "gnd";
if (sym != null)
{
bufPos += 3;
tList.remove(tList.size()-1);
new TokenList(TokenType.IDENTIFIER, sym, lineNum, space);
break;
}
}
}
}
new TokenList(TokenType.APOSTROPHE, null, lineNum, space);
bufPos++;
}
break;
case '(':
new TokenList(TokenType.LEFTPAREN, null, lineNum, space);
bufPos++;
break;
case ')':
new TokenList(TokenType.RIGHTPAREN, null, lineNum, space);
bufPos++;
break;
case '[':
new TokenList(TokenType.LEFTBRACKET, null, lineNum, space);
bufPos++;
break;
case ']':
new TokenList(TokenType.RIGHTBRACKET, null, lineNum, space);
bufPos++;
break;
case '{':
new TokenList(TokenType.LEFTBRACE, null, lineNum, space);
bufPos++;
break;
case '}':
new TokenList(TokenType.RIGHTBRACE, null, lineNum, space);
bufPos++;
break;
case ',':
new TokenList(TokenType.COMMA, null, lineNum, space);
bufPos++;
break;
case '?':
new TokenList(TokenType.QUESTION, null, lineNum, space);
bufPos++;
break;
case '#':
new TokenList(TokenType.HASH, null, lineNum, space);
bufPos++;
break;
case '@':
new TokenList(TokenType.ATSIGN, null, lineNum, space);
bufPos++;
break;
case '=':
new TokenList(TokenType.EQUALS, null, lineNum, space);
bufPos++;
break;
case '-':
if (bufPos+1 < buf.length() && buf.charAt(bufPos+1) == '-')
{
// got a comment, throw away rest of line
bufPos = buf.length();
} else
{
// got a minus sign
new TokenList(TokenType.MINUS, null, lineNum, space);
bufPos++;
}
break;
case '.':
// could be PERIOD or DOUBLEDOT
if (bufPos+1 < buf.length() && buf.charAt(bufPos+1) == '.')
{
new TokenList(TokenType.DOUBLEDOT, null, lineNum, space);
bufPos += 2;
} else
{
new TokenList(TokenType.PERIOD, null, lineNum, space);
bufPos++;
}
break;
case ':':
// could be COLON or VARASSIGN
if (bufPos+1 < buf.length() && buf.charAt(bufPos+1) == '=')
{
new TokenList(TokenType.VARASSIGN, null, lineNum, space);
bufPos += 2;
} else
{
new TokenList(TokenType.COLON, null, lineNum, space);
bufPos++;
}
break;
case ';':
new TokenList(TokenType.SEMICOLON, null, lineNum, space);
bufPos++;
break;
default:
new TokenList(TokenType.UNKNOWN, null, lineNum, space);
bufPos++;
break;
}
}
}
}
/******************************** THE VERILOG PARSER ********************************/
/**
* Method to parse the token list.
* Reports on any syntax errors and create the required syntax trees.
*/
private void doParser()
{
curModule = null;
resetTokenListPointer();
int tokenCount = 0;
for(;;)
{
TokenList token = getNextToken();
if (token == null) break;
tokenCount++;
if (verbose && (tokenCount%100) == 0)
Job.getUserInterface().setProgressValue( tokenIndex * 100 / tList.size());
if (token.type == TokenType.KEYWORD)
{
VKeyword vk = (VKeyword)token.pointer;
if (vk == VKeyword.MODULE || vk == VKeyword.PRIMITIVE)
{
curModule = parseModule(vk == VKeyword.PRIMITIVE);
continue;
}
if (vk == VKeyword.ENDMODULE || vk == VKeyword.ENDPRIMITIVE)
{
curModule = null;
continue;
}
if (vk == VKeyword.INPUT || vk == VKeyword.OUTPUT || vk == VKeyword.INOUT ||
vk == VKeyword.WIRE || vk == VKeyword.SUPPLY || vk == VKeyword.SUPPLY0 ||
vk == VKeyword.SUPPLY1)
{
parseDeclare(token);
continue;
}
if (vk == VKeyword.TRANIF0 || vk == VKeyword.TRANIF1)
{
VInstance inst = parseGate(token, vk == VKeyword.TRANIF0 ? PrimitiveNode.Function.TRAPMOS : PrimitiveNode.Function.TRANMOS);
if (inst != null) curModule.instances.add(inst);
continue;
}
if (vk == VKeyword.ASSIGN)
{
parseAssign();
continue;
}
if (vk == VKeyword.LOGIC || vk == VKeyword.REAL ||
vk == VKeyword.REG || vk == VKeyword.ELECTRICAL || vk == VKeyword.PARAMETER)
{
parseToSemicolon();
continue;
}
if (vk == VKeyword.ANALOG || vk == VKeyword.INITIAL)
{
ignoreNextStatement();
continue;
}
if (vk == VKeyword.TABLE)
{
ignoreToKeyword(VKeyword.ENDTABLE);
continue;
}
if (vk == VKeyword.SPECIFY)
{
ignoreToKeyword(VKeyword.ENDSPECIFY);
continue;
}
if (vk == VKeyword.ALWAYS)
{
ignoreAlwaysStatement();
continue;
}
if (vk == VKeyword.BEGIN)
{
ignoreToKeyword(VKeyword.END);
continue;
}
reportErrorMsg(token, "Unknown keyword");
} else if (token.type == TokenType.IDENTIFIER)
{
// identifier: parse as an instance declaration
if (curModule == null)
{
reportErrorMsg(token, "Instance declaration is not inside a Module");
parseToSemicolon();
break;
}
VInstance inst = parseInstance(token);
if (inst != null) curModule.instances.add(inst);
} else
{
reportErrorMsg(token, "Expecting an identifier");
parseToSemicolon();
}
}
// fill in ports for modules that were not generated
for(VModule module : allModules)
{
for(VInstance in : module.instances)
{
if (in.module == null) continue;
for(VPort lp : in.ports.keySet())
{
boolean found = false;
for(VExport subPort : in.module.ports)
{
if (subPort.name.equals(lp.portName)) { found = true; break; }
}
if (!found)
{
VExport fp = new VExport(lp.portName);
in.module.ports.add(fp);
}
}
}
}
}
/**
* Method to parse a module description of the form:
* module IDENTIFIER (FORMAL_PORT_LIST);
* FORMAL_PORT_LIST ::= [IDENTIFIER {, IDENTIFIER}]
*/
private VModule parseModule(boolean primitive)
{
// check for entity IDENTIFIER
TokenList token = needNextToken(TokenType.IDENTIFIER);
if (token == null) return null;
String name = (String)token.pointer;
VModule module = findModule(name);
if (module != null)
{
reportErrorMsg(token, "Module already exists");
parseToSemicolon();
return null;
}
module = new VModule(name, true, primitive);
// check for opening bracket of FORMAL_PORT_LIST
token = needNextToken(TokenType.LEFTPAREN);
if (token == null) return null;
// gather FORMAL_PORT_LIST
for(;;)
{
token = needNextToken(TokenType.IDENTIFIER);
if (token == null) return null;
VExport port = new VExport((String)token.pointer);
module.ports.add(port);
token = getNextToken();
if (getTokenType(token) != TokenType.COMMA) break;
}
// check for closing bracket of FORMAL_PORT_LIST
if (getTokenType(token) != TokenType.RIGHTPAREN)
{
reportErrorMsg(token, "Expecting a right parenthesis");
parseToSemicolon();
return null;
}
// check for SEMICOLON
token = needNextToken(TokenType.SEMICOLON);
if (token == null) return null;
return module;
}
private void parseDeclare(TokenList declareToken)
{
if (curModule == null)
{
reportErrorMsg(declareToken, "Not in a module");
parseToSemicolon();
return;
}
int mode = MODE_IN;
VKeyword vk = (VKeyword)declareToken.pointer;
if (vk == VKeyword.OUTPUT) mode = MODE_OUT; else
if (vk == VKeyword.INOUT) mode = MODE_INOUT;
TokenList token = getNextToken();
int firstRange = -1, secondRange = -1;
if (getTokenType(token) == TokenType.LEFTBRACKET)
{
// a bus of bits
token = getNextToken();
firstRange = TextUtils.atoi((String)token.pointer);
token = needNextToken(TokenType.COLON);
if (token == null) return;
token = getNextToken();
secondRange = TextUtils.atoi((String)token.pointer);
token = needNextToken(TokenType.RIGHTBRACKET);
if (token == null) return;
token = getNextToken();
}
// now get the list of identifiers
for(;;)
{
if (getTokenType(token) != TokenType.IDENTIFIER)
{
reportErrorMsg(token, "Expected identifier");
parseToSemicolon();
return;
}
String idName = (String)token.pointer;
boolean found = false;
if (vk == VKeyword.WIRE || vk == VKeyword.SUPPLY || vk == VKeyword.SUPPLY0 || vk == VKeyword.SUPPLY1)
{
if (firstRange != -1 && secondRange != -1)
{
if (firstRange > secondRange)
{
for(int i=firstRange; i>=secondRange; i--)
{
String realName = idName + "[" + i + "]";
if (curModule.wires.contains(realName))
{
reportErrorMsg(token, "Identifier " + realName + " defined twice");
parseToSemicolon();
return;
}
curModule.wires.add(realName);
}
} else
{
for(int i=firstRange; i<=secondRange; i++)
{
String realName = idName + "[" + i + "]";
if (curModule.wires.contains(realName))
{
reportErrorMsg(token, "Identifier " + realName + " defined twice");
parseToSemicolon();
return;
}
curModule.wires.add(realName);
}
}
} else
{
if (curModule.wires.contains(idName))
{
reportErrorMsg(token, "Identifier defined twice");
parseToSemicolon();
return;
}
curModule.wires.add(idName);
}
} else
{
for(VExport fp : curModule.ports)
{
if (fp.name.equals(idName))
{
fp.mode = mode;
fp.firstIndex = firstRange;
fp.secondIndex = secondRange;
found = true;
break;
}
}
if (!found)
{
reportErrorMsg(token, "Unknown identifier");
parseToSemicolon();
return;
}
}
// look for comma
token = getNextToken();
if (getTokenType(token) == TokenType.COMMA)
{
token = getNextToken();
continue;
}
if (getTokenType(token) == TokenType.SEMICOLON) break;
reportErrorMsg(token, "Unknown separator between identifiers");
parseToSemicolon();
return;
}
}
private void parseAssign()
{
// get first identifier
TokenList token = needNextToken(TokenType.IDENTIFIER);
if (token == null) return;
String[] firstNames = getSignalNames(token);
// get equals sign
token = needNextToken(TokenType.EQUALS);
if (token == null) return;
// get second identifier
token = needNextToken(TokenType.IDENTIFIER);
if (token == null) return;
String[] secondNames = getSignalNames(token);
// get semicolon
token = needNextToken(TokenType.SEMICOLON);
if (token == null) return;
// equate the symbols
if (firstNames.length != secondNames.length)
{
reportErrorMsg(token, "Assigning unequal length busses (first part is " + firstNames.length +
" long, second part is " + secondNames.length + " long)");
return;
}
for(int i=0; i signalNames = new ArrayList();
for(;;)
{
token = getNextToken();
if (getTokenType(token) != TokenType.IDENTIFIER)
{
reportErrorMsg(token, "Expecting an identifier");
parseToSemicolon();
return null;
}
String[] sns = getSignalNames(token);
for(int i=0; i 1), sigNames);
}
token = needNextToken(TokenType.RIGHTPAREN);
if (token == null) return null;
} else if (getTokenType(token) == TokenType.IDENTIFIER)
{
String[] sigNames = getSignalNames(token);
inst.addConnection(new VPort(inst, portName, sigNames.length > 1), sigNames);
} else
{
reportErrorMsg(token, "Unknown separator between identifiers");
parseToSemicolon();
return null;
}
token = getNextToken();
if (getTokenType(token) == TokenType.RIGHTPAREN) break;
if (getTokenType(token) != TokenType.COMMA)
{
reportErrorMsg(token, "Expecting a comma");
parseToSemicolon();
return null;
}
}
// must end with a semicolon
token = needNextToken(TokenType.SEMICOLON);
if (token == null) return null;
return inst;
}
private VInstance parseGate(TokenList declareToken, PrimitiveNode.Function fun)
{
if (curModule == null)
{
reportErrorMsg(declareToken, "Not in a module");
parseToSemicolon();
return null;
}
// get the instance name from the second token
TokenList token = needNextToken(TokenType.IDENTIFIER);
if (token == null) return null;
String instanceName = (String)token.pointer;
// must then be followed by an open parenthesis to start the argument list
token = needNextToken(TokenType.LEFTPAREN);
if (token == null) return null;
VInstance inst = new VInstance(fun, instanceName);
// get the arguments
int argNum = 1;
for(;;)
{
token = getNextToken();
if (getTokenType(token) == TokenType.RIGHTPAREN) break;
// guess at the name of the next port
String portName = null;
switch (argNum++)
{
case 1: portName = "s"; break;
case 2: portName = "d"; break;
case 3: portName = "g"; break;
}
if (getTokenType(token) == TokenType.IDENTIFIER)
{
String[] sigNames = getSignalNames(token);
inst.addConnection(new VPort(inst, portName, sigNames.length > 1), sigNames);
} else
{
reportErrorMsg(token, "Unknown separator between identifiers");
parseToSemicolon();
return null;
}
token = getNextToken();
if (getTokenType(token) == TokenType.RIGHTPAREN) break;
if (getTokenType(token) != TokenType.COMMA)
{
reportErrorMsg(token, "Expecting a comma");
parseToSemicolon();
return null;
}
}
// must end with a semicolon
token = needNextToken(TokenType.SEMICOLON);
if (token == null) return null;
return inst;
}
private String[] getSignalNames(TokenList token)
{
List signalNames = new ArrayList();
if (getTokenType(token) == TokenType.IDENTIFIER)
{
String signalName = (String)token.pointer;
// see if it is indexed
TokenList next = peekNextToken();
if (getTokenType(next) == TokenType.LEFTBRACKET)
{
// indexed signal
getNextToken();
TokenList index = needNextToken(TokenType.DECIMAL);
if (index == null) return new String[0];
TokenList nxt = getNextToken();
if (getTokenType(nxt) == TokenType.COLON)
{
TokenList index2 = needNextToken(TokenType.DECIMAL);
if (index2 == null) return new String[0];
TokenList cls = needNextToken(TokenType.RIGHTBRACKET);
if (cls == null) return new String[0];
int startIndex = TextUtils.atoi((String)index.pointer);
int endIndex = TextUtils.atoi((String)index2.pointer);
if (startIndex < endIndex)
{
for(int i=startIndex; i<=endIndex; i++)
signalNames.add(signalName + "[" + i + "]");
} else
{
for(int i=startIndex; i>=endIndex; i--)
signalNames.add(signalName + "[" + i + "]");
}
} else if (getTokenType(nxt) == TokenType.RIGHTBRACKET)
{
signalNames.add(signalName + "[" + (String)index.pointer + "]");
} else
{
return new String[0];
}
} else
{
// see if the name is a bus
boolean foundBus = false;
for(String wire : curModule.wires)
{
if (wire.startsWith(signalName) && wire.length() > signalName.length() && wire.charAt(signalName.length()) == '[')
{
signalNames.add(wire);
foundBus = true;
}
}
if (!foundBus)
{
for(VExport fp : curModule.ports)
{
if (fp.name.equals(signalName))
{
if (fp.firstIndex < fp.secondIndex)
{
foundBus = true;
for(int i=fp.firstIndex; i<=fp.secondIndex; i++)
signalNames.add(signalName + "[" + i + "]");
} else if (fp.firstIndex > fp.secondIndex)
{
foundBus = true;
for(int i=fp.firstIndex; i>=fp.secondIndex; i--)
signalNames.add(signalName + "[" + i + "]");
}
}
}
}
if (!foundBus) signalNames.add(signalName);
}
}
String[] sigNames = new String[signalNames.size()];
for(int i=0; i 0) continue;
break;
}
}
}
private void ignoreToKeyword(VKeyword keyword)
{
ignoreUntilEndOfStatement(keyword, 0);
}
/**
* Method to ignore up to a given keyword.
* @param keyword the terminating keyword to find.
* @param nestedLoop the level of "begin/end" nesting.
*/
private void ignoreUntilEndOfStatement(VKeyword keyword, int nestedLoop)
{
for(;;)
{
TokenList token = getNextToken();
if (token == null) return;
if (token.type != TokenType.KEYWORD) continue;
VKeyword vk = (VKeyword)token.pointer;
if (vk == VKeyword.BEGIN)
{
// ignore the next nested loop
ignoreUntilEndOfStatement(VKeyword.END, nestedLoop+1);
continue;
}
if (vk == keyword && nestedLoop == 0) return;
}
}
private void reportErrorMsg(TokenList tList, String errMsg)
{
hasErrors = true;
errorCount++;
if (errorCount == 30)
System.out.println("TOO MANY ERRORS...PRINTING NO MORE");
if (errorCount >= 30) return;
if (tList == null)
{
System.out.println("ERROR " + errMsg);
return;
}
System.out.println("ERROR on line " + tList.lineNum + ", " + errMsg + ":");
// back up to start of line
StringBuffer buffer = new StringBuffer();
int pointer = tList.makeErrorLine(buffer);
// print out line
System.out.println(buffer.toString());
// print out pointer
buffer = new StringBuffer();
for (int i = 0; i < pointer; i++) buffer.append(" ");
System.out.println(buffer.toString() + "^");
}
/******************************** THE RATS-NEST CELL GENERATOR ********************************/
/**
* Method to generate a cell that represents this netlist.
* @param destLib destination library.
* @param schematic true to make schematics; false for layout
*/
public Cell genCell(Library destLib, boolean schematic, EditingPreferences ep, IconParameters ip)
{
if (hasErrors()) return null;
Map> portLocMap = new HashMap>();
if (verbose)
Job.getUserInterface().startProgressDialog("Building Rats-Nest Cells", null);
Cell cell = null;
for(VModule mod : allModules)
{
if (!mod.defined) continue;
String cellName = mod.name + (schematic ? "{sch}" : "{lay}");
System.out.println("Creating cell " + cellName);
if (verbose)
{
Job.getUserInterface().setProgressNote("Creating Nodes in Cell " + cellName);
Job.getUserInterface().setProgressValue(0);
}
cell = Cell.makeInstance(ep, destLib, cellName);
if (cell == null)
{
if (verbose) Job.getUserInterface().stopProgressDialog();
return null;
}
// first place the instances
double GAP = 15;
double x = 0;
double y = 0;
double highest = 0;
double totalSize = 0;
for(VInstance in : mod.instances)
{
if (in.module == null)
{
NodeProto tranNP = Schematics.tech().transistorNode;
double width = tranNP.getDefWidth(ep);
double height = tranNP.getDefHeight(ep);
totalSize += (width + GAP) * (height + GAP);
} else
{
Cell subCell = in.module.cell;
if (subCell == null) continue;
double width = subCell.getDefWidth();
double height = subCell.getDefHeight();
totalSize += (width + GAP) * (height + GAP);
}
}
double cellSize = Math.sqrt(totalSize);
Map placed = new HashMap();
int instancesPlaced = 0;
for(VInstance in : mod.instances)
{
NodeInst ni = null;
NodeProto np;
double width=0, height=0;
if (in.module != null)
{
np = in.module.cell;
if (np != null)
{
width = np.getDefWidth(ep);
height = np.getDefHeight(ep);
ni = NodeInst.makeInstance(np, ep, new EPoint(x, y), width, height, cell,
Orientation.IDENT, in.instanceName);
}
} else
{
np = Schematics.tech().transistorNode;
width = np.getDefWidth(ep);
height = np.getDefHeight(ep);
ni = NodeInst.makeInstance(np, ep, new EPoint(x, y), width, height, cell, Orientation.R, in.instanceName, in.fun);
}
if (ni == null) continue;
placed.put(in, ni);
// cache port locations on this instance
Map portMap = portLocMap.get(np);
if (portMap == null)
{
portMap = new HashMap();
portLocMap.put(np, portMap);
for(Iterator it = ni.getPortInsts(); it.hasNext(); )
{
PortInst pi = it.next();
PortProto pp = pi.getPortProto();
EPoint ept = pi.getCenter();
Point2D pt = new Point2D.Double(ept.getX() - ni.getAnchorCenterX(), ept.getY() - ni.getAnchorCenterY());
portMap.put(pp, pt);
}
}
instancesPlaced++;
if (verbose && (instancesPlaced%100) == 0)
Job.getUserInterface().setProgressValue(instancesPlaced * 100 / mod.instances.size());
// advance the placement
x += width + GAP;
highest = Math.max(highest, height);
if (x >= cellSize)
{
x = 0;
y += highest + GAP;
highest = 0;
}
}
if (instancesPlaced > 0)
System.out.println("Placed " + instancesPlaced + " instances");
// now remove wires that do not make useful connections
Netlist nl = cell.getNetlist();
Set notFound = new HashSet();
for(String netName : mod.allNetworks.keySet())
{
List ports = mod.allNetworks.get(netName);
Set used = new HashSet();
for(int i=0; i 1) continue;
Network net = nl.getNetwork(pi);
if (used.contains(net))
{
ports.remove(i);
i--;
continue;
}
used.add(net);
}
}
// give errors about missing instances
for(VInstance in : notFound)
{
System.out.println("ERROR: Cannot find instance " + in.instanceName + " of module " + in.module.name);
}
// now wire the instances
if (verbose)
{
Job.getUserInterface().setProgressNote("Creating Arcs in Cell " + cellName);
Job.getUserInterface().setProgressValue(0);
}
int total = 0;
for(String netName : mod.allNetworks.keySet())
{
List ports = mod.allNetworks.get(netName);
for(int i=1; i= 0) { allScalar = false; break; }
if (allScalar) continue;
NodeInst ni = placed.get(in);
if (ni == null) continue;
PortProto pp = null;
for(Iterator it = ni.getProto().getPorts(); it.hasNext(); )
{
PortProto ppTry = it.next();
String tryName = ppTry.getName();
if (tryName.equals(lp.portName)) { pp = ppTry; break; }
if (tryName.startsWith(lp.portName)&& tryName.length() > lp.portName.length() &&
tryName.charAt(lp.portName.length()) == '[') { pp = ppTry; break; }
}
if (pp == null)
{
System.out.println("Cannot find port " + lp.portName + " on cell " + ni.getProto().describe(false));
continue;
}
if (pp == null) continue;
PortInst pi = ni.findPortInstFromProto(pp);
EPoint piLoc = pi.getCenter();
double dX=0, dY=0;
double leftDist = Math.abs(piLoc.getX() - ni.getBounds().getMinX());
double rightDist = Math.abs(piLoc.getX() - ni.getBounds().getMaxX());
double downDist = Math.abs(piLoc.getY() - ni.getBounds().getMinY());
double upDist = Math.abs(piLoc.getY() - ni.getBounds().getMaxY());
double minDist = Math.min(Math.min(leftDist, rightDist), Math.min(upDist, downDist));
if (minDist == leftDist) dX = -5; else
if (minDist == rightDist) dX = 5; else
if (minDist == upDist) dY = 5; else
dY = -5;
EPoint busPinLoc = new EPoint(piLoc.getX()+dX, piLoc.getY()+dY);
NodeProto np;
ArcProto ap;
String name;
if (signals.length == 1)
{
np = Schematics.tech().wirePinNode;
ap = Schematics.tech().wire_arc;
if (!pi.getPortProto().getBasePort().connectsTo(ap))
{
ap = pi.getPortProto().getBasePort().getConnections()[0];
np = ap.findPinProto();
}
name = signals[0];
} else
{
np = Schematics.tech().busPinNode;
ap = Schematics.tech().bus_arc;
name = makeBusName(signals);
}
NodeInst stubPin = NodeInst.makeInstance(np, ep, busPinLoc, np.getDefWidth(ep), np.getDefHeight(ep), cell);
ArcInst.makeInstance(ap, ep, pi, stubPin.getOnlyPortInst(), piLoc, busPinLoc, name);
}
}
// create arcs
int count = 0;
Map portMap = new HashMap();
for(String netName : mod.allNetworks.keySet())
{
List ports = mod.allNetworks.get(netName);
List scalarPorts = new ArrayList();
for(VPort lp : ports)
if (!lp.onBus) scalarPorts.add(lp);
if (scalarPorts.size() == 1)
{
VPort port = scalarPorts.get(0);
NodeInst ni = placed.get(port.in);
if (ni == null) continue;
PortInst pi = findPortOnNode(ni, port.portName);
if (pi != null) portMap.put(netName, pi);
}
for(int i=1; i allExports = new HashMap();
for(VExport port : mod.ports)
{
PortCharacteristic pc = null;
switch (port.mode)
{
case MODE_UNKNOWN: pc = PortCharacteristic.UNKNOWN; break;
case MODE_IN: pc = PortCharacteristic.IN; break;
case MODE_OUT: pc = PortCharacteristic.OUT; break;
case MODE_INOUT: pc = PortCharacteristic.BIDIR; break;
}
String portName = port.name;
if (port.firstIndex != port.secondIndex)
{
if (schematic) portName += "[" + port.firstIndex + ":" + port.secondIndex + "]"; else
{
int low = Math.min(port.firstIndex, port.secondIndex);
int high = Math.max(port.firstIndex, port.secondIndex);
for(int i=low; i<=high; i++)
{
String thisPortName = portName + "[" + i + "]";
PortInst pi = portMap.get(thisPortName);
if (pi == null)
{
List ports = mod.allNetworks.get(thisPortName);
if (ports != null && ports.size() > 0)
{
VPort lp = ports.get(0);
NodeInst ni = placed.get(lp.in);
if (ni != null)
pi = ni.findPortInst(lp.portName);
}
if (pi == null)
{
NodeProto np = Generic.tech().universalPinNode;
NodeInst ni = NodeInst.makeInstance(np, ep, new EPoint(x, y), np.getDefWidth(ep), np.getDefHeight(ep), cell);
pi = ni.getOnlyPortInst();
y += GAP;
}
}
Export.newInstance(cell, pi, thisPortName, ep, pc);
allExports.put(thisPortName, pi);
}
continue;
}
}
PortInst pi = portMap.get(portName);
if (pi == null)
{
List ports = mod.allNetworks.get(portName);
if (ports != null)
{
VPort lp = ports.get(0);
NodeInst ni = placed.get(lp.in);
if (lp != null && ni != null)
pi = ni.findPortInst(lp.portName);
}
if (pi == null)
{
NodeProto np = Generic.tech().universalPinNode;
NodeInst ni = NodeInst.makeInstance(np, ep, new EPoint(x, y), np.getDefWidth(ep), np.getDefHeight(ep), cell);
pi = ni.getOnlyPortInst();
y += GAP;
}
}
Export.newInstance(cell, pi, portName, ep, pc);
allExports.put(portName, pi);
}
// connect assigned exports
for(String name2 : mod.assignments.keySet())
{
PortInst pi2 = allExports.get(name2);
if (pi2 == null) continue;
String name1 = mod.assignments.get(name2);
PortInst pi1 = allExports.get(name1);
if (pi1 == null) continue;
ArcProto ap = Generic.tech().unrouted_arc;
ArcInst.makeInstance(ap, ep, pi1, pi2);
}
// make an icon if this is a schematic
if (schematic)
{
try
{
Cell iconCell = ip.makeIconForCell(cell, ep);
int exampleLocation = ep.getIconGenInstanceLocation();
if (exampleLocation != 4)
{
// place an icon in the schematic
Point2D iconPos = new Point2D.Double(0,0);
Rectangle2D cellBounds = cell.getBounds();
Rectangle2D iconBounds = iconCell.getBounds();
double halfWidth = iconBounds.getWidth() / 2;
double halfHeight = iconBounds.getHeight() / 2;
switch (exampleLocation)
{
case 0: // upper-right
iconPos.setLocation(cellBounds.getMaxX()+halfWidth, cellBounds.getMaxY()+halfHeight);
break;
case 1: // upper-left
iconPos.setLocation(cellBounds.getMinX()-halfWidth, cellBounds.getMaxY()+halfHeight);
break;
case 2: // lower-right
iconPos.setLocation(cellBounds.getMaxX()+halfWidth, cellBounds.getMinY()-halfHeight);
break;
case 3: // lower-left
iconPos.setLocation(cellBounds.getMinX()-halfWidth, cellBounds.getMinY()-halfHeight);
break;
}
DBMath.gridAlign(iconPos, ep.getAlignmentToGrid());
double px = iconCell.getBounds().getWidth();
double py = iconCell.getBounds().getHeight();
NodeInst.makeInstance(iconCell, ep, iconPos, px, py, cell);
}
} catch (JobException e) {}
}
if (count > 0)
System.out.println("Created " + count + " wires");
if (verbose) Job.getUserInterface().stopProgressDialog();
}
if (verbose) Job.getUserInterface().stopProgressDialog();
return cell;
}
private String makeBusName(String[] signals)
{
boolean breakBus = false;
int startIndex=0, lastIndex=0;
int dir = 0;
int braPos = signals[0].indexOf('[');
String prefix = null;
if (braPos >= 0)
{
prefix = signals[0].substring(0, braPos);
for(int i=0; i 0) name += ",";
name += signals[i];
}
return name;
}
return prefix + "[" + startIndex + ":" + lastIndex + "]";
}
private int getPortWidth(PortInst pi, Netlist nl)
{
int busWidth = 1;
if (pi.getNodeInst().isCellInstance()) busWidth = nl.getBusWidth((Export)pi.getPortProto());
return busWidth;
}
private PortInst findPortOnNode(NodeInst ni, String portName)
{
PortInst pi = ni.findPortInst(portName);
if (pi != null) return pi;
String desiredName = portName;
int bracketPos = desiredName.indexOf('[');
if (bracketPos >= 0) desiredName = desiredName.substring(0, bracketPos);
for(Iterator it = ni.getPortInsts(); it.hasNext(); )
{
PortInst pInst = it.next();
String pName = pInst.getPortProto().getName();
bracketPos = pName.indexOf('[');
if (bracketPos >= 0) pName = pName.substring(0, bracketPos);
if (pName.equals(desiredName))
{
if (pi != null)
{
pi = null;
break;
}
pi = pInst;
}
}
if (pi != null) return pi;
hasErrors = true;
System.out.println("Cannot find port " + portName + " on node " + ni.describe(false));
System.out.println("Check errors reported.");
if (verbose) Job.getUserInterface().stopProgressDialog();
return null;
}
/**
* Method to cache the center of ports.
* This is necessary because the call to "PortInst.getCenter()" is expensive.
* This method assumes that all nodes are unrotated.
* @param pi the PortInst being requested.
* @param portLocMap a caching map for port locations.
* @return the center of the PortInst.
*/
private EPoint getPortCenter(PortInst pi, Map> portLocMap)
{
NodeInst ni = pi.getNodeInst();
Map portMap = portLocMap.get(ni.getProto());
Point2D pt = portMap.get(pi.getPortProto());
return new EPoint(pt.getX() + ni.getAnchorCenterX(), pt.getY() + ni.getAnchorCenterY());
}
/******************************** THE ALS NETLIST GENERATOR ********************************/
/**
* Method to generate an ALS (simulation) netlist.
* @param destLib destination library.
* @return a List of strings with the netlist.
*/
public List getALSNetlist(Library destLib)
{
// now produce the netlist
if (hasErrors) return null;
// print file header
List netlist = new ArrayList();
netlist.add("#*************************************************");
netlist.add("# ALS Netlist file");
netlist.add("#");
if (User.isIncludeDateAndVersionInOutput())
netlist.add("# File Creation: " + TextUtils.formatDate(new Date()));
netlist.add("#*************************************************");
netlist.add("");
// determine top level cell
for(VModule mod : allModules)
{
if (mod.defined)
genALSInterface(mod, netlist);
}
// print closing line of output file
netlist.add("#********* End of netlist *******************");
return netlist;
}
/**
* Method to generate the ALS description for the specified model.
* @param module module to analyze
* @param netlist the List of strings to create.
*/
private void genALSInterface(VModule module, List netlist)
{
// write this entity
String modLine = "model " + module.name + "(";
boolean first = true;
for(VExport fp : module.ports)
{
for(int i=fp.firstIndex; i<=fp.secondIndex; i++)
{
if (!first) modLine += ", ";
first = false;
modLine += fp.name;
if (i != -1) modLine += "_" + i + "_";
}
}
modLine += ")";
netlist.add(modLine);
// write instances
for(VInstance in : module.instances)
{
first = true;
String inName = in.instanceName.replaceAll("/", "_").replaceAll("\\[", "_").replaceAll("\\]", "_");
String inLine = inName + ": " + in.module.name + "(";
for(VPort lp : in.ports.keySet())
{
if (!first) inLine += ", ";
first = false;
String[] signalNames = in.ports.get(lp);
for(int i=0; i getQUISCNetlist(Library destLib, boolean isIncludeDateAndVersionInOutput)
{
// now produce the netlist
if (hasErrors) return null;
List netlist = new ArrayList();
// print file header
netlist.add("!*************************************************");
netlist.add("! QUISC Command file");
netlist.add("!");
if (isIncludeDateAndVersionInOutput)
netlist.add("! File Creation: " + TextUtils.formatDate(new Date()));
netlist.add("!-------------------------------------------------");
netlist.add("");
// determine top level cell
for(VModule mod : allModules)
{
if (mod.defined)
genQuiscInterface(mod, netlist);
}
// print closing line of output file
netlist.add("!********* End of command file *******************");
return netlist;
}
/**
* Method to generate the QUISC description for the specified model.
* @param module module to analyze
* @param netlist the List of strings to create.
*/
private void genQuiscInterface(VModule module, List netlist)
{
// write this entity
netlist.add("create cell " + module.name);
// write instances
for(VInstance in : module.instances)
{
netlist.add("create instance " + in.instanceName + " " + in.module.name);
}
for(String netName : module.allNetworks.keySet())
{
List ports = module.allNetworks.get(netName);
VPort last = null;
for(VPort lp : ports)
{
if (last != null)
netlist.add("connect " + last.in.instanceName + " " + last.portName + " " + lp.in.instanceName + " " + lp.portName);
last = lp;
}
}
// create export list
for(VExport port : module.ports)
{
for(int i = port.firstIndex; i<=port.secondIndex; i++)
{
String name = port.name;
if (i != -1) name += "[" + i + "]";
boolean found = false;
for(VInstance in : module.instances)
{
for(VPort lp : in.ports.keySet())
{
String[] signalNames = in.ports.get(lp);
for(int j=0; j