📄 compilevhdl.java
字号:
public boolean hasErrors() { return hasErrors; }; /** * Method to generate a QUISC (silicon compiler) netlist. * @param destLib destination library. * @return a List of strings with the netlist. */ public List<String> getQUISCNetlist(Library destLib) { // now produce the netlist if (hasErrors) return null; List<String> netlistStrings = genQuisc(destLib); return netlistStrings; } /** * Method to generate an ALS (simulation) netlist. * @param destLib destination library. * @return a List of strings with the netlist. */ public List<String> getALSNetlist(Library destLib) { // now produce the netlist if (hasErrors) return null; Library behaveLib = null; List<String> netlistStrings = genALS(destLib, behaveLib); return netlistStrings; } /******************************** THE VHDL SCANNER ********************************/ /** * Method to do lexical scanning of input VHDL 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++]; 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 = isKeyword(buf.substring(bufPos, end)); if (key != null) { new TokenList(TOKEN_KEYWORD, key, lineNum, space); } else { String ident = buf.substring(bufPos, end); identTable.add(ident); new TokenList(TOKEN_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(TOKEN_DECIMAL, buf.substring(bufPos, end), lineNum, space); bufPos = end; } else { switch (c) { case '"': // got a start of a string int 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(TOKEN_STRING, newString, lineNum, space); if (buf.charAt(end) == '"') end++; bufPos = end; break; case '&': new TokenList(TOKEN_AMPERSAND, null, lineNum, space); bufPos++; break; case '\'': // character literal if (bufPos+2 < buf.length() && buf.charAt(bufPos+2) == '\'') { new TokenList(TOKEN_CHAR, new Character(buf.charAt(bufPos+1)), lineNum, space); bufPos += 3; } else bufPos++; break; case '(': new TokenList(TOKEN_LEFTBRACKET, null, lineNum, space); bufPos++; break; case ')': new TokenList(TOKEN_RIGHTBRACKET, null, lineNum, space); bufPos++; break; case '*': // could be STAR or DOUBLESTAR if (bufPos+1 < buf.length() && buf.charAt(bufPos+1) == '*') { new TokenList(TOKEN_DOUBLESTAR, null, lineNum, space); bufPos += 2; } else { new TokenList(TOKEN_STAR, null, lineNum, space); bufPos++; } break; case '+': new TokenList(TOKEN_PLUS, null, lineNum, space); bufPos++; break; case ',': new TokenList(TOKEN_COMMA, 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(TOKEN_MINUS, null, lineNum, space); bufPos++; } break; case '.': // could be PERIOD or DOUBLEDOT if (bufPos+1 < buf.length() && buf.charAt(bufPos+1) == '.') { new TokenList(TOKEN_DOUBLEDOT, null, lineNum, space); bufPos += 2; } else { new TokenList(TOKEN_PERIOD, null, lineNum, space); bufPos++; } break; case '/': // could be SLASH or NE if (bufPos+1 < buf.length() && buf.charAt(bufPos+1) == '=') { new TokenList(TOKEN_NE, null, lineNum, space); bufPos += 2; } else { new TokenList(TOKEN_SLASH, null, lineNum, space); bufPos++; } break; case ':': // could be COLON or VARASSIGN if (bufPos+1 < buf.length() && buf.charAt(bufPos+1) == '=') { new TokenList(TOKEN_VARASSIGN, null, lineNum, space); bufPos += 2; } else { new TokenList(TOKEN_COLON, null, lineNum, space); bufPos++; } break; case ';': new TokenList(TOKEN_SEMICOLON, null, lineNum, space); bufPos++; break; case '<': // could be LT or LE or BOX if (bufPos+1 < buf.length()) { if (buf.charAt(bufPos+1) == '=') { new TokenList(TOKEN_LE, null, lineNum, space); bufPos += 2; break; } if (buf.charAt(bufPos+1) == '>') { new TokenList(TOKEN_BOX, null, lineNum, space); bufPos += 2; break; } } new TokenList(TOKEN_LT, null, lineNum, space); bufPos++; break; case '=': // could be EQUAL or double delimiter ARROW if (bufPos+1 < buf.length() && buf.charAt(bufPos+1) == '>') { new TokenList(TOKEN_ARROW, null, lineNum, space); bufPos += 2; } else { new TokenList(TOKEN_EQ, null, lineNum, space); bufPos++; } break; case '>': // could be GT or GE if (bufPos+1 < buf.length() && buf.charAt(bufPos+1) == '=') { new TokenList(TOKEN_GE, null, lineNum, space); bufPos += 2; } else { new TokenList(TOKEN_GT, null, lineNum, space); bufPos++; } break; case '|': new TokenList(TOKEN_VERTICALBAR, null, lineNum, space); bufPos++; break; default: new TokenList(TOKEN_UNKNOWN, null, lineNum, space); bufPos++; break; } } } } /** * Method to get address in the keyword table. * @param tString string to lookup. * @return entry in keywords table if keyword, else null. */ public static VKeyword isKeyword(String tString) { int base = 0; int num = theKeywords.length; int aIndex = num >> 1; while (num != 0) { int check = tString.compareTo(theKeywords[base + aIndex].name); if (check == 0) return theKeywords[base + aIndex]; if (check < 0) { num = aIndex; aIndex = num >> 1; } else { base += aIndex + 1; num -= aIndex + 1; aIndex = num >> 1; } } return null; } /******************************** THE VHDL PARSER ********************************/ private boolean hasError; private TokenList nextToken; private PTree pTree; private class ParseException extends Exception {} /** * Method to parse the passed token list using the parse tables. * Reports on any syntax errors and create the required syntax trees. * @param tlist list of tokens. */ private boolean doParser(TokenList tList) { hasError = false; pTree = null; PTree endunit = null; nextToken = tList; try { while (nextToken != null) { if (nextToken.token == TOKEN_KEYWORD) { int type = NOUNIT; VKeyword vk = (VKeyword)nextToken.pointer; Object pointer = null; switch (vk.num) { case KEY_LIBRARY: parseToSemicolon(); break; case KEY_ENTITY: type = UNIT_INTERFACE; pointer = parseInterface(); break; case KEY_ARCHITECTURE: type = UNIT_BODY; pointer = parseBody(); break; case KEY_PACKAGE: type = UNIT_PACKAGE; pointer = parsePackage(); break; case KEY_USE: type = UNIT_USE; pointer = parseUse(); break; default: reportErrorMsg(nextToken, "No entry keyword - entity, architectural, behavioral"); nextToken = nextToken.next; break; } if (type != NOUNIT) { PTree newUnit = new PTree(); newUnit.type = type; newUnit.pointer = pointer; newUnit.next = null; if (endunit == null) { pTree = endunit = newUnit; } else { endunit.next = newUnit; endunit = newUnit; } } } else { reportErrorMsg(nextToken, "No entry keyword - entity, architectural, behavioral"); nextToken = nextToken.next; } } } catch (ParseException e) { } return hasError; } /** * Method to parse an interface description of the form: * ENTITY identifier IS PORT (formal_port_list); * END [identifier] ; */ private VInterface parseInterface() throws ParseException { getNextToken(); // check for entity IDENTIFIER TokenList name = null; if (nextToken.token != TOKEN_IDENTIFIER) { reportErrorMsg(nextToken, "Expecting an identifier"); } else { name = nextToken; } // check for keyword IS getNextToken(); if (!isKeySame(nextToken, KEY_IS)) { reportErrorMsg(nextToken, "Expecting keyword IS"); } // check for keyword PORT getNextToken(); if (!isKeySame(nextToken, KEY_PORT)) { reportErrorMsg(nextToken, "Expecting keyword PORT"); } // check for opening bracket of FORMAL_PORT_LIST getNextToken(); if (nextToken.token != TOKEN_LEFTBRACKET) { reportErrorMsg(nextToken, "Expecting a left bracket"); } // gather FORMAL_PORT_LIST getNextToken(); FPortList ports = parseFormalPortList(); if (ports == null) { reportErrorMsg(nextToken, "Interface must have ports"); } // check for closing bracket of FORMAL_PORT_LIST if (nextToken.token != TOKEN_RIGHTBRACKET) { reportErrorMsg(nextToken, "Expecting a right bracket"); } getNextToken(); // check for SEMICOLON if (nextToken.token != TOKEN_SEMICOLON) { reportErrorMsg(nextToken, "Expecting a semicolon"); } else getNextToken(); // check for keyword END if (!isKeySame(nextToken, KEY_END)) { reportErrorMsg(nextToken, "Expecting keyword END"); } // check for optional entity IDENTIFIER getNextToken(); if (nextToken.token == TOKEN_IDENTIFIER) { if (!nextToken.pointer.equals(name.pointer)) { reportErrorMsg(nextToken, "Unmatched entity identifier names"); } getNextToken(); } // check for closing SEMICOLON if (nextToken.token != TOKEN_SEMICOLON) { reportErrorMsg(nextToken, "Expecting a semicolon"); } nextToken = nextToken.next; // allocate an entity parse tree VInterface interfacef = new VInterface(); interfacef.name = name; interfacef.ports = ports; interfacef.interfacef = null; return interfacef; } /** * Method to parse a body. The syntax is of the form: * ARCHITECTURE identifier OF simple_name IS * body_declaration_part * BEGIN * set_of_statements * END [identifier] ; * @return the created body structure. */ private Body parseBody() throws ParseException { getNextToken();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -