📄 fpga.java
字号:
} public void terminateOK() { if (topCell != null) { // display top cell UserInterface ui = Job.getUserInterface(); ui.displayCell(topCell); } } } /** * Method to read the FPGA file in "f" and create a LISPTREE structure which is returned. * Returns zero on error. */ private LispTree readFile(String fileName) { // make the tree top LispTree treeTop = new LispTree(); treeTop.keyword = "TOP"; // initialize current position and stack treePosition = treeTop; treeDepth = 0; URL url = TextUtils.makeURLToFile(fileName); try { URLConnection urlCon = url.openConnection(); InputStreamReader is = new InputStreamReader(urlCon.getInputStream()); LineNumberReader lnr = new LineNumberReader(is); // read the file for(;;) { // get the next line of text String line = lnr.readLine(); if (line == null) break; // stop now if it is a comment line = line.trim(); if (line.length() == 0) continue; if (line.charAt(0) == '#') continue; // keep parsing it int pt = 0; for(;;) { // skip spaces while (pt < line.length() && Character.isWhitespace(line.charAt(pt))) pt++; if (pt >= line.length()) break; // check for special characters char chr = line.charAt(pt); if (chr == ')') { if (pushKeyword(line.substring(pt, pt+1), lnr)) return null; pt++; continue; } // gather a keyword int ptEnd = pt; for(;;) { if (ptEnd >= line.length()) break; char chEnd = line.charAt(ptEnd); if (chEnd == ')' || Character.isWhitespace(chEnd)) break; if (chEnd == '"') { ptEnd++; for(;;) { if (ptEnd >= line.length() || line.charAt(ptEnd) == '"') break; ptEnd++; } if (ptEnd < line.length()) ptEnd++; break; } ptEnd++; } if (pushKeyword(line.substring(pt, ptEnd), lnr)) return null; pt = ptEnd; } } lnr.close(); System.out.println(fileName + " read"); } catch (IOException e) { System.out.println("Error reading " + fileName); return null; } if (treeDepth != 0) { System.out.println("Not enough close parenthesis in file"); return null; } return treeTop; } /** * Method to add the next keyword "keyword" to the lisp tree in the globals. * Returns true on error. */ private boolean pushKeyword(String keyword, LineNumberReader lnr) { if (keyword.startsWith("(")) { if (treeDepth >= MAXDEPTH) { System.out.println("Nesting too deep (more than " + MAXDEPTH + ")"); return true; } // create a new tree branch LispTree newTree = new LispTree(); newTree.lineNumber = lnr.getLineNumber(); // add branch to previous branch treePosition.add(newTree); // add keyword int pt = 1; while (pt < keyword.length() && Character.isWhitespace(keyword.charAt(pt))) pt++; newTree.keyword = keyword.substring(pt); // push tree onto stack treeStack[treeDepth] = treePosition; treeDepth++; treePosition = newTree; return false; } if (keyword.equals(")")) { // pop tree stack if (treeDepth <= 0) { System.out.println("Too many close parenthesis"); return true; } treeDepth--; treePosition = treeStack[treeDepth]; return false; } // just add the atomic keyword if (keyword.startsWith("\"") && keyword.endsWith("\"")) keyword = keyword.substring(1, keyword.length()-1); treePosition.add(keyword); return false; } /******************** ARCHITECTURE PARSING: PRIMITIVES ********************/ /** * Method to parse the entire tree and create primitives. * Returns the number of primitives made. */ private int makePrimitives(LispTree lt) { // look through top level for the "primdef"s int total = 0; for(int i=0; i<lt.size(); i++) { if (lt.isLeaf(i)) continue; LispTree subLT = lt.getBranch(i); if (!subLT.keyword.equalsIgnoreCase("primdef")) continue; // create the primitive if (makePrimitive(subLT)) return(0); total++; } return total; } /** * Method to create a primitive from a subtree "lt". * Tree has "(primdef...)" structure. */ private boolean makePrimitive(LispTree lt) { // find all of the pieces of this primitive LispTree ltAttribute = null, ltNets = null, ltPorts = null, ltComponents = null; String primName = null; String primSizeX = null; String primSizeY = null; for(int i=0; i<lt.size(); i++) { if (lt.isLeaf(i)) continue; LispTree scanLT = lt.getBranch(i); if (scanLT.keyword.equalsIgnoreCase("attributes")) { if (ltAttribute != null) { System.out.println("Multiple 'attributes' sections for a primitive (line " + scanLT.lineNumber + ")"); return true; } for(int j=0; j<scanLT.size(); j++) { if (scanLT.isLeaf(j)) continue; LispTree subLT = scanLT.getBranch(j); if (subLT.keyword.equalsIgnoreCase("name")) { if (subLT.size() != 1 || subLT.isBranch(0)) { System.out.println("Primitive 'name' attribute should take a single atomic parameter (line " + subLT.lineNumber + ")"); return true; } primName = subLT.getLeaf(0); continue; } if (subLT.keyword.equalsIgnoreCase("size")) { if (subLT.size() != 2 || subLT.isBranch(0) || subLT.isBranch(1)) { System.out.println("Primitive 'size' attribute should take two atomic parameters (line " + subLT.lineNumber + ")"); return true; } primSizeX = subLT.getLeaf(0); primSizeY = subLT.getLeaf(1); continue; } } ltAttribute = scanLT; continue; } if (scanLT.keyword.equalsIgnoreCase("nets")) { if (ltNets != null) { System.out.println("Multiple 'nets' sections for a primitive (line " + scanLT.lineNumber + ")"); return true; } ltNets = scanLT; continue; } if (scanLT.keyword.equalsIgnoreCase("ports")) { if (ltPorts != null) { System.out.println("Multiple 'ports' sections for a primitive (line " + scanLT.lineNumber + ")"); return true; } ltPorts = scanLT; continue; } if (scanLT.keyword.equalsIgnoreCase("components")) { if (ltComponents != null) { System.out.println("Multiple 'components' sections for a primitive (line " + scanLT.lineNumber + ")"); return true; } ltComponents = scanLT; continue; } } // make sure a name and size were given if (primName == null) { System.out.println("Missing 'name' attribute in primitive definition (line " + lt.lineNumber + ")"); return true; } if (primSizeX == null || primSizeY == null) { System.out.println("Missing 'size' attribute in primitive definition (line " + lt.lineNumber + ")"); return true; } // make the primitive double sizeX = TextUtils.atof(primSizeX); double sizeY = TextUtils.atof(primSizeY); FPGANode primNP = new FPGANode(primName, this, sizeX, sizeY, new Technology.NodeLayer [] { new Technology.NodeLayer(componentLayer, 0, Poly.Type.CLOSED, Technology.NodeLayer.BOX, new Technology.TechPoint[] { new Technology.TechPoint(EdgeH.makeLeftEdge(), EdgeV.makeBottomEdge()), new Technology.TechPoint(EdgeH.makeRightEdge(), EdgeV.makeTopEdge()), }) }); primNP.setLockedPrim(); defined = true; // get ports if (ltPorts != null) { // count ports int portCount = 0; for(int j=0; j<ltPorts.size(); j++) { if (ltPorts.isLeaf(j)) continue; LispTree scanLT = ltPorts.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("port")) portCount++; } // create the ports primNP.portList = new FPGAPort[portCount]; int portNumber = 0; for(int j=0; j<ltPorts.size(); j++) { if (ltPorts.isLeaf(j)) continue; LispTree scanLT = ltPorts.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("port")) { FPGAPort fp = new FPGAPort(); primNP.portList[portNumber] = fp; if (makePrimPort(primNP, scanLT, fp, portNumber)) return true; for(int k=0; k<portNumber; k++) { if (primNP.portList[k].name.equalsIgnoreCase(fp.name)) { System.out.println("Duplicate port name: " + fp.name + " (line " + scanLT.lineNumber + ")"); return true; } } portNumber++; } } } // get nets if (ltNets != null) { // count the nets int netCount = 0; for(int j=0; j<ltNets.size(); j++) { if (ltNets.isLeaf(j)) continue; LispTree scanLT = ltNets.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("net")) netCount++; } // create the nets primNP.netList = new FPGANet[netCount]; int index = 0; for(int j=0; j<ltNets.size(); j++) { if (ltNets.isLeaf(j)) continue; LispTree scanLT = ltNets.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("net")) { primNP.netList[index] = new FPGANet(); if (makePrimNet(primNP, scanLT, primNP, primNP.netList[index])) return true; index++; } } } // associate nets and ports for(int k=0; k<primNP.numPorts(); k++) { FPGAPort fp = primNP.portList[k]; for(int i=0; i<primNP.numNets(); i++) { boolean found = false; for(int j=0; j<primNP.netList[i].segFrom.length; j++) { if ((primNP.netList[i].segFrom[j].getX() == fp.posX && primNP.netList[i].segFrom[j].getY() == fp.posY) || (primNP.netList[i].segTo[j].getX() == fp.posX && primNP.netList[i].segTo[j].getY() == fp.posY)) { fp.con = i; found = true; break; } } if (found) break; } } // create the ports on the primitive PrimitivePort [] ports = new PrimitivePort[primNP.numPorts()]; for(int i=0; i<primNP.numPorts(); i++) { FPGAPort fp = primNP.portList[i]; fp.pp = PrimitivePort.newInstance(this, primNP, new ArcProto [] {wireArc}, fp.name, 0,180, fp.con, fp.characteristic,EdgeH.fromCenter(fp.posX), EdgeV.fromCenter(fp.posY), EdgeH.fromCenter(fp.posX), EdgeV.fromCenter(fp.posY)); ports[i] = fp.pp; } primNP.addPrimitivePorts(ports); // get pips if (ltComponents != null) { // count the pips int pipCount = 0; for(int j=0; j<ltComponents.size(); j++) { if (ltComponents.isLeaf(j)) continue; LispTree scanLT = ltComponents.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("pip")) pipCount++; } // create the pips primNP.pipList = new FPGAPip[pipCount]; int i = 0; for(int j=0; j<ltComponents.size(); j++) { if (ltComponents.isLeaf(j)) continue; LispTree scanLT = ltComponents.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("pip")) { primNP.pipList[i] = new FPGAPip(); if (makePrimPip(primNP, scanLT, primNP, primNP.pipList[i])) return true; i++; } } } return false; } /** * Method to add a port to primitive "np" from the tree in "lt" and * store information about it in the local structure "fp". * Tree has "(port...)" structure. Returns true on error. */ private static boolean makePrimPort(PrimitiveNode np, LispTree lt, FPGAPort fp, int net) { // look for keywords LispTree ltName = null, ltPosition = null, ltDirection = null; for(int j=0; j<lt.size(); j++) { if (lt.isLeaf(j)) continue; LispTree scanLT = lt.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("name")) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -