Example #1
0
def func_info_to_func_and_kwargs(func_info):
    ''' There are several ways to specify commands in the YML file. This parses them into function name and arguments
        It can be a list where first element is a function and second is a dict of kwargs.
        It can be a dict where key is function and value is dict of kwargs.
    '''
    if isinstance(func_info, str):
        func_name = func_info
        kwargs = dict()
    elif isinstance(func_info, list):
        message(
            'Deprecation warning: spefifying a step as a list is going to go. Use dicts.'
        )
        func_name = func_info[0]
        if len(func_info) == 1:
            kwargs = dict()
        elif len(func_info) == 2:
            kwargs = func_info[1]
        else:
            raise TypeError(
                'Function not specified correctly as a list (needs two elements): {}'
                .format(func_info))
    elif isinstance(func_info, dict):
        if len(func_info.keys()) != 1:
            raise TypeError(
                'Function not specified correctly as a dictionary (needs one key): {}'
                .format(func_info))
        for k, v in func_info.items():
            func_name = k
            kwargs = v
    else:
        raise TypeError(
            'Function not specified correctly. Need str, list, dict: {}'.
            format(func_info))
    return func_name, kwargs
Example #2
0
def resolve_ymlspec(ymlspec=None, technology=None, category='dataprep'):
    ''' Find the yml file that describes the process. There are several options for inputs
        # Option 1: file path is specified directly
        # Option 2: search within a specified technology

        This also sets the active_technology stored in the module
    '''
    if ymlspec is not None and os.path.isfile(os.path.realpath(ymlspec)):
        # Option 1: file path is specified directly
        ymlfile = ymlspec
        if technology is not None:
            set_active_technology(technology)
        tech_obj = active_technology()
        if technology is None:
            message('Using the last used technology: {}'.format(tech_obj.name))
    else:
        # Option 2: search within a specified technology
        if technology is None:
            raise ValueError(
                'When specifying a relative dataprep file, you must also provide a technology.'
            )

        tech_obj = Technology.technology_by_name(technology)
        set_active_technology(technology)
        if ymlspec is None:
            # default dataprep test
            ymlspec = 'default'
        # find path to tech
        if not ymlspec.endswith('.yml'):
            ymlspec += '.yml'
        ymlfile = tech_obj.eff_path(os.path.join(category, ymlspec))
    if not os.path.isfile(ymlfile):
        raise FileNotFoundError(
            'Could not resolve YAML specification: {}'.format(ymlspec))
    return ymlfile
Example #3
0
def check_floorplan(cell, fp_safe=50):
    ''' Checks for floorplan. If you didn't make one, this makes one.
    '''
    if cell.shapes(lys.FLOORPLAN).is_empty():
        message('Warning: No floorplan found. Making one, but you should do this yourself')
        fp_box = cell.dbbox()  # this assumes that, if FLOORPLAN is present, that DRC has verified it forms the extent
        fp_box.enlarge(fp_safe, fp_safe)
        cell.shapes(lys.FLOORPLAN).insert(fp_box)
Example #4
0
def _main(layout, ymlfile, tech_obj=None):
    with open(ymlfile) as fx:
        step_list = yaml.load(fx, Loader=yaml.FullLoader)
    reload_lys(tech_obj, dataprep=True)
    assert_valid_dataprep_steps(step_list)
    for func_info in step_list:
        func_name, kwargs = func_info_to_func_and_kwargs(func_info)
        message('lymask doing {}'.format(func_name))
        func = all_dpfunc_dict[func_name]
        for TOP_ind in layout.each_top_cell():
            # call it
            func(layout.cell(TOP_ind), **kwargs)
    return layout
