📄 getnetlist.java
字号:
{ case SPECIALCELL: return ntp.ports; case COMPLEXCELL: for (port = ntp.ports; port != null; port = port.next) { if (((SCPort)port.port).name.equalsIgnoreCase(name)) break; } break; case LEAFCELL: for (port = ntp.ports; port != null; port = port.next) { Export pp = (Export)port.port; if (pp.getName().equalsIgnoreCase(name)) break; } break; } return port; } /** * Method to add a connection count for the two node instances indicated. */ private void conList(SCNiTree ntpA, SCNiPort portA, SCNiTree ntpB, SCNiPort portB) { // add connection to instance A ConList cl = new ConList(); cl.portA = portA; cl.nodeB = ntpB; cl.portB = portB; cl.extNode = null; // add to head of the list cl.next = ntpA.connect; ntpA.connect = cl; // add connection to instance B cl = new ConList(); cl.portA = portB; cl.nodeB = ntpA; cl.portB = portA; cl.extNode = null; // add to head of the list cl.next = ntpB.connect; ntpB.connect = cl; } /**************************************** NETLIST READING: THE EXPORT KEYWORD ****************************************/ private String export(List<String> keywords) { // check to see if working in a cell if (curSCCell == null) return "No cell selected"; // search current cell for node if (keywords.size() <= 1) return "No instance specified for EXPORT command"; String instName = keywords.get(1); SCNiTree nPtr = findNi(curSCCell, instName); if (nPtr == null) return "Cannot find instance '" + instName + "' for EXPORT command"; // search for port if (keywords.size() <= 2) return "No port specified for EXPORT command"; String portName = keywords.get(2); SCNiPort port = findPp(nPtr, portName); if (port == null) return "Cannot find port '" + portName + "' on instance '" + instName + "' for EXPORT command"; // check for export name if (keywords.size() <= 3) return "No export name specified for EXPORT command"; String exportName = keywords.get(3); // check possible port type int type = UNPORT; if (keywords.size() >= 5) { String typeName = keywords.get(4); if (typeName.equalsIgnoreCase("input")) { type = INPORT; } else if (typeName.equalsIgnoreCase("output")) { type = OUTPORT; } else if (typeName.equalsIgnoreCase("bidirectional")) { type = BIDIRPORT; } else { return "Unknown port type '" + typeName + "' for EXPORT command"; } } // create special node SCNiTree searchNPtr = findNi(curSCCell, exportName); if (searchNPtr != null) return "Export name '" + exportName + "' is not unique"; SCNiTree newNPtr = new SCNiTree(exportName, SPECIALCELL); curSCCell.niList.add(newNPtr); newNPtr.number = curSCCell.maxNodeNum++; searchNPtr = newNPtr; SCNiPort niPort = new SCNiPort(); niPort.port = null; niPort.extNode = null; niPort.next = null; newNPtr.ports = niPort; // add to export port list SCPort newPort = new SCPort(); niPort.port = newPort; newPort.name = exportName; newPort.node = newNPtr; newPort.parent = curSCCell; newPort.bits = type; newPort.next = null; if (curSCCell.lastPort == null) { curSCCell.ports = curSCCell.lastPort = newPort; } else { curSCCell.lastPort.next = newPort; curSCCell.lastPort = newPort; } // add to connect list conList(nPtr, port, newNPtr, niPort); return null; } /**************************************** NETLIST READING: THE SET KEYWORD ****************************************/ /** * Method to handle the "SET" keyword. * Current options are: * 1. leaf-cell-numbers = Magic numbers for leaf cells. * 2. node-name = Name an extracted node. * 3. port-direction = Direction allowed to attach to a port. */ private String xSet(List<String> keywords) { if (keywords.size() <= 1) return "No option for SET command"; String whatToSet = keywords.get(1); if (whatToSet.equalsIgnoreCase("leaf-cell-numbers")) { String cellName = keywords.get(2); Cell leafCell = findLeafCell(cellName); if (leafCell == null) return "Cannot find cell '" + cellName + "'"; SCCellNums cNums = getLeafCellNums(leafCell); int numPar = 3; while (numPar < keywords.size()) { String parName = keywords.get(numPar); if (parName.equalsIgnoreCase("top-active")) { numPar++; if (numPar < keywords.size()) cNums.topActive = TextUtils.atoi(keywords.get(numPar++)); continue; } if (parName.equalsIgnoreCase("bottom-active")) { numPar++; if (numPar < keywords.size()) cNums.bottomActive = TextUtils.atoi(keywords.get(numPar++)); continue; } if (parName.equalsIgnoreCase("left-active")) { numPar++; if (numPar < keywords.size()) cNums.leftActive = TextUtils.atoi(keywords.get(numPar++)); continue; } if (parName.equalsIgnoreCase("right-active")) { numPar++; if (numPar < keywords.size()) cNums.rightActive = TextUtils.atoi(keywords.get(numPar++)); continue; } return "Unknown option '" + parName + "' for SET LEAF-CELL-NUMBERS command"; } setLeafCellNums(leafCell, cNums); return null; } if (whatToSet.equalsIgnoreCase("node-name")) { // check for sufficient parameters if (keywords.size() <= 4) return "Insufficent parameters for SET NODE-NAME command"; // search for instance String instName = keywords.get(2); SCNiTree instPtr = findNi(curSCCell, instName); if (instPtr == null) return "Cannot find instance '" + instName + "' in SET NODE-NAME command"; // search for port on instance String portName = keywords.get(3); SCNiPort iPort; for (iPort = instPtr.ports; iPort != null; iPort = iPort.next) { if (instPtr.type == LEAFCELL) { Export e = (Export)iPort.port; if (e.getName().equalsIgnoreCase(portName)) break; } else if (instPtr.type == COMPLEXCELL) { SCPort scp = (SCPort)iPort.port; if (scp.name.equalsIgnoreCase(portName)) break; } } if (iPort == null) return "Cannot find port '" + portName + "' on instance '" + instName + "' in SET NODE-NAME command"; // set extracted node name if possible if (iPort.extNode == null) return "Cannot find extracted node to set name in SET NODE-NAME command"; iPort.extNode.name = keywords.get(4); return null; } if (whatToSet.equalsIgnoreCase("port-direction")) { String cellName = keywords.get(2); String portName = keywords.get(3); SCCell cell; for (cell = scCells; cell != null; cell = cell.next) { if (cell.name.equalsIgnoreCase(cellName)) break; } int bits = 0; if (cell == null) { Cell leafCell = findLeafCell(cellName); if (leafCell == null) return "Cannot find cell '" + cellName + "'"; Export leafPort = leafCell.findExport(portName); if (leafPort == null) return "Cannot find port '" + portName + "' on cell '" + cellName + "'"; } else { SCPort port; for (port = cell.ports; port != null; port = port.next) { if (port.name.equalsIgnoreCase(portName)) break; } if (port == null) return "Cannot find port '" + portName + "' on cell '" + cellName + "'"; bits = port.bits; } bits &= ~PORTDIRMASK; String dir = keywords.get(4); for(int i=0; i<dir.length(); i++) { char dirCh = dir.charAt(i); switch (dirCh) { case 'u': bits |= PORTDIRUP; break; case 'd': bits |= PORTDIRDOWN; break; case 'r': bits |= PORTDIRRIGHT; break; case 'l': bits |= PORTDIRLEFT; break; default: return "Unknown port direction specifier '" + dir + "'"; } } return null; } return "Unknown option '" + whatToSet+ "' for SET command"; } /** * Method to fill in the cell_nums structure for the indicated leaf cell. */ static SCCellNums getLeafCellNums(Cell leafCell) { SCCellNums sNums = new SCCellNums();// // check if variable exits// var = getvalkey((INTBIG)leafCell, VNODEPROTO, VINTEGER|VISARRAY, sc_numskey);// if (var != NOVARIABLE)// {// iarray = (int *)nums;// i = sizeof(SCCellNums) / sizeof(int);// iarray = (int *)nums;// jarray = (int *)var->addr;// for (j = 0; j < i; j++) iarray[j] = jarray[j];// } return sNums; } /** * Method to set the cell_nums variable for the indicated leaf cell. */ static void setLeafCellNums(Cell leafCell, SCCellNums nums) {// VARIABLE *var;// int i, j, *iarray;// INTBIG *jarray;//// i = sizeof(SCCellNums) / sizeof(int);//// // check if variable exits// var = getvalkey((INTBIG)leafCell, VNODEPROTO, VINTEGER|VISARRAY, sc_numskey);// if (var == NOVARIABLE)// {// if ((jarray = emalloc((i + 1) * sizeof(INTBIG), sc_tool->cluster)) == 0)// return(Sc_seterrmsg(SC_NOMEMORY));// iarray = (int *)nums;// for (j = 0; j < i; j++) jarray[j] = iarray[j];// jarray[j] = -1;// if (setvalkey((INTBIG)leafCell, VNODEPROTO, sc_numskey, (INTBIG)jarray,// VINTEGER | VISARRAY) == NOVARIABLE)// return(Sc_seterrmsg(SC_NOSET_CELL_NUMS));// return(SC_NOERROR);// }// iarray = (int *)nums;// jarray = (INTBIG *)var->addr;// for (j = 0; j < i; j++) jarray[j] = iarray[j];// return(SC_NOERROR); } /** * Method to find the named cell. * Looks in the main cell library, too. */ private Cell findLeafCell(String name) { NodeProto np = Cell.findNodeProto(name); if (!(np instanceof Cell)) np = null; Cell cell = (Cell)np; Library lib = Library.findLibrary(SilComp.SCLIBNAME); if (cell == null && lib != null) { cell = lib.findNodeProto(name); if (cell == null) return null; } if (cell != null) { Cell layCell = cell.otherView(View.LAYOUT); if (layCell != null) cell = layCell; } return cell; } /**************************************** NETLIST READING: THE EXTRACT KEYWORD ****************************************/ /** * Method to extract the node netlist for a given cell. */ private String extract(List keywords) { if (curSCCell == null) return "No cell selected"; extractClearFlag(curSCCell); curSCCell.exNodes = null; extractFindNodes(curSCCell); // get ground nodes curSCCell.ground = new ExtNode(); curSCCell.ground.name = "ground"; curSCCell.ground.flags = 0; curSCCell.ground.ptr = null; curSCCell.ground.firstPort = null; curSCCell.ground.next = null; ExtNode oldNList = curSCCell.exNodes; for (ExtNode nList = curSCCell.exNodes; nList != null; nList = nList.next) { ExtPort oldPList = nList.firstPort; ExtPort pList; for (pList = nList.firstPort; pList != null; pList = pList.next) { if (pList.node.number == GND) { curSCCell.ground.firstPort = nList.firstPort; if (oldNList == nList) { curSCCell.exNodes = nList.next; } else { oldNList.next = nList.next; } if (oldPList == pList) { curSCCell.ground.firstPort = pList.next; } else { oldPList.next = pList.next; } break; } oldPList = pList; } if (pList != null) break; oldNList = nList; } for (ExtPort pList = curSCCell.ground.firstPort; pList != null; pList = pList.next) pList.port.extNode = curSCCell.ground; // get power nodes curSCCell.power = new ExtNode(); curSCCell.power.name = "power"; curSCCell.power.flags = 0; curSCCell.power.ptr = null; curSCCell.power.firstPort = null; curSCCell.power.next = null; oldNList = curSCCell.exNodes; for (ExtNode nList = curSCCell.exNodes; nList != null; nList = nList.next) { ExtPort oldPList = nList.firstPort; ExtPort pList; for (pList = nList.firstPort; pList != null; pList = pList.next) { if (pList.node.number == PWR) { curSCCell.power.firstPort = nList.firstPort; if (oldNList == nList) { curSCCell.exNodes = nList.next; } else { oldNList.next = nList.next; } if (oldPList == pList) { curSCCell.power.firstPort = pList.next; } else { oldPList.next = pList.next; } break; } oldPList = pList; } if (pList != null) break; oldNList = nList; } for (ExtPort pList = curSCCell.power.firstPort; pList != null; pList = pList.next) pList.port.extNode = curSCCell.power; extractFindPower(curSCCell, curSCCell); extractCollectUnconnected(curSCCell); // give the names of the cell ports to the extracted node for (SCPort port = curSCCell.ports; port != null; port = port.next) { switch (port.bits & PORTTYPE) { case PWRPORT: case GNDPORT: break; default: // Note that special nodes only have one niport port.node.ports.extNode.name = port.name; break; } } // give arbitrary names to unnamed extracted nodes int nodenum = 2; for (ExtNode ext = curSCCell.exNodes; ext != null; ext = ext.next) { if (ext.name == null) ext.name = "n" + (nodenum++); } return null; } /** * Method to clear the extract pointer on all node instance ports. */ private void extractClearFlag(SCCell cell) { for (SCNiTree ntp : cell.niList) { ntp.flags &= Place.BITS_EXTRACT; for (SCNiPort port = ntp.ports; port != null; port = port.next) port.extNode = null; } } /** * Method to go though the INSTANCE list, finding all resultant connections. */ private void extractFindNodes(SCCell cell) { for (SCNiTree niTree : cell.niList) { niTree.flags |= Place.BITS_EXTRACT; for (ConList cl = niTree.connect; cl != null; cl = cl.next) { extractSnake(niTree, cl.portA, cl); } } } /** * Method to snake through connection list extracting common connections. */ private void extractSnake(SCNiTree nodeA, SCNiPort portA, ConList cl) { for ( ; cl != null; cl = cl.next) { if (cl.portA != portA) continue; if (portA != null && portA.extNode != null) { if (!(cl.portB != null && cl.portB.extNode != null)) { extractAddNode(portA.extNode, cl.nodeB, cl.portB); if ((cl.nodeB.flags & Place.BITS_EXTRACT) == 0) { cl.nodeB.flags |= Place.BITS_EXTRACT; extractSnake(cl.nodeB, cl.portB, cl.nodeB.connect); cl.nodeB.flags ^= Place.BITS_EXTRACT; } } } else { if (cl.portB != null && cl.portB.extNode != null) { extractAddNode(cl.portB.extNode, nodeA, portA); } else { ExtNode common = extractAddNode(null, nodeA, portA); common = extractAddNode(common, cl.nodeB, cl.portB); if ((cl.nodeB.flags & Place.BITS_EXTRACT) == 0) { cl.nodeB.flags |= Place.BITS_EXTRACT; extractSnake(cl.nodeB, cl.portB, cl.nodeB.connect); cl.nodeB.flags ^= Place.BITS_EXTRACT; } } } } } /** * Method to add a node and port to a ExtNode list. * Modify the root if necessary. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -