@@ -1913,6 +1913,42 @@ def add_io_pin(self, instance, pin_name, new_name, start_layer=None, directions=
1913
1913
# Just use the power pin function for now to save code
1914
1914
self .add_power_pin (new_name , pin .center (), start_layer = start_layer , directions = directions )
1915
1915
1916
+ def add_power_pin_m2 (self , name , loc , directions = None , start_layer = "m1" ):
1917
+ # same function like normal one, but add power pin at m2
1918
+ # Hack for min area
1919
+ if OPTS .tech_name == "sky130" :
1920
+ min_area = drc ["minarea_{}" .format (self .pwr_grid_layers [1 ])]
1921
+ width = round_to_grid (sqrt (min_area ))
1922
+ height = round_to_grid (min_area / width )
1923
+ else :
1924
+ width = None
1925
+ height = None
1926
+
1927
+ pin = None
1928
+ if start_layer == "m2" :
1929
+ pin = self .add_layout_pin_rect_center (text = name ,
1930
+ layer = start_layer ,
1931
+ offset = loc ,
1932
+ width = width ,
1933
+ height = height )
1934
+ else :
1935
+ via = self .add_via_stack_center (from_layer = start_layer ,
1936
+ to_layer = "m2" ,
1937
+ offset = loc ,
1938
+ directions = directions )
1939
+
1940
+ if not width :
1941
+ width = via .width
1942
+ if not height :
1943
+ height = via .height
1944
+ pin = self .add_layout_pin_rect_center (text = name ,
1945
+ layer = "m2" ,
1946
+ offset = loc ,
1947
+ width = width ,
1948
+ height = height )
1949
+
1950
+ return pin
1951
+
1916
1952
def add_power_pin (self , name , loc , directions = None , start_layer = "m1" ):
1917
1953
# Hack for min area
1918
1954
if OPTS .tech_name == "sky130" :
@@ -2027,7 +2063,7 @@ def add_perimeter_pin(self, name, pin, side, bbox):
2027
2063
layer = layer ,
2028
2064
offset = peri_pin_loc )
2029
2065
2030
- def add_dnwell (self , bbox = None , inflate = 1 ):
2066
+ def add_dnwell (self , bbox = None , inflate = 1 , route_option = "classic" ):
2031
2067
""" Create a dnwell, along with nwell moat at border. """
2032
2068
2033
2069
if "dnwell" not in tech_layer :
@@ -2049,11 +2085,20 @@ def add_dnwell(self, bbox=None, inflate=1):
2049
2085
ul = vector (ll .x , ur .y )
2050
2086
lr = vector (ur .x , ll .y )
2051
2087
2052
- # Add the dnwell
2053
- self .add_rect ("dnwell" ,
2054
- offset = ll ,
2055
- height = ur .y - ll .y ,
2056
- width = ur .x - ll .x )
2088
+ # Hack for sky130 klayout drc rule nwell.6
2089
+ if OPTS .tech_name == "sky130" :
2090
+ # Apply the drc rule
2091
+ # Add the dnwell
2092
+ self .add_rect ("dnwell" ,
2093
+ offset = ll - vector (0.5 * self .nwell_width , 0.5 * self .nwell_width ) - vector (drc ["minclosure_nwell_by_dnwell" ], drc ["minclosure_nwell_by_dnwell" ]),
2094
+ height = ur .y - ll .y + self .nwell_width + 2 * drc ["minclosure_nwell_by_dnwell" ],
2095
+ width = ur .x - ll .x + self .nwell_width + 2 * drc ["minclosure_nwell_by_dnwell" ])
2096
+ else : # other tech
2097
+ # Add the dnwell
2098
+ self .add_rect ("dnwell" ,
2099
+ offset = ll ,
2100
+ height = ur .y - ll .y ,
2101
+ width = ur .x - ll .x )
2057
2102
2058
2103
# Add the moat
2059
2104
self .add_path ("nwell" , [ll , lr , ur , ul , ll - vector (0 , 0.5 * self .nwell_width )])
@@ -2063,9 +2108,9 @@ def add_dnwell(self, bbox=None, inflate=1):
2063
2108
tap_spacing = 2
2064
2109
nwell_offset = vector (self .nwell_width , self .nwell_width )
2065
2110
2066
- # Every nth tap is connected to gnd
2111
+ # Every nth tap is connected to vdd
2067
2112
period = 5
2068
-
2113
+ moat_pins = []
2069
2114
# BOTTOM
2070
2115
count = 0
2071
2116
loc = ll + nwell_offset .scale (tap_spacing , 0 )
@@ -2080,9 +2125,10 @@ def add_dnwell(self, bbox=None, inflate=1):
2080
2125
to_layer = "m1" ,
2081
2126
offset = loc )
2082
2127
else :
2083
- self .add_power_pin (name = "vdd" ,
2084
- loc = loc ,
2085
- start_layer = "li" )
2128
+ pin = self .add_power_pin (name = "vdd" ,
2129
+ loc = loc ,
2130
+ start_layer = "li" )
2131
+ moat_pins .append (pin )
2086
2132
count += 1
2087
2133
loc += nwell_offset .scale (tap_spacing , 0 )
2088
2134
@@ -2100,9 +2146,10 @@ def add_dnwell(self, bbox=None, inflate=1):
2100
2146
to_layer = "m1" ,
2101
2147
offset = loc )
2102
2148
else :
2103
- self .add_power_pin (name = "vdd" ,
2104
- loc = loc ,
2105
- start_layer = "li" )
2149
+ pin = self .add_power_pin (name = "vdd" ,
2150
+ loc = loc ,
2151
+ start_layer = "li" )
2152
+ moat_pins .append (pin )
2106
2153
count += 1
2107
2154
loc += nwell_offset .scale (tap_spacing , 0 )
2108
2155
@@ -2120,9 +2167,15 @@ def add_dnwell(self, bbox=None, inflate=1):
2120
2167
to_layer = "m2" ,
2121
2168
offset = loc )
2122
2169
else :
2123
- self .add_power_pin (name = "vdd" ,
2124
- loc = loc ,
2125
- start_layer = "li" )
2170
+ if route_option == "classic" :
2171
+ pin = self .add_power_pin (name = "vdd" ,
2172
+ loc = loc ,
2173
+ start_layer = "li" )
2174
+ elif route_option == "quality" :
2175
+ pin = self .add_power_pin_m2 (name = "vdd" ,
2176
+ loc = loc ,
2177
+ start_layer = "li" )
2178
+ moat_pins .append (pin )
2126
2179
count += 1
2127
2180
loc += nwell_offset .scale (0 , tap_spacing )
2128
2181
@@ -2140,14 +2193,21 @@ def add_dnwell(self, bbox=None, inflate=1):
2140
2193
to_layer = "m2" ,
2141
2194
offset = loc )
2142
2195
else :
2143
- self .add_power_pin (name = "vdd" ,
2144
- loc = loc ,
2145
- start_layer = "li" )
2196
+ if route_option == "classic" :
2197
+ pin = self .add_power_pin (name = "vdd" ,
2198
+ loc = loc ,
2199
+ start_layer = "li" )
2200
+ elif route_option == "quality" :
2201
+ pin = self .add_power_pin_m2 (name = "vdd" ,
2202
+ loc = loc ,
2203
+ start_layer = "li" )
2204
+ moat_pins .append (pin )
2146
2205
count += 1
2147
2206
loc += nwell_offset .scale (0 , tap_spacing )
2148
2207
2149
- # Add the gnd ring
2208
+ # Add the vdd ring
2150
2209
self .add_ring ([ll , ur ])
2210
+ return moat_pins
2151
2211
2152
2212
def add_ring (self , bbox = None , width_mult = 8 , offset = 0 ):
2153
2213
"""
0 commit comments