📄 fpga.java
字号:
ltName = scanLT; continue; } if (scanLT.keyword.equalsIgnoreCase("position")) { ltPosition = scanLT; continue; } if (scanLT.keyword.equalsIgnoreCase("direction")) { ltDirection = scanLT; continue; } } // validate if (ltName == null) { System.out.println("Port has no name (line " + lt.lineNumber + ")"); return true; } if (ltName.size() != 1 || ltName.isBranch(0)) { System.out.println("Port name must be a single atom (line " + ltName.lineNumber + ")"); return true; } fp.name = ltName.getLeaf(0); if (ltPosition == null) { System.out.println("Port has no position (line " + lt.lineNumber + ")"); return true; } if (ltPosition.size() != 2 || ltPosition.isBranch(0) || ltPosition.isBranch(1)) { System.out.println("Port position must be two atoms (line " + ltPosition.lineNumber + ")"); return true; } fp.posX = TextUtils.atof(ltPosition.getLeaf(0)) - np.getDefWidth()/2; fp.posY = TextUtils.atof(ltPosition.getLeaf(1)) - np.getDefHeight()/2; // determine directionality fp.characteristic = PortCharacteristic.UNKNOWN; if (ltDirection != null) { if (ltDirection.size() != 1 || ltDirection.isBranch(0)) { System.out.println("Port direction must be a single atom (line " + ltDirection.lineNumber + ")"); return true; } String dir = ltDirection.getLeaf(0); if (dir.equalsIgnoreCase("input")) fp.characteristic = PortCharacteristic.IN; else if (dir.equalsIgnoreCase("output")) fp.characteristic = PortCharacteristic.OUT; else if (dir.equalsIgnoreCase("bidir")) fp.characteristic = PortCharacteristic.BIDIR; else { System.out.println("Unknown port direction (line " + ltDirection.lineNumber + ")"); return true; } } fp.con = net; return false; } /** * Method to add a net to primitive "np" from the tree in "lt" and store information * about it in the local object "fNet". * Tree has "(net...)" structure. Returns true on error. */ private static boolean makePrimNet(PrimitiveNode np, LispTree lt, FPGANode fn, FPGANet fNet) { // scan for information in the tree fNet.name = null; int segCount = 0; Point2D [] seg = new Point2D[2]; for(int j=0; j<lt.size(); j++) { if (lt.isLeaf(j)) continue; LispTree scanLT = lt.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("name") && scanLT.size() == 1 && scanLT.isLeaf(0)) { if (fNet.name != null) { System.out.println("Multiple names for network (line " + lt.lineNumber + ")"); return true; } fNet.name = scanLT.getLeaf(0); continue; } if (scanLT.keyword.equalsIgnoreCase("segment")) { int pos = 0; for(int i=0; i<2; i++) { // get end of net segment if (scanLT.size() < pos+1) { System.out.println("Incomplete block net segment (line " + scanLT.lineNumber + ")"); return true; } if (scanLT.isBranch(pos)) { System.out.println("Must have atoms in block net segment (line " + scanLT.lineNumber + ")"); return true; } if (scanLT.getLeaf(pos).equalsIgnoreCase("coord")) { if (scanLT.size() < pos+3) { System.out.println("Incomplete block net segment (line " + scanLT.lineNumber + ")"); return true; } if (scanLT.isBranch(pos+1) || scanLT.isBranch(pos+2)) { System.out.println("Must have atoms in block net segment (line " + scanLT.lineNumber + ")"); return true; } double x = TextUtils.atof(scanLT.getLeaf(pos+1)) - np.getDefWidth()/2; double y = TextUtils.atof(scanLT.getLeaf(pos+2)) - np.getDefHeight()/2; seg[i] = new Point2D.Double(x, y); pos += 3; } else if (scanLT.getLeaf(pos).equalsIgnoreCase("port")) { if (scanLT.size() < pos+2) { System.out.println("Incomplete block net segment (line " + scanLT.lineNumber + ")"); return true; } if (scanLT.isBranch(pos+1)) { System.out.println("Must have atoms in block net segment (line " + scanLT.lineNumber + ")"); return true; } // find port int found = -1; for(int k=0; k<fn.numPorts(); k++) { if (fn.portList[k].name.equalsIgnoreCase(scanLT.getLeaf(pos+1))) { found = k; break; } } if (found < 0) { System.out.println("Unknown port on primitive net segment (line " + scanLT.lineNumber + ")"); return true; } double x = fn.portList[found].posX; double y = fn.portList[found].posY; seg[i] = new Point2D.Double(x, y); pos += 2; } else { System.out.println("Unknown keyword '" + scanLT.getLeaf(pos) + "' in block net segment (line " + scanLT.lineNumber + ")"); return true; } } Point2D [] newFrom = new Point2D[segCount+1]; Point2D [] newTo = new Point2D[segCount+1]; for(int i=0; i<segCount; i++) { newFrom[i] = fNet.segFrom[i]; newTo[i] = fNet.segTo[i]; } newFrom[segCount] = seg[0]; newTo[segCount] = seg[1]; fNet.segFrom = newFrom; fNet.segTo = newTo; segCount++; continue; } } return false; } /** * Method to add a pip to primitive "np" from the tree in "lt" and save * information about it in the local object "fpip". * Tree has "(pip...)" structure. Returns true on error. */ private static boolean makePrimPip(PrimitiveNode np, LispTree lt, FPGANode fn, FPGAPip fPip) { // scan for information in this FPGAPIP object fPip.name = null; fPip.con1 = fPip.con2 = -1; for(int j=0; j<lt.size(); j++) { if (lt.isLeaf(j)) continue; LispTree scanLT = lt.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("name") && scanLT.size() == 1 && scanLT.isLeaf(0)) { if (fPip.name != null) { System.out.println("Multiple names for pip (line " + lt.lineNumber + ")"); return true; } fPip.name = scanLT.getLeaf(0); continue; } if (scanLT.keyword.equalsIgnoreCase("position") && scanLT.size() == 2 && scanLT.isLeaf(0) && scanLT.isLeaf(1)) { fPip.posX = TextUtils.atof(scanLT.getLeaf(0)) - np.getDefWidth()/2; fPip.posY = TextUtils.atof(scanLT.getLeaf(1)) - np.getDefHeight()/2; continue; } if (scanLT.keyword.equalsIgnoreCase("connectivity") && scanLT.size() == 2 && scanLT.isLeaf(0) && scanLT.isLeaf(1)) { for(int i=0; i<fn.numNets(); i++) { if (fn.netList[i].name.equalsIgnoreCase(scanLT.getLeaf(0))) fPip.con1 = i; if (fn.netList[i].name.equalsIgnoreCase(scanLT.getLeaf(1))) fPip.con2 = i; } continue; } } return false; } /******************** ARCHITECTURE PARSING: LAYOUT ********************/ /** * Method to scan the entire tree for block definitions and create them. */ private Cell placePrimitives(LispTree lt) { // look through top level for the "blockdef"s Cell topLevel = null; for(int i=0; i<lt.size(); i++) { if (lt.isLeaf(i)) continue; LispTree subLT = lt.getBranch(i); if (!subLT.keyword.equalsIgnoreCase("blockdef") && !subLT.keyword.equalsIgnoreCase("architecture")) continue; // create the primitive Cell np = makeCell(subLT); if (np == null) return null; if (subLT.keyword.equalsIgnoreCase("architecture")) topLevel = np; } return topLevel; } /** * Method to create a cell from a subtree "lt". * Tree has "(blockdef...)" or "(architecture...)" structure. * Returns nonzero on error. */ private Cell makeCell(LispTree lt) { // find all of the pieces of this block LispTree ltAttribute = null, ltNets = null, ltPorts = null, ltComponents = 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 block (line " + lt.lineNumber + ")"); return null; } ltAttribute = scanLT; continue; } if (scanLT.keyword.equalsIgnoreCase("nets")) { if (ltNets != null) { System.out.println("Multiple 'nets' sections for a block (line " + lt.lineNumber + ")"); return null; } ltNets = scanLT; continue; } if (scanLT.keyword.equalsIgnoreCase("ports")) { if (ltPorts != null) { System.out.println("Multiple 'ports' sections for a block (line " + lt.lineNumber + ")"); return null; } ltPorts = scanLT; continue; } if (scanLT.keyword.equalsIgnoreCase("components")) { if (ltComponents != null) { System.out.println("Multiple 'components' sections for a block (line " + lt.lineNumber + ")"); return null; } ltComponents = scanLT; continue; } } // scan the attributes section if (ltAttribute == null) { System.out.println("Missing 'attributes' sections on a block (line " + lt.lineNumber + ")"); return null; } String blockName = null; boolean gotSize = false; double sizeX = 0, sizeY = 0; for(int j=0; j<ltAttribute.size(); j++) { if (ltAttribute.isLeaf(j)) continue; LispTree scanLT = ltAttribute.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("name")) { if (scanLT.size() != 1 || scanLT.isBranch(0)) { System.out.println("Block 'name' attribute should take a single atomic parameter (line " + scanLT.lineNumber + ")"); return null; } blockName = scanLT.getLeaf(0); continue; } if (scanLT.keyword.equalsIgnoreCase("size") && scanLT.size() == 2 && scanLT.isLeaf(0) && scanLT.isLeaf(1)) { gotSize = true; sizeX = TextUtils.atof(scanLT.getLeaf(0)); sizeY = TextUtils.atof(scanLT.getLeaf(1)); continue; } } // validate if (blockName == null) { System.out.println("Missing 'name' attribute in block definition (line " + ltAttribute.lineNumber + ")"); return null; } // make the cell Cell cell = Cell.newInstance(Library.getCurrent(), blockName); if (cell == null) return null; System.out.println("Creating cell '" + blockName + "'"); // force size by placing pins in the corners if (gotSize) { NodeInst.makeInstance(wirePinNode, new Point2D.Double(0.5, 0.5), 1, 1, cell); NodeInst.makeInstance(wirePinNode, new Point2D.Double(sizeX-0.5, 0.5), 1, 1, cell); NodeInst.makeInstance(wirePinNode, new Point2D.Double(0.5, sizeY-0.5), 1, 1, cell); NodeInst.makeInstance(wirePinNode, new Point2D.Double(sizeX-0.5, sizeY-0.5), 1, 1, cell); } // add any unrecognized attributes for(int j=0; j<ltAttribute.size(); j++) { if (ltAttribute.isLeaf(j)) continue; LispTree scanLT = ltAttribute.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("name")) continue; if (scanLT.keyword.equalsIgnoreCase("size")) continue; if (scanLT.size() != 1 || scanLT.isBranch(0)) { System.out.println("Attribute '" + scanLT.keyword + "' attribute should take a single atomic parameter (line " + scanLT.lineNumber + ")"); return null; } cell.newVar(scanLT.keyword, scanLT.getLeaf(0)); } // place block components if (ltComponents != null) { for(int j=0; j<ltComponents.size(); j++) { if (ltComponents.isLeaf(j)) continue; LispTree scanLT = ltComponents.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("repeater")) { if (makeBlockRepeater(cell, scanLT)) return null; continue; } if (scanLT.keyword.equalsIgnoreCase("instance")) { if (makeBlockInstance(cell, scanLT)) return null; continue; } } } // place block ports if (ltPorts != null) { for(int j=0; j<ltPorts.size(); j++) { if (ltPorts.isLeaf(j)) continue; LispTree scanLT = ltPorts.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("port")) { if (makeBlockPort(cell, scanLT)) return null; } } } // place block nets if (ltNets != null) { // read the block nets for(int j=0; j<ltNets.size(); j++) { if (ltNets.isLeaf(j)) continue; LispTree scanLT = ltNets.getBranch(j); if (scanLT.keyword.equalsIgnoreCase("net")) { if (makeBlockNet(cell, scanLT)) return null; } } } return cell; } /** * Method to place an instance in cell "cell" from the LISPTREE in "lt". * Tree has "(instance...)" structure. Returns true on error. */ private boolean makeBlockInstance(Cell cell, LispTree lt) { // scan for information in this block instance object
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -