def full_output_checks(fsolve_res, full_output): if not full_output: return fsolve_res else: x, infodict, ier, mesg = fsolve_res my_print((x, infodict, ier, mesg), print_level, print_esc=False) return x
def calculate_delay_idm(channel_type, input_level, d_up, d_do, t_p, t_p_percent, t_p_mode, v_dd, v_th, now, last_output_time, first_transition, channel_parameters_dict): sys.stdout.flush() channel_type = extract_parameter(channel_type) input_level = std_logic_t(extract_parameter(input_level)) d_up = extract_parameter(d_up) d_do = extract_parameter(d_do) t_p = extract_parameter(t_p) t_p_percent = extract_parameter(t_p_percent) t_p_mode = tp_mode(extract_parameter(t_p_mode)) v_dd = extract_parameter(v_dd) v_th = extract_parameter(v_th) now = extract_parameter(now) last_output_time = extract_parameter(last_output_time) first_transition = extract_parameter(first_transition) channel_parameters_dict = extract_dict(channel_parameters_dict) if channel_type.lower() == str(ChannelType.PUREDELAY_CHANNEL).lower(): return pure_delay_channel_idm(input_level, d_up, d_do, t_p, t_p_percent, t_p_mode, v_dd, v_th, now, last_output_time, first_transition, channel_parameters_dict) elif channel_type.lower() == str(ChannelType.EXP_CHANNEL).lower(): return exp_delay_channel_idm(input_level, d_up, d_do, t_p, t_p_percent, t_p_mode, v_dd, v_th, now, last_output_time, first_transition, channel_parameters_dict) elif channel_type.lower() == str(ChannelType.HILL_CHANNEL).lower(): my_print('Not implemented yet!', EscCodes.FAIL, print_esc=False) elif channel_type.lower() == str(ChannelType.SUMEXP_CHANNEL).lower(): return sumexp_delay_channel_idm(input_level, d_up, d_do, t_p, t_p_percent, t_p_mode, v_dd, v_th, now, last_output_time, first_transition, channel_parameters_dict) else: my_print('Not implemented yet!', EscCodes.FAIL, print_esc=False) sys.stdout.flush()
def get_trace(switchingTimes, initialValue): data = [[], []] value = 0 if initialValue == 0: value = vss elif initialValue == 1: value = vdd else: my_print("Wrong initial value in crossings.json file", EscCodes.WARNING) data[0].append(0) data[1].append(value) for time in switchingTimes: time *= 1e9 data[0].append(time) data[1].append(data[1][-1]) data[0].append(time) if value == vss: value = vdd else: value = vss data[1].append(value) return data
def get_second_page_data(debug=False): """#get second page data, and save result to file ./api-data/second_page_data.json""" t0 = time.time() helper.remove_file(config.FILENAME_SECOND_PAGE_DATA) helper.remove_file(config.FILENAME_SECOND_PAGE_SECTIONIDS_DATA) helper.create_dir(config.SAVE_FILE_DIR) helper.my_print("total has %d grades...\n" % len(config.GRADES), debug) for grade in config.GRADES: time.sleep(config.SLEEP_TIME) helper.my_print("%s:" % grade, debug) url = helper.get_second_page_url(grade=grade) content = helper.get_url_content(url) # 获取知识章节列表 if content is None: helper.my_print_error("the content is None.") else: helper.save_content_to_file(config.FILENAME_SECOND_PAGE_DATA, content) helper.my_print(content, debug) # 获取知识章节对应的ID列表 json_data = json.loads(content, encoding='utf-8') for course_list in json_data['list']: for course in course_list['list']: section_id = course['courseSectionID'] helper.save_content_to_file( config.FILENAME_SECOND_PAGE_SECTIONIDS_DATA, section_id) helper.my_print(section_id, debug) helper.my_print("", debug) print('Done. %f seconds cost.' % (time.time() - t0))
def main(): if len(sys.argv) < 5: my_print( "usage: python readCrossings.py input_dir out_put_dir matching_file {input_names}", EscCodes.FAIL) sys.exit(1) read_crossings(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4:])
def read_circuit_structure(structure_file_path): circuit_structure = CircuitStructure() with open(structure_file_path, "r") as structure_file: try: jsonobject = json.load(structure_file) for cell in jsonobject["cells"]: cell_obj = Cell() cell_obj.__dict__ = cell circuit_structure.cells.append(cell_obj) for interconnect in jsonobject["interconnects"]: interconnect_obj = Interconnect() interconnect_obj.__dict__ = interconnect circuit_structure.interconnects.append(interconnect_obj) if 'init' in jsonobject: circuit_structure.init = jsonobject['init'] else: circuit_structure.init = dict() except ValueError: my_print("No valid json object found in structure_file_path", EscCodes.FAIL) return circuit_structure
def generate_gate_idm(gate, content, structure, name, channel, gate_dir, d_up, d_down, signal_list, generate_all, required_gates): for cell in structure.cells: # First we need to check if this is one of the cells we need to generate if cell.cell_type != gate.entity_name: continue # Correct initialization only implement for this ChannelLocation, other ChannelLocations are not really used any more, since they do not correspond to the model assert gate.channel_location == ChannelLocation.OUTPUT # For channel location OUTPUT, this is basically one signal, which is the value after the gate output. This needs to be set according to the init value assert (len(signal_list) == 1) init_value_out = "0" # We simply fix the init value to 0. If specified, we overwrite this value. if cell.instance in structure.init: init_value_out = structure.init[cell.instance] signals = build_idm_signals(structure, cell, signal_list, init_value_out) ports = "" for input in gate.inputs: # For IDM, we need to initialize both, the input and output ports with 0, because that is how the toggle indicator is initialized init_value_in = "0" pred_interconnect = find_pred_interconnect(structure, cell, input) if pred_interconnect is None: my_print( "Cell: {cell}, Input: {input}".format(cell=cell, input=input), EscCodes.FAIL) assert (False) if pred_interconnect.from_instance in structure.init: init_value_in = structure.init[pred_interconnect.from_instance] ports += input + " : IN STD_ULOGIC := '" + init_value_in + "';\n\t\t" # The output is set to our init value (if specified) init_value = "0" if cell.instance in structure.init: init_value = structure.init[cell.instance] for out in gate.outputs: ports += out + " : OUT STD_ULOGIC := '" + init_value + "';\n\t\t" ports = ports[:-4] delay_channel = build_delay_channel_idm(gate, channel[0], channel[1], d_up, d_down, cell, init_value_out) content_repl = content.replace( "##ENTITY_NAME##", gate.entity_name + "_" + cell.instance).replace( "##ARCH_INPUT_PROCESSES##", "").replace("##ARCH_DELAY_CHANNEL##", delay_channel).replace( "##PORTS##", ports).replace("##ARCH_SIGNALS##", signals) with open(os.path.join(gate_dir, name + "_" + cell.instance + ".vhd"), "w") as gate_file: gate_file.write(content_repl)
def main(): if len(sys.argv) != 4: my_print( "usage: python buildInstanceMapping.py circuit_folder sdf_file_path instance_mapping_path", EscCodes.FAIL) else: build_instance_mapping(sys.argv[1], sys.argv[2], sys.argv[3])
def print_to_results(gate_config_file, required_gates, results_file, prefix): gates = read_gate_config(gate_config_file, None) generate_all = required_gates is None or required_gates == "" or "ALL" in required_gates t_p_list = [] t_p_percent_list = [] t_p_mode_list = [] name_list = [] channel_type_list = [] channel_location_list = [] n_up_list = [] n_do_list = [] x_1_up_list = [] x_1_do_list = [] tau1_up_list = [] tau1_do_list = [] tau2_up_list = [] tau2_do_list = [] for name in sorted(gates.keys()): gate = gates[name] if not generate_all and name not in required_gates: my_print("Ignoring: " + name) continue # we do not want to generate all gates, if not necessary for the circuit t_p_list.append(gate.T_P) t_p_percent_list.append(gate.T_P_percent) t_p_mode_list.append(gate.T_P_mode) name_list.append(gate.entity_name) channel_type_list.append(gate.channel_type) channel_location_list.append(gate.channel_location) append_channel_parameter(n_up_list, gate, "N_UP") append_channel_parameter(n_do_list, gate, "N_DO") append_channel_parameter(x_1_up_list, gate, "X_1_UP") append_channel_parameter(x_1_do_list, gate, "X_1_DO") append_channel_parameter(tau1_up_list, gate, "TAU_1_UP") append_channel_parameter(tau1_do_list, gate, "TAU_1_DO") append_channel_parameter(tau2_up_list, gate, "TAU_2_UP") append_channel_parameter(tau2_do_list, gate, "TAU_2_DO") # Now extend the results dictionary results = dict() append_to_result_dict(results, prefix + 'T_P', t_p_list) append_to_result_dict(results, prefix + 'T_P_Percent', t_p_percent_list) append_to_result_dict(results, prefix + 'T_P_Mode', t_p_mode_list) append_to_result_dict(results, prefix + 'name', name_list) append_to_result_dict(results, prefix + 'channel_type', channel_type_list) append_to_result_dict(results, prefix + 'channel_location', channel_location_list) append_to_result_dict(results, prefix + 'n_up', n_up_list) append_to_result_dict(results, prefix + 'n_do', n_do_list) append_to_result_dict(results, prefix + 'x_1_up', x_1_up_list) append_to_result_dict(results, prefix + 'x_1_do', x_1_do_list) append_to_result_dict(results, prefix + 'tau_1_up', tau1_up_list) append_to_result_dict(results, prefix + 'tau_1_do', tau1_do_list) append_to_result_dict(results, prefix + 'tau_2_up', tau2_up_list) append_to_result_dict(results, prefix + 'tau_2_do', tau2_do_list) extend_results(results_file, results)
def main(): if len(sys.argv) != 2: my_print("usage: python multiExec.py config_file", EscCodes.FAIL, override_print_env_flag) sys.exit(1) multi_exec_sim(sys.argv[1])
def main(): if len(sys.argv) != 5: my_print( "usage: python gateGenerationToResults.py gate_config_file required_gates results_file prefix", EscCodes.FAIL) else: print_to_results(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
def main(): if len(sys.argv) != 6: my_print( "usage: python prepareGates.py default_config_file circuit_config_file template_gate_config_file output_file required_gates", EscCodes.FAIL) sys.exit(1) prepate_gates(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
def main(): if len(sys.argv) != 6: my_print( "usage: python prepareConfig.py root_folder circuit_structure_file_path config_output_file_path spice_var_names_path fitting_type", EscCodes.FAIL) else: prepare_config(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
def main(): # required_gates is optional, if not set, all gates are generated if len(sys.argv) != 4: my_print( "usage: python combineGateGeneration.py default_config_file circuit_config_file target_config_file", EscCodes.FAIL) else: combine_gates(sys.argv[1], sys.argv[2], sys.argv[3])
def main(): if len(sys.argv) != 7: my_print( "usage: python runCIDMChain.py circuit_folder conf_template_file conf_output_file conf_cell_file sub_folder fitting_type", EscCodes.FAIL) else: run_cidm_chain(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])
def main(): if len(sys.argv) != 8: my_print( "usage: python causalityChecker.py circuit_folder default_gate_config_file_path circuit_gate_config_file_path structure_file_path characterization_conf_file_path sdf_file_path instance_mapping_file_path", EscCodes.FAIL) else: causality_checker(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7])
def main(): if len(sys.argv) != 10: my_print( "usage: python prepareFigureData.py start_out_name crossings_file involution_vcd modelsim_vcd matching_file fig_dir tex_template_file results_file line_template", EscCodes.FAIL) sys.exit(1) prepareFigureData(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8], sys.argv[9])
def build_function(use_gidm, gate, output): signal_list = list() delay_channel_list = list() function_input_list = list() function = "" if not use_gidm and (gate.channel_location == ChannelLocation.INPUT or gate.channel_location == ChannelLocation.INPUT_SWAPPED): my_print("Before") function = output + " <= " for input in gate.inputs: function_input_list.append(input + "_del") for input in gate.inputs: signal_list.append(input + "_del") for input in gate.inputs: delay_channel_list.append((input, input + "_del")) if not use_gidm and (gate.channel_location == ChannelLocation.OUTPUT or gate.channel_location == ChannelLocation.OUTPUT_SWAPPED): my_print("After") function = output + "_pre <= " function_input_list = gate.inputs for out in gate.outputs: signal_list.append(out + "_pre") for out in gate.outputs: delay_channel_list.append((out + "_pre", out)) if use_gidm: # the function is built different when using GIDM # we ignore the ChannelLocation fpr GIDM # Currently just one output supported function = gate.outputs[0] + "PreDelay <= " for input in gate.inputs: function_input_list.append(input + "AfterDelta") for out in gate.outputs: delay_channel_list.append((out + "PreDelay", out)) if len(function_input_list) == 1: function += gate.function + " " + function_input_list[0] else: for input in function_input_list[:-1]: function += input + " " + gate.function + " " function += function_input_list[-1] function += ";" return function, function_input_list, delay_channel_list, signal_list
def main(): if len(sys.argv) == 6: digitize_raw(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], None) elif len(sys.argv) == 7: digitize_raw(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6]) else: my_print( "usage: python digitizeRaw.py raw_file vcd_file crossings_file vth maching_file discretization_thresholds_file", EscCodes.FAIL) sys.exit(1)
def main(): if len(sys.argv) == 8: prepare_testbench(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], "") elif len(sys.argv) == 9: prepare_testbench(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8]) else: my_print( "usage: python prepareTestbench.py circuit_file_in circuit_file_out process_template_file input_names vector_names default_gate_config_file circuit_gate_config_file [circuit_configuration_file]", EscCodes.FAIL) sys.exit(1)
def main(): if len(sys.argv) != 9 and len(sys.argv) != 10: my_print( "usage: python fitting.py circuit_folder data_folder result_folder fitting_type channel_type structure_file_path sdf_file_path instance_mapping_file_path", EscCodes.FAIL) else: disable_fitting = False if (len(sys.argv) == 10): disable_fitting = to_bool(sys.argv[9]) run_fitting(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8], disable_fitting)
def read_crossings(input_dir, output_dir, matching_file, names): in_filename = os.path.join(input_dir, 'crossings.json') with open(in_filename, 'r') as f: data = json.load(f) # check if output folder exists if not os.path.exists(output_dir): os.makedirs(output_dir) matching_dict = matching_file_to_dict(matching_file) matching_dict = dict_key_to_lower_case(matching_dict) data['initial_values'] = dict_key_to_lower_case(data['initial_values']) data['crossing_times'] = dict_key_to_lower_case(data['crossing_times']) for name in names: out_file_name = os.path.join(output_dir, outFileNameStart + name) # We need to find the key corresponding to the name name_spice = None for k, v in matching_dict.items(): if v.lower() == name.lower(): assert (not name_spice) # not set yet name_spice = k assert (name_spice) # set yet value = data['initial_values'][name_spice] f = open(out_file_name, 'w') f.write('# Input values for involution tool\n') f.write('# time [fs] \t value\n') f.write(str(int(0)) + '\t' + str(value) + '\n') for i in data['crossing_times'][name_spice]: if value == 0: value = 1 else: value = 0 # int() truncates, maybe we should use rounding instead of truncating? #f.write(str(int(i*1e15)) + '\t' + str(value) + '\n') f.write(str(int(round(i * 1e15))) + '\t' + str(value) + '\n') f.close() my_print("File '" + out_file_name + "' sucessfully generated")
def main(): # required_gates is optional, if not set, all gates are generated if len(sys.argv) == 11: generate_gates(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8], sys.argv[9], sys.argv[10], None) elif len(sys.argv) == 12: generate_gates(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8], sys.argv[9], sys.argv[10], sys.argv[11]) else: my_print( "usage: python generateGates.py default_config_file circuit_config_file gate_dir gate_template_file gate_input_process_template_file use_gidm structure_file tt_file_path generate_gate_per_instance required_gates", EscCodes.FAIL) sys.exit(1)
def get_main_page_data(debug=False): """#get main page data, and save the result to file ./api-data/main_page_data.json""" helper.remove_file(config.FILENAME_MAIN_PAGE_DATA) # 先删除可能已存在的文件后, 再重新保存 helper.create_dir(config.SAVE_FILE_DIR) t0 = time.time() url = helper.get_main_page_url() content = helper.get_url_content(url) # 获取首页的一级页面列表(包含年级列表,滚动图列表,学习计划列表等) if content is None: helper.my_print_error("main_page_data is None.") else: helper.save_content_to_file(config.FILENAME_MAIN_PAGE_DATA, content) helper.my_print(content, debug) print('Done. %f seconds cost.' % (time.time() - t0))
def build_pure_delay_code(func, pure_delay_up, pure_delay_down, current_input, all_inputs): (pd_up_val, pd_up_unit) = parse_pure_delay(pure_delay_up) (pd_down_val, pd_down_unit) = parse_pure_delay(pure_delay_down) code = "" if func.lower() == "not": code = ("if tt_level = '1' then" + "\n" + "\t\t\t\tpure_delay := " + build_pure_delay_string(pd_down_val, pd_down_unit) + ";\n" + "\t\t\telse" + "\n" + "\t\t\t\tpure_delay := " + build_pure_delay_string(pd_up_val, pd_up_unit) + ";\n" + "\t\t\tend if;") elif func.lower() == "": # Buffer code = ("if tt_level = '1' then" + "\n" + "\t\t\t\tpure_delay := " + build_pure_delay_string(pd_up_val, pd_up_unit) + ";\n" + "\t\t\telse" + "\n" + "\t\t\t\tpure_delay := " + build_pure_delay_string(pd_down_val, pd_down_unit) + ";\n" + "\t\t\tend if;") elif func.lower() == "nand" and len(all_inputs) == 2: # current_input = if (all_inputs[0] == current_input): other_input = all_inputs[1] else: other_input = all_inputs[0] # We only use \ddomin when we can get a falling transition on the output # Otherwise, we use \dupmin. # Note that this is still not an optimal solution, since it does not consider the Charlie effect for example. # Another thing is how to delay an input, if it would cause no transition after the gate, for example # if one input is 0, and the other one toggles? The output still remains the same (1). code = ("if tt_level = '1' and " + other_input + " = '1' then" + "\n" + "\t\t\t\tpure_delay := " + build_pure_delay_string(pd_down_val, pd_down_unit) + ";\n" + "\t\t\telse" + "\n" + "\t\t\t\tpure_delay := " + build_pure_delay_string(pd_up_val, pd_up_unit) + ";\n" + "\t\t\tend if;") else: assert pd_up_unit == pd_down_unit and pd_up_val == pd_down_val my_print( "No special pure delay calculation implemented for " + func + ". Either implement how you want to handle the specific function, or use equal pure delays!", EscCodes.WARNING) code = "pure_delay := " + build_pure_delay_string( pd_up_val, pd_up_unit) + ";" return code
def get_third_page_data(debug=False): """#get third page data, and save result to file ./api-data/third_page_data.json""" t0 = time.time() helper.remove_file(config.FILENAME_THIRD_PAGE_DATA) helper.remove_file(config.FILENAME_THIRD_SECTIONIDS_DATA) helper.create_dir(config.SAVE_FILE_DIR) with open(config.FILENAME_SECOND_PAGE_SECTIONIDS_DATA) as f: i = 0 lines = f.readlines() helper.my_print("total has %d chapters...\n" % len(lines), debug) for line in lines: i += 1 section_id = str(int(line)) helper.my_print("line:%d sectionID:%s" % (i, section_id), debug) time.sleep(config.SLEEP_TIME) url = helper.get_third_page_url(section_id) content = helper.get_url_content( url) # 根据某个章节的 sectionID, 获取其知识点列表 if content is None: helper.my_print_error("the content is None.") else: helper.save_content_to_file(config.FILENAME_THIRD_PAGE_DATA, content) helper.my_print(content, debug) # 获取知识点对应的课程ID列表(用于根据课程ID, 获取题目列表) json_data = json.loads(content) for course in json_data['list']: course_dic = { 'courseSectionID': course['courseSectionID'], 'sectionName': course['sectionName'], 'parentID': course['parentID'] } data = json.dumps(course_dic, ensure_ascii=False) helper.save_content_to_file( config.FILENAME_THIRD_SECTIONIDS_DATA, data) helper.my_print(data, debug) helper.my_print("", debug) print('Done. %f seconds cost.' % (time.time() - t0))
def prepate_gates(default_config_file, circuit_config_file, template_gate_config_file, output_file, required_gates): gates = read_gate_config(default_config_file, circuit_config_file) gate_config_template = "" with open(template_gate_config_file, 'r') as tempfile: gate_config_template = tempfile.read() generate_all = required_gates is None or "ALL" in required_gates file_content = "" # now that we have all the gates we want to create --> create them for name, gate in gates.items(): if not generate_all and name not in required_gates: my_print("Ignoring: " + name) continue # we do not want to generate all gates, if not necessary for the circuit channel_parameters = "" for param_key, param_value in gate.channel_parameters.items(): channel_parameters += replace_special_chars( str(param_key)) + ": " + replace_special_chars( str(param_value)) + "\\\\" if channel_parameters != "": channel_parameters = "Additional channel parameters: \\\\\n" + channel_parameters file_content = gate_config_template.replace( "%##ENTITY_NAME##%", replace_special_chars(gate.entity_name)).replace( "%##CHANNEL_TYPE##%", replace_special_chars(str(gate.channel_type))).replace( "%##EXP_CHANNEL_LOCATION##%", replace_special_chars(str(gate.channel_location))).replace( "%##CHANNEL_LOCATION##%", str(gate.channel_location)).replace( "%##T_P##%", str(gate.T_P)).replace( "%##FUNCTION##%", gate.function).replace( "%##INPUTS##%", ", ".join(gate.inputs)).replace( "%##OUTPUTS##%", ", ".join(gate.outputs)).replace( "%##CHANNEL_PARAMETERS##%", channel_parameters) with open(output_file, 'w') as outfile: outfile.write(file_content)
def execute_make_cmd(cmd): if (os.getenv('SKIP_SIMULATION', None)): return #make_process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=os.environ["EXPERIMENT_SETUP_DIR"]) postfix = "" print_level = get_print_level() if print_level > PrintLevel.INFORMATION: postfix = "--silent" make_process = subprocess.Popen(cmd + " " + postfix, shell=True, cwd=os.environ["EXPERIMENT_SETUP_DIR"]) if make_process.wait() != 0: my_print(cmd + " failed!", EscCodes.FAIL, override_print_env_flag) else: my_print(cmd + " succeeded!", EscCodes.OKGREEN, override_print_env_flag)
def power_to_si_prefix(power): if power == 1e-12: return "\pico" elif power == 1e-9: return "\nano" elif power == 1e-6: return "\micro" elif power == 1e-3: return "\milli" elif power == 1e3: return "\kilo" elif power == 1e6: return "\mega" elif power == 1e9: return "\giga" elif power == 1e12: return "\tera" my_print("No prefix found for power: " + str(power), EscCodes.WARNING) return ""
def prefix_to_power(prefix): if prefix == "m": return float(1e-3) elif prefix == "u": return float(1e-6) elif prefix == "n": return float(1e-9) elif prefix == "p": return float(1e-12) elif prefix == "k": return float(1e3) elif prefix == "M": return float(1e6) elif prefix == "G": return float(1e9) elif prefix == "T": return float(1e12) my_print("Prefix " + prefix + " not recognized!", EscCodes.WARNING) return float(1)