Example #1
0
def parse_lef(filename,
              tech_lef=None,
              look_for_cell=None,
              find_desired_cell_info=False):
    lef = {}
    with open(filename, 'r') as lef_file:
        search = False
        find_pin_info = False
        find_layer_info = False
        find_poly_coordinate = False
        find_rect_coordinate = False
        find_poly_info = False

        macro = None
        desired_macro = None

        macros = []
        pin_name = ''

        for line in lef_file:
            if re.search(r'^\s*MACRO', line, flags=re.IGNORECASE):
                macro = None
                cell_name = re.search(r'MACRO (\w+)',
                                      line,
                                      flags=re.IGNORECASE)
                cell_name = cell_name.group(1)
                if cell_name != None or cell_name != '':
                    search = True

                if look_for_cell != None:
                    if cell_name == look_for_cell:
                        find_desired_cell_info = True
                        macro = cl.MACRO(cell_name)

                    else:
                        find_desired_cell_info = False

                if find_desired_cell_info:
                    macro = cl.MACRO(cell_name)

            if search and re.match('^\s*END\s+' + re.escape(cell_name), line):
                if cell_name == look_for_cell:
                    find_desired_cell_info = False
                    desired_macro = macro
                if find_desired_cell_info:
                    macros.append(macro)
                search = False

            if search:
                if re.search(r'SIZE\s*\d+\.?\d*\sBY', line):
                    ## Search for the dimension of the cell
                    size = re.search(r'SIZE (\d+\.?\d*) BY (\d+\.?\d*)', line)
                    ## Input the dimension to the dictionary
                    lef[cell_name] = {'x': size.group(1), 'y': size.group(2)}
                    ## Insert the info to the class
                    if look_for_cell != None:
                        if cell_name == look_for_cell:
                            macro.set_width(float(size.group(1)))
                            macro.set_height(float(size.group(2)))

                if re.match(r'^\s*PIN\s+(\w+)',
                            line) and find_desired_cell_info:
                    pin_name = re.match(r'^\s*PIN\s+(\w+)', line).group(1)
                    find_pin_info = True
                    cl_pin = cl.MACRO_PIN(pin_name)

                if find_desired_cell_info and re.match(
                        r'^\s*END\s+' + re.escape(pin_name),
                        line) and find_pin_info:
                    find_pin_info = False

                if find_pin_info:
                    if re.match(r'^\s*DIRECTION\s+(\w+)\s+;', line):
                        direction = re.match(r'\s*DIRECTION\s+(\w+)\s+;',
                                             line).group(1)
                        if direction == 'INPUT' or direction == 'OUTPUT':
                            find_layer_info = True
                            cl_pin.set_direction(direction)
                            lef[cell_name][pin_name] = []

                        else:
                            find_layer_info = False

                    if find_layer_info:
                        if re.match(r'^\s*LAYER\s+(\w+)\s+;', line):
                            metal = re.match(r'^\s*LAYER\s+(\w+)',
                                             line).group(1)
                            if (tech_lef != None
                                    and tech_lef['Layer'][metal]['type'] !=
                                    'CUT') or metal == 'M1':
                                find_poly_info = True
                                coordinate = []

                        if re.match(r'^\s*END', line):
                            find_poly_info = False

                        if find_poly_info:
                            if re.search('POLY', line):
                                cl_pin._isRect = False
                                find_poly_coordinate = True

                            if re.search('RECT', line):
                                cl_pin._isRect = True
                                find_rect_coordinate = True

                            if find_poly_coordinate:
                                coordinate.extend(
                                    re.findall('([-+]?\d*\.?\d+)+', line))
                                if look_for_cell == cell_name:
                                    cl_pin.set_coordinate(coordinate)

                            if find_rect_coordinate:
                                rect_pattern = r'^\s*(RECT)\s+(\s*MASK\s*\d+\s*)?(\d*\.?\d+\s*)(\d*\.?\d+\s*)(\d*\.?\d+\s*)(\d*\.?\d+\s*)\s*;'
                                coordinate = re.search(rect_pattern, line)
                                coordinate = [coordinate.group(1),metal,coordinate.group(3),\
                                              coordinate.group(4),coordinate.group(5),coordinate.group(6)]

                                lef[cell_name][pin_name].append(coordinate)
                                if len(coordinate) > 4:
                                    coordinate = coordinate[-4:]

                                cl_pin.set_coordinate(coordinate)

                            if re.search(';',
                                         line) and (find_rect_coordinate
                                                    or find_poly_coordinate):
                                if find_poly_coordinate:
                                    # Only store the PIN class that has coordinate data
                                    if len(coordinate) > 0:
                                        if look_for_cell == cell_name:
                                            cl_pin.convert_coordinate_to_Point(
                                            )
                                        coordinate.insert(0, metal)
                                        coordinate.insert(0, 'POLY')
                                        lef[cell_name][pin_name].append(
                                            coordinate)

                                if look_for_cell == cell_name:
                                    macro.set_pin(cl_pin)
                                find_poly_coordinate = False
                                find_rect_coordinate = False

    if desired_macro != None:
        # Process the data
        POX, POY, start_length = desired_macro.get_starting_point
        print(str(POX) + ' ' + str(POY) + ' ' + str(start_length))

    return lef