def check_overall_TMR(in_circ_file): main_circuit_etalon = sa.read_scheme(in_circ_file) initial_area = get_area(main_circuit_etalon) initial_reliability = external_reliability(main_circuit_etalon, 100000) tmr_circ = createTMRCirc(main_circuit_etalon) new_area = get_area(tmr_circ) new_reliability = external_reliability(tmr_circ, 100000) print('Initial reliability: {}'.format(initial_reliability)) print('TMR reliability: {}'.format(new_reliability)) print('New area: {} Initial Area: {} Growth Percent: {}%'.format(new_area, initial_area, round((100.0*new_area)/initial_area), 2))
def create_circuit_external_yosys (circuit): dfile = get_project_directory() run_path = os.path.join(dfile, "utils", "bin", "win32", "yosys") yosys_exe = os.path.join(run_path, "yosys.exe") circuit_file = os.path.join(dfile, "temp", "tmp_sheme_yosys.v") run_file = os.path.join(dfile, "temp", "tmp_runfile_yosys.txt") synth_file = os.path.join(dfile, "temp", "tmp_synth.v") converted_circuit_file = os.path.join(dfile, "temp", "tmp_synth_conv.txt") graph_file = os.path.join(dfile, "temp", "synth.svg") debug_file = os.path.join(dfile, "temp", "yosys_fail.txt") if os.path.isfile(circuit_file): os.remove(circuit_file) if os.path.isfile(run_file): os.remove(run_file) if os.path.isfile(synth_file): os.remove(synth_file) if os.path.isfile(converted_circuit_file): os.remove(converted_circuit_file) print_circuit_in_verilog_file(circuit, "circ", circuit_file) print_run_file(run_file, circuit_file, synth_file, graph_file) exe = yosys_exe + " < " + run_file try: ret = subprocess.check_output(exe, shell=True, cwd=run_path).decode('UTF-8') except: ret = 'Error' if not os.path.isfile(synth_file): # Если была проблема с Yosys выводим схему для последующего дебага circuit.print_circuit_in_file(debug_file) print('Yosys error') return None convert_file_to_relic_format(circuit, synth_file, converted_circuit_file) if os.path.isfile(converted_circuit_file) == False: return None new_ckt = sa.read_scheme(converted_circuit_file) return new_ckt
def improve_circuit_by_resynthesis_ver6(in_circ_file, out_circ_file, needed_replacements, max_area_overhead): """ :param in_circ_file: File with input circuit . :param out_circ_file: File to store resulted circuit :param needed_replacements: Number of successfull replacemnts :param max_area_overhead: koeff for defined maximum area of generated circuit related to initial circuit (from 1.0) :return: true or false """ overall_start = timeit.default_timer() calc_type = 1 print("Start processing circuit:") main_circuit_etalon = sa.read_scheme(in_circ_file) initial_area = get_area(main_circuit_etalon) initial_circ_delay = getMaxLevel(main_circuit_etalon) main_circuit = sa.read_scheme(in_circ_file) (initial_reliability, vulnerability_map) = external_vulnerability_map(main_circuit, MONTE_CARLO_ITER) latest_reliability = initial_reliability success_replacements_part1 = 0 success_replacements = 0 between_replacements = 0 iterations = 50000 bestFunction = [0] * 6 bestFunctionReplace = [0] * 6 inputOutputTotal = dict() inputOutputReplacements = dict() replacementLevelIncrease = [] for zzz in range(1, iterations): print("\n|||||||||||||| Iteration "+ zzz.__str__() + " ||||||||||||||") # main_circuit = cleanCKTFromBUFs(main_circuit) if calc_type == 1: rnd1 = get_random_subcircuit_v2(main_circuit, vulnerability_map, random.randint(2,6), 1) else: rnd1 = get_random_subcircuit(main_circuit, random.randint(2,6), 1) if rnd1.inputs() < 2: print("Too small subckt") continue if rnd1.inputs() > 9: print("Too big subckt") continue if rnd1.outputs() > 11: print("Too many outputs subckt") continue if (rnd1.inputs(), rnd1.outputs()) in inputOutputTotal: inputOutputTotal[rnd1.inputs(), rnd1.outputs()] += 1 else: inputOutputTotal[rnd1.inputs(), rnd1.outputs()] = 1 between_replacements += 1 print("OK subckt [Inputs: {} Outputs: {}]".format(rnd1.inputs(), rnd1.outputs())) trtable = create_truth_table(rnd1) data = goEspresso_external(trtable, rnd1) # Здесь добавляем произвольный набор схем претендентов на замену t1 = current_milli_time() subckt = [] subckt.append(createSubckt_method1(data, rnd1)) subckt.append(createSubckt_method2(data, rnd1)) subckt.append(createSubckt_method3(data, rnd1)) yosys_subckt = create_circuit_external_yosys(rnd1) if yosys_subckt != None: subckt.append(yosys_subckt) if 0: tmrSubCkt = createTMRCirc(rnd1) # Проверяем что троирование не приведет к увеличению схемы сверх указанного if (get_area(main_circuit) - get_area(rnd1) + get_area(tmrSubCkt)) < initial_area*max_area_overhead: subckt.append(tmrSubCkt) else: print('TMR SUBCKT skipped due to large area growth') t2 = current_milli_time() # print('Gen {} subckt OK. Generation time: {}'.format(len(subckt), round((t2-t1)/1000, 3))) # Проверяем что все сгенерированные подсхемы работают одинаково # Это можно будет убрать после полноценного тестирования for s in subckt: try: cmp = scheme_cmp(rnd1, s) if cmp == False: print('Subckt have less inputs. Skip for now') continue elif cmp < 0.99999: print('Error with subckt it works incorrect check it') exit(0) except: print(rnd1) print(s) main_circuit.print_circuit_in_file(os.path.join(get_project_directory(), 'temp', 'main_circuit_io_problem.txt')) rnd1.print_circuit_in_file(os.path.join(get_project_directory(), 'temp', 'rnd1_io_problem.txt')) s.print_circuit_in_file(os.path.join(get_project_directory(), 'temp', 'subckt_io_problem.txt')) print('Input/output problem') exit() continue # Рассчитываем вероятности комбинаций на входах подсхемы iternum = pow(2, rnd1.inputs())*1000 t1 = current_milli_time() distr = distribution_estim_external(main_circuit, rnd1.input_labels(), rnd1.output_labels(), iternum) t2 = current_milli_time() # print('Distribution Estim C: {} seconds'.format(round((t2-t1)/1000, 3))) t1 = current_milli_time() subckt_reliability = external_reliability_uneven(rnd1, distr) t2 = current_milli_time() # print('Reliability uneven: {} seconds'.format(round((t2-t1)/1000, 3))) bestval = subckt_reliability + 1000000 # Из набора подсхем выбираем самую надежную t1 = current_milli_time() subCKTNum = 0 bestCKTIndex = 0 allVals = [] for s in subckt: subCKTNum += 1 if s.input_labels() != rnd1.input_labels(): print('Invalid input order in subckt') print(s.input_labels()) print(rnd1.input_labels()) exit() val2 = external_reliability_uneven(s, distr) allVals.append(val2) if val2 < bestval: bestckt = copy.deepcopy(s) bestval = val2 bestCKTIndex = subCKTNum bestFunction[bestCKTIndex] += 1 t2 = current_milli_time() # print('Get best CKT {}: {} seconds'.format(bestCKTIndex, round((t2-t1)/1000, 3))) print('Array of reliability: {}'.format(allVals)) if subckt_reliability > bestval + 0.05: print("Success (Stage 1) {} > {} (CKT Index {})! =)".format(subckt_reliability, bestval, bestCKTIndex)) success_replacements_part1 += 1 t1 = current_milli_time() main_circuit_new = replace_subckt_v2(main_circuit, rnd1, bestckt) t2 = current_milli_time() # print('Replace subckt: {} seconds'.format(round((t2-t1)/1000, 3))) t1 = current_milli_time() (val_main_circuit_new, vulnerability_new) = external_vulnerability_map(main_circuit_new, MONTE_CARLO_ITER) compare_same_logic_for_circuit_monte_carlo(main_circuit, main_circuit_new, 10) if latest_reliability > val_main_circuit_new: print("Success (Stage 2) {} > {} ! =)".format(latest_reliability, val_main_circuit_new)) # Заменяем карту уязвимостей vulnerability_map = copy.deepcopy(vulnerability_new) main_circuit = copy.deepcopy(main_circuit_new) latest_reliability = val_main_circuit_new cur_area = get_area(main_circuit_new) print('New area: {} Initial Area: {} Growth Percent: {}%'.format(cur_area, initial_area, round((100.0*cur_area)/initial_area), 2)) success_replacements += 1 between_replacements = 0 # Статистика по входам выходам замененной подсхемы if (rnd1.inputs(), rnd1.outputs()) in inputOutputReplacements: inputOutputReplacements[rnd1.inputs(), rnd1.outputs()] += 1 else: inputOutputReplacements[rnd1.inputs(), rnd1.outputs()] = 1 # Сохраняем значение увеличения уровней подсхемы levelRnd1 = getMaxLevel(rnd1) levelBestCkt = getMaxLevel(bestckt) replacementLevelIncrease.append(levelBestCkt/levelRnd1) bestFunctionReplace[bestCKTIndex] += 1 else: print("Fail (Stage 2) {} < {} ! =(".format(latest_reliability, val_main_circuit_new)) # Для тестирования ошибок во внешней проге rnd1.print_circuit_in_file(os.path.join(get_project_directory(), 'temp', 'rnd1.txt')) bestckt.print_circuit_in_file(os.path.join(get_project_directory(), 'temp', 'subckt.txt')) main_circuit.print_circuit_in_file(os.path.join(get_project_directory(), 'temp', 'main_circuit.txt')) main_circuit_new.print_circuit_in_file(os.path.join(get_project_directory(), 'temp', 'main_circuit_new.txt')) t2 = current_milli_time() print('External reliability: {} seconds'.format(round((t2-t1)/1000, 3))) if success_replacements >= needed_replacements: break else: print("Fail (Stage 1)! =( " + subckt_reliability.__str__() + " <= " + bestval.__str__()) # Если за тысячу итераций не было успешных замен выходим if between_replacements > 1000: break endpoint_reliability = external_reliability(main_circuit, MONTE_CARLO_ITER) print("Total Iterations : " + zzz.__str__()) print("Success replacements (P1): " + success_replacements_part1.__str__()) print("Success replacements (P2): " + success_replacements.__str__()) if success_replacements_part1 == 0: percent = 100 else: percent = round((100*success_replacements)/success_replacements_part1, 2) print("Success rate: ", percent.__str__()) print("Initial reliability: " + initial_reliability.__str__()) print("Endpoint reliability: " + endpoint_reliability.__str__()) print("Initial number of elements: {}".format(initial_area)) print("Endpoint number of elements: {}".format(get_area(main_circuit))) print("Best subckt generators: {}".format(bestFunction)) overall_end = timeit.default_timer() print("Total runtime: {} seconds".format((overall_end - overall_start))) main_circuit.print_circuit_in_file(out_circ_file) compare_same_logic_for_circuit_monte_carlo(main_circuit_etalon, main_circuit, 1000) printInputOutputNumbersInReplaceStats(inputOutputTotal, inputOutputReplacements) printLevelIncreaseStat(replacementLevelIncrease) print("Best CKT for replace") print(bestFunctionReplace) resynt_circ_delay = getMaxLevel(main_circuit) circ_delay_percent = round((100*resynt_circ_delay)/initial_circ_delay, 2) print("Levels in circ. Initial: {}, Resyntesized: {}, Percent: {}".format(initial_circ_delay, resynt_circ_delay, circ_delay_percent))