Esempio n. 1
0
def setup():
    p = Pdk().load('../PDK_Abstraction/FinFET14nm_Mock_PDK/FinFET_Mock_PDK_Abstraction.json')
    c = Canvas(p)
    c.addGen( Wire( nm='m1', layer='M1', direction='v', clg=None, spg=None))
    c.addGen( Wire( nm='m2', layer='M2', direction='h', clg=None, spg=None))
    c.addGen( Via( nm="v1", layer="V1", h_clg=None, v_clg=None))
    return c
def test_m3():
    p = Pdk().load(
        '../PDK_Abstraction/FinFET14nm_Mock_PDK/FinFET_Mock_PDK_Abstraction.json'
    )
    c = DefaultCanvas(p)

    m = c.generators['m3']
    mt = MetalTemplate(m)

    print("m3 clg grid", m.clg.grid, "m3 clg legal indices",
          m.clg.legalIndices)
    print("m3 spg grid", m.spg.grid, "m3 spg legal indices",
          m.spg.legalIndices)

    assert 1 in m.spg.legalIndices
    assert 3 in m.spg.legalIndices
    ### The following assertions are modified based on the updtaed PDK
    assert m.spg.grid[1][0] == 36
    assert m.spg.grid[3][0] == 48

    assert mt.widths == [40, 40, 40]
    assert mt.colors == ["c1", "c2", "c1"]
    assert mt.spaces == [40, 40]
    assert mt.offset == 0

    assert mt.stop_offset == 36
    assert mt.stops == [12, 72]
Esempio n. 3
0
def setup():
    p = Pdk().load(
        '../PDK_Abstraction/FinFET14nm_Mock_PDK/FinFET_Mock_PDK_Abstraction.json'
    )
    c = DefaultCanvas(p)
    for (i, nm) in itertools.chain(itertools.product([0, 2, 4], ['a']),
                                   itertools.product([1, 3, 5], ['b'])):
        c.addWire(c.m1, nm, None, i, (0, -1), (3, -1))
    return c
Esempio n. 4
0
def test_v3(setup):
    p = Pdk().load(
        '../PDK_Abstraction/FinFET14nm_Mock_PDK/FinFET_Mock_PDK_Abstraction.json'
    )
    c = DefaultCanvas(p)

    c.addWire(c.m3, "a", None, 1, (-2, 1), (4, -1))
    c.addWire(c.m4, "a", None, 1, (-2, 1), (4, -1))
    c.addVia(c.v3, None, None, 1, 1)
    data = c.gen_data()

    fn = "tests/__json_v3"

    with open(fn + "_cand", "wt") as fp:
        fp.write(json.dumps(data, indent=2) + '\n')
