def cell(diameter=diameter): """Create a DCpad cell. Args: diameter (float): diameter of circular debt Returns: Cell """ with nd.Cell(hashme=True) as C: C.groupname = groupname pdk.addBBmap(name) bb_width = diameter + 2*buf_width bb_length = diameter + 2*buf_length C.default_pins('c0', 'c0') nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0'], remark='electrical').\ put(0.5*bb_length, 0, 180) pdk.put_stub('c0', length=pinwidth['c0'], shape='circle') pdk.put_boundingbox('org', bb_length, bb_width) for lay, grow, acc in nd.layeriter(xs['c0']): pad = nd.geom.circle(radius=0.5*diameter, N=100) nd.Polygon(layer=lay, points=pad).\ put('cc') return C
def cell(length=length, angle=angle): anglerad = radians(angle) """Create a trapezoidal IO cell. Returns: Cell """ with nd.Cell(hashme=True, instantiate=False) as C: #When instantiate is True, cell put in (0,0,0) nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180) nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).\ put(length/cos(anglerad)-0.5*width*tan(abs(anglerad))) pdk.put_stub(['b0']) pdk.cellname(length=0.5 * length).put(-0.1 * length, 0, 180, 'a0') for lay, grow, acc in nd.layeriter(xs['a0']): outline = nd.geom.trapezoid(length=length / cos(anglerad) + grow * tan(abs(anglerad)), height=width + 2 * grow, angle1=90 + angle, angle2=90, position=2) nd.Polygon(layer=lay, points=outline).put(0) cfg.cp = C.pin['b0'] C.groupname = groupname return C
def cell(length=length, width=width): """Create a DCpad_lw cell. Args: length (float): length of the pad in um width (float): width of the pad in um Returns: Cell: dcpad element """ with nd.Cell(hashme=True) as C: C.groupname = groupname C.default_pins('c0','c0') buf = 10 bb_width = width + buf bb_length = length + buf nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0'], remark='electrical').\ put(0.5*bb_length, 0, 180) pdk.put_stub('c0', length=pinwidth['c0'], shape='circle') pdk.put_boundingbox('org', bb_length, bb_width) for lay, grow, acc in nd.layeriter(xs['c0']): pad = nd.geom.rounded_rect( length=length+grow, height=width, position=5) nd.Polygon(layer=lay, points=pad).\ put(C.pin['c0']) return C
def cell(length=length, angle=angle): anglerad = radians(angle) """Create a trapezoidal IO cell. Returns: Cell """ with nd.Cell(hashme=True, instantiate=False) as C: """When instantiate is True, cell put in (0, 0, 0)""" nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180) nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).\ put(0.5*length*(1.0+1.0/cos(anglerad))) pdk.put_stub(['a0', 'b0']) pdk.cellname(length=0.5 * length).put(C.pin['a0'].rot(180)) temp_a = tan(anglerad) + 0.5 * width * tan(anglerad) temp_b = length / cos(anglerad) + length for lay, grow, acc in nd.layeriter(xs['a0']): outline = [(0, 0.5 * width + grow), (0.5 * temp_b - (width + grow) * temp_a, 0.5 * width + grow), (0.5 * temp_b + grow * temp_a, -0.5 * width - grow), (0, -0.5 * width - grow)] nd.Polygon(layer=lay, points=outline).put(0) cfg.cp = C.pin['b0'] C.groupname = groupname return C
def cell(length=length, height=height, cleave=cleave, pitch=pitch): """Create a cell boundary. Returns: Cell """ with nd.Cell(hashme=True) as C: pdk.parameters('hashme').put(0) #TODO: No foundry specific stuff here: remove. for lay, grow, acc in nd.layeriter(xs): frame = geom.frame(sizew=cleave, sizel=length, sizeh=height, grow=grow) nd.Polygon(layer=lay, points=frame).put(0) #Placing IOs amount_ios = round((height - cleave - pitch) / pitch) #IOs positions lay = 'AnnotationIO' for no in range(0, amount_ios): pinID = 'ioL{:03d}'.format(no) angle = 0 p = nd.Pin(name=pinID).put(-cleave, pitch + no * pitch, angle) p = nd.Pin(name='ioL' + str(no)).put(-cleave, pitch + no * pitch, angle) pdk.arrow.put(p) nd.text(pinID, layer=lay, height=0.15, align='rc').put(p.move(-0.1)) for no in range(0, amount_ios): mo = amount_ios + no pinID = 'ioR{:03d}'.format(no) angle = 0 p = nd.Pin(name=pinID).put(length, pitch + no * pitch, 180 + angle) p = nd.Pin(name='ioR' + str(no)).put(length, pitch + no * pitch, 180 + angle) pdk.arrow.put(p) nd.text(pinID, layer=lay, height=0.15, align='lc').\ put(p.move(-0.1, 0, 180)) C.groupname = groupname return C
def cell(length=length, angle=angle): """Create a trapezoidal IO cell. Returns: Cell """ a = radians(angle) with nd.Cell(hashme=True, instantiate=False) as C: l = 0.5 * length / cos(a) # half the length of the hypotenuse. """When instantiate is True, cell put in (0,0,0)""" nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180) nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).put(l) pdk.put_stub(['b0']) pdk.cellname(C.cell_name, -0.5 * l).put(0, 'a0') for lay, grow, acc in nd.layeriter(xs['a0']): w = (width + 2 * grow) / 2 x = w * tan(a) outline = [(l, w), (-l + x, w), (-l - x, -w), (l, -w)] nd.Polygon(layer=lay, points=outline).put(0) cfg.cp = C.pin['b0'] C.groupname = groupname return C
def cell(cleave=cleave, length=length, height=height, coatingW=coatingW, coatingE=coatingE): """Create a Cell_Boundary cell. Returns: Cell """ with nd.Cell(hashme=True) as C: pdk.put_boundingbox('org', length, height, outline=False, \ move=(-0.5*cleave, 0.5*height-0.5*cleave)) pdk.parameters('hashme').put(0, 'cc') #TODO: No foundry specific stuff here: remove. outline = [(0, 0), (length - cleave, 0), (length - cleave, height - cleave), (0, height - cleave)] nd.Polygon(layer='Polyimide1Base', points=outline).put(0) for lay, grow, acc in nd.layeriter(xs): frame = geom.frame(sizew=cleave, sizel=length, sizeh=height, grow=grow) nd.Polygon(layer=lay, points=frame).put(0) ##adding coating to nd.Cell boundary: west and east options = { 'AR': 'Coating_AR', 'HR': 'Coating_HR', 'NO': 'Coating_NO', 'DC': 'Coating_DC' } coating_on_chip = nd.get_parameter('cell_coating_on_chip') box_coatno = [(0, 0), (cleave / 2, 0), (cleave / 2, height), (0, height)] box_coatother = [(0, 0), (coating_on_chip + 0.5 * cleave, 0), (coating_on_chip + 0.5 * cleave, height), (0, height)] pinW = nd.Pin().put(-0.5 * cleave, -0.5 * cleave) pinE = nd.Pin().put(length - 0.5 * cleave, height - 0.5 * cleave, 180) coatings = {'E': (coatingE, pinE), 'W': (coatingW, pinW)} for coat, pin in coatings.values(): if coat in options.keys(): layer = options[coat] else: print( 'Available coating options: AR | HR | NO | DC. Default is NO.' ) if coat is 'NO': box = box_coatno else: box = box_coatother nd.Polygon(layer=layer, points=box).put(pin) #Placing IOs pitch = 12.5 amount_ios = round((height - cleave - pitch) / pitch) #IOs positions lay = 'bb_pin' for no in range(0, amount_ios): pinID = 'io{:03d}'.format(no) if no % 2 is 0: angle = 7 else: angle = 0 p = nd.Pin(name=pinID).put(-cleave / 2, 12.5 + no * pitch, angle) p = nd.Pin(name='io' + str(no)).put(-cleave / 2, 12.5 + no * pitch, angle) pdk.make_pincell().put(p) nd.text(pinID, layer=lay, height=0.15, align='rc').put(p.move(-0.1)) for no in range(0, amount_ios): mo = amount_ios + no pinID = 'io{:03d}'.format(mo) if mo % 2 is 0: angle = 7 else: angle = 0 p = nd.Pin(name=pinID).put(length - cleave / 2, 2 * 12.5 + no * pitch, 180 + angle) pdk.make_pincell().put(p) nd.text(pinID, layer=lay, height=0.15, align='lc').\ put(p.move(-0.1, 0, 180)) C.groupname = groupname return C
def _makestub(xs_guide=None, width=0, length=2.0, shape=None, pinshape=None, pinsize=None, pinlayer=None, cell=None): """Create a stub in the logical layers. A stub is the stub of a xsection shape around a pin to visualize a connection. A pincell is added to the stub to indicate the pin position inside the stub. The new stub is added to the stubs dictionary: {name: stubcell} Args: xs_guide (str): name of xsection width (float): stub width thick (float): thickness of stub into cell (length) shape (str): shape of the stub: 'box' | 'circ' (default = 'box') pinshape (string): pinshape used in the stub pinsize (float): scaling factor of the pinshape (default = 1) cell (Cell): use the provided cell as stub instead of creating a new stub cell Returns: str: name of the stub """ try: xs_logic = cfg.stubmap[xs_guide] except: # if no stub defined, use the xs as its own stub. if xs_guide is None: arrow = make_pincell(layer=pinlayer, shape=pinshape, size=pinsize) return arrow if xs_guide not in cfg.XSdict.keys(): if xs_guide not in missing_xs: missing_xs.append(xs_guide) if xs_guide != cfg.default_xs_name: print("Can not make a stub in undefined xsection '{0}'.\n"\ " Possible causes: '{0}' is misspelled or not yet defined.\n"\ " Will use xsection '{2}' instead and continue.\n" " To define a new xsection:\n"\ " add_xsection(name='{0}')\n"\ " or with layers info and adding a custom stub:\n"\ " add_xsection(name='{0}', layer=1)\n"\ " add_xsection(name='{1}', layer=2)\n"\ " add_stub(xsection='{0}', stub='{1}')".\ format(xs_guide, 'stubname', cfg.default_xs_name)) xs_guide = cfg.default_xs_name cfg.stubmap[xs_guide] = xs_guide xs_logic = xs_guide name = stubname(xs_guide, width, length, shape, pinshape, pinsize, pinlayer) if name in stubs.keys(): return name # make a new stub: stubshapes = ['box', 'circle'] arrow = make_pincell(layer=pinlayer, shape=pinshape, size=pinsize) if width is None: width = 0 with nd.Cell(name, instantiate=cfg.stub_instantiate, store_pins=False) as C: arrow.put(0) if cell is not None: cell.put() else: for lay, growx, acc in nd.layeriter(xs_logic): if shape is 'circle': outline = geom.circle(radius=0.5 * length, N=32) else: outline = geom.box(width=width + 2 * growx, length=length) if width != 0: nd.Polygon(layer=lay, points=outline).put(0, 0, 180) if shape not in stubshapes: print( "Warning: stub shape '{}' not recognized, possible options are {}." .format(shape, stubshapes)) stubs[name] = C return name #name can have change to default_xs