Skip to content
Snippets Groups Projects
Commit 7cf4dfd6 authored by David Lanzendörfer's avatar David Lanzendörfer
Browse files

Via strips

Adding a via stripes class
parent c5591346
No related branches found
No related tags found
No related merge requests found
import gdsfactory as gf
from gdsfactory.components.compass import compass
from librepdk.structure import LibrePDKStructure
class ViaStripe(LibrePDKStructure):
device_layers = ['nwell','ndiffusion','pdiffusion', 'poly', 'pwell',]
min_row_vias = 1
def __init__(self, config, name, from_layer, w, h, conlayer_name, less_vias=False):
LibrePDKStructure.__init__(self, config, name)
# the layers:
self.from_layer = from_layer
self.conlayer_name = conlayer_name
self.conlayer = self.config.get_layer_id(self.conlayer_name)
self.less_vias = less_vias
self.get_via_stripe(w, h)
def get_via_stripe(self, w, h):
viastackup = []
metalstackup = []
if self.from_layer in self.device_layers:
origlayer = 1
metalstackup.append(self.from_layer)
else:
origlayer = int(self.from_layer.replace("metal","").strip())
# what's the highest metal layer number?
toplayer = int(self.conlayer_name.replace("metal","").strip())
match self.from_layer:
case 'ndiffusion':
viastackup.append("ndiff_contact")
case 'pdiffusion':
viastackup.append("pdiff_contact")
case 'poly':
viastackup.append("poly_contact")
for lidx in range(origlayer, toplayer):
viastackup.append("via"+str(lidx))
for lidx in range(origlayer, toplayer):
metalstackup.append("metal"+str(lidx))
# the interconnects
via = gf.Component(self.name+"_single_via")
maxdim = 0
spacing = 0
for vln in viastackup:
vlid = self.config.get_layer_id(vln)
space = self.config.get_min_spacing((vln,vln))
vdim = self.config.get_via_size(vln)
vs = self.to_nm(vdim)
vr = gf.components.rectangle(size=(vs,vs), layer=vlid)
dxy = self.to_nm(-vdim/2)
via << vr.move(self.snap_to_grid([dxy,dxy]))
# find spacing of largest via layer
if vdim > maxdim:
maxdim = vdim
spacing = space
if maxdim > 0:
col = w/(spacing+maxdim)
col = int(col)
if col < self.min_row_vias:
col = self.min_row_vias
row = h/(spacing+maxdim)
row = int(row)
if row < self.min_row_vias:
row = self.min_row_vias
if (maxdim+spacing)*col < w and not self.less_vias:
col += 1
if(maxdim+spacing)*row < h and not self.less_vias:
row += 1
# the metal rectancles on the various layers
wn = (maxdim+spacing)*col
hn = (maxdim+spacing)*row
if self.less_vias:
w = wn if w < wn else w
h = hn if h < hn else h
else:
w = wn
h = hn
# centering the via group
sp = self.to_nm(spacing+maxdim)
varr = gf.components.array(component=via, spacing=(sp, sp), columns=col, rows=row)
if self.less_vias:
dcpx = (self.to_nm(w+spacing)-varr.xsize)/2
dcpy = (self.to_nm(h+spacing)-varr.ysize)/2
else:
dcpx = dcpy = self.to_nm((maxdim+spacing)/2)
self << varr.move(self.snap_to_grid([dcpx, dcpy]))
s = (self.to_nm(w),self.to_nm(h))
for mln in metalstackup:
lid = self.config.get_layer_id(mln)
r1 = gf.components.rectangle(size=s, layer=lid)
self << r1
lid = self.config.get_layer_id("metal"+str(toplayer))
pad = gf.components.rectangle(size=s, layer=lid)
self << pad
rect = compass(size=s, layer=lid)
rect = rect.move([-rect.xmin,-rect.ymin])
c_ref = self.add_ref(rect)
self.add_ports(c_ref.ports)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment