Example #1
0
def test_m2_and_m3():
    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))

    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( 'b', None, m2, v1, 3, [(0,1), (1,1), (2,1)])
    c.addWireAndViaSet( 'a', None, m2, v1, 2, [(0,0), (1,0), (2,0)])
    c.addWireAndMultiViaSet( 'b', None, m2, 1, [(v1, [(0,1), (1,1)]), (v2, [(2,1)])])

    c.addWireAndViaSet( 'b', None, m3, v2, (2,1), [1,3])


    print( c.terminals)

    c.computeBbox()

    fn = "tests/__json_via_set_m2_m3"

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

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

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

        assert data == data2
def test_via_multi_terminal_short():
    c = Canvas()
    c.addGen(Wire(nm='m1', layer='M1', direction='v', clg=None, spg=None))
    c.addGen(Via(nm="v0", layer="via0", h_clg=None, v_clg=None))
    c.terminals = [{
        'layer': 'M1',
        'netName': 'x',
        'rect': [100, -150, 200, 150]
    }, {
        'layer': 'M1',
        'netName': 'y',
        'rect': [300, -150, 600, 150]
    }, {
        'layer': 'via0',
        'netName': 'M1:S',
        'rect': [100, -50, 200, 50]
    }, {
        'layer': 'via0',
        'netName': 'M1:S',
        'rect': [300, -50, 600, 50]
    }]
    c.layer_stack.append(('via0', ('M1', None)))
    c.removeDuplicates()
    assert len(c.rd.subinsts) == 1
    assert len(c.rd.subinsts['M1']) == 1
    assert len(c.rd.shorts) == 1
    assert len(c.rd.opens) == 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_via_multi_terminal_open():
    c = Canvas()
    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="via1", h_clg=None, v_clg=None))
    c.terminals = [{
        'layer': 'M2',
        'netName': None,
        'rect': [0, -50, 300, 50]
    }, {
        'layer': 'M1',
        'netName': 'M1:S',
        'rect': [100, -150, 200, 150]
    }, {
        'layer': 'M1',
        'netName': 'M1:D',
        'rect': [0, -150, 50, 150]
    }, {
        'layer': 'via1',
        'netName': None,
        'rect': [100, -50, 200, 50]
    }, {
        'layer': 'via1',
        'netName': None,
        'rect': [0, -50, 50, 50]
    }]
    c.removeDuplicates()
    assert len(c.rd.shorts) == 0
    assert len(c.rd.opens) == 2
    assert len(c.rd.subinsts) == 1
    assert len(c.rd.subinsts['M1']) == 2
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_via_short1():
    c = Canvas()
    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="via1", h_clg=None, v_clg=None))
    c.terminals = [{
        'layer': 'M2',
        'netName': 'a',
        'rect': [0, -50, 300, 50]
    }, {
        'layer': 'M1',
        'netName': 'b',
        'rect': [100, -150, 200, 150]
    }, {
        'layer': 'via1',
        'netName': None,
        'rect': [100, -50, 200, 50]
    }]
    print(c.removeDuplicates())
    assert len(c.rd.shorts) == 1
def test_via_connectf():
    c = Canvas()
    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="via1", h_clg=None, v_clg=None))
    c.terminals = [{
        'layer': 'M2',
        'netName': 'b',
        'rect': [0, -50, 300, 50]
    }, {
        'layer': 'M1',
        'netName': None,
        'rect': [100, -150, 200, 150]
    }, {
        'layer': 'via1',
        'netName': None,
        'rect': [100, -50, 200, 50]
    }]
    terms = c.removeDuplicates()
    print(terms)
    assert len(c.rd.shorts) == 0
    assert {d['netName'] for d in terms} == {'b'}
Example #8
0
    def unit(self, x, y, x_length, y_length, x_cells, y_cells):
        m2factor = 2  ### number of m2-tracks (m2factor-1)in between two unitcells in y-direction
        m1factor = 3

        x_number = int(2 * round(
            ((x_length + self.m1Pitch - self.m1Width) / (2.0 * self.m1Pitch))))
        y_number = int(2 * round(
            ((y_length + self.m2Pitch_narrow - self.m2Width) /
             (2.0 * self.m2Pitch_narrow))))

        print("x_number, y_number:", x_number, y_number)

        last_y1_track = ((y_number - 1) * self.m2Pitch_narrow +
                         self.m2Pitch_standard - 1) // self.m2Pitch_standard
        last_x_track = x_number - 1

        if (y_number - 1) % 2 != last_y1_track % 2:
            last_y1_track += 1  # so the last color is compatible with the external view of the cell

        if last_y1_track % 2 == 1:
            m2factor += 1  # so colors match in arrayed blocks

        grid_cell_x_pitch = m1factor + last_x_track
        grid_cell_y_pitch = m2factor + last_y1_track

        print("last_x_track (m1Pitches)", last_x_track,
              "last_y1_track (m2Pitch_standards)", last_y1_track)

        gcd = math.gcd(self.m2Pitch_narrow, self.m2Pitch_standard)
        print(
            "GCD,LCM,(LCM in m2Pitch_narrowes),(LCM in m2Pitch_standards) of m2Pitch_narrow (minimum) and m2Pitch_standard (devices)",
            gcd, self.m2Pitch_narrow, self.m2Pitch_standard,
            (self.m2Pitch_narrow * self.m2Pitch_standard) // gcd,
            self.m2Pitch_standard // gcd, self.m2Pitch_narrow // gcd)

        grid_y0 = y * grid_cell_y_pitch
        grid_y1 = grid_y0 + last_y1_track

        for i in range(x_number):
            grid_x = i + x * grid_cell_x_pitch

            net = 'PLUS' if i % 2 == 1 else 'MINUS'

            self.addWire(self.m1, net, None, grid_x, (grid_y0, -1),
                         (grid_y1, 1))
            self.addWire(self.m3, net, None, grid_x, (grid_y0, -1),
                         (grid_y1, 1))

            grid_y = ((i + 1) % 2) * last_y1_track + grid_y0

            self.addVia(self.v1, net, None, grid_x, grid_y)
            self.addVia(self.v2, net, None, grid_x, grid_y)


#
# Build the narrow m2 pitch grid starting at grid_cell_y_pitch*y in standard m2 pitch grids (m2.clg)
#
        m2n = Wire(self.m2n.nm,
                   self.m2n.layer,
                   self.m2n.direction,
                   clg=self.m2n.clg.copyShift(
                       self.m2.clg.value(grid_cell_y_pitch * y)[0]),
                   spg=self.m2n.spg)

        v1n = Via('v1', 'via1', h_clg=m2n.clg, v_clg=self.m1.clg)
        v2n = Via('v2', 'via2', h_clg=m2n.clg, v_clg=self.m3.clg)

        grid_x0 = x * grid_cell_x_pitch
        grid_x1 = grid_x0 + last_x_track

        for i in range(y_number - 1):
            grid_x = x * grid_cell_x_pitch + ((i + 1) % 2) * (x_number - 1)

            pin = 'PLUS' if y == 0 and x == 0 and i == 0 else None

            net = 'PLUS' if i % 2 == 0 else 'MINUS'

            self.addVia(v1n, net, None, grid_x, i)
            self.addVia(v2n, net, None, grid_x, i)

            self.addWire(m2n, net, pin, i, (grid_x0, -1), (grid_x1, 1))

        grid_y = last_y1_track + grid_cell_y_pitch * y

        pin = 'MINUS'
        self.addWire(self.m2, 'MINUS', pin, grid_y, (grid_x0, -1),
                     (grid_x1, 1))

        if x == x_cells - 1 and y == y_cells - 1:
            self.addRegion(self.boundary, 'boundary', None, -1, -1,
                           last_x_track + x * grid_cell_x_pitch + 1,
                           last_y1_track + y * grid_cell_y_pitch + 1)
Example #9
0
    def __init__(self):
        super().__init__()

        self.m1Pitch = 64
        self.m1Width = 32
        self.m2Pitch_narrow = 64
        self.m2Pitch_standard = 84
        self.m2Width = 32
        self.m3Pitch = 64
        self.m3Width = 32

        self.v1_xenclosure = 20
        self.v1_yenclosure = 20

        self.v2_xenclosure = 20
        self.v2_yenclosure = 20

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

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

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

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

        self.boundary = self.addGen(
            Region('nwell', 'nwell', h_grid=self.m2.clg, v_grid=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))
Example #10
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)
Example #11
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)
Example #12
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
        m1hPitch  = m2Pitch
        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))
Example #13
0
def test_one():
    c = Canvas()

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

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

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

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

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

    ch = 5
    for base in [0, ch]:
        c.addWire(m1, 'S', None, 0, (base + 1, 1), (base + ch + 1, -1))
        c.addWire(m1, 'S', None, 6, (base + 1, 1), (base + ch + 1, -1))
        c.addWire(m1, 'S', None, 12, (base + 1, 1), (base + ch + 1, -1))
        c.addWire(m1, 'S', None, 18, (base + 1, 1), (base + ch + 1, -1))

        c.addWire(m1, 'DA', None, 2, (base + 1, 1), (base + ch + 1, -1))
        c.addWire(m1, 'DA', None, 20, (base + 1, 1), (base + ch + 1, -1))
        c.addWire(m1, 'DB', None, 8, (base + 1, 1), (base + ch + 1, -1))
        c.addWire(m1, 'DB', None, 14, (base + 1, 1), (base + ch + 1, -1))

        c.addWire(m2, 'GND', None, 0 + base, (0, 1), (24, -1))
        c.addWireAndViaSet('S', None, m2, v1, 1 + base, [0, 6, 12, 18])
        c.addWireAndViaSet('DA', None, m2, v1, 2 + base, [2, 20])
        c.addWireAndViaSet('DB', None, m2, v1, 3 + base, [8, 14])

    c.addWireAndViaSet('S', 'S', m3, v2, 5, [1, ch + 1])
    c.addWireAndViaSet('DA', 'DA', m3, v2, 4, [2, ch + 2])
    c.addWireAndViaSet('DB', 'DB', m3, v2, 9, [3, ch + 3])

    fn = "tests/__json_diff_pair"

    print(c.terminals)

    with open(fn + "_cand", "wt") as fp:
        data = c.writeJSON(fp)

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

        assert data == data2
Example #14
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))
Example #15
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))
Example #16
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))