Example #1
0
 def LoadSettings(self):
     self.timer.setInterval(60000 * int(self.settings.value("interval", 20)))
     self.hideAfterStart = to_bool(self.settings.value("hide", "true"))
     self.showNotifications = to_bool(self.settings.value("notifications", "true"))
     self.accessKey = str(self.settings.value("access_key", ""))
     self.secretKey = str(self.settings.value("secret_key", ""))
     self.associateTag = str(self.settings.value("associate_tag", ""))
     self.sysNotify = to_bool(self.settings.value("sys_notify", "false"))
     self.lastUpdate = self.settings.value("last_update", QtCore.QDateTime())
     
     self.LoadAppearanceSettings()
Example #2
0
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)
Example #3
0
    def LoadSettings(self):
        self.timeSpin.setValue(int(self.settings.value("interval", 20)))
        self.akEdit.setText(self.settings.value("access_key", ""))
        self.skEdit.setText(self.settings.value("secret_key", ""))
        self.atEdit.setText(self.settings.value("associate_tag", ""))
        self.hideCheck.setChecked(to_bool(self.settings.value("hide", "true")))
        self.notifyCheck.setChecked(to_bool(self.settings.value("notifications", "true")))
        self.sendCheck.setChecked(to_bool(self.settings.value("sys_notify", "true")))
        self.notifyGB.setEnabled(self.notifyCheck.isChecked())
        
        self.settings.beginGroup("Appearance")
        
        self.samplesSpin.setValue(int(self.settings.value("graph_n_samples", defaults.GetNumSamples())))
        self.ulcButton.SetColor(ReadColorValue(self.settings, "graph_up_line_color", defaults.GetUpLineColor()))
        self.ufcButton.SetColor(ReadColorValue(self.settings, "graph_up_fill_color", defaults.GetUpFillColor()))
        self.dlcButton.SetColor(ReadColorValue(self.settings, "graph_down_line_color", defaults.GetDownLineColor()))
        self.dfcButton.SetColor(ReadColorValue(self.settings, "graph_down_fill_color", defaults.GetDownFillColor()))
        self.nlcButton.SetColor(ReadColorValue(self.settings, "graph_neutral_line_color", defaults.GetNeutralLineColor()))
        self.nfcButton.SetColor(ReadColorValue(self.settings, "graph_neutral_fill_color", defaults.GetDefaultNeutralFillColor()))
        self.utcButton.SetColor(ReadColorValue(self.settings, "text_up_foreground_color", defaults.GetTextUpForegroundColor()))
        self.dtcButton.SetColor(ReadColorValue(self.settings, "text_down_foreground_color", defaults.GetTextDownForegroundColor()))

        self.settings.endGroup()
Example #4
0
def generate_gates(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, vectors_dir_file_path,
                   required_gates):

    gates = read_gate_config(default_config_file, circuit_config_file)
    use_gidm = to_bool(use_gidm)
    generate_gate_per_instance = to_bool(generate_gate_per_instance)

    # read template for gate
    gate_template = ""
    with open(gate_template_file, 'r') as template_file:
        gate_template = template_file.read()

    # read template for gate input process
    gate_input_process_template = ""
    with open(gate_input_process_template_file, 'r') as template_file:
        gate_input_process_template = template_file.read()

    generate_all = required_gates is None or "ALL" in required_gates

    structure = CircuitStructure()
    if use_gidm or generate_gate_per_instance:
        # now we need to read the structure.json file and generate
        structure = read_circuit_structure(structure_file)
    else:
        # This case is obsolete, we do not want to maintain this option any more.
        # Simply switch to GIDM or to generate_gate_per_instance
        # There is no function reduction, only a little performance sacrifice
        my_print("Gate generation configuration not supported any more!",
                 EscCodes.FAIL)

    # now that we have all the gates we want to create --> create them
    for name, gate in gates.items():
        if not check_gate_creation(generate_all, name, required_gates, gate):
            continue

        output = gate.outputs[0]

        function, function_input_list, delay_channel_list, signal_list = build_function(
            use_gidm, gate, output)

        entity_generic = build_entity_generic(gate)

        channel, d_up, d_down = build_channel_parameters(
            delay_channel_list, gate, output, use_gidm)

        arch_name = build_arch_name(use_gidm, gate)

        # Replace stuff that is independent of GIDM / IDM, and the ImplementationType
        content = gate_template.replace("##ARCH_NAME##", arch_name).replace(
            "##ARCH_FUNCTION##",
            function).replace("##ENTITY_GENERIC##", entity_generic).replace(
                "##GATE_SPECIFIC_PARAMETERS##", "")

        if use_gidm:
            generate_gate_gidm(gate, content, structure, name, channel,
                               gate_dir, gate_input_process_template,
                               tt_file_path, function_input_list, output,
                               vectors_dir_file_path)
        else:
            generate_gate_idm(gate, content, structure, name, channel,
                              gate_dir, d_up, d_down, signal_list,
                              generate_all, required_gates)
def generate_cell_initialization(circuit_folder, characterization_conf_file_path, structure_file_path, default_gate_config_file_path, circuit_gate_config_file_path, start_value):
    characterization_conf_file_path =  os.path.join(circuit_folder, characterization_conf_file_path)
    structure_file_path =  os.path.join(circuit_folder, structure_file_path)
    default_gate_config_file_path =  os.path.join(circuit_folder, default_gate_config_file_path)
    circuit_gate_config_file_path =  os.path.join(circuit_folder, circuit_gate_config_file_path)
    start_value = str(start_value)

    init_mapping = dict()

    # Need to read the characterization file
    char_conf = None
    with open(characterization_conf_file_path) as json_file:
        char_conf = json.load(json_file)

    # Need to read structure file
    structure = read_circuit_structure(structure_file_path)

    # Need to read the gate config file, to check which gate type we have
    gate_config = read_gate_config(default_gate_config_file_path, circuit_gate_config_file_path)

    # Traverse over the dependeny tree and fill out init mapping
    importer = DictImporter()
    dependency_tree = importer.import_(char_conf['dependency_tree'])
    for node in PreOrderIter(dependency_tree):	        
        if node.name == 'Top':
            continue

        cellname = get_cellname(char_conf, node.name)

        # Now use the cellname to find the cell_type in the structure.json file

        found_cell = find_cell_in_structure(structure, cellname)
        assert(found_cell)

        # Now we use the cell_type and find the function in the gate config
        gate = gate_config[found_cell.cell_type]
        # print(node.name, cellname, found_cell, gate, gate.function)

        assert(gate.function == "not" or gate.function == "")
        input_found_cell = gate.inputs
        assert(len(input_found_cell) == 1)
        input_found_cell = input_found_cell[0]

        # We need to find the predecessor and get the output value of the predecessor
        pred = find_pred_interconnect(structure, found_cell, input_found_cell)
        print(pred, cell)

        # Get the value of the predecessor from the dict
        in_value = None
        if pred.from_instance in init_mapping:
            in_value = init_mapping[pred.from_instance]
        else:
            in_value = start_value

        in_value = to_bool(in_value)
        logic_function = None
        if gate.function == "not":
            logic_function = my_not
        elif gate.funtion == "":
            logic_function = my_id
        else:
            assert(False)

        init_mapping[cell.instance] = bool_to_logic(logic_function(in_value))       
    

    # Write the init mapping to the structure file and save it
    structure.init = init_mapping
    save_circuit_structure(structure_file_path, structure)
def prepareFigureData(start_out_name, crossings_file, involution_vcd,
                      modelsim_vcd, matching_file, fig_dir, tex_template_file,
                      results_file, line_template):
    global vdd, vss, vth

    MATCHING = []

    fig_folder = fig_dir
    # check if output folder exists
    if not os.path.exists(fig_folder):
        os.makedirs(fig_folder)

    MATCHING = matching_file_to_list(matching_file)

    if "VDD" in os.environ:
        vdd = float(os.environ["VDD"])

    if "VTH" in os.environ:
        vth = float(os.environ["VTH"])

    if "VSS" in os.environ:
        vss = float(os.environ["VSS"])

    my_print(str(MATCHING))

    with open(crossings_file, 'r') as f:
        spiceData = json.load(f)

    involutionData = read_modelsim(involution_vcd, vdd, vth, vss)
    modelsimData = read_modelsim(modelsim_vcd, vdd, vth, vss)

    my_print("\ttransition count \t \t \tsum(error(.))")
    my_print("name\tSPICE\tInvolution\tModelsim\tInvolution\tModelsim")

    content = ""
    # extend the results file with the max / sum values
    max_values_dict = dict()
    max_values_dict["max_tc_dev_per_inv"] = 0
    max_values_dict["max_tc_dev_abs_inv"] = 0
    max_values_dict["max_tc_dev_per_msim"] = 0
    max_values_dict["max_tc_dev_abs_msim"] = 0

    max_values_dict["total_sum_error_inv"] = 0
    max_values_dict["total_pos_area_under_dev_trace_inv"] = 0
    max_values_dict["total_neg_area_under_dev_trace_inv"] = 0
    max_values_dict["total_pos_area_under_dev_trace_inv_wo_glitches"] = 0
    max_values_dict["total_neg_area_under_dev_trace_inv_wo_glitches"] = 0
    max_values_dict["total_pos_area_under_dev_trace_inv_transitions"] = 0
    max_values_dict["total_neg_area_under_dev_trace_inv_transitions"] = 0
    max_values_dict[
        "total_pos_area_under_dev_trace_inv_transitions_wo_glitches"] = 0
    max_values_dict[
        "total_neg_area_under_dev_trace_inv_transitions_wo_glitches"] = 0

    max_values_dict["total_sum_error_msim"] = 0
    max_values_dict["total_pos_area_under_dev_trace_msim"] = 0
    max_values_dict["total_neg_area_under_dev_trace_msim"] = 0
    max_values_dict["total_pos_area_under_dev_trace_msim_wo_glitches"] = 0
    max_values_dict["total_neg_area_under_dev_trace_msim_wo_glitches"] = 0
    max_values_dict["total_pos_area_under_dev_trace_msim_transitions"] = 0
    max_values_dict["total_neg_area_under_dev_trace_msim_transitions"] = 0
    max_values_dict[
        "total_pos_area_under_dev_trace_msim_transitions_wo_glitches"] = 0
    max_values_dict[
        "total_neg_area_under_dev_trace_msim_transitions_wo_glitches"] = 0

    max_values_dict["total_sum_glitches_spice_inv"] = 0
    max_values_dict["total_sum_glitches_orig_spice_inv"] = 0
    max_values_dict["total_sum_glitches_inverted_spice_inv"] = 0

    max_values_dict["total_sum_glitches_inv"] = 0
    max_values_dict["total_sum_glitches_orig_inv"] = 0
    max_values_dict["total_sum_glitches_inverted_inv"] = 0

    max_values_dict["total_sum_glitches_spice_msim"] = 0
    max_values_dict["total_sum_glitches_orig_spice_msim"] = 0
    max_values_dict["total_sum_glitches_inverted_spice_msim"] = 0

    max_values_dict["total_sum_glitches_msim"] = 0
    max_values_dict["total_sum_glitches_orig_msim"] = 0
    max_values_dict["total_sum_glitches_inverted_msim"] = 0

    max_values_dict["total_tc_spice"] = 0
    max_values_dict["total_tc_msim"] = 0
    max_values_dict["total_tc_inv"] = 0

    max_values_dict["last_transition_time"] = 0
    max_values_dict["first_transition_time"] = 0

    # Define y-axis limits
    y_margin = 0.2
    ylim_start = vss - y_margin
    ylim_end = vdd + y_margin

    # Define x-axis limits (global for all signals, so that we can better compare different plots)
    # we can ignore the "deviation" traces for this part, since the first "transition" is at the first transition
    # of either the trace or the inv / modelsim signal
    x_first = sys.float_info.max
    x_last = sys.float_info.min
    overlapping = 0.1
    zoom_number = 3
    export_signal_result = False

    if "FIGURE_ZOOM_NUMBER" in os.environ:
        zoom_number = int(os.environ["FIGURE_ZOOM_NUMBER"])

    if "FIGURE_ZOOM_OVERLAPPING" in os.environ:
        overlapping = float(os.environ["FIGURE_ZOOM_OVERLAPPING"])

    inv_export_dev_trace_inf = True
    if "FIGURE_INV_EXPORT_DEV_TRACE_INFO" in os.environ:
        inv_export_dev_trace_inf = to_bool(
            os.environ["FIGURE_INV_EXPORT_DEV_TRACE_INFO"])

    msim_export_dev_trace_inf = True
    if "FIGURE_MSIM_EXPORT_DEV_TRACE_INFO" in os.environ:
        msim_export_dev_trace_inf = to_bool(
            os.environ["FIGURE_MSIM_EXPORT_DEV_TRACE_INFO"])

    if "EXPORT_SIGNAL_RESULT" in os.environ:
        export_signal_result = to_bool(os.environ["EXPORT_SIGNAL_RESULT"])

    round_digits = -1  # next 10e-1, e.g. 0.17 = 0.2, 0.13 = 0.1

    # before we do anything => convert key to lower()
    for idx, (spice_name, msim_name) in enumerate(MATCHING):
        MATCHING[idx] = (spice_name.lower(), msim_name.lower())
    spiceData['crossing_times'] = dict_key_to_lower_case(
        spiceData['crossing_times'])
    spiceData['initial_values'] = dict_key_to_lower_case(
        spiceData['initial_values'])
    involutionData = dict_key_to_lower_case(involutionData)
    modelsimData = dict_key_to_lower_case(modelsimData)

    for entry in MATCHING:
        #print(spiceData['crossing_times'])
        signal_name = entry[1]

        if len(spiceData['crossing_times'][entry[0]]) > 1:
            # print spiceData['crossing_times'][entry[0]]
            # print trace[0][1]

            x_first = min(x_first,
                          spiceData['crossing_times'][entry[0]][0] * 1e-9)
            x_last = max(x_last,
                         spiceData['crossing_times'][entry[0]][-1] * 1e-9)

        if len(involutionData[signal_name][0]) > 1:
            x_first = min(x_first, involutionData[signal_name][0][1])
            x_last = max(x_last, involutionData[signal_name][0][-1])
        if len(modelsimData[signal_name][0]) > 1:
            x_first = min(x_first, modelsimData[signal_name][0][1])
            x_last = max(x_last, modelsimData[signal_name][0][-1])

    # Used for evaluating the overall simulation time
    max_values_dict["last_transition_time"] = x_last
    max_values_dict["first_transition_time"] = x_first

    x_first = math.floor(x_first * pow(10, round_digits * -1)) / (pow(
        10, round_digits * -1))
    x_last = math.ceil(x_last * pow(10, round_digits * -1)) / (pow(
        10, round_digits * -1))
    x_last = x_last + 0.2  # "margin" at the right border

    signal_ignore_set = set()
    if "FIGURE_IGNORE_SIGNALS" in os.environ:
        # signal_ignore_set =
        signal_ignore_set = set([
            item.lower()
            for item in json.loads(os.environ["FIGURE_IGNORE_SIGNALS"])
        ])

    for entry in MATCHING:

        signal_name = entry[1]

        if signal_name in signal_ignore_set:
            my_print("Ignore signal: " + signal_name +
                     " during trace deviation extraction")
            continue

        # get the traces from the various dump files
        trace = get_trace(spiceData['crossing_times'][entry[0]],
                          spiceData['initial_values'][entry[0]])

        dataInv = involutionData[signal_name]
        # print("Inv", dataInv)
        dev_trace_inv_results = get_deviation_trace(trace, dataInv,
                                                    inv_export_dev_trace_inf,
                                                    fig_folder,
                                                    'inv_' + signal_name)

        dataModelsim = modelsimData[signal_name]
        # print("MSIM", dataModelsim)
        dev_trace_msim_results = get_deviation_trace(
            trace, dataModelsim, msim_export_dev_trace_inf, fig_folder,
            'msim_' + signal_name)

        tc_spice = (len(trace[0]) - 1) / 2
        tc_involution = len(dataInv[0]) / 2
        tc_modelsim = len(dataModelsim[0]) / 2
        if dataModelsim[1][0] == vth:
            # if the first transition is from X to 0 or 1,
            # ignore this transition, because neither SPICE nor Involution have this transition
            tc_modelsim -= 1

        # print the trace "results"
        my_print("%s\t%d\t%d\t\t%d\t\t%.3f\t\t%.3f" %
                 (signal_name, tc_spice, tc_involution, tc_modelsim,
                  dev_trace_inv_results["total_area_under_dev_trace"],
                  dev_trace_msim_results["total_area_under_dev_trace"]))

        # prepare the content for the waveform comparison table in the report
        content += line_template \
        .replace("%##NAME##%", replace_special_chars(signal_name)) \
        .replace("%##TC_SPICE##%", str(tc_spice)) \
        .replace("%##TC_INVOLUTION##%", str(tc_involution)) \
        .replace("%##TC_MSIM##%", str(tc_modelsim)) \
        .replace("%##TOTAL_AREA_UNDER_DEV_TRACE_INV##%", str(dev_trace_inv_results["total_area_under_dev_trace"])) \
        .replace("%##TOTAL_POS_AREA_UNDER_DEV_TRACE_INV##%", str(dev_trace_inv_results["pos_area_under_dev_trace"])) \
        .replace("%##TOTAL_NEG_AREA_UNDER_DEV_TRACE_INV##%", str(dev_trace_inv_results["neg_area_under_dev_trace"])) \
        .replace("%##TOTAL_AREA_UNDER_DEV_TRACE_MSIM##%", str(dev_trace_msim_results["total_area_under_dev_trace"])) \
        .replace("%##TOTAL_POS_AREA_UNDER_DEV_TRACE_MSIM##%", str(dev_trace_msim_results["pos_area_under_dev_trace"]))\
        .replace("%##TOTAL_NEG_AREA_UNDER_DEV_TRACE_MSIM##%", str(dev_trace_msim_results["neg_area_under_dev_trace"])) \
        .replace("%##GLITCHES_SPICE_INV##%", str(dev_trace_inv_results["total_glitches_tr0"])) \
        .replace("%##GLITCHES_ORIG_SPICE_INV##%", str(dev_trace_inv_results["orig_glitches_tr0"])) \
        .replace("%##GLITCHES_INVERTED_SPICE_INV##%", str(dev_trace_inv_results["inverted_glitches_tr0"])) \
        .replace("%##GLITCHES_SPICE_MSIM##%", str(dev_trace_msim_results["total_glitches_tr0"])) \
        .replace("%##GLITCHES_ORIG_SPICE_MSIM##%", str(dev_trace_msim_results["orig_glitches_tr0"])) \
        .replace("%##GLITCHES_INVERTED_SPICE_MSIM##%", str(dev_trace_msim_results["inverted_glitches_tr0"])) \
        .replace("%##GLITCHES_INV##%", str(dev_trace_inv_results["total_glitches_tr1"])) \
        .replace("%##GLITCHES_ORIG_INV##%", str(dev_trace_inv_results["orig_glitches_tr1"])) \
        .replace("%##GLITCHES_INVERTED_INV##%", str(dev_trace_inv_results["inverted_glitches_tr1"])) \
        .replace("%##GLITCHES_MSIM##%", str(dev_trace_msim_results["total_glitches_tr1"])) \
        .replace("%##GLITCHES_ORIG_MSIM##%", str(dev_trace_msim_results["orig_glitches_tr1"])) \
        .replace("%##GLITCHES_INVERTED_MSIM##%", str(dev_trace_msim_results["inverted_glitches_tr1"])) \
        + "\n"

        # store the signal value into a dict
        signal_values_dict = dict()

        signal_values_dict["total_sum_error_inv"] = dev_trace_inv_results[
            "total_area_under_dev_trace"]
        signal_values_dict[
            "total_pos_area_under_dev_trace_inv"] = dev_trace_inv_results[
                "pos_area_under_dev_trace"]
        signal_values_dict[
            "total_neg_area_under_dev_trace_inv"] = dev_trace_inv_results[
                "neg_area_under_dev_trace"]

        signal_values_dict[
            "total_pos_area_under_dev_trace_inv_wo_glitches"] = dev_trace_inv_results[
                "pos_area_under_dev_trace_wo_glitches"]
        signal_values_dict[
            "total_neg_area_under_dev_trace_inv_wo_glitches"] = dev_trace_inv_results[
                "neg_area_under_dev_trace_wo_glitches"]
        signal_values_dict[
            "total_pos_area_under_dev_trace_inv_transitions"] = dev_trace_inv_results[
                "pos_area_under_dev_trace_transitions"]
        signal_values_dict[
            "total_neg_area_under_dev_trace_inv_transitions"] = dev_trace_inv_results[
                "neg_area_under_dev_trace_transitions"]
        signal_values_dict[
            "total_pos_area_under_dev_trace_inv_transitions_wo_glitches"] = dev_trace_inv_results[
                "pos_area_under_dev_trace_transitions_wo_glitches"]
        signal_values_dict[
            "total_neg_area_under_dev_trace_inv_transitions_wo_glitches"] = dev_trace_inv_results[
                "neg_area_under_dev_trace_transitions_wo_glitches"]

        signal_values_dict["total_sum_error_msim"] = dev_trace_msim_results[
            "total_area_under_dev_trace"]
        signal_values_dict[
            "total_pos_area_under_dev_trace_msim"] = dev_trace_msim_results[
                "pos_area_under_dev_trace"]
        signal_values_dict[
            "total_neg_area_under_dev_trace_msim"] = dev_trace_msim_results[
                "neg_area_under_dev_trace"]

        signal_values_dict[
            "total_pos_area_under_dev_trace_msim_wo_glitches"] = dev_trace_msim_results[
                "pos_area_under_dev_trace_wo_glitches"]
        signal_values_dict[
            "total_neg_area_under_dev_trace_msim_wo_glitches"] = dev_trace_msim_results[
                "neg_area_under_dev_trace_wo_glitches"]
        signal_values_dict[
            "total_pos_area_under_dev_trace_msim_transitions"] = dev_trace_msim_results[
                "pos_area_under_dev_trace_transitions"]
        signal_values_dict[
            "total_neg_area_under_dev_trace_msim_transitions"] = dev_trace_msim_results[
                "neg_area_under_dev_trace_transitions"]
        signal_values_dict[
            "total_pos_area_under_dev_trace_msim_transitions_wo_glitches"] = dev_trace_msim_results[
                "pos_area_under_dev_trace_transitions_wo_glitches"]
        signal_values_dict[
            "total_neg_area_under_dev_trace_msim_transitions_wo_glitches"] = dev_trace_msim_results[
                "neg_area_under_dev_trace_transitions_wo_glitches"]

        signal_values_dict[
            "total_sum_glitches_spice_inv"] = dev_trace_inv_results[
                "total_glitches_tr0"]
        signal_values_dict[
            "total_sum_glitches_orig_spice_inv"] = dev_trace_inv_results[
                "orig_glitches_tr0"]
        signal_values_dict[
            "total_sum_glitches_inverted_spice_inv"] = dev_trace_inv_results[
                "inverted_glitches_tr0"]

        signal_values_dict["total_sum_glitches_inv"] = dev_trace_inv_results[
            "total_glitches_tr1"]
        signal_values_dict[
            "total_sum_glitches_orig_inv"] = dev_trace_inv_results[
                "orig_glitches_tr1"]
        signal_values_dict[
            "total_sum_glitches_inverted_inv"] = dev_trace_inv_results[
                "inverted_glitches_tr1"]

        signal_values_dict[
            "total_sum_glitches_spice_msim"] = dev_trace_msim_results[
                "total_glitches_tr0"]
        signal_values_dict[
            "total_sum_glitches_orig_spice_msim"] = dev_trace_msim_results[
                "orig_glitches_tr0"]
        signal_values_dict[
            "total_sum_glitches_inverted_spice_msim"] = dev_trace_msim_results[
                "inverted_glitches_tr0"]

        signal_values_dict["total_sum_glitches_msim"] = dev_trace_msim_results[
            "total_glitches_tr1"]
        signal_values_dict[
            "total_sum_glitches_orig_msim"] = dev_trace_msim_results[
                "orig_glitches_tr1"]
        signal_values_dict[
            "total_sum_glitches_inverted_msim"] = dev_trace_msim_results[
                "inverted_glitches_tr1"]

        signal_values_dict["total_tc_spice"] = tc_spice
        signal_values_dict["total_tc_msim"] = tc_modelsim
        signal_values_dict["total_tc_inv"] = tc_involution

        # now add all the values from the signal_values_dict to the max_values_dict
        for key, value in signal_values_dict.items():
            max_values_dict[key] += signal_values_dict[key]

        if export_signal_result:
            export_signal_values_dict = dict()
            for key, value in signal_values_dict.items():
                export_signal_values_dict[
                    key + "_" + signal_name] = signal_values_dict[key]

            extend_results(results_file, export_signal_values_dict)

        if abs(max_values_dict["max_tc_dev_abs_inv"]) < abs(tc_spice -
                                                            tc_involution):
            max_values_dict["max_tc_dev_abs_inv"] = tc_spice - tc_involution

        if abs(max_values_dict["max_tc_dev_abs_msim"]) < abs(tc_spice -
                                                             tc_modelsim):
            max_values_dict["max_tc_dev_abs_msim"] = tc_spice - tc_modelsim

        # Changed according to https://en.wikipedia.org/wiki/Relative_change_and_difference#Percent_error
        #dev_per_inv = (tc_spice - tc_involution) / (tc_spice * 1.0)
        dev_per_inv = (tc_involution - tc_spice) / (tc_spice * 1.0)
        if abs(max_values_dict["max_tc_dev_per_inv"]) < abs(dev_per_inv):
            max_values_dict["max_tc_dev_per_inv"] = dev_per_inv

        #dev_per_msim = (tc_spice - tc_modelsim) / (tc_spice * 1.0)
        dev_per_msim = (tc_modelsim - tc_spice) / (tc_spice * 1.0)
        if abs(max_values_dict["max_tc_dev_per_msim"]) < abs(dev_per_msim):
            max_values_dict["max_tc_dev_per_msim"] = dev_per_msim

        # we do not want to generate plots
        if (zoom_number == 0):
            continue

        plt.rcParams['font.size'] = 16
        plt.rcParams['lines.linewidth'] = 5.0

        # Fig 1: print the traces (SPICE, Involution, ModelSim)
        spice_caption = "SPICE"
        inv_channel_caption = "Inv. Ch."
        vhdl_vital_caption = "VHDL Vital"

        name = start_out_name + signal_name
        filename = convert_string_to_filename(name)

        plt.figure()
        axes = list()
        axes.append(plt.subplot(3, 1, 1))
        plt.plot(trace[0], trace[1], '-r', linewidth=3)
        #plt.title('transition count: SPICE(%d), Involution(%d), Modelsim(%d)'% (tc_spice, tc_involution, tc_modelsim))
        plt.ylabel(spice_caption)
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        axes.append(plt.subplot(3, 1, 2))
        plt.plot(dataInv[0], dataInv[1], '#4DAF4A', linewidth=3)
        plt.ylabel(inv_channel_caption)
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        axes.append(plt.subplot(3, 1, 3))
        plt.plot(dataModelsim[0], dataModelsim[1], '#377EB8', linewidth=3)
        plt.xlabel('time [ns]')
        plt.ylabel(vhdl_vital_caption)
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        plt.savefig(fig_folder + filename + '.png')

        print_zoom_plots(fig_folder + filename, '.png', plt, axes, x_first,
                         x_last, zoom_number, overlapping)

        # Fig 2: print the deviation traces SPICE vs Involution

        plt.figure()
        axes = list()
        axes.append(plt.subplot(3, 1, 1))
        plt.plot(trace[0], trace[1], '-r', linewidth=2)
        plt.title('sum(error(%s)) = %.3f, sum(error(%s)) = %.3f' %
                  (inv_channel_caption,
                   dev_trace_inv_results["total_area_under_dev_trace"],
                   vhdl_vital_caption,
                   dev_trace_msim_results["total_area_under_dev_trace"]))
        plt.ylabel('SPICE')
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        axes.append(plt.subplot(3, 1, 2))
        plt.plot(dataInv[0], dataInv[1], '-b', linewidth=2)
        plt.ylabel(inv_channel_caption)
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        axes.append(plt.subplot(3, 1, 3))
        plt.plot(dev_trace_inv_results['dev_trace'][0],
                 dev_trace_inv_results['dev_trace'][1],
                 '-r',
                 linewidth=2)
        plt.xlabel('time [ns]')
        plt.ylabel('deviation')
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        plt.savefig(fig_folder + filename + '_devInv.png')

        print_zoom_plots(fig_folder + filename, '_devInv.png', plt, axes,
                         x_first, x_last, zoom_number, overlapping)

        # Fig 3: print the deviation traces SPICE vs Modelsim

        plt.figure()
        axes = list()
        axes.append(plt.subplot(3, 1, 1))
        plt.plot(trace[0], trace[1], '-r', linewidth=2)
        plt.title('sum(error(%s)) = %.3f, sum(error(%s)) = %.3f' %
                  (inv_channel_caption,
                   dev_trace_inv_results["total_area_under_dev_trace"],
                   vhdl_vital_caption,
                   dev_trace_msim_results["total_area_under_dev_trace"]))
        plt.ylabel('SPICE')
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        axes.append(plt.subplot(3, 1, 2))
        plt.plot(dataModelsim[0], dataModelsim[1], '-g', linewidth=2)
        plt.ylabel(vhdl_vital_caption)
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        axes.append(plt.subplot(3, 1, 3))
        plt.plot(dev_trace_msim_results["dev_trace"][0],
                 dev_trace_msim_results["dev_trace"][1],
                 '-r',
                 linewidth=2)
        plt.xlabel('time [ns]')
        plt.ylabel('deviation')
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        plt.savefig(fig_folder + filename + '_devModelsim.png')

        print_zoom_plots(fig_folder + filename, '_devModelsim.png', plt, axes,
                         x_first, x_last, zoom_number, overlapping)

        # Fig 4: deviation traces Involution vs Modelsim
        plt.figure()
        axes = list()
        axes.append(plt.subplot(2, 1, 1))
        plt.title('sum(error(%s)) = %.3f, sum(error(%s)) = %.3f' %
                  (inv_channel_caption,
                   dev_trace_inv_results["total_area_under_dev_trace"],
                   vhdl_vital_caption,
                   dev_trace_msim_results["total_area_under_dev_trace"]))
        plt.plot(dev_trace_inv_results["dev_trace"][0],
                 dev_trace_inv_results["dev_trace"][1],
                 '-b',
                 linewidth=2)
        plt.ylabel(inv_channel_caption)
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        axes.append(plt.subplot(2, 1, 2))
        plt.plot(dev_trace_msim_results["dev_trace"][0],
                 dev_trace_msim_results["dev_trace"][1],
                 '-g',
                 linewidth=2)
        plt.xlabel('time [ns]')
        plt.ylabel(vhdl_vital_caption)
        plt.ylim([ylim_start, ylim_end])
        plt.xlim([x_first, x_last])
        plt.grid()

        plt.savefig(fig_folder + filename + '_diff.png')

        print_zoom_plots(fig_folder + filename, '_diff.png', plt, axes,
                         x_first, x_last, zoom_number, overlapping)

    # now write the results in the tex file

    # read the content from the template file
    template_content = ""
    with open(tex_template_file, 'r') as infile:
        template_content = infile.read()

    content = template_content.replace("%##LINES##%", content)

    with open(tex_template_file, 'w') as outfile:
        outfile.write(content)

    max_values_dict["max_tc_dev_per_inv"] *= 100
    max_values_dict["max_tc_dev_per_msim"] *= 100

    max_values_dict["total_tc_deviation_per_msim"] = (
        max_values_dict["total_tc_msim"] - max_values_dict["total_tc_spice"]
    ) / (max_values_dict["total_tc_spice"] * 1.0) * 100
    max_values_dict["total_tc_deviation_per_inv"] = (
        max_values_dict["total_tc_inv"] - max_values_dict["total_tc_spice"]
    ) / (max_values_dict["total_tc_spice"] * 1.0) * 100

    extend_results(results_file, max_values_dict)