Exemplo n.º 1
0
def waveguide_sleeve(cell, Delta_nw_si=2.0, Delta=2.0, delta=0.2, do_photo=True):
    ''' Does a bulk-sleeve for waveguide full, but first adds it under nanowires.
        Endcaps end where the explicit waveguide ends.
        Recognizes the wg_deep_photo layer as a photolith-only layer (lower resolution, faster EBeam write)
    '''
    Delta_nw_si /= dbu
    Delta /= dbu
    delta /= dbu
    for dp_lay in ['wg_full_photo', 'wg_full_ebeam']:
        cell.clear(lys[dp_lay])

    # add silicon under the nanowires
    nw_compressed = fast_smoothed(as_region(cell, 'm2_nw'))
    wg_explicit = as_region(cell, 'wg_deep')
    nw_except_on_wg = nw_compressed - fast_sized(wg_explicit, Delta_nw_si)
    wg_all = fast_sized(nw_except_on_wg, Delta_nw_si) + wg_explicit

    # do the bulk-sleeve
    # wg_compressed = filter_large_polygons(wg_all)
    wg_compressed = fast_smoothed(wg_all)
    ebeam_region = fast_sized(wg_compressed, Delta + delta) - wg_all
    cell.shapes(lys.wg_full_ebeam).insert(ebeam_region)
    if do_photo:
        phoas_region = as_region(cell, 'FLOORPLAN') - fast_sized(wg_compressed, Delta - delta)
        try:
            phoas_region -= as_region(cell, 'wg_deep_photo')
        except KeyError: pass
        cell.shapes(lys.wg_full_photo).insert(phoas_region)
Exemplo n.º 2
0
def nanowire_sleeve(cell, Delta=2.5, delta=0.2, do_photo=True):
    Delta /= dbu
    delta /= dbu  # new naming convention?
    for dp_lay in ['m2_nw_photo', 'm2_nw_ebeam']:
        cell.clear(lys[dp_lay])
    nw_region = as_region(cell, 'm2_nw')
    nw_compressed = fast_smoothed(nw_region)
    ebeam_region = fast_sized(nw_compressed, Delta + delta) - nw_region
    cell.shapes(lys.m2_nw_ebeam).insert(ebeam_region)
    if do_photo:
        phoas_region = as_region(cell, 'FLOORPLAN') - fast_sized(nw_compressed, Delta - delta)
        cell.shapes(lys.m2_nw_photo).insert(phoas_region)
Exemplo n.º 3
0
def exclusion(cell, rdb, lay1, lay2, exclude):
    rdb_category = rdb.create_category('{} from {}'.format(lay1, lay2))
    rdb_category.description = '{} from {} [{:1.3f} um] - Minimum exclusion violation'.format(
        lay1, lay2, exclude)

    # do it
    r1 = as_region(cell, lay1)
    r2 = as_region(cell, lay2)
    overlaps = r1 & r2
    too_close = r1.separation_check(r2, exclude / dbu)
    rdb_create(rdb, cell, rdb_category, overlaps)
    rdb_create(rdb, cell, rdb_category, too_close)
Exemplo n.º 4
0
def metal_pedestal(cell, pedestal_layer='wg_full_photo', offset=0, keepout=None):
    metal_region = pya.Region()
    for layname in ['m5_wiring', 'm5_gnd', 'gp_photo']:
        try:
            metal_region += as_region(cell, layname)
        except: pass
    valid_metal = metal_region - fast_sized(as_region(cell, lys.wg_deep), offset / dbu)
    pedestal_region = fast_sized(valid_metal, offset / dbu)
    if keepout is not None:
        if not isinstance(keepout, (list, tuple)):
            keepout = [keepout]
        for ko_layer in keepout:
            pedestal_region -= as_region(cell, ko_layer)
    cell.shapes(lys[pedestal_layer]).insert(pedestal_region)
Exemplo n.º 5
0
def precomp(cell, **kwargs):
    '''
        Arguments are keyed by layer name with the value of bias in microns, so for example

            precomp(TOP, wg_deep=0.05, nw_pad=-0.6)

        The behavior is to overwrite the layer.
        Problem if it runs twice is that it expands too much, so it stores which layers have been biased.
        Currently, it doesn't act on this, assuming that if you have run twice that you hit Undo in between.
    '''
    global has_precomped
    for layer_name, bias_um in kwargs.items():
        # do a check for repeated precomp
        if cell in has_precomped.keys():
            if layer_name in has_precomped[cell]:
                pya.MessageBox.info('Dataprep precomp', 'Warning: precompensating {} twice. '.format(layer_name) + '(in this process)\n'
                                    'If the last precomp was not undone with Ctrl-Z, this will turn out wrong', pya.MessageBox.Ok)
                pass#raise RuntimeError('At this time, precomp cannot be run twice on the same layer.')
            else:
                has_precomped[cell].add(layer_name)
        else:
            has_precomped[cell] = set([layer_name])

        # size the layer in place
        bias = bias_um / dbu
        layer_region = as_region(cell, layer_name)
        layer_region.size(bias)
        cell.clear(lys[layer_name])
        cell.shapes(lys[layer_name]).insert(layer_region)
Exemplo n.º 6
0
def drcX(cell, rdb, on_input=[], on_output=[], none=None):
    ''' DRC exclude handling. It takes lists of layers. There are three kinds
            on_input: removes that layer in the DRC_exclude regions. This is fast but dangerous if you create a small hole in some polygon
                This modifies the layout as you see it, so don't save.
            on_output (default): does the full computations but does not output edges that fall within the DRC_exclude parts
            none: output everything regardless of DRC_exclude
    '''
    if none is not None:
        raise RuntimeError('none-type DRC exclude is not supported yet.')
    for layer in on_input:
        pre_exclude = as_region(cell, layer)
        post_exclude = pre_exclude - as_region(cell, 'DRC_exclude')
        cell.clear(lys[layer])
        cell.shapes(lys[layer]).insert(post_exclude)
    for layer in on_output:
        pass  # good job you picked the default
