📄 libtotech.java
字号:
// if ((us_tecflags&HASUNCONDRCM) != 0)// (void)setvalkey((INTBIG)tech, VTECHNOLOGY, dr_unconnected_distancesMkey,// (INTBIG)us_tecdrc_rules.unconlistM, VFRACT|VDONTSAVE|VISARRAY|(drcsize<<VLENGTHSH));// if ((us_tecflags&HASUNCONDRCMR) != 0)// (void)setvalkey((INTBIG)tech, VTECHNOLOGY, dr_unconnected_distancesM_rulekey,// (INTBIG)us_tecdrc_rules.unconlistMR, VSTRING|VDONTSAVE|VISARRAY|(drcsize<<VLENGTHSH));// if ((us_tecflags&HASEDGEDRC) != 0)// (void)setvalkey((INTBIG)tech, VTECHNOLOGY, dr_edge_distanceskey,// (INTBIG)us_tecdrc_rules.edgelist, VFRACT|VDONTSAVE|VISARRAY|(drcsize<<VLENGTHSH));// if ((us_tecflags&HASEDGEDRCR) != 0)// (void)setvalkey((INTBIG)tech, VTECHNOLOGY, dr_edge_distances_rulekey,// (INTBIG)us_tecdrc_rules.edgelistR, VSTRING|VDONTSAVE|VISARRAY|(drcsize<<VLENGTHSH));// if ((us_tecflags&HASMINNODE) != 0)// (void)setvalkey((INTBIG)tech, VTECHNOLOGY, dr_min_node_sizekey,// (INTBIG)us_tecdrc_rules.minnodesize, VFRACT|VDONTSAVE|VISARRAY|((us_tecdrc_rules.numnodes*2)<<VLENGTHSH));// if ((us_tecflags&HASMINNODER) != 0)// (void)setvalkey((INTBIG)tech, VTECHNOLOGY, dr_min_node_size_rulekey,// (INTBIG)us_tecdrc_rules.minnodesizeR, VSTRING|VDONTSAVE|VISARRAY|(us_tecdrc_rules.numnodes<<VLENGTHSH)); return lis; } /************************************* ARC ANALYSIS *************************************/ /** * Method to scan the "dependentlibcount" libraries in "dependentLibs", * and build the arc structures for it in technology "tech". Returns true on error. */ private ArcInfo [] extractArcs(Library [] dependentLibs, LayerInfo [] lList) { // count the number of arcs in the technology Cell [] arcCells = Info.findCellSequence(dependentLibs, "arc-", Info.ARCSEQUENCE_KEY); if (arcCells.length <= 0) { System.out.println("No arcs found"); return null; } ArcInfo [] allArcs = new ArcInfo[arcCells.length]; for(int i=0; i<arcCells.length; i++) { Cell np = arcCells[i]; allArcs[i] = ArcInfo.parseCell(np); // build a list of examples found in this arc List<Example> neList = Example.getExamples(np, false, error); if (neList == null) return null; if (neList.size() > 1) { error.markError(null, np, "Can only be one drawing of an arc, but more were found"); return null; } Example arcEx = neList.get(0); // sort the layers in the example Collections.sort(arcEx.samples, new SamplesByLayerOrder(lList)); // get width and polygon count information double hWid = -1; int count = 0; for(Sample ns : arcEx.samples) { double wid = Math.min(ns.node.getXSize(), ns.node.getYSize()); if (ns.layer == null) hWid = wid; else count++; } // error if there is no highlight box if (hWid < 0) { error.markError(null, np, "No highlight layer found"); return null; } allArcs[i].arcDetails = new ArcInfo.LayerDetails[count]; // fill the individual arc layer structures int layerIndex = 0; for(int k=0; k<2; k++) { for(Sample ns : arcEx.samples) { if (ns.layer == null) continue; // get the layer index String sampleLayer = ns.layer.getName().substring(6); LayerInfo li = null; for(int j=0; j<lList.length; j++) { if (sampleLayer.equals(lList[j].name)) { li = lList[j]; break; } } if (li == null) { error.markError(ns.node, np, "Unknown layer: " + sampleLayer); return null; } // only add transparent layers when k=0 if (k == 0) { if (li.desc.getTransparentLayer() == 0) continue; } else { if (li.desc.getTransparentLayer() != 0) continue; } allArcs[i].arcDetails[layerIndex] = new ArcInfo.LayerDetails(); allArcs[i].arcDetails[layerIndex].layer = li; // determine the style of this arc layer Poly.Type style = Poly.Type.CLOSED; if (ns.node.getProto() == Artwork.tech().filledBoxNode) style = Poly.Type.FILLED; allArcs[i].arcDetails[layerIndex].style = style; // determine the width offset of this arc layer double wid = Math.min(ns.node.getXSize(), ns.node.getYSize()); allArcs[i].arcDetails[layerIndex].width = wid; layerIndex++; } } } return allArcs; } /************************************* NODE ANALYSIS *************************************/ /** * Method to scan the "dependentlibcount" libraries in "dependentLibs", * and build the node structures for it in technology "tech". Returns true on error. */ private NodeInfo [] extractNodes(Library [] dependentLibs, LayerInfo [] lList, ArcInfo [] aList) { Cell [] nodeCells = Info.findCellSequence(dependentLibs, "node-", Info.NODESEQUENCE_KEY); if (nodeCells.length <= 0) { System.out.println("No nodes found"); return null; } NodeInfo [] nList = new NodeInfo[nodeCells.length]; // get the nodes int nodeIndex = 0; for(int pass=0; pass<3; pass++) for(int m=0; m<nodeCells.length; m++) { // make sure this is the right type of node for this pass of the nodes Cell np = nodeCells[m]; NodeInfo nIn = NodeInfo.parseCell(np); Netlist netList = np.acquireUserNetlist(); if (netList == null) { System.out.println("Sorry, a deadlock technology generation (network information unavailable). Please try again"); return null; } // only want pins on pass 0, pure-layer nodes on pass 2 if (pass == 0 && nIn.func != PrimitiveNode.Function.PIN) continue; if (pass == 1 && (nIn.func == PrimitiveNode.Function.PIN || nIn.func == PrimitiveNode.Function.NODE)) continue; if (pass == 2 && nIn.func != PrimitiveNode.Function.NODE) continue; if (nIn.func == PrimitiveNode.Function.NODE) { if (nIn.serp) { error.markError(null, np, "Pure layer " + nIn.name + " can not be serpentine"); return null; } nIn.specialType = PrimitiveNode.POLYGONAL; } nList[nodeIndex] = nIn; nIn.name = np.getName().substring(5); // build a list of examples found in this node List<Example> neList = Example.getExamples(np, true, error); if (neList == null || neList.size() == 0) { System.out.println("Cannot analyze " + np); return null; } Example firstEx = neList.get(0); nIn.xSize = firstEx.hx - firstEx.lx; nIn.ySize = firstEx.hy - firstEx.ly; // sort the layers in the main example Collections.sort(firstEx.samples, new SamplesByLayerOrder(lList)); // associate the samples in each example if (associateExamples(neList, np)) return null; // derive primitives from the examples nIn.nodeLayers = makePrimitiveNodeLayers(neList, np, lList); if (nIn.nodeLayers == null) return null; // count the number of ports on this node int portCount = 0; for(Sample ns : firstEx.samples) { if (ns.layer == Generic.tech().portNode) portCount++; } if (portCount == 0) { error.markError(null, np, "No ports found"); return null; } // fill the port structures List<NodeInfo.PortDetails> ports = new ArrayList<NodeInfo.PortDetails>(); Map<NodeInfo.PortDetails,Sample> portSamples = new HashMap<NodeInfo.PortDetails,Sample>(); for(Sample ns : firstEx.samples) { if (ns.layer != Generic.tech().portNode) continue; // port connections NodeInfo.PortDetails nipd = new NodeInfo.PortDetails(); portSamples.put(nipd, ns); // port name nipd.name = Info.getPortName(ns.node); if (nipd.name == null) { error.markError(ns.node, np, "Port does not have a name"); return null; } for(int c=0; c<nipd.name.length(); c++) { char str = nipd.name.charAt(c); if (str <= ' ' || str >= 0177) { error.markError(ns.node, np, "Invalid port name"); return null; } } // port angle and range nipd.angle = 0; Variable varAngle = ns.node.getVar(Info.PORTANGLE_KEY); if (varAngle != null) nipd.angle = ((Integer)varAngle.getObject()).intValue(); nipd.range = 180; Variable varRange = ns.node.getVar(Info.PORTRANGE_KEY); if (varRange != null) nipd.range = ((Integer)varRange.getObject()).intValue(); // port area rule nipd.values = ns.values; ports.add(nipd); } // sort the ports by name within angle Collections.sort(ports, new PortsByAngleAndName()); // now find the poly/active ports for transistor rearranging int pol1Port = -1, pol2Port = -1, dif1Port = -1, dif2Port = -1; for(int i=0; i<ports.size(); i++) { NodeInfo.PortDetails nipd = ports.get(i); Sample ns = portSamples.get(nipd); nipd.connections = new ArcInfo[0]; Variable var = ns.node.getVar(Info.CONNECTION_KEY); if (var != null) { // convert "arc-CELL" pointers to indices CellId [] arcCells = (CellId [])var.getObject(); List<ArcInfo> validArcCells = new ArrayList<ArcInfo>(); for(int j=0; j<arcCells.length; j++) { // find arc that connects if (arcCells[j] == null) continue; Cell arcCell = EDatabase.serverDatabase().getCell(arcCells[j]); if (arcCell == null) continue; String cellName = arcCell.getName().substring(4); for(int k=0; k<aList.length; k++) { if (aList[k].name.equalsIgnoreCase(cellName)) { validArcCells.add(aList[k]); break; } } } ArcInfo [] connections = new ArcInfo[validArcCells.size()]; nipd.connections = connections; for(int j=0; j<validArcCells.size(); j++) connections[j] = validArcCells.get(j); for(int j=0; j<connections.length; j++) { // find port characteristics for possible transistors Variable meaningVar = ns.node.getVar(Info.PORTMEANING_KEY); int meaning = 0; if (meaningVar != null) meaning = ((Integer)meaningVar.getObject()).intValue(); if (connections[j].func.isPoly() || meaning == 1) { if (pol1Port < 0) { pol1Port = i; break; } else if (pol2Port < 0) { pol2Port = i; break; } } else if (connections[j].func.isDiffusion() || meaning == 2) { if (dif1Port < 0) { dif1Port = i; break; } else if (dif2Port < 0) { dif2Port = i; break; } } } } } // save the ports in an array nIn.nodePortDetails = new NodeInfo.PortDetails[ports.size()]; for(int j=0; j<ports.size(); j++) nIn.nodePortDetails[j] = ports.get(j); // establish port connectivity for(int i=0; i<nIn.nodePortDetails.length; i++) { NodeInfo.PortDetails nipd = nIn.nodePortDetails[i]; Sample ns = portSamples.get(nipd); nipd.netIndex = i; if (ns.node.hasConnections()) { ArcInst ai1 = ns.node.getConnections().next().getArc(); Network net1 = netList.getNetwork(ai1, 0); for(int j=0; j<i; j++) { NodeInfo.PortDetails onipd = nIn.nodePortDetails[j]; Sample oNs = portSamples.get(onipd); if (oNs.node.hasConnections()) { ArcInst ai2 = oNs.node.getConnections().next().getArc(); Network net2 = netList.getNetwork(ai2, 0); if (net1 == net2) { nipd.netIndex = j; break; } } } } } // on MOS transistors, make sure the first 4 ports are poly/active/poly/active if (nIn.func.isFET()) { if (pol1Port < 0 || pol2Port < 0 || dif1Port < 0 || dif2Port < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -