def run_simulation_questa(a_mp7_tag, a_menu, a_url_menu, a_vivado, a_questasim,
                          a_questasimlibs, a_output, a_view_wave, a_wlf,
                          a_verbose):
    print("a_mp7_tag: ", a_mp7_tag)
    print("a_menu: ", a_menu)
    print("a_url_menu: ", a_url_menu)
    print("a_vivado: ", a_vivado)
    print("a_questasim: ", a_questasim)
    print("a_questasimlibs: ", a_questasimlibs)
    # Check Questa sim version
    if a_questasim == '10.6a':
        questasim_path = QuestaSimPathVersion106a
    elif a_questasim == '10.7c':
        questasim_path = QuestaSimPathVersion107c
    else:
        raise RuntimeError("Questa sim version '%s' does NOT exist" %
                           a_questasim)

    if not os.path.isdir(questasim_path):
        raise RuntimeError("No installation of Questa sim in '%s'" %
                           questasim_path)

    # Set sim_dir
    sim_dir = os.path.join(os.path.dirname(__file__), '../firmware/sim')

    # Copy dofile from gtl_fdl_wrapper_tpl_questa_v<vivado version>.do to gtl_fdl_wrapper_tpl_questa.do
    src_do = os.path.join(
        sim_dir,
        'scripts/templates/gtl_fdl_wrapper_tpl_questa_v{}.do'.format(a_vivado))
    dest_do = os.path.join(sim_dir,
                           'scripts/templates/gtl_fdl_wrapper_tpl_questa.do')
    shutil.copyfile(src_do, dest_do)

    ## Path to Questa sim libs for selected vivado version
    #questasimlibs_name = a_questasimlibs + a_vivado
    #questasimlib_path = os.path.join('/opt/mentor/', questasimlibs_name)

    #print "questasimlib_path: ", questasimlib_path

    # Copy modelsim.ini from questasimlib dir to sim dir (to get questasim libs corresponding to Vivado version)
    command = 'bash -c "cp /opt/mentor/questasim/modelsim.ini {sim_dir}/modelsim.ini"'.format(
        **locals())
    print("command cp modelsim.ini: ", command)
    run_command(command)

    ## Run compile Vivado sim libs for Questa (if not exist)
    #run_compile_simlib(a_vivado, questasim_path, questasimlib_path)

    # using SIM_ROOT dir as default output path
    if not a_output:
        a_output = sim_dir

    # Set message mode:
    # wlf => no output to console for transcript info, warning and error messages (transccd -ript output to vsim.wlf).
    # tran => output to console.
    msgmode = 'wlf' if a_wlf else 'tran'

    temp_dir = os.path.join(sim_dir, "temp_dir")
    if not os.path.exists(temp_dir):
        os.makedirs(temp_dir)  #makes folders

    logging.info(
        "==========================================================================="
    )
    logging.info("download XML and testvector file from L1Menu repository ...")
    # Get l1menus_path for URL
    #url_menu = "{}/{}".format(url_menu_default, a_menu)
    url_menu = "{}/{}".format(a_url_menu, a_menu)
    print("=== url_menu: ", url_menu)
    xml_name = "{}{}".format(a_menu, '.xml')
    print("=== xml_name: ", xml_name)
    menu_filepath = os.path.join(temp_dir, xml_name)
    print("=== menu_filepath: ", menu_filepath)
    url = "{}/xml/{}".format(url_menu, xml_name)
    print("=== url: ", url)
    download_file_from_url(url, menu_filepath)
    # Remove "distribution number" from a_menu for testvector file name
    tv_name = "TestVector_{}{}".format((re.split("-", a_menu)[0]), '.txt')
    testvector_filepath = os.path.join(temp_dir, tv_name)
    url = "{}/testvectors/{}".format(url_menu, tv_name)
    download_file_from_url(url, testvector_filepath)

    # Get VHDL snippets from menu URL
    #print "menu_filepath: ", menu_filepath
    #print "testvector_filepath: ", testvector_filepath

    timestamp = time.time()  #creates timestamp
    _time = datetime.datetime.fromtimestamp(timestamp).strftime(
        '%Y-%m-%dT%H-%M-%S')  #changes time apperance

    base_dir = '%s/sim_results/%s_%s' % (
        a_output, _time, a_menu)  #creates base directory for later use

    modules = []
    menu = xmlmenu.XmlMenu(menu_filepath)
    for _id in range(menu.n_modules):  #makes list for each module
        modules.append(Module(menu, _id, base_dir))

    # Get VHDL snippets from menu URL
    for module in modules:
        vhdl_src_path = "vhdl/module_{}/src".format(module._id)
        temp_dir_module = os.path.join(temp_dir, vhdl_src_path)
        if not os.path.exists(temp_dir_module):
            os.makedirs(temp_dir_module)  #makes folders
        #print "temp_dir_module: ", temp_dir_module
        for vhdl_name in vhdl_snippets_names:
            vhdl_name_ext = vhdl_name + ".vhd"
            vhdl_file_local_path = os.path.join(temp_dir_module, vhdl_name_ext)
            #print "vhdl_file_local_path: ", vhdl_file_local_path
            vhdl_file_path = os.path.join(vhdl_src_path, vhdl_name_ext)
            url = "{}/{}".format(url_menu, vhdl_file_path)
            #print "url: ", url
            download_file_from_url(url, vhdl_file_local_path)

    if not os.path.exists(menu_filepath):  #checks for menu
        raise RuntimeError('Missing %s File' % menu_filepath)  #help
    if not os.path.exists(testvector_filepath):  #checks for testvector
        raise RuntimeError('Missing %s' %
                           testvector_filepath)  #its not working as intended
    if os.path.exists(base_dir):  #checks if directory alredy exists
        raise RuntimeError('Directory already exists!')

    os.makedirs(base_dir)  #makes folders

    ini_file = os.path.join(sim_dir, INI_FILE)

    logging.info('Creating Modules and Masks...')

    for module in modules:  #gives each module the information
        module_id = 'module_%d' % module._id
        testvector_base_name = os.path.splitext(
            os.path.basename(testvector_filepath))[0]
        module.testvector_filepath = os.path.join(
            module.path, '%s_%s.txt' % (testvector_base_name, module_id))

        os.makedirs('%s/testbench' % module.path)
        os.makedirs('%s/vhdl' % module.path)
        logging.debug('Module_%d: %0128x' % (module._id, module.get_mask()))

        make_testvector(
            module.get_mask(), testvector_filepath,
            module.testvector_filepath)  #mask, testvectorfile, out_dir

        logging.debug('Module_%d created at %s' % (module._id, base_dir))

        #module.make_files(sim_dir, a_view_wave, a_mp7_tag, a_menu)#sim_dir, view_wave, mp7_tag, menu_path
        module.make_files(sim_dir, a_view_wave, a_mp7_tag,
                          temp_dir)  #sim_dir, view_wave, mp7_tag, temp_dir

    logging.info('finished creating modules and masks')
    logging.info(
        "==========================================================================="
    )
    logging.info(
        'starting simulations with Questa Simulator version %s (from directory %s)'
        % (a_questasim, questasim_path))

    threads = []
    for module in modules:  #makes for all simulations a thread
        thread = Thread(target=run_vsim,
                        args=(questasim_path, module, msgmode, ini_file))
        threads.append(thread)
        thread.start()
        while not os.path.exists(
                os.path.join(module.path, 'running.lock')
        ):  #stops starting of new threads if .do file is still in use
            time.sleep(0.5)
        os.remove(os.path.join(module.path, 'running.lock'))

    for thread in threads:  #waits for all threads to finish
        thread.join()
    logging.info('finished all simulations')
    print('')

    algos_sim = {}
    algos_tv = {}

    for module in modules:  #steps through all modules and makes a list with trigger count and module
        jsonf = json.load(open(module.results_json))
        counts = jsonf['counts']
        for count in counts:
            index = count['algo_index']
            if index not in algos_sim:
                algos_sim[index] = []
            algos_sim[index].append(count['algo_sim'])
            if index not in algos_tv:
                algos_tv[index] = []
            algos_tv[index].append(count['algo_tv'])

    for index in range(len(
            algos_sim)):  #makes a list with tuples (module id, trigger count)
        algos_sim[index] = check_algocount(algos_sim[index])

    for index in range(len(algos_tv)):
        algos_tv[index] = check_algocount(algos_tv[index])

    # Summary logging
    sum_log = logging.getLogger("sum_log")
    sum_log.propagate = False
    handler = logging.StreamHandler(stream=sys.stdout)
    handler.setFormatter(logging.Formatter(fmt='%(message)s'))
    handler.setLevel(logging.DEBUG)
    sum_log.addHandler(handler)

    sum_file = os.path.join(base_dir, 'summary.txt')
    handler = logging.FileHandler(sum_file, mode='w')
    handler.setFormatter(logging.Formatter(fmt='%(message)s'))
    handler.setLevel(logging.DEBUG)
    sum_log.addHandler(handler)

    sum_log.info(
        "|-----|-----|------------------------------------------------------------------|--------|--------|--------|"
    )
    sum_log.info(
        "| Mod | Idx | Name of algorithm                                                | l1a.tv | l1a.hw | Result |"
    )
    sum_log.info(
        "|-----|-----|------------------------------------------------------------------|--------|--------|--------|"
    )
    #      |   1 |   0 | L1_SingleMuCosmics                                               |    86  |     0  | ERROR  |

    algorithms = sorted(menu.algorithms, key=lambda algorithm: algorithm.index
                        )  #sorts all algorithms by index number
    success = True
    for algo in algorithms:
        result = ok_green
        if algo.name in IGNORED_ALGOS:
            result = ignore_yellow
        #checks if algorithm trigger count is equal in both hardware and testvectors
        elif algos_tv[algo.index][0][1] != algos_sim[algo.index][0][1]:
            result = error_red
            success = False

        sum_log.info(
            '|{:>5}|{:>5}|{:<66}|{:>8}|{:>8}|{:>8}|'.
            format(  #prints line with information about each algo present in the menu
                algo.module_id, algo.index, algo.name,
                algos_tv[algo.index][0][1], algos_sim[algo.index][0][1],
                result))

    sum_log.info(
        "|-----|-----|------------------------------------------------------------------|--------|--------|--------|"
    )

    trigger_liste = trigger_list(
        testvector_filepath
    )  #gets a list: index is algorithm index and content is the trigger count in the testvector file

    # prints bits which are present in the testvector but have no corresponding algo in the menu
    errors = []

    for index in range(len(trigger_liste)):
        if menu.algorithms.byIndex(index) == None and trigger_liste[index] > 0:
            errors.append((index, trigger_liste[index]))

    if errors:
        success = False
        sum_log.info("")
        sum_log.info("Found triggers which are not defined in the menu")
        sum_log.info("|-------|--------|")
        sum_log.info("| Index |triggers|")
        sum_log.info("|-------|--------|")
        for index, triggers in errors:
            sum_log.info(
                '|{:>7}|{:>8}|'.format(index, triggers)
            )  #prints all algorithms witch are not in the menu but also triggert for some reason
        sum_log.info("|-------|--------|")

    for index in range(
            len(algos_sim)
    ):  #checks if algorithm triggert more than once in simulation and testvector file and prints it red on screen
        if check_multiple(algos_sim[index]):
            sum_log.info("Multiple algorithms found in simulation!")
            for i in range(len(algos_sim[index])):
                sum_log.info('Module: {}'.format(algos_sim[index][0][0]))
                sum_log.info('    Index: {}'.format(index))
                sum_log.info('    algoname: {}'.format(
                    menu.algorithms.byIndex(index).name if menu.algorithms.
                    byIndex(index).name else 'not found in menu'))

    for index in range(len(algos_tv)):
        if check_multiple(algos_tv[index]):
            sum_log.info("Multiple algorithms found in testvectors!")
            for i in range(len(algos_tv[index])):
                sum_log.info('Module: {}'.format(algos_tv[index][0][0]))
                sum_log.info('    Index: {}'.format(index))
                sum_log.info('    algoname: {}'.format(
                    menu.algorithms.byIndex(index).name if menu.algorithms.
                    byIndex(index).name else 'not found in menu'))

    print("")

    if success:
        logging.info(success_green)
    else:
        logging.error(failed_red)

    logging.info(
        "==========================================================================="
    )
    logging.info("removed temporary directory ('temp_dir') ...")
    if os.path.exists(os.path.join(sim_dir, "temp_dir")):
        shutil.rmtree(os.path.join(sim_dir, "temp_dir"))
Beispiel #2
0
def main():
    args = parse()

    sim_dir = os.getcwd()

    # Setup console logging
    logging.basicConfig(format='%(levelname)s: %(message)s',
                        level=args.verbose)

    _base = os.path.basename(os.path.abspath(args.menu))

    menu_filepath = os.path.join(args.menu,
                                 ('xml/%s.xml' % (_base)))  #gets xmlmenu
    testvector_filepath = os.path.join(
        args.menu, ('testvectors/TestVector_%s.txt' %
                    (_base)))  #gets path to testvector file
    timestamp = time.time()  #creates timestamp

    base_dir = '%s/sim/sim_results/' % (
        os.getcwd())  #creates base directory for later use

    if args.testvector:  #checks if testvector file argument is given else uses default path
        testvector_filepath = os.path.abspath(args.testvector)
    if not os.path.exists(menu_filepath):  #checks for menu
        raise RuntimeError('Missing %s File' % menu_filepath)  #help
    if not os.path.exists(testvector_filepath):  #checks for testvector
        raise RuntimeError('Missing %s' %
                           testvector_filepath)  #its not working as intended
    #if os.path.exists(base_dir):#checks if directory alredy exists
    #raise RuntimeError('Directory exist alredy!')

    #os.makedirs(base_dir)#makes folders

    menu = xmlmenu.XmlMenu(menu_filepath)

    modules = []
    for _id in range(menu.n_modules):  #makes list for each module
        modules.append(Module(menu, _id, base_dir))

    logging.info('Creating Modules and Masks...')

    for module in modules:  #gives each module the information
        module_id = 'module_%d' % module._id
        testvector_base_name = os.path.splitext(
            os.path.basename(testvector_filepath))[0]
        module.testvector_filepath = os.path.join(
            module.path,
            'testvector/%s_%s.txt' % (testvector_base_name, module_id))

        if not os.path.exists('%s/testvector' % module.path):
            os.makedirs('%s/testvector' % module.path)

        logging.debug('Module_%d: %0128x' % (module._id, module.get_mask()))

        make_testvector(
            module.get_mask(), testvector_filepath,
            module.testvector_filepath)  #mask, testvectorfile, out_dir

        logging.debug('Module_%d created at %s' % (module._id, base_dir))

        module.make_files(sim_dir, args.menu)  #sim_dir, menu_path

    logging.info('finished creating modules and masks')
    logging.info('starting simulations...')

    threads = []
    for module in modules:  #makes for all simulations a thread
        tcl_file = sim_dir + '/module_%d/' % module._id + TCL_FILE_PATH
        xpr_file = sim_dir + '/module_%d/' % module._id + XPR_FILE_PATH

        thread = Thread(target=run_vivado_sim,
                        args=(module, tcl_file, xpr_file))
        threads.append(thread)
        thread.start()
        #while not os.path.exists(os.path.join(module.path, 'running.lock')):#stops starting of new threads if .do file is still in use
        #time.sleep(0.5)
        #os.remove(os.path.join(module.path, 'running.lock'))

    for thread in threads:  #waits for all threads to finish
        thread.join()
    logging.info('finished all simulations')
    print('')

    algos_sim = {}
    algos_tv = {}

    for module in modules:  #steps through all modules and makes a list with trigger count and module
        jsonf = json.load(open(module.results_json))
        counts = jsonf['counts']
        for count in counts:
            index = count['algo_index']
            if index not in algos_sim:
                algos_sim[index] = []
            algos_sim[index].append(count['algo_sim'])
            if index not in algos_tv:
                algos_tv[index] = []
            algos_tv[index].append(count['algo_tv'])

    for index in range(len(
            algos_sim)):  #makes a list with tuples (module id, trigger count)
        algos_sim[index] = check_algocount(algos_sim[index])

    for index in range(len(algos_tv)):
        algos_tv[index] = check_algocount(algos_tv[index])

    # Summary logging
    sum_log = logging.getLogger("sum_log")
    sum_log.propagate = False
    handler = logging.StreamHandler(stream=sys.stdout)
    handler.setFormatter(logging.Formatter(fmt='%(message)s'))
    handler.setLevel(logging.DEBUG)
    sum_log.addHandler(handler)

    sum_file = os.path.join(base_dir, 'summary.txt')
    handler = logging.FileHandler(sum_file, mode='w')
    handler.setFormatter(logging.Formatter(fmt='%(message)s'))
    handler.setLevel(logging.DEBUG)
    sum_log.addHandler(handler)

    sum_log.info(
        "|-----|-----|------------------------------------------------------------------|--------|--------|--------|"
    )
    sum_log.info(
        "| Mod | Idx | Name of algorithm                                                | l1a.tv | l1a.hw | Result |"
    )
    sum_log.info(
        "|-----|-----|------------------------------------------------------------------|--------|--------|--------|"
    )
    #      |   1 |   0 | L1_SingleMuCosmics                                               |    86  |     0  | ERROR  |

    algorithms = sorted(menu.algorithms, key=lambda algorithm: algorithm.index
                        )  #sorts all algorithms by index number
    success = True
    for algo in algorithms:
        result = ' \033[92mOK\033[0m     '
        if algo.name in IGNORED_ALGOS:
            result = ' \033[94mIGNORE\033[0m '  # blue color
        #checks if algorithm trigger count is equal in both hardware and testvectors
        elif algos_tv[algo.index][0][1] != algos_sim[algo.index][0][1]:
            result = ' \033[91mERROR\033[0m  '  # red color
            success = False

        sum_log.info(
            '|{:>5}|{:>5}|{:<66}|{:>8}|{:>8}|{:>8}|'.
            format(  #prints line with information about each algo present in the menu
                algo.module_id, algo.index, algo.name,
                algos_tv[algo.index][0][1], algos_sim[algo.index][0][1],
                result))

    sum_log.info(
        "|-----|-----|------------------------------------------------------------------|--------|--------|--------|"
    )

    trigger_liste = trigger_list(
        testvector_filepath
    )  #gets a list: index is algorithm index and content is the trigger count in the testvector file

    # prints bits which are present in the testvector but have no corresponding algo in the menu
    errors = []

    for index in range(len(trigger_liste)):
        if menu.algorithms.byIndex(index) == None and trigger_liste[index] > 0:
            errors.append((index, trigger_liste[index]))

    if errors:
        success = False
        sum_log.info("")
        sum_log.info("Found triggers which are not defined in the menu")
        sum_log.info("|-------|--------|")
        sum_log.info("| Index |triggers|")
        sum_log.info("|-------|--------|")
        for index, triggers in errors:
            sum_log.info(
                '|{:>7}|{:>8}|'.format(index, triggers)
            )  #prints all algorithms witch are not in the menu but also triggert for some reason
        sum_log.info("|-------|--------|")

    for index in range(
            len(algos_sim)
    ):  #checks if algorithm triggert more than once in simulation and testvector file and prints it red on screen
        if check_multiple(algos_sim[index]):
            sum_log.info("Multiple algorithms found in simulation!")
            for i in range(len(algos_sim[index])):
                sum_log.info('Module: {}'.format(algos_sim[index][0][0]))
                sum_log.info('    Index: {}'.format(index))
                sum_log.info('    algoname: {}'.format(
                    menu.algorithms.byIndex(index).name if menu.algorithms.
                    byIndex(index).name else 'not found in menu'))

    for index in range(len(algos_tv)):
        if check_multiple(algos_tv[index]):
            sum_log.info("Multiple algorithms found in testvectors!")
            for i in range(len(algos_tv[index])):
                sum_log.info('Module: {}'.format(algos_tv[index][0][0]))
                sum_log.info('    Index: {}'.format(index))
                sum_log.info('    algoname: {}'.format(
                    menu.algorithms.byIndex(index).name if menu.algorithms.
                    byIndex(index).name else 'not found in menu'))

    print("")

    if success:
        logging.info("\033[92m Success! \033[0m")
    else:
        logging.error("\033[91m Failed! \033[0m")