Esempio n. 5
0
    def __init__(self, fin_u, fin, finDummy, gate, gateDummy, pdkfile=pdkfile):

        p = Pdk().load(pdkfile)
        super().__init__(p)
        assert 3 * p['Fin']['Pitch'] < 2 * p['M2']['Pitch']

        ######### Derived Parameters ############
        self.gatesPerUnitCell = gate + 2 * gateDummy
        self.finsPerUnitCell = fin + 2 * finDummy
        # Should be a multiple of 4 for maximum utilization
        assert self.finsPerUnitCell % 4 == 0
        assert fin >= fin_u, "number of fins in the transistor is greater than unit cell fins"
        assert fin_u > 3, "number of fins in the transistor must be more than 2"
        assert finDummy % 2 == 0
        assert gateDummy > 0
        self.m2PerUnitCell = self.finsPerUnitCell // 2 + 0
        self.unitCellHeight = self.m2PerUnitCell * p['M2']['Pitch']
        unitCellLength = self.gatesPerUnitCell * p['Poly']['Pitch']
        activeWidth1 = p['Fin']['Pitch'] * fin_u
        activeWidth = p['Fin']['Pitch'] * fin
        activeOffset = activeWidth // 2 + finDummy * p['Fin']['Pitch'] - p[
            'Fin']['Pitch'] // 2
        activePitch = self.unitCellHeight
        RVTWidth = activeWidth1 + 2 * p['Feol']['active_enclosure']

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

        self.pl = self.addGen(
            Wire('pl',
                 'poly',
                 'v',
                 clg=UncoloredCenterLineGrid(pitch=p['Poly']['Pitch'],
                                             width=p['Poly']['Width'],
                                             offset=p['Poly']['Offset']),
                 spg=SingleGrid(offset=p['M2']['Offset'],
                                pitch=self.unitCellHeight)))

        self.fin = self.addGen(
            Wire('fin',
                 'fin',
                 'h',
                 clg=UncoloredCenterLineGrid(pitch=p['Fin']['Pitch'],
                                             width=p['Fin']['Width'],
                                             offset=p['Fin']['Offset']),
                 spg=SingleGrid(offset=0, pitch=unitCellLength)))

        stoppoint = (gateDummy - 1) * p['Poly']['Pitch'] + p['Poly']['Offset']
        self.active = self.addGen(
            Wire('active',
                 'active',
                 'h',
                 clg=UncoloredCenterLineGrid(pitch=activePitch,
                                             width=activeWidth1,
                                             offset=activeOffset),
                 spg=EnclosureGrid(pitch=unitCellLength,
                                   offset=0,
                                   stoppoint=stoppoint,
                                   check=True)))

        self.RVT = self.addGen(
            Wire('RVT',
                 'polycon',
                 'h',
                 clg=UncoloredCenterLineGrid(pitch=activePitch,
                                             width=RVTWidth,
                                             offset=activeOffset),
                 spg=EnclosureGrid(pitch=unitCellLength,
                                   offset=0,
                                   stoppoint=stoppoint,
                                   check=True)))

        self.nselect = self.addGen(
            Region('nselect',
                   'nselect',
                   v_grid=CenteredGrid(offset=p['Poly']['Pitch'] // 2,
                                       pitch=p['Poly']['Pitch']),
                   h_grid=self.fin.clg))
        self.pselect = self.addGen(
            Region('pselect',
                   'pselect',
                   v_grid=CenteredGrid(offset=p['Poly']['Pitch'] // 2,
                                       pitch=p['Poly']['Pitch']),
                   h_grid=self.fin.clg))
        self.nwell = self.addGen(
            Region('nwell',
                   'nwell',
                   v_grid=CenteredGrid(offset=p['Poly']['Pitch'] // 2,
                                       pitch=p['Poly']['Pitch']),
                   h_grid=self.fin.clg))

        self.v0 = self.addGen(
            Via('v0', 'V0', h_clg=CenterLineGrid(), v_clg=self.m1.clg))

        self.v0.h_clg.addCenterLine(0, p['V0']['WidthY'], False)
        for i in range(
                max(activeWidth1 // (2 * p['M2']['Pitch']), 1) +
            ((fin - fin_u) // 2 + finDummy + 1) // 2):
            self.v0.h_clg.addCenterLine(
                (i - 1 + fin_u // fin) * 3 * p['Fin']['Pitch'],
                p['V0']['WidthY'], True)
        self.v0.h_clg.addCenterLine(self.unitCellHeight, p['V0']['WidthY'],
                                    False)
Esempio n. 6
0
def remove_duplicates(hN):
    p = Pdk().load(
        "../../PDK_Abstraction/FinFET14nm_Mock_PDK/FinFET_Mock_PDK_Abstraction.json"
    )

    cnv = DefaultCanvas(p)

    cnv.bbox = transformation.Rect(0, 0, hN.width, hN.height)

    cnv.terminals = []

    def add_terminal(netName, layer, b):
        check_bbox(b)
        cnv.terminals.append({
            "netName": netName,
            "layer": layer,
            "rect": [b.LL.x, b.LL.y, b.UR.x, b.UR.y]
        })

    for n in hN.Nets:
        print(n.name)
        for c in n.connected:
            if c.type == 'Block':
                cblk = hN.Blocks[c.iter2]
                blk = cblk.instance[cblk.selectedInstance]
                block_name = blk.name
                master_name = blk.master
                pin = blk.blockPins[c.iter]
                formal_name = pin.name

                print(
                    f'\tBlock formal_index: {c.iter},{formal_name} block_index: {c.iter2},{block_name},{master_name}'
                )
                for con in pin.pinContacts:
                    add_terminal(n.name, con.metal, con.placedBox)

            else:
                term = hN.Terminals[c.iter]
                terminal_name = term.name
                assert terminal_name == n.name
                print(f'\tTerminal formal_index: {c.iter},{terminal_name}')
                for con in term.termContacts:
                    add_terminal(n.name, con.metal, con.placedBox)

        for metal in n.path_metal:
            con = metal.MetalRect
            add_terminal(n.name, con.metal, con.placedBox)

        for via in n.path_via:
            for con in [via.UpperMetalRect, via.LowerMetalRect, via.ViaRect]:
                add_terminal(n.name, con.metal, con.placedBox)

        for via in n.interVias:
            for con in [via.UpperMetalRect, via.LowerMetalRect, via.ViaRect]:
                add_terminal(n.name, con.metal, con.placedBox)

    for cblk in hN.Blocks:
        blk = cblk.instance[cblk.selectedInstance]
        for con in blk.interMetals:
            #            add_terminal( '!interMetals', con.metal, con.placedBox)
            pass

        for via in blk.interVias:
            for con in [via.UpperMetalRect, via.LowerMetalRect, via.ViaRect]:
                #                add_terminal( '!interVias', con.metal, con.placedBox)
                pass

    cnv.removeDuplicates()

    return cnv
Esempio n. 7
0
    def __init__( self, fin_u, fin, finDummy, gate, gateDummy):
        p = Pdk().load('../PDK_Abstraction/FinFET14nm_Mock_PDK/FinFET_Mock_PDK_Abstraction.json')
        super().__init__(p)
        assert   3*p['Fin']['Pitch'] < 2*p['M2']['Pitch']

######### Derived Parameters ############
        self.gatesPerUnitCell = gate + 2*gateDummy
        self.finsPerUnitCell = fin + 2*finDummy
        # Must be a multiple of 2
        assert self.finsPerUnitCell % 2 == 0
        assert finDummy % 2 == 0
        assert gateDummy > 0
        # Should be a multiple of 4 for maximum utilization
        assert self.finsPerUnitCell % 4 == 0
        self.m2PerUnitCell = self.finsPerUnitCell//2 + 0
        self.unitCellHeight = self.m2PerUnitCell* p['M2']['Pitch']
        unitCellLength = self.gatesPerUnitCell* p['Poly']['Pitch']
        activeWidth =  p['Fin']['Pitch']*fin
        activeOffset = activeWidth//2 + finDummy* p['Fin']['Pitch']-p['M2']['Pitch']//2+p['Fin']['Offset']
        activePitch = self.unitCellHeight
        RVTPitch = activePitch
        RVTWidth = activeWidth + 2*p['Feol']['active_enclosure']
        RVTOffset = RVTWidth//2 + finDummy* p['Fin']['Pitch']-p['Fin']['Pitch']//2-p['Feol']['active_enclosure']+p['Fin']['Offset']

############Include these all ###########

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

        self.pl = self.addGen( Wire( 'pl', 'poly', 'v',
                                     clg=UncoloredCenterLineGrid( pitch= p['Poly']['Pitch'], width= p['Poly']['Width'], offset= p['Poly']['Offset']),
                                     spg=SingleGrid( offset= p['M2']['Offset'], pitch=self.unitCellHeight)))


        self.fin = self.addGen( Wire( 'fin', 'fin', 'h',
                                      clg=UncoloredCenterLineGrid( pitch= p['Fin']['Pitch'], width= p['Fin']['Width'], offset= p['Fin']['Offset']),
                                      spg=SingleGrid( offset=0, pitch=unitCellLength)))

        stoppoint = (gateDummy-1)* p['Poly']['Pitch'] +  p['Poly']['Offset']

        self.active = self.addGen( Wire( 'active', 'active', 'h',
                                         clg=UncoloredCenterLineGrid( pitch=activePitch, width=activeWidth, offset=activeOffset),
                                         spg=EnclosureGrid( pitch=unitCellLength, offset=0, stoppoint=stoppoint, check=True)))

        self.RVT = self.addGen( Wire( 'RVT', 'polycon', 'h',
                                      clg=UncoloredCenterLineGrid( pitch=RVTPitch, width=RVTWidth, offset=RVTOffset),
                                      spg=EnclosureGrid( pitch=unitCellLength, offset=0, stoppoint=stoppoint, check=True)))

        self.nselect = self.addGen( Region( 'nselect', 'nselect',
                                            v_grid=CenteredGrid( offset= p['Poly']['Pitch']//2, pitch= p['Poly']['Pitch']),
                                            h_grid=self.fin.clg))
        self.pselect = self.addGen( Region( 'pselect', 'pselect',
                                            v_grid=CenteredGrid( offset= p['Poly']['Pitch']//2, pitch= p['Poly']['Pitch']),
                                            h_grid=self.fin.clg))
        self.nwell = self.addGen( Region( 'nwell', 'nwell',
                                            v_grid=CenteredGrid( offset= p['Poly']['Pitch']//2, pitch= p['Poly']['Pitch']),
                                            h_grid=self.fin.clg))

        v0x_offset =  p['M2']['Offset'] + (1+finDummy//2)* p['M2']['Pitch']

        self.v0 = self.addGen( Via( 'v0', 'V0',
                                    h_clg=CenterLineGrid(),
                                    v_clg=self.m1.clg))

        self.v0.h_clg.addCenterLine( 0,                 p['V0']['WidthY'], False)
        for i in range(activeWidth//(2* p['M2']['Pitch'])):
            self.v0.h_clg.addCenterLine( v0x_offset+i*  3*p['Fin']['Pitch'],    p['V0']['WidthY'], True)
        self.v0.h_clg.addCenterLine( self.unitCellHeight,    p['V0']['WidthY'], False)
Esempio n. 8
0
def setup():
    p = Pdk().load('../PDK_Abstraction/FinFET14nm_Mock_PDK/FinFET_Mock_PDK_Abstraction.json')
    c = DefaultCanvas(p)
    return c
Esempio n. 9
0
    def __init__(self, x_length, y_length):
        super().__init__()
        p = Pdk().load(pdkfile)

        self.x_number = int(2 * round(
            ((x_length + p['Cap']['m1Pitch'] - p['Cap']['m1Width']) /
             (2.0 * p['Cap']['m1Pitch']))))
        self.y_number = int(2 * round(
            ((y_length + p['Cap']['m2Pitch'] - p['Cap']['m2Width']) /
             (2.0 * p['Cap']['m2Pitch']))))

        self.last_y1_track = ((self.y_number - 1) * p['Cap']['m2Pitch'] +
                              p['M2']['Pitch'] - 1) // p['M2']['Pitch']
        self.last_x_track = self.x_number - 1

        self.m1 = self.addGen(
            Wire('m1',
                 'M1',
                 'v',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=p['Cap']['m1Pitch'],
                                           width=p['Cap']['m1Width']),
                 spg=EnclosureGrid(pitch=p['M2']['Pitch'],
                                   stoppoint=p['V1']['VencA_L'] +
                                   p['Cap']['m2Width'] // 2,
                                   check=True)))

        self.m2 = self.addGen(
            Wire('m2',
                 'M2',
                 'h',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=p['M2']['Pitch'],
                                           width=p['Cap']['m2Width']),
                 spg=EnclosureGrid(pitch=p['Cap']['m1Pitch'],
                                   stoppoint=p['V1']['VencA_H'] +
                                   p['Cap']['m1Width'] // 2,
                                   check=False)))

        self.m2n = self.addGen(
            Wire('m2n',
                 'M2',
                 'h',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=p['Cap']['m2Pitch'],
                                           width=p['Cap']['m2Width']),
                 spg=EnclosureGrid(pitch=p['Cap']['m1Pitch'],
                                   stoppoint=p['V1']['VencA_H'] +
                                   p['Cap']['m1Width'] // 2)))

        self.m3 = self.addGen(
            Wire('m3',
                 'M3',
                 'v',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=p['Cap']['m3Pitch'],
                                           width=p['Cap']['m3Width']),
                 spg=EnclosureGrid(pitch=p['M2']['Pitch'],
                                   stoppoint=p['V2']['VencA_H'] +
                                   p['Cap']['m2Width'] // 2,
                                   check=True)))

        self.boundary = self.addGen(
            Region('boundary',
                   'boundary',
                   h_grid=self.m2.clg,
                   v_grid=self.m1.clg))

        self.v1 = self.addGen(
            Via('v1', 'V1', h_clg=self.m2.clg, v_clg=self.m1.clg))
        self.v2 = self.addGen(
            Via('v2', 'V1', h_clg=self.m2.clg, v_clg=self.m3.clg))
Esempio n. 10
0
    def __init__(self, x_number, y_length):
        super().__init__()
        p = Pdk().load(pdkfile)

        ga = 2 if x_number == 1 else 1  ## when number of wires is 2 then large spacing req. so contact can be placed without a DRC error
        self.x_length = (x_number - 1) * ga * p['Cap']['m1Pitch']

        self.y_number = int(2 * round(
            ((y_length + p['Cap']['m2Pitch'] - p['Cap']['m2Width']) /
             (2.0 * p['Cap']['m2Pitch']))))

        self.last_y1_track = ((self.y_number - 1) * p['Cap']['m2Pitch'] +
                              p['M2']['Pitch'] - 1) // p['M2']['Pitch']
        self.last_x_track = x_number - 1

        self.m1 = self.addGen(
            Wire('m1',
                 'M1',
                 'v',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=p['Cap']['m1Pitch'],
                                           width=p['Cap']['m1Width']),
                 spg=EnclosureGrid(pitch=p['M2']['Pitch'],
                                   stoppoint=p['V1']['VencA_L'] +
                                   p['Cap']['m2Width'] // 2,
                                   check=True)))

        self.m1h = self.addGen(
            Wire('m1h',
                 'M1',
                 'h',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=p['M2']['Pitch'],
                                           width=p['Cap']['m1Width']),
                 spg=EnclosureGrid(pitch=p['Cap']['m1Pitch'],
                                   stoppoint=p['Cap']['m1Width'] // 2,
                                   check=False)))

        self.m2 = self.addGen(
            Wire('m2',
                 'M2',
                 'h',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=p['M2']['Pitch'],
                                           width=p['Cap']['m2Width']),
                 spg=EnclosureGrid(pitch=p['Cap']['m1Pitch'],
                                   stoppoint=p['V1']['VencA_H'] +
                                   p['Cap']['m1Width'] // 2,
                                   check=False)))

        self.m2n = self.addGen(
            Wire('m2n',
                 'M2',
                 'h',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=p['Cap']['m2Pitch'],
                                           width=p['Cap']['m2Width']),
                 spg=EnclosureGrid(pitch=p['Cap']['m1Pitch'],
                                   stoppoint=p['V1']['VencA_H'] +
                                   p['Cap']['m1Width'] // 2)))

        self.m3 = self.addGen(
            Wire('m3',
                 'M3',
                 'v',
                 clg=ColoredCenterLineGrid(colors=['c1', 'c2'],
                                           pitch=p['Cap']['m3Pitch'],
                                           width=p['Cap']['m3Width']),
                 spg=EnclosureGrid(pitch=p['M2']['Pitch'],
                                   stoppoint=p['V2']['VencA_H'] +
                                   p['Cap']['m2Width'] // 2,
                                   check=True)))

        self.boundary = self.addGen(
            Region('boundary',
                   'boundary',
                   h_grid=self.m2.clg,
                   v_grid=self.m1.clg))
        self.v1 = self.addGen(
            Via('v1', 'V1', h_clg=self.m2.clg, v_clg=self.m1.clg))
        self.v2 = self.addGen(
            Via('v2', 'V2', h_clg=self.m2.clg, v_clg=self.m3.clg))
def test_one():
    p = Pdk().load(
        '../PDK_Abstraction/FinFET14nm_Mock_PDK/FinFET_Mock_PDK_Abstraction.json'
    )
    c = DefaultCanvas(p)
    assert c.generate_routing_collateral("tests/routing_collateral_cand")