示例#1
0
def check_results(ckt_name):

    ckt_name_json = ckt_name
    if not ckt_name.endswith('.json'):
        ckt_name_json += '.json'

    with open(ckt_name_json, "rt") as fp:
        d = json.load(fp)

    layers = [f'M{k}' for k in range(7)] + [f'V{k}' for k in range(6)]

    p = re.compile("^(.*)_gr$")

    terminals = []
    for term in d['terminals']:
        if term['layer'] not in layers:
            continue
        nm = term['netName']
        if nm is not None and p.match(nm):
            continue
        # # !kor and !float signals might be need. Right now, just excluding them.
        # if nm in ['!kor', '!float']: continue
        terminals.append(term)
    d['terminals'] = terminals

    cnv = IntelP1276p31canvas()
    cnv.bbox = transformation.Rect(*d['bbox'])
    cnv.terminals = d['terminals']

    # data = cnv.gen_data(run_pex=True, run_drc=True, postprocess=True)

    with open(ckt_name + "_prim.json", "w") as fp:
        data = cnv.writeJSON(fp, postprocess=True)

    return data
示例#2
0
def aux(fn):
    fpath = get_fpath(fn)
    with fpath.open("rt") as fp:
        d = json.load(fp)

    pdkdir = mydir.parent.parent / "pdks" / "FinFET14nm_Mock_PDK"
    generator = primitive.get_generator('MOSGenerator', pdkdir)
    # TODO: Remove these hardcoded widths & heights from __init__()
    #       (Height may be okay since it defines UnitCellHeight)
    cnv = generator(pdk.Pdk().load(pdkdir / 'layers.json'), 12, 4, 2, 3)

    layer_map = {
        'metal1': 'M1',
        'metal2': 'M2',
        'metal3': 'M3',
        'metal4': 'M4',
        'metal5': 'M5',
        'metal6': 'M6',
        'metal7': 'M7',
        'via1': 'V1',
        'via2': 'V2',
        'via3': 'V3',
        'via4': 'V4',
        'via5': 'V5',
        'via6': 'V6',
    }

    p_exclude = re.compile('^((.*_gr)|(!kor))$')

    terminals = []
    for term in d["terminals"]:
        # crazy hack to remove two different via sizes
        if term['layer'] == 'V2':
            r = term['rect']
            if r[2] - r[0] == 320:  # make it be 400
                r[0] -= 40
                r[2] += 40
            term['rect'] = r

        if term['layer'] in layer_map:
            term['layer'] = layer_map[term['layer']]
            if not p_exclude.match(term['netName']):
                terminals.append(term)
    d["terminals"] = terminals

    rational_scaling(d, div=5)

    cnv.bbox = transformation.Rect(*d["bbox"])
    cnv.terminals = d["terminals"]

    #
    # We need to merge in the leaf cells
    #

    cnv.gen_data(run_pex=False)

    assert len(cnv.rd.shorts) == 0, pformat(cnv.rd.shorts)
    assert len(cnv.rd.opens) == 0, pformat(cnv.rd.opens)
    assert len(cnv.drc.errors) == 0, pformat(cnv.drc.errors)