Beispiel #3
0
def main():
    args = parse()

    sim_dir = os.getenv('SIM_ROOT')
    if not sim_dir:
        raise RuntimeError(
            "var SIM_ROOT is not defined (source setup.sh first!)"
        )  #checks if setup.py was executed

    # using SIM_ROOT dir as default output path
    if not args.output:
        args.output = sim_dir

    # Setup console logging
    logging.basicConfig(format='%(levelname)s: %(message)s',
                        level=args.verbose)

    # Set message mode:
    # wlf => no output to console for transcript info, warning and error messages (transcript output to vsim.wlf).
    # tran => output to console.
    msgmode = 'wlf' if args.wlf else 'tran'

    _base = os.path.basename(os.path.abspath(args.menu))

    menu_filepath = os.path.join(args.menu,
                                 ('xml/%s.xml' % (_base)))  #gets xmlmenu
    testvector_filepath = os.path.join(
        args.menu, ('testvectors/TestVector_%s.txt' %
                    (_base)))  #gets path to testvector file
    timestamp = time.time()  #creates timestamp
    _time = datetime.datetime.fromtimestamp(timestamp).strftime(
        '%Y-%m-%dT%H-%M-%S')  #changes time apperance

    base_dir = '%s/sim_results/%s_%s' % (
        args.output, _time, _base)  #creates base directory for later use

    if args.testvector:  #checks if testvector file argument is given else uses default path
        testvector_filepath = os.path.abspath(args.testvector)
    if not os.path.exists(menu_filepath):  #checks for menu
        raise RuntimeError('Missing %s File' % menu_filepath)  #help
    if not os.path.exists(testvector_filepath):  #checks for testvector
        raise RuntimeError('Missing %s' %
                           testvector_filepath)  #its not working as intended
    if os.path.exists(base_dir):  #checks if directory alredy exists
        raise RuntimeError('Directory exist alredy!')

    os.makedirs(base_dir)  #makes folders

    menu = xmlmenu.XmlMenu(menu_filepath)

    modules = []
    for _id in range(menu.n_modules):  #makes list for each module
        modules.append(Module(menu, _id, base_dir))

    ini_file = os.path.join(base_dir, INI_FILE)
    render_template(#makes render template
        os.path.join(sim_dir, INI_FILE_TPL),
        ini_file, {
        '{{XILINX_PATH}}' : args.xilinx_path,
        '{{MODELSIM_VERSION}}' : args.modelsim,
    })

    logging.info('Creating Modules and Masks...')

    for module in modules:  #gives each module the information
        module_id = 'module_%d' % module._id
        testvector_base_name = os.path.splitext(
            os.path.basename(testvector_filepath))[0]
        module.testvector_filepath = os.path.join(
            module.path, '%s_%s.txt' % (testvector_base_name, module_id))

        os.makedirs('%s/testbench' % module.path)
        os.makedirs('%s/vhdl' % module.path)
        logging.debug('Module_%d: %0128x' % (module._id, module.get_mask()))

        make_testvector(
            module.get_mask(), testvector_filepath,
            module.testvector_filepath)  #mask, testvectorfile, out_dir

        logging.debug('Module_%d created at %s' % (module._id, base_dir))

        module.make_files(sim_dir, args.view_wave, args.mp7_tag,
                          args.menu)  #sim_dir, view_wave, mp7_tag, menu_path

    logging.info('finished creating modules and masks')
    logging.info('starting simulations...')

    gtu_settings = os.getenv('GTU_SETTINGS_MODELSIM_INI_VERSION')
    if not gtu_settings:  #checks for gtu settings
        raise RuntimeError("GTU settings not set (run gtu-settings-XXX)")

    threads = []
    for module in modules:  #makes for all simulations a thread
        thread = Thread(target=run_vsim, args=(module, msgmode, ini_file))
        threads.append(thread)
        thread.start()
        while not os.path.exists(
                os.path.join(module.path, 'running.lock')
        ):  #stops starting of new threads if .do file is still in use
            time.sleep(0.5)
        os.remove(os.path.join(module.path, 'running.lock'))

    for thread in threads:  #waits for all threads to finish
        thread.join()
    logging.info('finished all simulations')
    print('')

    algos_sim = {}
    algos_tv = {}

    for module in modules:  #steps through all modules and makes a list with trigger count and module
        with open(module.results_json) as fp:
            jsonf = json.load(fp)
        counts = jsonf['counts']
        for count in counts:
            index = count['algo_index']
            if index not in algos_sim:
                algos_sim[index] = []
            algos_sim[index].append(count['algo_sim'])
            if index not in algos_tv:
                algos_tv[index] = []
            algos_tv[index].append(count['algo_tv'])

    for index in range(len(
            algos_sim)):  #makes a list with tuples (module id, trigger count)
        algos_sim[index] = check_algocount(algos_sim[index])

    for index in range(len(algos_tv)):
        algos_tv[index] = check_algocount(algos_tv[index])

    # Summary logging
    sum_log = logging.getLogger("sum_log")
    sum_log.propagate = False
    handler = logging.StreamHandler(stream=sys.stdout)
    handler.setFormatter(logging.Formatter(fmt='%(message)s'))
    handler.setLevel(logging.DEBUG)
    sum_log.addHandler(handler)

    sum_file = os.path.join(base_dir, 'summary.txt')
    handler = logging.FileHandler(sum_file, mode='w')
    handler.setFormatter(logging.Formatter(fmt='%(message)s'))
    handler.setLevel(logging.DEBUG)
    sum_log.addHandler(handler)

    sum_log.info(
        "|-----|-----|------------------------------------------------------------------|--------|--------|--------|"
    )
    sum_log.info(
        "| Mod | Idx | Name of algorithm                                                | l1a.tv | l1a.hw | Result |"
    )
    sum_log.info(
        "|-----|-----|------------------------------------------------------------------|--------|--------|--------|"
    )
    #      |   1 |   0 | L1_SingleMuCosmics                                               |    86  |     0  | ERROR  |

    algorithms = sorted(menu.algorithms, key=lambda algorithm: algorithm.index
                        )  #sorts all algorithms by index number
    success = True
    for algo in algorithms:
        result = ok_green
        if algo.name in IGNORED_ALGOS:
            result = ignore_yellow
        #checks if algorithm trigger count is equal in both hardware and testvectors
        elif algos_tv[algo.index][0][1] != algos_sim[algo.index][0][1]:
            result = error_red
            success = False

        sum_log.info(
            '|{:>5}|{:>5}|{:<66}|{:>8}|{:>8}|{:>8}|'.
            format(  #prints line with information about each algo present in the menu
                algo.module_id, algo.index, algo.name,
                algos_tv[algo.index][0][1], algos_sim[algo.index][0][1],
                result))

    sum_log.info(
        "|-----|-----|------------------------------------------------------------------|--------|--------|--------|"
    )

    trigger_liste = trigger_list(
        testvector_filepath
    )  #gets a list: index is algorithm index and content is the trigger count in the testvector file

    # prints bits which are present in the testvector but have no corresponding algo in the menu
    errors = []

    for index in range(len(trigger_liste)):
        if menu.algorithms.byIndex(index) == None and trigger_liste[index] > 0:
            errors.append((index, trigger_liste[index]))

    if errors:
        success = False
        sum_log.info("")
        sum_log.info("Found triggers which are not defined in the menu")
        sum_log.info("|-------|--------|")
        sum_log.info("| Index |triggers|")
        sum_log.info("|-------|--------|")
        for index, triggers in errors:
            sum_log.info(
                '|{:>7}|{:>8}|'.format(index, triggers)
            )  #prints all algorithms witch are not in the menu but also triggert for some reason
        sum_log.info("|-------|--------|")

    for index in range(
            len(algos_sim)
    ):  #checks if algorithm triggert more than once in simulation and testvector file and prints it red on screen
        if check_multiple(algos_sim[index]):
            sum_log.info("Multiple algorithms found in simulation!")
            for i in range(len(algos_sim[index])):
                sum_log.info('Module: {}'.format(algos_sim[index][0][0]))
                sum_log.info('    Index: {}'.format(index))
                sum_log.info('    algoname: {}'.format(
                    menu.algorithms.byIndex(index).name if menu.algorithms.
                    byIndex(index).name else 'not found in menu'))

    for index in range(len(algos_tv)):
        if check_multiple(algos_tv[index]):
            sum_log.info("Multiple algorithms found in testvectors!")
            for i in range(len(algos_tv[index])):
                sum_log.info('Module: {}'.format(algos_tv[index][0][0]))
                sum_log.info('    Index: {}'.format(index))
                sum_log.info('    algoname: {}'.format(
                    menu.algorithms.byIndex(index).name if menu.algorithms.
                    byIndex(index).name else 'not found in menu'))

    print("")

    if success:
        logging.info(success_green)
    else:
        logging.error(failed_red)