Example #5
0
def parse_message(msg):
    ''' Takes a msg read from the socket and does something with it.

        Careful of name conflict with lygadgets.

        The returned payload is not the same as what is returned from the called function:
        It is prepended with a status token and encoded (as a str) to be sent back over the socket
    '''
    return_val = None
    tokens = msg.split(' ')
    try:
        # if msg == 'kill':
        #     message('Stopping server -- remote shutdown')
        #     pya.Application.exit(pya.Application.instance())

        if tokens == ['reload', 'view']:
            main = pya.Application.instance().main_window()
            main.cm_reload()

        elif tokens[0] == 'ping':
            message_loud('I heard something')

        elif tokens[0] == 'load':
            filename = os.path.realpath(tokens[1])
            message(filename)
            if len(tokens) > 2:
                mode = int(tokens[2])
                quiet_load_layout(filename, mode)
            else:
                quiet_load_layout(filename)

        elif tokens[0] == 'cellview':
            cellname = tokens[1]
            main = pya.Application.instance().main_window()
            view = main.current_view()
            cv = view.active_cellview()
            cv.set_cell_name(cellname)
            # show all layers of hierarchy
            # fit to screen

        else:
            message('Received {}'.format(msg))

    except Exception:
        # Convert the stack trace to string to send to client
        payload = 'ERR ' + repr(traceback.format_exc(
        ))  # repr makes it so multi-line strings go as one string
    else:
        # Tell the client that it worked
        payload = 'ACK ' + str(return_val)
    return payload
Example #6
0
def batch_drc_main(infile, ymlspec=None, technology=None, outfile=None):
    # covers everything that is not GUI
    if outfile is None:
        outfile = infile[:-4] + '.lyrdb'
    # Load it
    layout = pya.Layout()
    layout.read(infile)
    lys.active_layout = layout
    ymlfile = resolve_ymlspec(ymlspec, technology,
                              category='drc')  # this also sets the technology
    tech_obj = active_technology()
    # Process it
    rdb = _drc_main(layout, ymlfile=ymlfile, tech_obj=tech_obj)
    # Write it
    rdb.save(outfile)
    # Brief report
    message('DRC violations:', rdb.num_items())
    message('Full report:', outfile)
Example #7
0
def _drc_main(layout, ymlfile, tech_obj=None):
    with open(ymlfile) as fx:
        step_list = yaml.load(fx, Loader=yaml.FullLoader)
    if func_info_to_func_and_kwargs(step_list[0])[0] != 'make_rdbcells':
        step_list.insert(0, ['make_rdbcells'])
    reload_lys(tech_obj, dataprep=True)
    # assert_valid_drc_steps(step_list)

    rdb = pya.ReportDatabase('DRC: {}'.format(os.path.basename(ymlfile)))
    rdb.description = 'DRC: {}'.format(os.path.basename(ymlfile))

    for func_info in step_list:
        func_name, kwargs = func_info_to_func_and_kwargs(func_info)
        message('lymask doing {}'.format(func_name))
        func = all_drcfunc_dict[func_name]
        for TOP_ind in layout.each_top_cell():
            func(layout.cell(TOP_ind), rdb, **kwargs)
    return rdb
Example #8
0
 def __init__(self, port=lyipc.PORT, parent=None):
     pya.QTcpServer.__init__(self, parent)
     localhost = pya.QHostAddress()
     self.listen(localhost, port)
     self.newConnection(self.new_connection)
     message('Server initialized with {}, {}'.format(localhost, port))
Example #9
0
def run_xor_phidl(file1, file2, tolerance=1, verbose=False, hash_geom=True):
    import phidl.geometry as pg
    from lytest.phidl_oas import import_oas
    TOPS = []
    for fn in [file1, file2]:
        TOPS.append(import_oas(fn))
    TOP1, TOP2 = TOPS
    XOR = xor_polygons_phidl(TOP1, TOP2, hash_geom=True)
    if len(XOR.flatten().get_polygons()) > 0:
        raise GeometryDifference(
            "Differences found between layouts {} and {}".format(file1, file2))


# if you have failed to import klayout.db or pya, it's going to go slower but it can be done with phidl
if pya is None:
    message('Detected no klayout standalone. We will use phidl.')
    message('You should "pip install klayout"')
    run_xor = run_xor_phidl

if __name__ == "__main__":
    ''' For command line argument usage, run ``python kdb_xor.py --help``

        If there is a difference found, this script will return a non-zero exit code.

        Typical usage from a bash script::

            python kdb_xor.py a.gds b.gds || failed=true
            # alternatively:
            if !(python kdb_xor.py a.gds b.gds); then
              failed=true
            fi