def setup():
    c = Canvas()

    m1 = c.addGen(
        Wire(nm='m1',
             layer='M1',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    m2 = c.addGen(
        Wire(nm='m2',
             layer='M2',
             direction='h',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=5),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    m3 = c.addGen(
        Wire(nm='m3',
             layer='M3',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    v1 = c.addGen(Via(nm='v1', layer='via1', h_clg=m2.clg, v_clg=m1.clg))
    v2 = c.addGen(Via(nm='v2', layer='via2', h_clg=m2.clg, v_clg=m3.clg))

    return (c, m1, v1, m2, v2, m3)
def test_one():
    c = Canvas()

    c.pdk = {'M1': {'MaxL': None}, 'M2': {'MaxL': 10000}}

    m1 = c.addGen(
        Wire(nm='m1',
             layer='M1',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    m2 = c.addGen(
        Wire(nm='m2',
             layer='M2',
             direction='h',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=5),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    # These three should be merged
    c.addWire(m1, 'a', 0, (0, 1), (3, 3))
    c.addWire(m1, 'a', 0, (4, 1), (5, 3))
    c.addWire(m1, 'a', 0, (6, 1), (50, 3))

    # Only the first two should be merged
    c.addWire(m2, 'a', 1, (0, 1), (3, 3))
    c.addWire(m2, 'a', 1, (4, 1), (5, 3))
    c.addWire(m2, 'a', 1, (6, 1), (50, 3))

    new_terminals = c.removeDuplicates(allow_opens=True)
    print('OLD:', new_terminals)
    c.join_wires(m1)
    c.join_wires(m2)
    new_terminals = c.removeDuplicates(allow_opens=True)
    print('NEW:', new_terminals)

    c.computeBbox()

    fn = "__json_join_wires_one"

    data = {
        'bbox': c.bbox.toList(),
        'globalRoutes': [],
        'globalRouteGrid': [],
        'terminals': c.removeDuplicates(allow_opens=True)
    }

    with open(mydir / (fn + "_cand"), "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')

    with open(mydir / (fn + "_gold"), "rt") as fp:
        data2 = json.load(fp)

    assert data == data2
def test_one():
    c = Canvas()

    m1 = c.addGen(
        Wire(nm='m1',
             layer='M1',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    m2 = c.addGen(
        Wire(nm='m2',
             layer='M2',
             direction='h',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=5),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    v1 = c.addGen(Via(nm='v1', layer='via1', h_clg=m2.clg, v_clg=m1.clg))

    for i in [0, 2, 4]:
        c.addWire(m1, 'a', None, i, (0, 1), (4, -1))

    for i in [1, 3, 5]:
        c.addWire(m1, 'b', None, i, (0, 1), (4, -1))

    c.addWireAndViaSet('a', None, m2, v1, 2, [0, 2, 4])
    c.addWireAndViaSet('b', None, m2, v1, 1, [1, 3, 5])

    print(c.terminals)

    c.computeBbox()

    fn = "__json_via_set"

    data = {
        'bbox': c.bbox.toList(),
        'globalRoutes': [],
        'globalRouteGrid': [],
        'terminals': c.removeDuplicates()
    }

    with open(mydir / (fn + "_cand"), "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')

    with open(mydir / (fn + "_gold"), "rt") as fp:
        data2 = json.load(fp)

        assert data == data2
Beispiel #4
0
    def _add_metal_generator(self, layer):

        m = Wire(layer.name, layer.name, layer.direction, clg=None, spg=None)

        index = layer.offset
        m.clg = CenterLineGrid()
        m.clg.addCenterLine(index, layer.width[0], isLegal=True,
                            color=None if layer.color is None else layer.color[0])
        for i in range(1, len(layer.width)):
            index += (layer.width[i-1] + layer.width[i])//2 + layer.space[i-1]
            m.clg.addCenterLine(index, layer.width[i], isLegal=True,
                                color=None if layer.color is None else layer.color[i])

        i = len(layer.width) - 1
        index += (layer.width[i] + layer.width[0])//2 + layer.space[i]
        m.clg.addCenterLine(index, layer.width[0], isLegal=True,
                            color=None if layer.color is None else layer.color[0])
        m.clg.semantic()

        m.spg = EnclosureGrid(pitch=layer.stop_pitch,
                              offset=layer.stop_offset,
                              stoppoint=layer.stop_point,
                              check=True)

        setattr(self, layer.name, self.addGen(m))

        if layer.color is not None:
            self.postprocessor.register(layer.name, color_closure(layer=layer, generator=m))
def test_two():
    c = Canvas()

    c.pdk = {'M1': {'MaxL': None}, 'M2': {'MaxL': 10000}}

    m1 = c.addGen(
        Wire(nm='m1',
             layer='M1',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    # None of the below should merge
    c.addWire(m1, 'a', 1, (0, 1), (1, 3))
    c.addWire(m1, 'b', 1, (2, 1), (3, 3))
    c.addWire(m1, 'a', 1, (4, 1), (5, 3))

    # Append different width
    c.terminals.append({
        'layer': 'M1',
        'netName': 'a',
        'rect': [540, 4680, 900, 5400],
        'netType': 'drawing'
    })

    c.addWire(m1, None, 1, (8, 1), (9, 3))

    new_terminals = c.removeDuplicates(allow_opens=True)
    print(new_terminals)
    c.join_wires(m1)
    new_terminals = c.removeDuplicates(allow_opens=True)
    print('new:', new_terminals)

    c.computeBbox()

    fn = "__json_join_wires_two"

    data = {
        'bbox': c.bbox.toList(),
        'globalRoutes': [],
        'globalRouteGrid': [],
        'terminals': c.removeDuplicates(allow_opens=True)
    }

    with open(mydir / (fn + "_cand"), "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')

    with open(mydir / (fn + "_gold"), "rt") as fp:
        data2 = json.load(fp)

    assert data == data2
def test_four():
    c = Canvas()

    c.pdk = {'M1': {'MaxL': None}, 'M2': {'MaxL': 10000}}

    m1 = c.addGen(
        Wire(nm='m1',
             layer='M1',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    # Below wires on same centerline should not be merged
    c.addWire(m1, 'a', 1, (0, 1), (1, 3), netType="blockage")
    c.addWire(m1, 'a', 1, (2, 1), (3, 3), netType="blockage")
    c.addWire(m1, 'a', 2, (0, 1), (1, 3), netType="drawing")
    c.addWire(m1, 'a', 2, (2, 1), (3, 3), netType="pin")
    c.addWire(m1, 'a', 4, (0, 1), (1, 3), netType="drawing")
    c.addWire(m1, 'a', 4, (2, 1), (3, 3), netType="blockage")
    # Below wires on same centerline should be merged
    c.addWire(m1, 'a', 3, (0, 1), (1, 3), netType="drawing")
    c.addWire(m1, 'a', 3, (2, 1), (3, 3), netType="drawing")
    c.addWire(m1, 'a', 5, (0, 1), (1, 3), netType="pin")
    c.addWire(m1, 'a', 5, (2, 1), (3, 3), netType="pin")

    new_terminals = c.removeDuplicates(allow_opens=True)
    print(new_terminals)
    c.join_wires(m1)
    new_terminals = c.removeDuplicates(allow_opens=True)
    print('new:', new_terminals)

    c.computeBbox()

    fn = "__json_join_wires_four"

    data = {
        'bbox': c.bbox.toList(),
        'globalRoutes': [],
        'globalRouteGrid': [],
        'terminals': c.removeDuplicates(allow_opens=True)
    }

    with open(mydir / (fn + "_cand"), "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')

    with open(mydir / (fn + "_gold"), "rt") as fp:
        data2 = json.load(fp)

    assert data == data2
def test_three():
    c = Canvas()

    c.pdk = {'M1': {'MaxL': 5000}}

    m1 = c.addGen(
        Wire(nm='m1',
             layer='M1',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=720, repeat=2),
             spg=EnclosureGrid(pitch=720, stoppoint=360)))

    # Below should be merged
    c.addWire(m1, 'a', 0, (0, 1), (3, 3))
    c.addWire(m1, 'a', 0, (4, 1), (5, 3))
    # Below should be merged (but not with above)
    c.addWire(m1, 'a', 0, (6, 1), (8, 3))
    c.addWire(m1, 'a', 0, (10, 1), (11, 3))

    c.addWire(m1, 'b', 0, (12, 1), (13, 3))
    c.addWire(m1, 'a', 0, (14, 1), (15, 3))

    new_terminals = c.removeDuplicates(allow_opens=True)
    print('OLD:', new_terminals)
    c.join_wires(m1)
    new_terminals = c.removeDuplicates(allow_opens=True)
    print('NEW:', new_terminals)

    c.computeBbox()

    fn = "__json_join_wires_three"

    data = {
        'bbox': c.bbox.toList(),
        'globalRoutes': [],
        'globalRouteGrid': [],
        'terminals': c.removeDuplicates(allow_opens=True)
    }

    with open(mydir / (fn + "_cand"), "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')

    with open(mydir / (fn + "_gold"), "rt") as fp:
        data2 = json.load(fp)

    assert data == data2
def test_one():

    c = Canvas()

    c.pdk = {
        "M1": {
            "Direction": "V"
        },
        "M2": {
            "Direction": "H"
        },
        "M3": {
            "Direction": "H"
        },
        "V1": {
            "Stack": ["M1", "M2"],
            "SpaceX": 400,
            "SpaceY": 500,
            "WidthX": 400,
            "WidthY": 300,
            "VencA_L": 0,
            "VencA_H": 0,
            "VencP_L": 0,
            "VencP_H": 0
        },
        "V2": {
            "Stack": ["M2", "M3"],
            "SpaceX": 400,
            "SpaceY": 500,
            "WidthX": 400,
            "WidthY": 300,
            "VencA_L": 0,
            "VencA_H": 0,
            "VencP_L": 0,
            "VencP_H": 0
        }
    }

    c.M1 = c.addGen(
        Wire(nm='m1',
             layer='M1',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=800, repeat=2),
             spg=EnclosureGrid(pitch=900, stoppoint=450)))

    c.M2 = c.addGen(
        Wire(nm='m2',
             layer='M2',
             direction='h',
             clg=UncoloredCenterLineGrid(width=400, pitch=900, repeat=5),
             spg=EnclosureGrid(pitch=800, stoppoint=400)))

    c.M3 = c.addGen(
        Wire(nm='m3',
             layer='M3',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=800, repeat=2),
             spg=EnclosureGrid(pitch=900, stoppoint=450)))

    c.V1 = c.addGen(
        Via(nm='v1',
            layer='V1',
            h_clg=c.M2.clg,
            v_clg=c.M1.clg,
            WidthX=c.pdk['V1']['WidthX'],
            WidthY=c.pdk['V1']['WidthY']))

    c.V2 = c.addGen(
        Via(nm='v2',
            layer='V2',
            h_clg=c.M2.clg,
            v_clg=c.M3.clg,
            WidthX=c.pdk['V2']['WidthX'],
            WidthY=c.pdk['V2']['WidthY']))

    for x in [1, 2, 3]:
        c.addWire(c.M1, 'a', x, (0, 1), (3, 3))
    for y in [1, 2, 3]:
        c.addWire(c.M2, 'a', y, (1, 1), (5, 3))
    for x in [4, 5, 6]:
        c.addWire(c.M3, 'a', x, (0, 1), (3, 3))

    c.drop_via(c.V1)
    c.drop_via(c.V2)
    c.computeBbox()

    data = {
        'bbox': c.bbox.toList(),
        'globalRoutes': [],
        'globalRouteGrid': [],
        'terminals': c.terminals
    }

    # for viewing
    with open(
            pathlib.Path(os.getenv('ALIGN_HOME')) / 'Viewer' / 'INPUT' /
            'drop_via_one.json', "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')

    fn = "__json_drop_via_one"
    with open(mydir / (fn + "_cand"), "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')

    with open(mydir / (fn + "_gold"), "rt") as fp:
        data2 = json.load(fp)

    assert data == data2
def test_two():

    c = Canvas()

    c.pdk = {
        "M1": {
            "Direction": "V"
        },
        "M2": {
            "Direction": "H"
        },
        "V1": {
            "Stack": ["M1", "M2"],
            "SpaceX": 700,
            "SpaceY": 700,
            "WidthX": 400,
            "WidthY": 300,
            "VencA_L": 50,
            "VencA_H": 50,
            "VencP_L": 0,
            "VencP_H": 0
        }
    }

    c.M1 = c.addGen(
        Wire(nm='m1',
             layer='M1',
             direction='v',
             clg=UncoloredCenterLineGrid(width=400, pitch=800, repeat=2),
             spg=EnclosureGrid(pitch=900, stoppoint=450)))

    c.M2 = c.addGen(
        Wire(nm='m2',
             layer='M2',
             direction='h',
             clg=UncoloredCenterLineGrid(width=400, pitch=900, repeat=5),
             spg=EnclosureGrid(pitch=800, stoppoint=400)))

    c.V1 = c.addGen(
        Via(nm='v1',
            layer='V1',
            h_clg=c.M2.clg,
            v_clg=c.M1.clg,
            WidthX=c.pdk['V1']['WidthX'],
            WidthY=c.pdk['V1']['WidthY']))

    # via existing
    c.addWire(c.M1, 'a', 1, (0, 1), (1, 3))
    c.addWire(c.M2, 'a', 1, (0, 1), (1, 3))
    c.addVia(c.V1, 'a', 1, 1)

    # SpaceY violation
    c.addWire(c.M1, 'a', 3, (0, 1), (2, 3))
    c.addWire(c.M2, 'a', 1, (2, 1), (3, 3))
    c.addWire(c.M2, 'a', 2, (2, 1), (3, 3))

    # SpaceX violation
    c.addWire(c.M1, 'a', 5, (0, 1), (2, 3))
    c.addWire(c.M1, 'a', 6, (0, 1), (2, 3))
    c.addWire(c.M2, 'a', 1, (4, 1), (6, 3))

    # enclosure violation
    c.terminals.append({
        "layer": "M1",
        "netName": "a",
        "rect": [6200, 750, 6600, 2250],
        "netType": "drawing"
    })
    c.terminals.append({
        "layer": "M2",
        "netName": "a",
        "rect": [6200, 1600, 7000, 2000],
        "netType": "drawing"
    })
    c.addWire(c.M2, 'a', 1, (7, 1), (8, 3))

    c.drop_via(c.V1)
    c.computeBbox()
    data = {
        'bbox': c.bbox.toList(),
        'globalRoutes': [],
        'globalRouteGrid': [],
        'terminals': c.terminals
    }

    # for viewing
    with open(
            pathlib.Path(os.getenv('ALIGN_HOME')) / 'Viewer' / 'INPUT' /
            'drop_via_two.json', "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')

    fn = "__json_drop_via_two"
    with open(mydir / (fn + "_cand"), "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')

    with open(mydir / (fn + "_gold"), "rt") as fp:
        data2 = json.load(fp)

    assert data == data2
Beispiel #10
0
    def __init__(self):
        super().__init__()

        self.finsPerUnitCell = 12
        # Must be a multiple of 2
        assert self.finsPerUnitCell % 2 == 0
        # Should be a multiple of 4 for maximum utilization
        assert self.finsPerUnitCell % 4 == 0

        self.m2PerUnitCell = self.finsPerUnitCell // 2 + 3

        m2Pitch = 720

        unitCellHeight = self.m2PerUnitCell * m2Pitch

        pcPitch = unitCellHeight // 2
        m1Pitch = 720
        m3Pitch = 720

        plPitch = m1Pitch
        plOffset = plPitch // 2
        dcPitch = 2 * m1Pitch

        pcWidth = 200
        m1Width = 400
        m2Width = 400
        m3Width = 400
        dcWidth = 200
        plWidth = 200

        ndWidth = 120
        ndPitch = 360

        self.nd = self.addGen(
            Wire('nd',
                 'ndiff',
                 'h',
                 clg=UncoloredCenterLineGrid(pitch=ndPitch,
                                             width=ndWidth,
                                             repeat=2 * self.m2PerUnitCell),
                 spg=SingleGrid(pitch=dcPitch)))

        self.pc = self.addGen(
            Wire('pc',
                 'polycon',
                 'h',
                 clg=UncoloredCenterLineGrid(width=pcWidth, pitch=pcPitch),
                 spg=EnclosureGrid(pitch=dcPitch,
                                   stoppoint=plOffset - plWidth // 2)))

        self.m1 = self.addGen(
            Wire('m1',
                 'M1',
                 'v',
                 clg=UncoloredCenterLineGrid(width=m1Width,
                                             pitch=m1Pitch,
                                             repeat=2),
                 spg=EnclosureGrid(pitch=unitCellHeight,
                                   stoppoint=unitCellHeight // 2 - m2Pitch)))

        self.m3 = self.addGen(
            Wire('m3',
                 'M3',
                 'v',
                 clg=UncoloredCenterLineGrid(width=m3Width,
                                             pitch=m3Pitch,
                                             repeat=2),
                 spg=EnclosureGrid(pitch=unitCellHeight,
                                   stoppoint=unitCellHeight // 2 - m2Pitch)))

        self.m2 = self.addGen(
            Wire('m2',
                 'M2',
                 'h',
                 clg=UncoloredCenterLineGrid(width=m2Width,
                                             pitch=m2Pitch,
                                             repeat=self.m2PerUnitCell),
                 spg=EnclosureGrid(pitch=2 * m1Pitch, stoppoint=m1Pitch // 2)))

        self.pl = self.addGen(
            Wire('pl',
                 'poly',
                 'v',
                 clg=UncoloredCenterLineGrid(width=plWidth,
                                             pitch=plPitch,
                                             offset=plOffset,
                                             repeat=2),
                 spg=EnclosureGrid(pitch=unitCellHeight,
                                   stoppoint=m1Pitch // 2)))

        self.dc = self.addGen(
            Wire('dc',
                 'diffcon',
                 'v',
                 clg=UncoloredCenterLineGrid(width=dcWidth, pitch=dcPitch),
                 spg=Grid()))
        stoppoint = m1Pitch // 2
        self.dc.spg.addGridLine(0, False)
        self.dc.spg.addGridLine(stoppoint, True)
        self.dc.spg.addGridLine(unitCellHeight // 2 - stoppoint, True)
        self.dc.spg.addGridLine(unitCellHeight // 2, False)
        self.dc.spg.addGridLine(unitCellHeight // 2 + stoppoint, True)
        self.dc.spg.addGridLine(unitCellHeight - stoppoint, True)
        self.dc.spg.addGridLine(unitCellHeight, False)
Beispiel #11
0
    def __init__(self):
        super().__init__()

        self.finsPerUnitCell = 14
        self.m2PerUnitCell = 7

        ndPitch = 360
        pdPitch = 360

        m2Pitch = 720

        self.unitCellHeight = self.m2PerUnitCell * m2Pitch

        pcPitch = self.unitCellHeight // 2
        m1Pitch = 864
        m3Pitch = 720
        self.unitCellWidth = 2 * m1Pitch

        plPitch = m1Pitch
        plOffset = plPitch // 2
        dcPitch = m1Pitch

        pcWidth = 200
        m1Width = 400
        m2Width = 400
        m3Width = 400
        dcWidth = 200
        plWidth = 200

        ndWidth = 120
        ndPitch = 360

        self.pl = self.addGen(
            Wire('pl',
                 'poly',
                 'v',
                 clg=CenterLineGrid(),
                 spg=EnclosureGrid(pitch=m2Pitch // 2, stoppoint=16)))
        for i in range(5):
            self.pl.clg.addCenterLine(i * plPitch // 2, plWidth, i % 2 == 1)
        self.pl.clg.semantic()

        self.nd = self.addGen(
            Region('nd',
                   'ndiff',
                   h_grid=SingleGrid(pitch=ndPitch),
                   v_grid=self.pl.clg))

        self.pd = self.addGen(
            Region('pd',
                   'pdiff',
                   h_grid=SingleGrid(pitch=pdPitch),
                   v_grid=self.pl.clg))

        self.pc = self.addGen(
            Wire('pc',
                 'polycon',
                 'h',
                 clg=UncoloredCenterLineGrid(width=pcWidth, pitch=pcPitch),
                 spg=EnclosureGrid(pitch=dcPitch,
                                   stoppoint=plOffset - plWidth // 2)))

        self.m1 = self.addGen(
            Wire('m1',
                 'M1',
                 'v',
                 clg=UncoloredCenterLineGrid(width=m1Width,
                                             pitch=m1Pitch,
                                             repeat=2),
                 spg=EnclosureGrid(pitch=m2Pitch, stoppoint=m2Width // 2)))

        self.m2 = self.addGen(
            Wire('m2',
                 'M2',
                 'h',
                 clg=UncoloredCenterLineGrid(width=m2Width,
                                             pitch=m2Pitch,
                                             repeat=self.m2PerUnitCell),
                 spg=EnclosureGrid(pitch=2 * m1Pitch, stoppoint=m1Pitch // 2)))

        self.m3 = self.addGen(
            Wire('m3',
                 'M3',
                 'v',
                 clg=UncoloredCenterLineGrid(width=m3Width, pitch=m3Pitch),
                 spg=EnclosureGrid(pitch=self.unitCellHeight,
                                   stoppoint=self.unitCellHeight // 2 -
                                   m2Pitch)))

        self.dc = self.addGen(
            Wire('dc',
                 'diffcon',
                 'v',
                 clg=CenterLineGrid(),
                 spg=EnclosureGrid(pitch=m2Pitch // 2, stoppoint=0)))

        for i in range(5):
            self.dc.clg.addCenterLine(i * dcPitch // 2, dcWidth, i % 2 == 0)
        self.dc.clg.semantic()

        self.v0 = self.addGen(
            Via('v0', 'via0', v_clg=self.m1.clg, h_clg=self.pc.clg))
        self.v1 = self.addGen(
            Via('v1', 'via1', v_clg=self.m1.clg, h_clg=self.m2.clg))
        self.v2 = self.addGen(
            Via('v2', 'via2', v_clg=self.m3.clg, h_clg=self.m2.clg))
Beispiel #12
0
    def __init__(self, gate_u, fin_u, fin_u1):
        super().__init__()

        ##### PDK Abstraction   #####

        self.plPitch = 80  ### Use from DRM
        self.plWidth = 14
        self.finPitch = 42  ### finPitch from DRM
        self.finWidth = 10
        self.m0Pitch = self.plPitch
        self.m0Width = 34
        self.m1Pitch = self.plPitch  ### Distance between Source and Drain
        self.m1Width = 32
        self.m2Pitch = 84  ### Can be directly used from DRM (usually twice of the fin pitch)
        self.m2Width = 32
        self.m3Pitch = self.plPitch  ### Use same as for m1
        self.m3Width = 32
        self.v0Pitch = 3 * self.finPitch  ### V0 spacing rule
        self.v0Width = 32

        self.plActive_s = 73  ### Active horizontal extension over the Gate
        self.plActive = 7
        self.v_enclosure = 20
        self.fin_enclosure = (self.finPitch -
                              self.finWidth) // 2  ### Fin enclosure by active
        self.active_enclosure = 42

        self.finOffset = 0
        self.plOffset = 0

        self.finDummy = 5  ### Number of dummy fins
        self.gateDummy = 3  ### Number of dummy gates
        self.gate = int(
            round(gate_u + 2 *
                  self.gateDummy))  #### Total number of gates per unit cell
        self.extension_x = (
            self.plPitch - self.plWidth
        ) // 2  ### Minimum horizontal extension of GCUT past GATE
        self.activeWidth = self.finPitch * fin_u1
        self.activeWidth_h = (
            (gate_u - 1) * self.plPitch) + (self.plActive_s * 2) + self.plWidth
        self.activePitch = self.finPitch * (fin_u + 2 * self.finDummy)
        self.activeOffset = (
            self.activeWidth // 2
        ) + self.finDummy * self.finPitch - self.fin_enclosure - self.finWidth // 2 + self.finOffset
        self.RVTWidth = self.activeWidth + 2 * self.active_enclosure
        self.RVTPitch = self.activePitch
        self.RVTOffset = (
            self.RVTWidth // 2
        ) + self.finDummy * self.finPitch - self.fin_enclosure - self.active_enclosure - self.finWidth // 2 + self.finOffset

        self.m0 = self.addGen(
            Wire('m0',
                 'M0',
                 'v',
                 clg=UncoloredCenterLineGrid(pitch=self.m0Pitch,
                                             width=self.m0Width,
                                             offset=self.m0Pitch // 2),
                 spg=EnclosureGrid(pitch=self.activePitch,
                                   offset=self.activeOffset,
                                   stoppoint=self.activeWidth // 2,
                                   check=True)))

        self.m1 = self.addGen(
            Wire('m1',
                 'M1',
                 'v',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=self.m1Pitch,
                                           width=self.m1Width,
                                           offset=self.m1Pitch // 2),
                 spg=EnclosureGrid(pitch=self.m2Pitch,
                                   offset=self.m2Pitch // 2,
                                   stoppoint=self.m2Width // 2 +
                                   self.v_enclosure,
                                   check=True)))

        self.m2 = self.addGen(
            Wire('m2',
                 'M2',
                 'h',
                 clg=ColoredCenterLineGrid(colors=['c2', 'c1'],
                                           pitch=self.m2Pitch,
                                           width=self.m2Width,
                                           offset=self.m2Pitch // 2),
                 spg=EnclosureGrid(pitch=self.m1Pitch,
                                   offset=self.m1Pitch // 2,
                                   stoppoint=self.m1Width // 2 +
                                   self.v_enclosure,
                                   check=True)))

        self.m3 = self.addGen(
            Wire('m3',
                 'M3',
                 'v',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=self.m3Pitch,
                                           width=self.m3Width,
                                           offset=self.m3Pitch // 2),
                 spg=EnclosureGrid(pitch=self.m2Pitch,
                                   offset=self.m2Pitch // 2,
                                   stoppoint=self.m2Width // 2 +
                                   self.v_enclosure,
                                   check=True)))

        self.pl = self.addGen(
            Wire('pl',
                 'poly',
                 'v',
                 clg=UncoloredCenterLineGrid(pitch=self.plPitch,
                                             width=self.plWidth,
                                             offset=self.plOffset),
                 spg=EnclosureGrid(pitch=self.finPitch,
                                   stoppoint=self.m2Pitch // 2)))

        self.fin = self.addGen(
            Wire('fin',
                 'fin',
                 'h',
                 clg=UncoloredCenterLineGrid(pitch=self.finPitch,
                                             width=self.finWidth,
                                             offset=self.finOffset),
                 spg=CenteredGrid(pitch=self.plPitch)))

        self.active = self.addGen(
            Wire('active',
                 'active',
                 'h',
                 clg=UncoloredCenterLineGrid(pitch=self.activePitch,
                                             width=self.activeWidth,
                                             offset=self.activeOffset),
                 spg=SingleGrid(pitch=self.plPitch)))

        self.RVT = self.addGen(
            Wire('RVT',
                 'polycon',
                 'h',
                 clg=UncoloredCenterLineGrid(pitch=self.RVTPitch,
                                             width=self.RVTWidth,
                                             offset=self.RVTOffset),
                 spg=SingleGrid(pitch=self.plPitch)))

        self.nselect = self.addGen(
            Region('nselect',
                   'nselect',
                   v_grid=CenteredGrid(pitch=self.plPitch),
                   h_grid=self.fin.clg))

        v0x_offset = self.finDummy * self.finPitch - self.fin_enclosure - self.finWidth // 2 + self.finOffset + self.v0Width // 2
        self.v0 = self.addGen(
            Via('v0',
                'via0',
                h_clg=UncoloredCenterLineGrid(pitch=self.v0Pitch,
                                              width=self.v0Width,
                                              offset=v0x_offset),
                v_clg=self.m1.clg))

        self.v1 = self.addGen(
            Via('v1', 'via1', h_clg=self.m2.clg, v_clg=self.m1.clg))

        self.v2 = self.addGen(
            Via('v2', 'via2', h_clg=self.m2.clg, v_clg=self.m3.clg))
Beispiel #13
0
def setup():
    p = Pdk()
    p.pdk['M2'] = {
        'Direction': 'H',
        'Width': 60,
        'Pitch': 100,
        'MinL': 10,
        'EndToEnd': 10
    }
    p.pdk['M3'] = {
        'Direction': 'V',
        'Width': 50,
        'Pitch': 100,
        'MinL': 10,
        'EndToEnd': 10
    }

    #
    # Adjacent via violation
    # *****    *****
    #   ^        ^
    # WidthX + SpaceX > Pitch(X)
    #
    # Both okay below
    #
    p.pdk['V2'] = {
        'Stack': ['M2', 'M3'],
        'WidthX': 50,
        'WidthY': 60,
        'SpaceX': 50,
        'SpaceY': 40,
        'VencA_L': 0,
        'VencA_H': 0,
        'VencP_L': 0,
        'VencP_H': 0
    }

    c = Canvas(p)

    m2 = c.addGen(
        Wire(nm='m2',
             layer='M2',
             direction='h',
             clg=UncoloredCenterLineGrid(width=p['M2']['Width'],
                                         pitch=p['M2']['Pitch']),
             spg=EnclosureGrid(pitch=p['M3']['Pitch'],
                               stoppoint=p['M3']['Pitch'] // 2)))

    m3 = c.addGen(
        Wire(nm='m3',
             layer='M3',
             direction='v',
             clg=UncoloredCenterLineGrid(width=p['M3']['Width'],
                                         pitch=p['M3']['Pitch']),
             spg=EnclosureGrid(pitch=p['M2']['Pitch'],
                               stoppoint=p['M2']['Pitch'] // 2)))

    v2 = c.addGen(Via(nm='v2', layer='V2', h_clg=m2.clg, v_clg=m3.clg))

    n = 40
    gridlines = list(range(n))

    for i in gridlines:
        c.addWire(m3, 'a', None, i, (0, 1), (n + 1, -1))

    for j in gridlines:
        c.addWireAndViaSet('a', None, m2, v2, j + 1, gridlines)

    return c, n