Exemplo n.º 7
0
def smooth_floating(cell, deviation=0.005):
    ''' Removes teeny tiny edges that sometimes show up in curved edges with angles 0 or 90 plus tiny epsilon
    '''
    for layer_name in lys.keys():
        layer_region = as_region(cell, layer_name)
        layer_region = fast_smoothed(layer_region, deviation)
        cell.clear(lys[layer_name])
        cell.shapes(lys[layer_name]).insert(layer_region)
Exemplo n.º 8
0
def inclusion(cell, rdb, inner, outer, include):
    rdb_category = rdb.create_category('{} in {}'.format(inner, outer))
    rdb_category.description = '{} in {} [{:1.3f} um] - Minimum inclusion violation'.format(
        inner, outer, include)

    # do it
    rin = as_region(cell, inner)
    rout = as_region(cell, outer)
    # violations = rin.sized(include / dbu) - rout
    big_rin = turbo(rin,
                    'sized',
                    include / dbu,
                    tile_border=1.1 * include,
                    job_name='{} in {}'.format(inner, outer))
    violations = big_rin - rout

    rdb_create(rdb, cell, rdb_category, violations)
Exemplo n.º 9
0
def ground_plane(cell, Delta_gp=15.0, points_per_circle=100, air_open=None):
    Delta_gp /= dbu
    cell.clear(lys.gp_photo)
    # Accumulate everything that we don't want to cover in metal
    gp_exclusion_things = pya.Region()
    for layname in ['wg_deep', 'wg_deep_photo', 'wg_shallow', 'm1_nwpad',
                    'm4_ledpad', 'm3_res', 'm5_wiring', 'm2_nw',
                    'GP_KO']:
        try:
            gp_exclusion_things += fast_smoothed(as_region(cell, layname))
        except KeyError: pass
    # Where ground plane is explicitly connected to wires, cut it out of the exclusion region
    gnd_explicit = as_region(cell, 'm5_gnd')
    gp_exclusion_tight = gp_exclusion_things - fast_sized(gnd_explicit, Delta_gp)
    # Inflate the buffer around excluded things and pour
    gp_exclusion_zone = fast_sized(gp_exclusion_tight, Delta_gp)
    gp_region = as_region(cell, 'FLOORPLAN') - gp_exclusion_zone

    # Connect to ground pads
    gp_region.merge()
    gp_region = fast_sized(gp_region, 1 / dbu)  # kill narrow spaces
    gp_region = fast_sized(gp_region, -2 / dbu)  # kill narrow widths
    gp_region = fast_sized(gp_region, 1 / dbu)
    gp_region += as_region(cell, 'm5_gnd')
    gp_region.round_corners(Delta_gp / 5, Delta_gp / 3, points_per_circle)
    gp_region = gp_region.smoothed(.001)  # avoid some bug in pya
    gp_region.merge()
    cell.shapes(lys.gp_photo).insert(gp_region)

    # Open up to the air
    if air_open is not None:
        Delta_air = 5
        fp_safe = as_region(cell, 'FLOORPLAN')
        air_rects = fp_safe - fp_safe.sized(0, -air_open / dbu, 0)
        air_region = air_rects & gp_region
        air_region = fast_sized(air_region, -Delta_air / dbu)
        air_region = fast_sized(air_region, 4 / dbu)  # kill narrow spaces
        air_region = fast_sized(air_region, -8 / dbu)  # kill narrow widths
        air_region = fast_sized(air_region, 4 / dbu)
        air_region.round_corners(Delta_gp / 5, Delta_gp / 3, points_per_circle)
        cell.shapes(lys.gp_v5).insert(air_region)
Exemplo n.º 10
0
def space(cell, rdb, layer, value, angle=90):
    rdb_category = rdb.create_category('{}_Space'.format(layer))
    rdb_category.description = '{} [{:1.3f} um] - Minimum feature spacing violation'.format(
        layer, value)
    # message_loud('lymask doing {}'.format(rdb_category.name()))

    # do it
    polys = as_region(cell, layer)
    # violations = fast_space(polys, value / dbu, angle)
    violations = turbo(polys,
                       'space_check',
                       [value / dbu, False, None, angle, None, None],
                       tile_border=1.1 * value,
                       job_name='{}_Space'.format(layer))
    rdb_create(rdb, cell, rdb_category, violations)
Exemplo n.º 11
0
def width(cell, rdb, layer, value, angle=90):
    rdb_category = rdb.create_category('{}_Width'.format(layer))
    rdb_category.description = '{} [{:1.3f} um] - Minimum feature width violation'.format(
        layer, value)
    # message_loud('lymask doing {}'.format(rdb_category.name()))

    # do it
    polys = as_region(cell, layer)
    # violations = polys.width_check(value / dbu, False, pya.Region.Square, angle, None, None)
    violations = turbo(polys,
                       'width_check',
                       [value / dbu, False, None, angle, None, None],
                       tile_border=1.1 * value,
                       job_name='{}_Width'.format(layer))
    rdb_create(rdb, cell, rdb_category, violations)
Exemplo n.º 12
0
def invert_tone(cell, layer):
    inverted = as_region(cell, 'FLOORPLAN') - as_region(cell, layer)
    cell.clear(lys[layer])
    cell.shapes(lys[layer]).insert(inverted)