📄 schemtolay.java
字号:
StdCellParams stdCell, Cell gasp) { for (int i=0; i<segs.size(); i++) { RouteSeg r = segs.get(i); if (exports==r.hasExports()) connectSegment(r, trackAlloc, stdCell, gasp); } }// // find the sums of the lengths of all routing segments// private static double estimateWireLength(ArrayList<RouteSeg> routeSegs) {// double len = 0;// for (int i=0; i<routeSegs.size(); i++) {// len += routeSegs.get(i).estimateLength();// }// return len;// } private static void buildPlacerNetlist(Placer placer, ArrayList<NodeInst> insts, ArrayList<RouteSeg> routeSegs) { // create Placer instances HashMap<PortInst,Placer.Port> portToPlacerPort = new HashMap<PortInst,Placer.Port>(); for (int i=0; i<insts.size(); i++) { NodeInst inst = insts.get(i); //inst.alterShape(1, 1, 0, 0, 0); int type; if (isNstk(inst)) type=Placer.N; else if (isPstk(inst)) type=Placer.P; else type=Placer.PN; double w = inst.getBounds().getWidth(); Placer.Inst plInst = placer.addInst(type, w, inst); Iterator<PortInst> it = inst.getPortInsts(); while (it.hasNext()) { PortInst port = it.next(); double x = LayoutLib.roundCenterX(port); double y = LayoutLib.roundCenterY(port); Placer.Port plPort = plInst.addPort(x, y); portToPlacerPort.put(port, plPort); } } // create Placer nets for (int i=0; i<routeSegs.size(); i++) { RouteSeg seg = routeSegs.get(i); Placer.Net plNet = placer.addNet(); ArrayList<PortInst> ports = seg.getAllPorts(); for (int j=0; j<ports.size(); j++) { PortInst port = ports.get(j); Placer.Port plPort = portToPlacerPort.get(port); error(plPort==null, "can't find placer port"); plNet.addPort(plPort); } } } // try again using data structures built just for placement private static ArrayList<NodeInst> place(ArrayList<NodeInst> insts, ArrayList<RouteSeg> routeSegs, StdCellParams stdCell, Cell gasp) { //long sT = System.currentTimeMillis(); Placer placer = new Placer(stdCell, gasp); buildPlacerNetlist(placer, insts, routeSegs); ArrayList<NodeInst> ans = placer.place1row(); //long eT = System.currentTimeMillis(); //double seconds = (eT-sT)/1000.0; //System.out.println("Placement took: "+seconds+" seconds"); return ans; } private static void connectWellTies(ArrayList<NodeInst> layInsts, StdCellParams stdCell, Cell gasp) { TechType tech = stdCell.getTechType(); if (stdCell.getSeparateWellTies()) { // Rock connects well ties to exports rather than to vdd or gnd TrackRouter nTie = new TrackRouterH(tech.m2(), stdCell.getNmosWellTieWidth(), stdCell.getNmosWellTieY(), tech, gasp); LayoutLib.newExport(gasp, stdCell.getNmosWellTieName(), stdCell.getNmosWellTieRole(), tech.m2(), 4, // m1_m1_sp/2 stdCell.getNmosWellTieWidth()/2 + 1.5, stdCell.getNmosWellTieY()); nTie.connect(gasp.findExport(stdCell.getNmosWellTieName())); nTie.connect(layInsts, stdCell.getNmosWellTieName()); TrackRouter pTie = new TrackRouterH(tech.m2(), stdCell.getPmosWellTieWidth(), stdCell.getPmosWellTieY(), tech, gasp); LayoutLib.newExport(gasp, stdCell.getPmosWellTieName(), stdCell.getPmosWellTieRole(), tech.m2(), 4, // m1_m1_sp/2 stdCell.getPmosWellTieWidth()/2 + 1.5, stdCell.getPmosWellTieY()); pTie.connect(gasp.findExport(stdCell.getPmosWellTieName())); pTie.connect(layInsts, stdCell.getPmosWellTieName()); } } /* private static ArrayList wireEquivPortsList() { ArrayList equivPortsLists = new ArrayList(); // search all libraries for the wire icon Iterator it = Electric.getLibraries(); while (it.hasNext()) { Library lib = it.next(); Cell wireIcon = lib.findCell("wire{ic}"); if (wireIcon==null) continue; PortProto a = wireIcon.findPort("a"); if (a==null) continue; PortProto b = wireIcon.findPort("b"); if (b==null) continue; // Well, it's got the right type, name, and port names. I might // as well treat it like a wire icon. ArrayList equivPortsList = new ArrayList(); equivPortsList.add(a); equivPortsList.add(b); equivPortsLists.add(equivPortsList); } return equivPortsLists; } */ // Remove from instance name first open bracket and everything // following it. private static String stripBusNotation(String instNm) { int openBrack = instNm.indexOf("["); return (openBrack>=0) ? instNm.substring(0,openBrack) : instNm; } private static void instPath1(StringBuffer path, VarContext context) { Nodable ni = context.getNodable(); if (ni==null) return; instPath1(path, context.pop()); String me = ni.getName(); error(me==null, "instance in VarContext with no name!!!"); String noBus = stripBusNotation(me); path.append("/"+noBus); } private static String instPath(VarContext context) { StringBuffer path = new StringBuffer(); instPath1(path, context); return path.toString(); } private static PortInst findFirstPort(ArrayList<NodeInst> layInsts, String nm) { for (int i=0; i<layInsts.size(); i++) { NodeInst pi = layInsts.get(i); PortInst port = pi.findPortInst(nm); if (port!=null) return port; } error(true, "no NodeInst with port found: "+nm); return null; } // Create the name of the new layout Cell by appending the instance // path to the schematic facet name. private static String layoutCellName(Cell schematic, VarContext context) { // get the name of the schematic (without the "{sch}" suffix) String schemNm = schematic.getName(); int sfxPos = schemNm.indexOf("{sch}"); error(sfxPos==-1, "SchemToLay: no {sch} suffix on Cell schematic name?"); schemNm = schemNm.substring(0, sfxPos); return schemNm + "__" + instPath(context) + "{lay}"; } private static void blockAssignedTracks(TrackAllocator trackAlloc, ArrayList<RouteSeg> routeSegs, StdCellParams stdCell) { for (int i=0; i<routeSegs.size(); i++) { RouteSeg r = routeSegs.get(i); if (r.hasExpTrk()) { trackAlloc.occupyTrack(r, stdCell.getPhysTrackY(r.getExpTrk()), 4.0); } } } /** A schematic may have track assignments in the form of variables: * "ATTR_track=234" attached to Exports. Track assignments may also * be specified by the program calling SchemToLay.makePart(). In * the case of conflicts, the programatic assignments will override * the schematic assignments. */ private static HashMap<String,Object> mergeTrackAssign(Cell schem, HashMap<String,Object> progAsgn, StdCellParams stdCell) { // get assignment from schematic HashMap<String,Object> schAsgn = stdCell.getSchemTrackAssign(schem); // program assignments override schematic assignments HashMap<String,Object> combAsgn = new HashMap<String,Object>(schAsgn); combAsgn.putAll(progAsgn); // report erroneous assignments stdCell.validateTrackAssign(progAsgn, schem); stdCell.validateTrackAssign(combAsgn, schem); return combAsgn; } /** Read a Gasp cell schematic and produce the layout for it. <p> * Equivalent to: * *<p> <code> makePart(schematic, context, new HashMap(), stdCell); *</code>*/ public static Cell makePart(Cell schem, VarContext context, StdCellParams stdCell) { return makePart(schem, context, new HashMap<String,Object>(), stdCell); } /** Read a Gasp cell schematic and produce the layout for it. * @param schem Schematic view Cell * @param context Hierarchical path from root schematic. * @param exportTrackAssign Map from export name to Integer track * index. Negative indices represent NMOS tracks. Non-negative * indices represent PMOS tracks. Index 0 is PMOS track closest to * the center. Index -1 is NMOS track closest to the center. * @param stdCell Standard cell parameters used to build the layout */ public static Cell makePart(Cell schem, VarContext context, HashMap<String,Object> exportTrackAssign, StdCellParams stdCell) { TechType tech = stdCell.getTechType(); error(!schem.getView().getFullName().equals("schematic"), "not a schematic: "+schem.getName()); String nm = layoutCellName(schem, context); System.out.println("SchemToLay making: "+nm); Cell gasp = stdCell.findPart(nm); if (gasp!=null) return gasp; gasp = stdCell.newPart(nm); // create layout for each schematic instance HashMap<NodeInst,NodeInst> iconToLay = new HashMap<NodeInst,NodeInst>(); ArrayList<NodeInst> layInsts = new ArrayList<NodeInst>(); makeLayoutInsts(layInsts, iconToLay, schem, gasp, context, stdCell); HashMap<String,Object> combTrkAsgn = mergeTrackAssign(schem, exportTrackAssign, stdCell); // create routing segments that will each require a track to route Netlist netlist = schem.getNetlist(ShortResistors.PARASITIC); ArrayList<RouteSeg> stkSegs = new ArrayList<RouteSeg>(); ArrayList<RouteSeg> noStkSegs = new ArrayList<RouteSeg>(); ArrayList<NodeInst> vertTracks = new ArrayList<NodeInst>(); buildRouteSegs(stkSegs, noStkSegs, vertTracks, netlist.getNetworks(), iconToLay, combTrkAsgn, stdCell, gasp); // Append parts containing space for vertical routing tracks // needed to connect NMOS stacks and PMOS stacks. layInsts.addAll(vertTracks); ArrayList<RouteSeg> allSegs = new ArrayList<RouteSeg>(stkSegs); allSegs.addAll(noStkSegs); layInsts = place(layInsts, allSegs, stdCell, gasp); // vdd and gnd wires TrackRouter gnd = new TrackRouterH(tech.m2(), stdCell.getGndWidth(), stdCell.getGndY(), tech, gasp); TrackRouter vdd = new TrackRouterH(tech.m2(), stdCell.getVddWidth(), stdCell.getVddY(), tech, gasp); // place vdd and gnd exports on the first full height layout instance Export.newInstance(gasp, findFirstPort(layInsts, "gnd"), "gnd") .setCharacteristic(PortCharacteristic.GND); gnd.connect(gasp.findExport("gnd")); Export.newInstance(gasp, findFirstPort(layInsts, "vdd"), "vdd") .setCharacteristic(PortCharacteristic.PWR); vdd.connect(gasp.findExport("vdd")); // connect up vdd and gnd vdd.connect(layInsts, "vdd"); gnd.connect(layInsts, "gnd"); // Rock connect well ties to exports rather than to vdd or gnd connectWellTies(layInsts, stdCell, gasp); // // Route signal wires. // // The key problem is that a P-stack is only half height and only // allocates vertical routing channels in the upper half of a // cell. N-stack devices have a corresponding restriction. It's // difficult to connect a P-stack to an N-stack because there's no // single vertical channel that is guaranteed to be clear in both. // Thus we route nets connected to P-stacks in the upper half of // the cell, and nets connected to N-stacks in the lower half of // the cell. A Net that connects to both N-stacks and P-stacks // must be be split into an N-stack segment and a P-stack // segment. The two segments must be connected by a non-stack cell // or a special vertical routing channel. TrackAllocator trackAlloc = new TrackAllocator(stdCell); blockAssignedTracks(trackAlloc, stkSegs, stdCell); blockAssignedTracks(trackAlloc, noStkSegs, stdCell); // First connect segments that have no exports. These can // potentially share tracks. Then connect segments that are cell // exports. We need to leave track clear for these. for (int i=0; i<2; i++) { boolean exports = i==0 ? false : true; // Route RouteSegs that must be in the top of the cell and // RouteSegs that must be in the bottom of the cell. connectSegments(trackAlloc, stkSegs, exports, stdCell, gasp); // Route segments that can be either in the top or bottom of the // cell. connectSegments(trackAlloc, noStkSegs, exports, stdCell, gasp); } // Compare schematic to layout /* if (stdCell.nccEnabled()) { NccOptions options = new NccOptions(); options.checkExportNames = true; options.hierarchical = true; options.mergeParallel = true; boolean mismatch = Electric.networkConsistencyCheck(schem, context, gasp, options); error(mismatch, "SchemToLay: gasp cell topological mismatch"); } */ return gasp; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -