/** gate score = smallest noise margin (distance in log(REU) of input REU to margin REU) */ public static void evaluateGateNoiseMargin(Gate g, Args options) { if (options.is_noise_margin() == false) { g.get_scores().set_noise_margin_contract(true); return; } if (g.Type == GateType.INPUT || g.Type == GateType.OUTPUT || g.Type == GateType.OUTPUT_OR) { return; } // "x" to value HashMap<String, Double> lowest_on_reu = GateUtil.getIncomingONlow(g); HashMap<String, Double> highest_off_reu = GateUtil.getIncomingOFFhigh(g); ArrayList<Double> all_margins = new ArrayList<Double>(); for (String var : highest_off_reu.keySet()) { if (g.get_variable_thresholds().get(var) != null) { // IL is the input-low threshold Double IL = g.get_variable_thresholds().get(var)[0]; // actual REU Double log_input_reu = Math.log10(highest_off_reu.get(var)); // NML is the margin/width between the actual REU and the threshold REU Double NML = Math.log10(IL) - log_input_reu; all_margins.add(NML); } } for (String var : lowest_on_reu.keySet()) { if (g.get_variable_thresholds().get(var) != null) { Double IH = g.get_variable_thresholds().get(var)[1]; Double NMH = Math.log10(lowest_on_reu.get(var)) - Math.log10(IH); all_margins.add(NMH); } } if (all_margins.isEmpty()) { g.get_scores().set_noise_margin(0.0); g.get_scores().set_noise_margin_contract(true); } else { Collections.sort(all_margins); g.get_scores().set_noise_margin(all_margins.get(0)); if (all_margins.get(0) < 0) { g.get_scores().set_noise_margin_contract(false); } else { g.get_scores().set_noise_margin_contract(true); } } }
/** * To evaluate the ON/OFF ratio for a circuit, calculate the ON/OFF ratio for each output gate, * and choose the worst score among the outputs (#outputs >= 1). */ public static void evaluateCircuitONOFFRatio(LogicCircuit lc) { double worst_out = Double.MAX_VALUE; for (int out = 0; out < lc.get_output_gates().size(); ++out) { // if multiple outputs, average _scores Gate output = lc.get_output_gates().get(out); evaluateGateONOFFRatio(output); // if multiple outputs, circuit score = score of worst output if (output.get_scores().get_onoff_ratio() < worst_out) { worst_out = output.get_scores().get_onoff_ratio(); } } lc.get_scores().set_onoff_ratio(worst_out); }
/** noise_margin */ public static void evaluateCircuitNoiseMargin(LogicCircuit lc, Args options) { // initialize to true. circuit will fail if any gate fails. lc.get_scores().set_noise_margin_contract(true); if (options.is_noise_margin() == false) { return; } double sum_noise_margin = 0.0; double min_noise_margin = 999.0; for (Gate g : lc.get_logic_gates()) { // 'options' are passed in to read the _noise_margin boolean evaluateGateNoiseMargin(g, options); if (g.get_scores().get_noise_margin() < min_noise_margin) { min_noise_margin = g.get_scores().get_noise_margin(); } // g.get_noise_margin() returns the min of the NML and NMH values (noise margin low, noise // margin high) sum_noise_margin += g.get_scores().get_noise_margin(); // sum_noise_margin += g.get_scores().get_noise_margin() * g.get_distance_to_input(); /** if one gate fails, the whole circuit fails threshold analysis */ if (g.get_scores().is_noise_margin_contract() == false) { lc.get_scores().set_noise_margin_contract(false); // lc.get_scores().set_noise_margin(0.0); lc.get_scores().set_noise_margin(min_noise_margin); break; } } // noise margin value is not being used. // noise margin is only used as a pass/fail filter, not a score term. if (lc.get_scores().is_noise_margin_contract() == true) { // lc.get_scores().set_noise_margin(sum_noise_margin / lc.get_logic_gates().size()); lc.get_scores().set_noise_margin(sum_noise_margin); } }
/** * A gate with two transcriptional units (e.g. AND) can have two different wirings. Doesn't matter * for a gate with one txn unit. * * @param g * @param gate_library * @param options */ public static void setBestVariableMapping(Gate g, GateLibrary gate_library, Args options) { ArrayList<ArrayList<String>> variable_name_orders = Permute.getVariableNamePermutation(g.get_variable_names()); Integer best_variable_name_order_index = 0; Double best_score = 0.0; int v = 0; for (ArrayList<String> variable_name_order : variable_name_orders) { g.get_outreus().clear(); for (int i = 0; i < g.get_logics().size(); ++i) { // rows in truth table /*if (Args.dontcare_rows.contains(i)) { g.get_outreus().add(0.0); continue; }*/ GateUtil.mapWiresToVariables(g, variable_name_order); double output_reu = ResponseFunction.computeOutput( GateUtil.getVariableValues(g, i, gate_library, options), g.get_params(), g.get_equation()); g.get_outreus().add(output_reu); } evaluateGate(g, options); if (g.get_scores().get_score() > best_score) { best_score = g.get_scores().get_score(); best_variable_name_order_index = v; } v++; } // this is the critical part, it's ordering the variable names in the list g.set_variable_names(variable_name_orders.get(best_variable_name_order_index)); }
/** * histogram * * <p>Histogram overlap score worst-case = 0.0 and best-case = 1.0 */ public static void evaluateCircuitHistogramOverlap( LogicCircuit lc, GateLibrary gate_library, Args options) { // output gate _score (average) refreshGateAttributes(lc, gate_library); // if sequential if (options.get_circuit_type() == DNACompiler.CircuitType.sequential) { // set initial SequentialHelper.setInitialHistogramREUs(lc, gate_library); // track HashMap<String, ArrayList<ArrayList<double[]>>> track_reus = new HashMap<>(); for (Gate g : lc.get_Gates()) { track_reus.put(g.Name, new ArrayList<ArrayList<double[]>>()); ArrayList<double[]> copy_hist_reus = new ArrayList<double[]>(g.get_histogram_reus()); track_reus.get(g.Name).add(copy_hist_reus); track_reus.get(g.Name).add(copy_hist_reus); // looks for i-1 } // converge SequentialHelper.convergeHistogramREUs(lc, gate_library, options, track_reus); } // if combinational else if (options.get_circuit_type() == DNACompiler.CircuitType.combinational) { Evaluate.simulateHistogramREU(lc, gate_library, options); } double worst_out = Double.MAX_VALUE; for (int out = 0; out < lc.get_output_gates().size(); ++out) { Gate output = lc.get_output_gates().get(out); evaluateGateHistogramOverlap(output); if (output.get_scores().get_conv_overlap() < worst_out) { worst_out = output.get_scores().get_conv_overlap(); } } lc.get_scores().set_conv_overlap(worst_out); }
public static void evaluateGateSNR(Gate g, Args options) { if (g.Type == GateType.INPUT) { return; } ArrayList<Double> ons = new ArrayList<>(); ArrayList<Double> offs = new ArrayList<>(); // get ons and offs for (int i = 0; i < g.get_logics().size(); ++i) { if (g.get_logics().get(i) == 1) { ons.add(g.get_outreus().get(i)); } else if (g.get_logics().get(i) == 0) { offs.add(g.get_outreus().get(i)); } } ArrayList<Double> child_ons = new ArrayList<>(); ArrayList<Double> child_offs = new ArrayList<>(); for (Gate child : g.getChildren()) { for (int i = 0; i < child.get_logics().size(); ++i) { if (child.get_logics().get(i) == 1) { child_ons.add(child.get_outreus().get(i)); } else if (child.get_logics().get(i) == 0) { child_offs.add(child.get_outreus().get(i)); } } } Double on_min = Collections.min(ons); Double off_max = Collections.max(offs); Double child_on_min = Collections.min(child_ons); Double child_off_max = Collections.max(child_offs); Double out_snr = 20 * Math.log10((Math.log10(on_min / off_max)) / (2 * Math.log10(3.2))); Double in_snr = 20 * Math.log10((Math.log10(child_on_min / child_off_max)) / (2 * Math.log10(3.2))); Double dsnr = out_snr - in_snr; g.get_scores().set_snr(out_snr); g.get_scores().set_dsnr(dsnr); }
/** find ON_lowest and OFF_highest as worst-case scenario */ public static void evaluateGateONOFFRatio(Gate g) { double lowest_on_reu = Double.MAX_VALUE; double highest_off_reu = Double.MIN_VALUE; for (int i = 0; i < g.get_logics().size(); ++i) { // for each row in the truth table... // if (!Args.dontcare_rows.contains(i)) { //don't score dontcare rows Double reu = g.get_outreus().get(i); if (g.get_logics().get(i) == 1) { if (lowest_on_reu > reu) { lowest_on_reu = reu; } } else if (g.get_logics().get(i) == 0) { if (highest_off_reu < reu) { highest_off_reu = reu; } } // } } // g.get_scores().set_onoff_ratio( Math.log10(lowest_on_reu/highest_off_reu) ); g.get_scores().set_onoff_ratio(lowest_on_reu / highest_off_reu); }
/** * score = 1 - penalty of histogram overlap score all ON:OFF pairs and report the worst score * * <p>overlap penalty: for each bin, compute geometric mean of two ON:OFF histogram values, add * add bin penalty to total penalty alternative is to penalize the min of the two ON:OFF histogram * values */ public static void evaluateGateHistogramOverlap(Gate g) { ArrayList<Double> scores_conv_overlap = new ArrayList<Double>(); ArrayList<Integer> ons = new ArrayList<Integer>(); ArrayList<Integer> offs = new ArrayList<Integer>(); // get ons and offs for (int i = 0; i < g.get_logics().size(); ++i) { if (g.get_logics().get(i) == 1) { ons.add(i); } else if (g.get_logics().get(i) == 0) { offs.add(i); } } // compute scores of all on-off pairs for (int on = 0; on < ons.size(); ++on) { for (int off = 0; off < offs.size(); ++off) { // if(!Args.dontcare_rows.contains(on) && !Args.dontcare_rows.contains(off)) { double median_on = Math.pow( Math.E, HistogramUtil.median( g.get_histogram_reus().get(ons.get(on)), g.get_histogram_bins())); double median_off = Math.pow( Math.E, HistogramUtil.median( g.get_histogram_reus().get(offs.get(off)), g.get_histogram_bins())); double score = 1 - median_off / median_on; double overlap_penalty = 0.0; // if ON histogram is lower than OFF histogram, broken circuit if (score < 0) { scores_conv_overlap.add(0.0); continue; } else { double[] on_norm = HistogramUtil.normalize(g.get_histogram_reus().get(ons.get(on))); double[] off_norm = HistogramUtil.normalize(g.get_histogram_reus().get(offs.get(off))); // penalty is sum of geometric means for each bin // total counts have been normalized to 1 for (int bin = 0; bin < g.get_histogram_bins().get_NBINS(); ++bin) { overlap_penalty += Math.sqrt(on_norm[bin] * off_norm[bin]); // geometric mean // overlap_penalty += Math.min( on_norm[bin] , off_norm[bin]); //min of the two bin // counts } } score = 1 - overlap_penalty; scores_conv_overlap.add(score); // } } } Collections.sort(scores_conv_overlap); g.get_scores().set_conv_overlap(scores_conv_overlap.get(0)); // worst }