📄 letool.java
字号:
* @param context context of <CODE>no</CODE> * @return a variable if found, null otherwise */ private Variable getLEDRIVEleaf(Nodable no, VarContext context) { String drive = context.getInstPath("."); Variable var = null; while (!drive.equals("")) { if (DEBUG) System.out.println(" Looking for: LEDRIVE_"+drive); Variable.Key key = Variable.findKey("LEDRIVE_"+drive); var = (key != null ? no.getVar(key) : null); if (var != null) return var; // look for var int i = drive.indexOf('.'); if (i == -1) return null; drive = drive.substring(i+1); // remove top level of hierarchy } return null; } /** * Makes a string denoting hierarchy path. * @param context var context of node * @return a string denoting hierarchical path of node */ private static String makeDriveStr(VarContext context) { return "LEDRIVE_" + context.getInstPath("."); } /** * Makes a string denoting hierarchy path. * This is the old version compatible with Java Electric. * @param context var context of node * @return a string denoting hierarchical path of node */ private static String makeDriveStrOLD(VarContext context) { String s = "LEDRIVE_"+makeDriveStrOLDRecurse(context)+";0;S"; //System.out.println("name is "+s); return s; } private static String makeDriveStrOLDRecurse(VarContext context) { if (context == VarContext.globalContext) return ""; String prefix = context.pop() == VarContext.globalContext ? "" : makeDriveStrOLDRecurse(context.pop()); Nodable no = context.getNodable(); if (no == null) { System.out.println("VarContext.getInstPath: context with null NodeInst?"); } String me; String name = getCElectricDefaultName(no); me = name + ",0"; if (prefix.equals("")) return me; return prefix + ";" + me; } private static String getCElectricDefaultName(Nodable no) { String name = no.getNodeInst().getName(); int at = name.indexOf('@'); if (at != -1) { // convert to old default name style if possible if ((at+1) < name.length()) { String num = name.substring(at+1, name.length()); try { Integer i = new Integer(num); name = name.substring(0, at) + (i.intValue()+1); } catch (NumberFormatException e) {} } } return name; } private static final Pattern celecDefaultNamePattern = Pattern.compile("^(\\D+)(\\d+)$"); private static String convertToJElectricDefaultName(String celectricDefaultName) { Matcher mat = celecDefaultNamePattern.matcher(celectricDefaultName); if (mat.matches()) { try { Integer i = new Integer(mat.group(2)); int ii = i.intValue() - 1; if (ii >= 0) { celectricDefaultName = mat.group(1) + "@" + ii; } } catch (NumberFormatException e) {} } return celectricDefaultName; } protected static Variable getMFactor(Nodable no) { Variable var = no.getVar(Simulation.M_FACTOR_KEY); if (var == null) var = no.getParameter(Simulation.M_FACTOR_KEY); return var; } /** * Quantize gate sizes so that the maximum error is less than or equal * to 'error'. This result always returns a whole integer, unless * the number is less than or equal to the minValue. * @param d the number to quantize * @param error the percentage error as a number, so 0.1 for 10% * @param minValue the minimum allowed value for the return value * @return a quantized value for d */ public static double quantize(double d, double error, double minValue) { if (d <= minValue) return minValue; // (1+error)^power = dd; dd is the quanitized value of d double power = Math.log10(d)/Math.log10(1+error); long p = Math.round(power); long quan = Math.round( Math.pow(1+error, p)); return (double)quan; } // ============================== Menu Commands =================================== /** * Optimizes a Cell containing logical effort gates for equal gate delays. * @param cell the cell to be sized * @param context varcontext of the cell */ public void optimizeEqualGateDelays(Cell cell, VarContext context, boolean newAlg) { AnalyzeCell acjob = new AnalyzeCell(LESizer.Alg.EQUALGATEDELAYS, cell, context, newAlg); acjob.startJob(true, false); } private static AnalyzeCell lastLEJobExecuted = null; /** * Performs a cell analysis. The algorithm argument tells the LESizer how to size * the netlist generated by LENetlist. */ public static class AnalyzeCell extends Job { /** progress */ private String progress; /** cell to analyze */ private Cell cell; /** var context */ private VarContext context; /** algorithm type */ private LESizer.Alg algorithm; /** netlist */ private LENetlister netlister; private boolean newAlg; public AnalyzeCell(LESizer.Alg algorithm, Cell cell, VarContext context, boolean newAlg) { super("Analyze "+cell, tool, Job.Type.EXAMINE, null, cell, Job.Priority.USER); progress = null; this.algorithm = algorithm; this.cell = cell; this.context = context; this.newAlg = newAlg; } public boolean doIt() throws JobException { // delete last job, if any if (lastLEJobExecuted != null) lastLEJobExecuted.remove(); lastLEJobExecuted = this; setProgress("building equations"); System.out.print("Building equations..."); // sleep for testing purposes only, remove later// try {// boolean donesleeping = false;// while(!donesleeping) {// Thread.sleep(1);// donesleeping = true;// }// } catch (InterruptedException e) {} // get sizer and netlister Technology layoutTech = cell.getTechnology(); if (layoutTech == Schematics.tech()) layoutTech = Schematics.getDefaultSchematicTechnology(); if (newAlg) netlister = new LENetlister2(this, layoutTech); else netlister = new LENetlister1(this, layoutTech); boolean success = netlister.netlist(cell, context, true); if (!success) return false; // calculate statistics long equationsDone = System.currentTimeMillis(); String elapsed = TextUtils.getElapsedTime(equationsDone-startTime); System.out.println("done ("+elapsed+")"); // if user aborted, return, and do not run sizer if (checkAbort(null)) { netlister.done(); return false; } System.out.println("Starting iterations: "); setProgress("iterating"); boolean success2 = netlister.size(algorithm); // if user aborted, return, and do not update sizes if (checkAbort(null)) { netlister.done(); return false; } if (success2) { System.out.println("Sizing finished, updating sizes..."); netlister.printStatistics(); List<Float> sizes = new ArrayList<Float>(); List<String> varNames = new ArrayList<String>(); List<NodeInst> nodes = new ArrayList<NodeInst>(); List<VarContext> contexts = new ArrayList<VarContext>(); netlister.getSizes(sizes, varNames, nodes, contexts); // check for small sizes for (int i=0; i<sizes.size(); i++) { float f = sizes.get(i).floatValue(); NodeInst ni = nodes.get(i); VarContext context = contexts.get(i); if (f < 1.0f) { String msg = "WARNING: Instance "+ni+" has size "+TextUtils.formatDouble(f, 3)+" less than 1"; System.out.println(msg); if (ni != null) { netlister.getErrorLogger().logWarning(msg, ni, ni.getParent(), context, 2); } } } new UpdateSizes(sizes, varNames, nodes, contexts, cell, 0.10); netlister.getErrorLogger().termLogging(true); //netlister.nullErrorLogger(); } else { System.out.println("Sizing failed, sizes unchanged"); netlister.done(); } return true; } /** * Check if we are scheduled to abort. If so, print msg if non null * and return true. * @param msg message to print if we are aborted * @return true on abort, false otherwise */ protected boolean checkAbort(String msg) { boolean aborted = super.checkAbort(); if (aborted) { if (msg != null) System.out.println("LETool aborted: "+msg); else System.out.println("LETool aborted: no changes made"); } return aborted; } // add more info to default getInfo public String getInfo() { StringBuffer buf = new StringBuffer(); buf.append(super.getInfo()); if (getScheduledToAbort()) buf.append(" Job aborted, no changes made\n"); else { buf.append(" Job completed successfully\n"); } return buf.toString(); } public LENetlister getNetlister() { return netlister; } } private static class UpdateSizes extends Job { private List<Float> sizes; private List<String> varNames; private List<NodeInst> nodes; private List<VarContext> contexts; private Cell cell; private double standardCellErrorTolerancePrint = 0.10; private UpdateSizes(List<Float> sizes, List<String> varNames, List<NodeInst> nodes, List<VarContext> contexts, Cell cell, double standardCellErrorTolerancePrint) { super("Update LE Sizes", tool, Job.Type.CHANGE, null, cell, Job.Priority.USER); this.sizes = sizes; this.varNames = varNames; this.nodes = nodes; this.contexts = contexts; this.cell = cell; this.standardCellErrorTolerancePrint = standardCellErrorTolerancePrint; startJob(); } public boolean doIt() throws JobException { // handle changed standard cells UniqueNodeMap standardCellNodeMap = new UniqueNodeMap(); boolean standardCellArrayError = false; System.out.println("Standard cell quantization errors over "+ (standardCellErrorTolerancePrint*100)+"%:"); StringBuffer errBuf = new StringBuffer(); for (int i=0; i<sizes.size(); i++) { NodeInst ni = nodes.get(i); VarContext context = contexts.get(i); Float f = sizes.get(i); Cell standardCell = getStandardCell(ni, context, f.doubleValue()); if (standardCell != null) { VarContext nicontext = context.push(ni); Cell previousStandardCell = standardCellNodeMap.get(nicontext); if (previousStandardCell != null && previousStandardCell != standardCell.iconView()) { // we have an arrayed NodeInst that has been assigned different sizes, // this is not allowed for standard cells errBuf.append("ERROR: Arrayed Standard Cell " +context.getInstPath(".")+"."+ni.getName()+"\n"); errBuf.append(" cannot yield separate sizes for nodes in array: "+previousStandardCell.getName()+" vs "+standardCell.getName()+"\n"); standardCellArrayError = true; } VarContext nocontext = context.push(Netlist.getNodableFor(ni, 0)); standardCellNodeMap.put(nocontext, standardCell.iconView()); } else { // this is not a standard cell, must be purple gate - apply size // as top level cell parameter String varName = varNames.get(i); cell.newVar(varName, f); } } // if there are standard cells, replace them in the hierarchy if (standardCellNodeMap.size() > 0) { Uniquifier uniquifier = new Uniquifier(standardCellNodeMap);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -