Example #1
0
def def_parser(def_file,
               pins,
               nets,
               cell_coor_dict,
               load_cap_dict,
               cell_dimension,
               buildPath=True):
    print('# READING DEF')
    with open(def_file) as f:
        blocks = []
        mapping_number = 1

        # Parsing Components Section
        parsing_component = False
        comp_syn = False
        cur_comp = []

        # NET BOOLEAN
        find_net = False
        find_data = False

        # PIN BOOLEAN
        find_pin = False
        pin_info = False

        # VIAS BOOLEAN
        find_vias = False
        via_info = False

        for line in f:
            """ HEADER SECTION"""
            # Finding the PER UNIT VALUE
            if re.search('UNITS DISTANCE MICRONS', line, flags=re.IGNORECASE):
                data = re.findall(r'\d+', line)
                glob.UNIT_DISTANCE = (int(data[0]))

            if re.match('^VERSION\s*(\d+\.?\d*)\s*[;]', line):
                def_version = re.match('^VERSION\s*(\d+\.?\d*)\s*[;]',
                                       line).group(1)

            if re.match('^DIVIDERCHAR\s*["](.+)["]\s*[;]', line):
                glob.DIVIDER = re.match('^DIVIDERCHAR\s*["](.+)["]\s*[;]',
                                        line).group(1)

            if re.match('^BUSBITCHARS\s*["](.+)["]\s*[;]', line):
                glob.BUS_CHAR = re.match('^BUSBITCHARS\s*["](.+)["]\s*[;]',
                                         line).group(1)

            if re.match('^DESIGN\s*\w+\s*[;]', line):
                glob.DESIGN = re.match('^DESIGN\s*(\w+)\s*[;]', line).group(1)
            """" END HEADER SECTION """
            """FILLING THE FIRST PART OF THE RECT CLASS"""
            if re.match('^[\t ]*COMPONENTS \d+', line, flags=re.IGNORECASE):
                parsing_component = True
                continue

            if re.match('^[\t ]*END COMPONENTS', line, flags=re.IGNORECASE):
                parsing_component = False
                # Create dictionary that contains all the COMPONENTS info
                create_block_dict(blocks, load_cap_dict, cell_dimension,
                                  cell_coor_dict)
                continue

            if parsing_component:
                if re.match('^[\t ]*-[\t ]+\w+[\t ]+\w+', line):
                    comp_name = re.search(r'[\t ]*-[\t ]+(\w+)[\t ]+(\w+)',
                                          line)
                    cur_comp = cl.Component(name=comp_name.group(1),
                                            cell=comp_name.group(2),
                                            number=mapping_number)
                    comp_syn = True
                    mapping_number += 1

                if re.search('PLACED|FIXED|COVER', line,
                             flags=re.IGNORECASE) and comp_syn:
                    comp_loc = re.search(
                        r'[+] (PLACED|FIXED|COVER)\s+[(] ([-+]?\d+\.?\d*)\s+([-+]?\d+\.?\d*) [)] (\w+)',
                        line)
                    cur_comp.set_location(comp_loc.group(2), comp_loc.group(3))
                    cur_comp.set_orientation(comp_loc.group(4))

                if re.search('PLACED|FIXED|COVER', line,
                             flags=re.IGNORECASE) and comp_syn:
                    Property = re.search(
                        r'[+] (PROPERTY)\s+(\w+)\s+([-+]?\d+\.?\d*|\w+)', line)
                    if Property != None:
                        cur_comp.set_property(
                            [Property.group(2),
                             Property.group(3)])

                if re.search(
                        ';', line
                ) and comp_syn:  #semicolon at the begining of the line
                    comp_syn = False
                    blocks.append(cur_comp)
            """ FIRST PART ENDS HERE """
            """ PINS START """
            if re.match('^[\t ]*PINS \d+', line, flags=re.IGNORECASE):
                find_pin = True
                continue

            if re.match('^[\t ]*END PINS*', line, flags=re.IGNORECASE):
                find_pin = False
                continue

            if find_pin:
                if re.match('^\s*-\s+(\w+)', line):
                    pin_info = True
                    pin_class = cl.Pin(number=mapping_number)
                    pin_class.set_name(
                        re.match('^\s*-\s+(\S+)\s*', line).group(1))
                    mapping_number += 1

                if pin_info:
                    if re.match('. .+', line):
                        data = re.findall(r'(?![(|)|+|;])\S+', line)
                        processPinData(pin_class, data)

                if re.search(';', line):
                    pin_info = False
                    add_pin_info_toDict(pin_class, pins)
                    continue
            """ END PINS """
            """ VIAS SECTION """
            if find_vias:
                if re.search(r';', line):
                    via_info = False
                    # Set the cut layer of the via
                    num_cuts = compute_via_number_of_cuts(
                        cur_via, glob.TECH_LEF_DICT)
                    cur_via.set_viaCuts(num_cuts)
                    def_via.append_via_data_to_dict(cur_via,
                                                    glob.TECH_LEF_DICT)

                if via_info:
                    def_via.parse_def_via_section(line, cur_via,
                                                  glob.TECH_LEF_DICT)

                if re.match(r'^\s*[-]\s+(\w+)', line):
                    via_name = re.findall(r'\S+', line)
                    via_name = (via_name[1])
                    cur_via = cl.LEF_VIA_Info(via_name=via_name)
                    via_info = True

            if re.match('^VIAS\s+\d+\s+[;]', line):
                find_vias = True

            if re.match('^END VIAS*', line):
                find_vias = False
            """ END VIA SECTION """
            """ NETS PART """
            if re.match('^[\t ]*NETS \d+', line, flags=re.IGNORECASE):
                find_net = True
                print('# Process Nets information...')
                net_count = 0
                continue

            if re.match('^[\t ]*END NETS*', line, flags=re.IGNORECASE):
                find_net = False
                print('# Finsihed processing Nets information')
                print('# Total Net Count: {}'.format(net_count))
                continue

            if find_net == True:
                if re.match('^[\t ]*-[\t ]+\w+', line):
                    mapped = False
                    data = re.findall(r'\S+', line)
                    # Create an Instance of a net
                    cur_net = cl.NET(data[1])
                    cur_net.add_cell = blocks
                    # ADDING THE MAPPING NUMBER OF THE NET TO THE PIN INFO
                    if data[1] in pins:
                        cur_net.number = pins[data[1]]['number']
                        mapped = True

                    if not mapped:
                        cur_net.number = mapping_number
                        mapping_number += 1

                    find_data = True

                # End of the particular NET, process the wire data
                if re.search('^\s*;',
                             line):  #semicolon at the begining of the line
                    find_data = False
                    net_count += 1
                    if cur_net.wire_list == []:
                        nets.append(cur_net)
                        print(
                            '# Warning: Net {} does not contain any interconnect information!'
                            .format(cur_net.name))
                        continue

                    # Use for SPEF writer, creating PATH from DEF
                    if buildPath:
                        build_path(cur_net, cell_coor_dict, pins)

                    nets.append(cur_net)
                    continue

                if find_data:
                    parse_net(line, cur_net, cell_coor_dict)
            """ END NETS """

#    if buildPath:
#        import multiprocessing as mp
#        print('# Building Path ...')
#        processes = []
#        end = 0
#
#        cpu_count = mp.cpu_count() + 10
#        for i in range (cpu_count):
#            start = end
#
#            if i == cpu_count-1:
#                end = len(nets)
#            else:
#                end = (i+1) * int(len(nets)/cpu_count)
#
#            p = mp.Process(target=fork_build_path, args=(start, end, nets, cell_coor_dict, pins,))
#            processes.append(p)
#            p.start()
#
#        for process in processes:
#            process.join()

    print('# Finish Rading DEF')