#!/usr/bin/env python3
"""
Gather data from given lib file. This data is then used to populate JSON file
that has delay numbers for some parameters related to F2A and A2F pins.
"""
import argparse
from collections import defaultdict

# =============================================================================


def main():
    """
    Gather lib information from the given library file
    """
    parser = argparse.ArgumentParser(
        description='Gather lib information from the given library file.'
    )
    parser.add_argument(
        "--lib",
        "-l",
        "-L",
        type=str,
        required=True,
        help='Specify input lib file'
    )

    args = parser.parse_args()

    lib_fp = open(args.lib, newline='')

    for line in lib_fp:
        if line.find("bus ( gfpga_pad_IO_A2F") != -1:
            a2f_process_lib_data(lib_fp)
        elif line.find("bus ( gfpga_pad_IO_F2A") != -1:
            f2a_process_lib_data(lib_fp)


# =============================================================================


def f2a_process_lib_data(lib_fp):
    """
    Process F2A pin lib_data
    """
    f2a_data_max = defaultdict(set)
    f2a_data_min = defaultdict(set)
    max_transition = set()
    capacitance = set()
    for f2a_line in lib_fp:

        pin_pos = f2a_line.find("pin(\"")
        if pin_pos != -1:

            for pin_line in lib_fp:
                if pin_line.find("rising_edge") != -1:
                    f2a_data_max, f2a_data_min = f2a_timing_type(
                        lib_fp, pin_line, "rising_edge", f2a_data_max,
                        f2a_data_min
                    )
                elif pin_line.find("max_transition") != -1:
                    val_list = pin_line.split(' : ')
                    max_transition.add(
                        float(val_list[1].split(' ;')[0].strip())
                    )
                elif pin_line.find("capacitance") != -1:
                    val_list = pin_line.split(' : ')
                    capacitance.add(float(val_list[1].split(' ;')[0].strip()))
                elif pin_line.find("end of bus") != -1:
                    break

            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "max_transition", next(iter(sorted(max_transition))),
                    sorted(max_transition).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "capacitance", next(iter(sorted(capacitance))),
                    sorted(capacitance).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "rising_edge_cell_rise_val",
                    next(iter(sorted(f2a_data_min['rising_edge_cell_rise']))),
                    sorted(f2a_data_max['rising_edge_cell_rise']).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "rising_edge_cell_fall_val",
                    next(iter(sorted(f2a_data_min['rising_edge_cell_fall']))),
                    sorted(f2a_data_max['rising_edge_cell_fall']).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "rising_edge_rise_tran_val",
                    next(iter(sorted(f2a_data_min['rising_edge_rise_tran']))),
                    sorted(f2a_data_max['rising_edge_rise_tran']).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "rising_edge_fall_tran_val",
                    next(iter(sorted(f2a_data_min['rising_edge_fall_tran']))),
                    sorted(f2a_data_max['rising_edge_fall_tran']).pop()
                )
            )
            break


# =============================================================================


def a2f_process_lib_data(lib_fp):
    """
    Process A2F pin lib_data
    """
    a2f_data_max = defaultdict(set)
    a2f_data_min = defaultdict(set)

    max_transition = set()
    capacitance = set()
    for a2f_line in lib_fp:

        pin_pos = a2f_line.find("pin(\"")
        if pin_pos != -1:

            for pin_line in lib_fp:
                if pin_line.find("setup_rising") != -1:
                    a2f_data_max, a2f_data_min = a2f_timing_type(
                        lib_fp, pin_line, "setup_rising", a2f_data_max,
                        a2f_data_min
                    )
                elif pin_line.find("hold_rising") != -1:
                    a2f_data_max, a2f_data_min = a2f_timing_type(
                        lib_fp, pin_line, "hold_rising", a2f_data_max,
                        a2f_data_min
                    )
                elif pin_line.find("max_transition") != -1:
                    val_list = pin_line.split(' : ')
                    max_transition.add(
                        float(val_list[1].split(' ;')[0].strip())
                    )
                elif pin_line.find("capacitance") != -1:
                    val_list = pin_line.split(' : ')
                    capacitance.add(float(val_list[1].split(' ;')[0].strip()))
                elif pin_line.find("end of bus gfpga_pad_IO_A2F") != -1:
                    break

            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "max_transition", next(iter(sorted(max_transition))),
                    sorted(max_transition).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "capacitance", next(iter(sorted(capacitance))),
                    sorted(capacitance).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "setup_rising_rise_constraint_val",
                    next(
                        iter(
                            sorted(
                                a2f_data_min['setup_rising_rise_constraint']
                            )
                        )
                    ),
                    sorted(a2f_data_max['setup_rising_rise_constraint']).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "setup_rising_fall_constraint_val",
                    next(
                        iter(
                            sorted(
                                a2f_data_min['setup_rising_fall_constraint']
                            )
                        )
                    ),
                    sorted(a2f_data_max['setup_rising_fall_constraint']).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "hold_rising_rise_constraint_val",
                    next(
                        iter(
                            sorted(
                                a2f_data_min['hold_rising_rise_constraint']
                            )
                        )
                    ),
                    sorted(a2f_data_max['hold_rising_rise_constraint']).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "hold_rising_fall_constraint_val",
                    next(
                        iter(
                            sorted(
                                a2f_data_min['hold_rising_fall_constraint']
                            )
                        )
                    ),
                    sorted(a2f_data_max['hold_rising_fall_constraint']).pop()
                )
            )
            break