示例#3
0
def mos(canvas_gen, tx: Transistor, track_pattern=None):

    assert tx.nf % 2 == 0, f'Odd number of fingers are not allowed'

    c = canvas_gen()

    if tx.device_type == 'stack':
        c.addWire(c.m1, 'S', 'S', 1, (1, -1), (4, 1))
        c.addWire(c.m1, 'D', 'D', 1 + tx.nf, (1, -1), (4, 1))
    else:
        for x in range(1, 2 + tx.nf):
            p = 'D' if x % 2 == 0 else 'S'
            c.addWire(c.m1, p, p, x, (1, -1), (4, 1))

    for x in range(2, 1 + tx.nf, 2):
        c.addWire(c.m1, 'G', 'G', x, (5, -1), (6, 1))

    if track_pattern is not None:

        if 'G' in track_pattern:
            for y in track_pattern['G']:
                if tx.nf > 2:
                    g_b_idx = (2, -1)
                    g_e_idx = (tx.nf, 1)
                else:
                    g_b_idx = (1, -1)
                    g_e_idx = (1 + tx.nf, 1)
                c.addWire(c.m2, 'G', 'G', y, g_b_idx, g_e_idx)

        if tx.device_type == 'stack':
            s_b_idx = (1, -1)
            s_e_idx = (2, 1)
            d_b_idx = (tx.nf, -1)
            d_e_idx = (1 + tx.nf, 1)
        else:
            s_b_idx = (1, -1)
            s_e_idx = (1 + tx.nf, 1)
            d_b_idx = (1, -1)
            d_e_idx = (1 + tx.nf, 1)

        if 'S' in track_pattern:
            for y in track_pattern['S']:
                c.addWire(c.m2, 'S', 'S', y, s_b_idx, s_e_idx)

        if 'D' in track_pattern:
            for y in track_pattern['D']:
                c.addWire(c.m2, 'D', 'D', y, d_b_idx, d_e_idx)

        c.drop_via(c.v1)

    # Precomputed bounding box
    x1 = c.m1.clg.value(2 + tx.nf)
    y1 = c.m2.clg.value(7)
    r = [0, 0, x1[0], y1[0]]
    c.bbox = transformation.Rect(*r)

    return {"bbox": c.bbox.toList(), "instance": {}, "terminals": c.terminals}