# =============================================================================


def a2f_timing_type(lib_fp, pin_line, type_str, a2f_data_max, a2f_data_min):
    """
    Collect A2F pin data
    """
    type_pos = pin_line.find(type_str)
    if type_pos != -1:
        for type_line in lib_fp:
            rise_pos = type_line.find("rise_constraint")
            if rise_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        if type_str == "setup_rising":
                            a2f_data_max['setup_rising_rise_constraint'].add(
                                sorted(val_set).pop()
                            )
                            a2f_data_min['setup_rising_rise_constraint'].add(
                                next(iter(sorted(val_set)))
                            )
                        else:
                            a2f_data_max['hold_rising_rise_constraint'].add(
                                sorted(val_set).pop()
                            )
                            a2f_data_min['hold_rising_rise_constraint'].add(
                                next(iter(sorted(val_set)))
                            )
                        break
                break

        for type_line in lib_fp:
            fall_pos = type_line.find("fall_constraint")
            if fall_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        if type_str == "setup_rising":
                            a2f_data_max['setup_rising_fall_constraint'].add(
                                sorted(val_set).pop()
                            )
                            a2f_data_min['setup_rising_fall_constraint'].add(
                                next(iter(sorted(val_set)))
                            )
                        else:
                            a2f_data_max['hold_rising_fall_constraint'].add(
                                sorted(val_set).pop()
                            )
                            a2f_data_min['hold_rising_fall_constraint'].add(
                                next(iter(sorted(val_set)))
                            )
                        break
                break

    return a2f_data_max, a2f_data_min


# =============================================================================


def f2a_timing_type(lib_fp, pin_line, type_str, f2a_data_max, f2a_data_min):
    """
    Collect F2A pin data
    """
    type_pos = pin_line.find(type_str)
    if type_pos != -1:
        for type_line in lib_fp:
            rise_pos = type_line.find("cell_rise")
            if rise_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        f2a_data_max['rising_edge_cell_rise'].add(
                            sorted(val_set).pop()
                        )
                        f2a_data_min['rising_edge_cell_rise'].add(
                            next(iter(sorted(val_set)))
                        )

                        break
                break

        for type_line in lib_fp:
            fall_pos = type_line.find("rise_transition")
            if fall_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        f2a_data_max['rising_edge_rise_tran'].add(
                            sorted(val_set).pop()
                        )
                        f2a_data_min['rising_edge_rise_tran'].add(
                            next(iter(sorted(val_set)))
                        )
                        break
                break

        for type_line in lib_fp:
            fall_pos = type_line.find("cell_fall")
            if fall_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        f2a_data_max['rising_edge_cell_fall'].add(
                            sorted(val_set).pop()
                        )
                        f2a_data_min['rising_edge_cell_fall'].add(
                            next(iter(sorted(val_set)))
                        )
                        break
                break

        for type_line in lib_fp:
            fall_pos = type_line.find("fall_transition")
            if fall_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        f2a_data_max['rising_edge_fall_tran'].add(
                            sorted(val_set).pop()
                        )
                        f2a_data_min['rising_edge_fall_tran'].add(
                            next(iter(sorted(val_set)))
                        )
                        break
                break

    return f2a_data_max, f2a_data_min


# =============================================================================


def populate_set(line, val_set):
    """
    Collects values and put it in a set
    """
    pos = line.find("\"")
    pos1 = line.rfind("\"")
    sub = line[pos + 1:pos1]
    val_list = sub.split(',')
    for val in val_list:
        val_set.add(float(val.strip()))

    return val_set


# =============================================================================

if __name__ == '__main__':
    main()

#!/usr/bin/env python3
"""
Gather data from given lib file. This data is then used to populate JSON file
that has delay numbers for some parameters related to F2A and A2F pins.
"""
import argparse
from collections import defaultdict

# =============================================================================


def main():
    """
    Gather lib information from the given library file
    """
    parser = argparse.ArgumentParser(
        description='Gather lib information from the given library file.'
    )
    parser.add_argument(
        "--lib",
        "-l",
        "-L",
        type=str,
        required=True,
        help='Specify input lib file'
    )

    args = parser.parse_args()

    lib_fp = open(args.lib, newline='')

    for line in lib_fp:
        if line.find("bus ( gfpga_pad_IO_A2F") != -1:
            a2f_process_lib_data(lib_fp)
        elif line.find("bus ( gfpga_pad_IO_F2A") != -1:
            f2a_process_lib_data(lib_fp)


# =============================================================================


def f2a_process_lib_data(lib_fp):
    """
    Process F2A pin lib_data
    """
    f2a_data_max = defaultdict(set)
    f2a_data_min = defaultdict(set)
    max_transition = set()
    capacitance = set()
    for f2a_line in lib_fp:

        pin_pos = f2a_line.find("pin(\"")
        if pin_pos != -1:

            for pin_line in lib_fp:
                if pin_line.find("rising_edge") != -1:
                    f2a_data_max, f2a_data_min = f2a_timing_type(
                        lib_fp, pin_line, "rising_edge", f2a_data_max,
                        f2a_data_min
                    )
                elif pin_line.find("max_transition") != -1:
                    val_list = pin_line.split(' : ')
                    max_transition.add(
                        float(val_list[1].split(' ;')[0].strip())
                    )
                elif pin_line.find("capacitance") != -1:
                    val_list = pin_line.split(' : ')
                    capacitance.add(float(val_list[1].split(' ;')[0].strip()))
                elif pin_line.find("end of bus") != -1:
                    break

            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "max_transition", next(iter(sorted(max_transition))),
                    sorted(max_transition).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "capacitance", next(iter(sorted(capacitance))),
                    sorted(capacitance).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "rising_edge_cell_rise_val",
                    next(iter(sorted(f2a_data_min['rising_edge_cell_rise']))),
                    sorted(f2a_data_max['rising_edge_cell_rise']).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "rising_edge_cell_fall_val",
                    next(iter(sorted(f2a_data_min['rising_edge_cell_fall']))),
                    sorted(f2a_data_max['rising_edge_cell_fall']).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "rising_edge_rise_tran_val",
                    next(iter(sorted(f2a_data_min['rising_edge_rise_tran']))),
                    sorted(f2a_data_max['rising_edge_rise_tran']).pop()
                )
            )
            print(
                'F2A {} least_val: {}, highest_val: {}'.format(
                    "rising_edge_fall_tran_val",
                    next(iter(sorted(f2a_data_min['rising_edge_fall_tran']))),
                    sorted(f2a_data_max['rising_edge_fall_tran']).pop()
                )
            )
            break


# =============================================================================


def a2f_process_lib_data(lib_fp):
    """
    Process A2F pin lib_data
    """
    a2f_data_max = defaultdict(set)
    a2f_data_min = defaultdict(set)

    max_transition = set()
    capacitance = set()
    for a2f_line in lib_fp:

        pin_pos = a2f_line.find("pin(\"")
        if pin_pos != -1:

            for pin_line in lib_fp:
                if pin_line.find("setup_rising") != -1:
                    a2f_data_max, a2f_data_min = a2f_timing_type(
                        lib_fp, pin_line, "setup_rising", a2f_data_max,
                        a2f_data_min
                    )
                elif pin_line.find("hold_rising") != -1:
                    a2f_data_max, a2f_data_min = a2f_timing_type(
                        lib_fp, pin_line, "hold_rising", a2f_data_max,
                        a2f_data_min
                    )
                elif pin_line.find("max_transition") != -1:
                    val_list = pin_line.split(' : ')
                    max_transition.add(
                        float(val_list[1].split(' ;')[0].strip())
                    )
                elif pin_line.find("capacitance") != -1:
                    val_list = pin_line.split(' : ')
                    capacitance.add(float(val_list[1].split(' ;')[0].strip()))
                elif pin_line.find("end of bus gfpga_pad_IO_A2F") != -1:
                    break

            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "max_transition", next(iter(sorted(max_transition))),
                    sorted(max_transition).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "capacitance", next(iter(sorted(capacitance))),
                    sorted(capacitance).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "setup_rising_rise_constraint_val",
                    next(
                        iter(
                            sorted(
                                a2f_data_min['setup_rising_rise_constraint']
                            )
                        )
                    ),
                    sorted(a2f_data_max['setup_rising_rise_constraint']).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "setup_rising_fall_constraint_val",
                    next(
                        iter(
                            sorted(
                                a2f_data_min['setup_rising_fall_constraint']
                            )
                        )
                    ),
                    sorted(a2f_data_max['setup_rising_fall_constraint']).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "hold_rising_rise_constraint_val",
                    next(
                        iter(
                            sorted(
                                a2f_data_min['hold_rising_rise_constraint']
                            )
                        )
                    ),
                    sorted(a2f_data_max['hold_rising_rise_constraint']).pop()
                )
            )
            print(
                'A2F {} least_val: {}, highest_val: {}'.format(
                    "hold_rising_fall_constraint_val",
                    next(
                        iter(
                            sorted(
                                a2f_data_min['hold_rising_fall_constraint']
                            )
                        )
                    ),
                    sorted(a2f_data_max['hold_rising_fall_constraint']).pop()
                )
            )
            break


# =============================================================================


def a2f_timing_type(lib_fp, pin_line, type_str, a2f_data_max, a2f_data_min):
    """
    Collect A2F pin data
    """
    type_pos = pin_line.find(type_str)
    if type_pos != -1:
        for type_line in lib_fp:
            rise_pos = type_line.find("rise_constraint")
            if rise_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        if type_str == "setup_rising":
                            a2f_data_max['setup_rising_rise_constraint'].add(
                                sorted(val_set).pop()
                            )
                            a2f_data_min['setup_rising_rise_constraint'].add(
                                next(iter(sorted(val_set)))
                            )
                        else:
                            a2f_data_max['hold_rising_rise_constraint'].add(
                                sorted(val_set).pop()
                            )
                            a2f_data_min['hold_rising_rise_constraint'].add(
                                next(iter(sorted(val_set)))
                            )
                        break
                break

        for type_line in lib_fp:
            fall_pos = type_line.find("fall_constraint")
            if fall_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        if type_str == "setup_rising":
                            a2f_data_max['setup_rising_fall_constraint'].add(
                                sorted(val_set).pop()
                            )
                            a2f_data_min['setup_rising_fall_constraint'].add(
                                next(iter(sorted(val_set)))
                            )
                        else:
                            a2f_data_max['hold_rising_fall_constraint'].add(
                                sorted(val_set).pop()
                            )
                            a2f_data_min['hold_rising_fall_constraint'].add(
                                next(iter(sorted(val_set)))
                            )
                        break
                break

    return a2f_data_max, a2f_data_min


# =============================================================================


def f2a_timing_type(lib_fp, pin_line, type_str, f2a_data_max, f2a_data_min):
    """
    Collect F2A pin data
    """
    type_pos = pin_line.find(type_str)
    if type_pos != -1:
        for type_line in lib_fp:
            rise_pos = type_line.find("cell_rise")
            if rise_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        f2a_data_max['rising_edge_cell_rise'].add(
                            sorted(val_set).pop()
                        )
                        f2a_data_min['rising_edge_cell_rise'].add(
                            next(iter(sorted(val_set)))
                        )

                        break
                break

        for type_line in lib_fp:
            fall_pos = type_line.find("rise_transition")
            if fall_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        f2a_data_max['rising_edge_rise_tran'].add(
                            sorted(val_set).pop()
                        )
                        f2a_data_min['rising_edge_rise_tran'].add(
                            next(iter(sorted(val_set)))
                        )
                        break
                break

        for type_line in lib_fp:
            fall_pos = type_line.find("cell_fall")
            if fall_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        f2a_data_max['rising_edge_cell_fall'].add(
                            sorted(val_set).pop()
                        )
                        f2a_data_min['rising_edge_cell_fall'].add(
                            next(iter(sorted(val_set)))
                        )
                        break
                break

        for type_line in lib_fp:
            fall_pos = type_line.find("fall_transition")
            if fall_pos != -1:
                for constraint_line in lib_fp:
                    if constraint_line.find("}") != -1:
                        break

                    if constraint_line.find('values') != -1:
                        val_set = set()
                        val_set = populate_set(constraint_line, val_set)

                        for val_line in lib_fp:
                            if val_line.find(");") != -1:
                                val_set = populate_set(val_line, val_set)
                                break

                            val_set = populate_set(val_line, val_set)

                        f2a_data_max['rising_edge_fall_tran'].add(
                            sorted(val_set).pop()
                        )
                        f2a_data_min['rising_edge_fall_tran'].add(
                            next(iter(sorted(val_set)))
                        )
                        break
                break

    return f2a_data_max, f2a_data_min


# =============================================================================


def populate_set(line, val_set):
    """
    Collects values and put it in a set
    """
    pos = line.find("\"")
    pos1 = line.rfind("\"")
    sub = line[pos + 1:pos1]
    val_list = sub.split(',')
    for val in val_list:
        val_set.add(float(val.strip()))

    return val_set


# =============================================================================

if __name__ == '__main__':
    main()

#!/usr/bin/env python3 Gather data from given lib file. This data is then used to populate JSON file that has delay numbers for some parameters related to F2A and A2F pins. # ============================================================================= Gather lib information from the given library file # ============================================================================= Process F2A pin lib_data # ============================================================================= Process A2F pin lib_data # ============================================================================= Collect A2F pin data # ============================================================================= Collect F2A pin data # ============================================================================= Collects values and put it in a set # =============================================================================