示例#4
0
def import_result(name):

    if not name.endswith('.json'):
        name += '.json'

    with open(name, "rt") as fp:
        d = json.load(fp)

    layer_tbl = {
        "tcn": "Diffcon",
        "gcn": "Polycon",
        "diffcon": "Diffcon",
        "polycon": "Polycon",
        "nwell": "Nwell",
        "ndiff": "Ndiff",
        "pdiff": "Pdiff",
        "metal1": "M1",
        "metal2": "M2",
        "metal3": "M3",
        "metal4": "M4",
        "metal5": "M5",
        "via0": "V0",
        "via1": "V1",
        "via2": "V2",
        "via3": "V3",
        "via4": "V4"
    }

    p = re.compile("^(.*)_gr$")

    def s(r):
        assert all(v % 10 == 0 for v in r)
        return [v // 10 for v in r]

    terminals = []
    for term in d['terminals']:
        ly = term['layer']
        nm = term['netName'] if 'netName' in term else term['net_name']
        if nm is not None and p.match(nm): continue
        term['layer'] = layer_tbl.get(ly, ly)
        term['rect'] = s(term['rect'])
        # SY: Remove net_name from boundary terminals for improve viewing
        if str(term['layer']).lower() == 'boundary':
            net_name = 'netName' if 'netName' in term else 'net_name'
            term[net_name] = None
        terminals.append(term)
    d['terminals'] = terminals

    cnv = IntelP1222p2Canvas()
    cnv.bbox = transformation.Rect(*s(d['bbox']))
    cnv.terminals = d['terminals']
    return (cnv)
示例#5
0
    def place(self, rows):
        # keep record of what x, y, sx, sy the instance is stamped
        x_offset = y_offset = 0
        for row in rows:
            x_offset = 0
            for device in row:
                [cell, instance_name, pin_map, flip_x] = device
                self.stamp_cell(cell, instance_name, pin_map, x_offset,
                                y_offset, flip_x)
                x_offset += cell['bbox'][2] - cell['bbox'][0]
            y_offset += cell['bbox'][3] - cell['bbox'][1]

        self.bbox = transformation.Rect(*[0, 0, x_offset, y_offset])
        print(self.bbox)
示例#6
0
    def place(self, rows):
        x_offset = 0
        y_offset = 0

        x_offset += 0*self.pdk['Poly']['Pitch'] # whitespace for feol rules

        for row in rows:
            x_offset = 0
            for device in row:
                [cell, instance_name, pin_map, flip_x] = device
                self.stamp_cell(cell, instance_name, pin_map, x_offset, y_offset, flip_x)
                x_offset += cell['bbox'][2] - cell['bbox'][0]
            y_offset += cell['bbox'][3] - cell['bbox'][1]

        x_offset += 0*self.pdk['Poly']['Pitch'] # whitespace for feol rules

        self.bbox = transformation.Rect(*[0, 0, x_offset, y_offset])
        logger_func(f'bounding box: {self.bbox}')
示例#7
0
def test_remove_duplicates(fn):
    with (rdir / fn).open("rt") as fp:
        d = json.load(fp)

    pdkdir = pathlib.Path(
        __file__).parent.parent.parent / "pdks" / "FinFET14nm_Mock_PDK"
    generator = primitive.get_generator('MOSGenerator', pdkdir)

    # TODO: Remove these hardcoded widths & heights from __init__()
    #       (Height may be okay since it defines UnitCellHeight)
    cnv = generator(pdk.Pdk().load(pdkdir / 'layers.json'), 12, 4, 2, 3)
    cnv.bbox = transformation.Rect(*d["bbox"])
    cnv.terminals = d["terminals"]

    cnv.gen_data(run_pex=False)

    assert len(cnv.rd.different_widths) == 0, pformat(cnv.rd.different_widths)
    assert len(cnv.rd.shorts) == 0, pformat(cnv.rd.shorts)
    #    assert len(cnv.rd.opens) == 0, pformat(cnv.rd.opens)
    assert len(cnv.drc.errors) == 0, pformat(cnv.drc.errors)
示例#8
0
def tap(canvas_gen, tx: Transistor):

    assert tx.nf % 2 == 0, f'Odd number of fingers are not allowed'

    c = canvas_gen()

    c.addWire(c.m1, 'B', 'B', 1, (2, -1), (5, 1))
    c.addWire(c.m1, 'B', 'B', 1 + tx.nf, (2, -1), (5, 1))
    c.addWire(c.m2, 'B', 'B', 2, (1, -1), (1 + tx.nf, 1))
    c.addWire(c.m2, 'B', 'B', 5, (1, -1), (1 + tx.nf, 1))

    c.drop_via(c.v1)

    # Precomputed bounding box
    x1 = c.m1.clg.value(2 + tx.nf)
    y1 = c.m2.clg.value(7)
    r = [0, 0, x1[0], y1[0]]
    c.bbox = transformation.Rect(*r)

    return {"bbox": c.bbox.toList(), "instance": {}, "terminals": c.terminals}
示例#9
0
def mos(tx: Transistor):

    assert tx.nf % 2 == 0, f'Odd number of fingers are not allowed in this PDK.'

    # TODO: Below is an example of parameters to instantiate a PCELL
    # When flow is completed, instance is used to stamp the PCELLs where instantiated
    params = ' '.join([f'(\"dev_type\" \"string\" \"{tx.device_type}\")',
                       f'(\"vt_type\" \"string\" \"{tx.model_name}\")',
                       f'(\"nfin\" \"string\" \"{tx.nfin}\")'
                       f'(\"nf\" \"string\" \"{tx.nf}\")'
                       ])
    instance = {"library": "pdk_library", "cell": "pdk_mos", "view": "layout", "params": f'({params})'},

    c = CanvasPDK()

    if tx.device_type == 'stack':
        c.addWire(c.M1, 'S', 'S', 1,       (0, 1), (3, 3))
        c.addWire(c.M1, 'D', 'D', 1+tx.nf, (0, 1), (3, 3))
    else:
        for x in range(1, 2+tx.nf):
            p = 'D' if x % 2 == 0 else 'S'
            c.addWire(c.M1, p, p, x, (0, 1), (3, 3))

    for x in range(2, 1+tx.nf, 2):
        c.addWire(c.M1,  'G', 'G',  x, (4, 1), (5, 3))

    # for x in range(0, 8):
    #     c.addWire(c.M2,  None, None,  x, (0, 1), (6, 1))

    # Precomputed bounding box
    # rx = c.M1.segment(None, None, 2+tx.nf, (0, 1), (1, 3))
    # ry = c.M2.segment(None, None, 7,       (0, 1), (1, 3))
    x1 = c.M1.clg.value(2+tx.nf)
    y1 = c.M2.clg.value(7)
    r = [0, 0, x1[0], y1[0]]
    c.bbox = transformation.Rect(*r)
    # c.computeBbox()

    return {"bbox": c.bbox.toList(), "instance": instance, "terminals": c.terminals}
示例#10
0
    def s(r):
        assert all(v % 10 == 0 for v in r)
        return [v // 10 for v in r]

    terminals = []
    for term in d['terminals']:
        ly = term['layer']
        if ly in skip_layers:
            continue
        nm = term['netName'] if 'netName' in term else term['net_name']
        if nm is not None and p.match(nm): continue
        term['layer'] = layer_tbl.get(ly, ly)
        term['rect'] = s(term['rect'])
        terminals.append(term)
    d['terminals'] = terminals

    pdkfile = pathlib.Path('Intel/Intel_P1222p2_PDK/layers.json')
    cnv = IntelP1222p2Canvas(pdkfile)

    cnv.bbox = transformation.Rect(*s(d['bbox']))
    cnv.terminals = d['terminals']

    cnv.gen_data(run_pex=False)

    if False:
        assert len(cnv.rd.different_widths) == 0, pformat(
            cnv.rd.different_widths)
        assert len(cnv.rd.shorts) == 0, pformat(cnv.rd.shorts)
        assert len(cnv.rd.opens) == 0, pformat(cnv.rd.opens)
        assert len(cnv.drc.errors) == 0, pformat(cnv.drc.errors)
示例#11
0
def check_results(ckt_name):

    ckt_name_json = ckt_name
    if not ckt_name.endswith('.json'):
        ckt_name_json += '.json'

    with open(ckt_name_json, "rt") as fp:
        d = json.load(fp)

    skip_layers = set([
        "boundary", "diearea", "cellarea", "ndiff", "pdiff", "nwell", "poly",
        "gcn", "tcn", "polycon", "diffcon"
    ])

    layer_tbl = {
        "diffcon": "Diffcon",
        "polycon": "Polycon",
        "nwell": "Nwell",
        "metal1": "M1",
        "metal2": "M2",
        "metal3": "M3",
        "metal4": "M4",
        "metal5": "M5",
        "via0": "V0",
        "via1": "V1",
        "via2": "V2",
        "via3": "V3",
        "via4": "V4"
    }

    p = re.compile("^(.*)_gr$")

    def s(r):
        assert all(v % 10 == 0 for v in r)
        return [v // 10 for v in r]

    terminals = []
    for term in d['terminals']:
        ly = term['layer']
        if str(ly).lower() in skip_layers:
            continue
        nm = term['netName'] if 'netName' in term else term['net_name']
        #
        # !kor and !float signals might be need. Right now, just excluding them.
        #
        if nm in ['!kor', '!float']: continue
        if nm is not None and p.match(nm): continue
        term['layer'] = layer_tbl.get(ly, ly)
        term['rect'] = s(term['rect'])
        terminals.append(term)
    d['terminals'] = terminals

    cnv = IntelP1222p2Canvas()

    cnv.bbox = transformation.Rect(*s(d['bbox']))
    cnv.terminals = d['terminals']

    data = cnv.gen_data(run_pex=True, run_drc=True)

    with open(ckt_name + "_prim.json", "w") as fp:
        cnv.writeJSON(fp)

    tbl = cnv.pex.getSummaryCaps()

    def diffs(n0, n1):
        a, b = tbl[n0], tbl[n1]
        s = (a + b) / 2
        return f"{n0},{n1}: {a:.2f}f, {b:.2f}f, {100*(a/s-1):.1f}%, {100*(b/s-1):.1f}%"

    if ckt_name.startswith('comp'):
        print(diffs('vin', 'vip'))
        print(diffs('vin_d', 'vip_d'))
        print(diffs('vin_o', 'vip_o'))
        print(diffs('von', 'vop'))

    if False:
        assert len(cnv.rd.different_widths) == 0, pformat(
            cnv.rd.different_widths)
        assert len(cnv.rd.shorts) == 0, pformat(cnv.rd.shorts)
        assert len(cnv.rd.opens) == 0, pformat(cnv.rd.opens)
        assert len(cnv.drc.errors) == 0, pformat(cnv.drc.errors)

    return (data)