fixing contact placement for gf180 in rom

This commit is contained in:
SWalker 2023-09-13 11:41:15 -07:00
parent b279791762
commit 75f7a5847f
12 changed files with 232 additions and 192 deletions

View File

@ -10,6 +10,8 @@ from openram.base import design
from openram.sram_factory import factory from openram.sram_factory import factory
from openram.base import vector from openram.base import vector
from openram.tech import layer, drc from openram.tech import layer, drc
from openram import OPTS
@ -111,16 +113,25 @@ class rom_address_control_buf(design):
Aint_in = self.addr_bar_nand.get_pin("B") Aint_in = self.addr_bar_nand.get_pin("B")
A_in = self.inv_inst.get_pin("A") A_in = self.inv_inst.get_pin("A")
vdd_rail = self.addr_nand.get_pin("vdd")
# Find the center of the pmos poly/gate # Find the center of the pmos poly/gate
poly_right = clk1_pin.cx() + self.poly_enclose_contact + 0.5 * self.contact_width poly_right = clk1_pin.cx() + self.poly_enclose_contact + 0.5 * self.contact_width
ppoly_center = poly_right - 0.7 * self.poly_width ppoly_center = poly_right - 0.7 * self.poly_width
poly_y = A_out.cy()
if OPTS.tech_name == "gf180mcu":
poly_y = vdd_rail.cy() + 0.5 * drc("minwidth_tx") * 3 + self.poly_extend_active
ppoly_center = A_out.cx() + 0.5 * self.interconnect_width + 0.5 * self.poly_width
else:
ppoly_center = poly_right - 0.7 * self.poly_width
poly_y = A_out.cy()
contact_offset = vector(ppoly_center, clk2_pin.cy()) contact_offset = vector(ppoly_center, clk2_pin.cy())
self.add_layout_pin_rect_center("cont", offset=contact_offset, layer="poly")
self.add_layout_pin_rect_center("ppoly", offset=vector(ppoly_center, poly_y), layer="poly")
# Route the two shared clk inputs together by connecting poly # Route the two shared clk inputs together by connecting poly
self.add_segment_center("poly", contact_offset, vector(ppoly_center, A_out.cy())) self.add_segment_center("poly", contact_offset, vector(ppoly_center, poly_y))
clk_offset = vector(clk2_pin.cx(), self.addr_nand.uy()) clk_offset = vector(clk2_pin.cx(), self.addr_nand.uy())

View File

@ -88,6 +88,8 @@ class rom_base_array(bitcell_base_array):
else: else:
self.poly_tap = factory.create(module_type="rom_poly_tap", add_active_tap=True) self.poly_tap = factory.create(module_type="rom_poly_tap", add_active_tap=True)
self.end_poly_tap = factory.create(module_type="rom_poly_tap", place_poly=True) self.end_poly_tap = factory.create(module_type="rom_poly_tap", place_poly=True)
print("poly tap width", self.poly_tap.width, "height", self.poly_tap.height, self.tap_direction)
self.precharge_array = factory.create(module_type="rom_precharge_array", self.precharge_array = factory.create(module_type="rom_precharge_array",
cols=self.column_size, cols=self.column_size,
strap_spacing=self.strap_spacing, strap_spacing=self.strap_spacing,
@ -100,6 +102,7 @@ class rom_base_array(bitcell_base_array):
self.route_pitch = drc("{0}_to_{0}".format(self.bitline_layer)) self.route_pitch = drc("{0}_to_{0}".format(self.bitline_layer))
def add_pins(self): def add_pins(self):
print(self.get_wordline_names())
for bl_name in self.get_bitline_names(): for bl_name in self.get_bitline_names():
self.add_pin(bl_name, "OUTPUT") self.add_pin(bl_name, "OUTPUT")
for wl_name in self.get_wordline_names(): for wl_name in self.get_wordline_names():
@ -215,7 +218,7 @@ class rom_base_array(bitcell_base_array):
self.remove_layout_pin("gnd") self.remove_layout_pin("gnd")
active_tap_pins = [self.active_tap_list[i].get_pin("active_tap") for i in range(len(self.active_tap_list))] active_tap_pins = [self.active_tap_list[i].get_pin("active_tap") for i in range(len(self.active_tap_list))]
self.connect_col_pins(layer=self.supply_stack[0], pins=active_tap_pins, name="gnd_tmp") self.connect_col_pins(layer=self.supply_stack[0], pins=active_tap_pins, name="gnd_tmp", directions="nonpref")
gnd_y = gnd_l.y gnd_y = gnd_l.y
min_x = float('inf') min_x = float('inf')
@ -246,7 +249,6 @@ class rom_base_array(bitcell_base_array):
self.cell_pos = {} self.cell_pos = {}
self.strap_pos = {} self.strap_pos = {}
pitch_offset = 0 pitch_offset = 0
for row in range(self.row_size + 1): for row in range(self.row_size + 1):
if row % self.tap_spacing == 0 and self.pitch_match and row != self.row_size: if row % self.tap_spacing == 0 and self.pitch_match and row != self.row_size:
@ -331,7 +333,7 @@ class rom_base_array(bitcell_base_array):
else: else:
output_layer = "m3" output_layer = "m3"
rail_y = self.precharge_inst.get_pins("vdd")[0].cy() rail_y = self.precharge_inst.get_pins("vdd")[0].cy()
print("cols ", self.bitline_names[0])
for bl in range(self.column_size): for bl in range(self.column_size):
src_pin = self.cell_list[0][bl].get_pin("S") src_pin = self.cell_list[0][bl].get_pin("S")
@ -382,3 +384,5 @@ class rom_base_array(bitcell_base_array):
poly_tap_pins = [self.poly_tap_list[i].get_pin("poly_tap") for i in range(len(self.poly_tap_list))] poly_tap_pins = [self.poly_tap_list[i].get_pin("poly_tap") for i in range(len(self.poly_tap_list))]
self.connect_row_pins(layer=self.wordline_layer, pins=poly_tap_pins) self.connect_row_pins(layer=self.wordline_layer, pins=poly_tap_pins)
self.connect_row_pins(layer="poly", pins=poly_tap_pins)

View File

@ -9,15 +9,19 @@ from math import ceil, log
from openram.sram_factory import factory from openram.sram_factory import factory
from openram.base import vector, design from openram.base import vector, design
from openram import OPTS from openram import OPTS
from openram.tech import drc from openram.tech import drc, layer
class rom_decoder(design): class rom_decoder(design):
def __init__(self, num_outputs, fanout, strap_spacing, name="", route_layer="m1", output_layer="m1", invert_outputs=False): def __init__(self, num_outputs, fanout, strap_spacing, name="", route_layer="m1", output_layer="m1", invert_outputs=False):
# word lines in the base array become the address lines/cols in the decoder # word lines in the base array become the address lines/cols in the decoder
# bit lines in the base array become the word lines/rows in the decoder # bit lines in the base array become the word lines/rows in the decoder
# array gets rotated 90deg so rows/cols switch # array gets rotated 90deg so rows/cols switch
if "li" in layer:
self.output_layer = "m1"
self.inv_route_layer = "m2"
else:
self.output_layer = "m1"
self.inv_route_layer = "m3"
self.strap_spacing=strap_spacing self.strap_spacing=strap_spacing
self.num_outputs = num_outputs self.num_outputs = num_outputs
self.num_inputs = ceil(log(num_outputs, 2)) self.num_inputs = ceil(log(num_outputs, 2))
@ -28,8 +32,6 @@ class rom_decoder(design):
b = factory.create(module_type=OPTS.bitcell) b = factory.create(module_type=OPTS.bitcell)
self.cell_height = b.height self.cell_height = b.height
self.route_layer = route_layer self.route_layer = route_layer
self.output_layer = output_layer
self.inv_route_layer = "m2"
self.fanout=fanout self.fanout=fanout
self.invert_outputs=invert_outputs self.invert_outputs=invert_outputs
self.create_netlist() self.create_netlist()
@ -203,13 +205,12 @@ class rom_decoder(design):
for j in range(self.num_outputs): for j in range(self.num_outputs):
self.copy_layout_pin(self.wordline_buf_inst, "out_{}".format(j), "wl_{}".format(j)) self.copy_layout_pin(self.wordline_buf_inst, "out_{}".format(j), "wl_{}".format(j))
offset = self.wordline_buf_inst.get_pin("out_{}".format(j)).center()
array_pins = [self.array_inst.get_pin("bl_0_{}".format(bl)) for bl in range(self.num_outputs)] array_pins = [self.array_inst.get_pin("bl_0_{}".format(bl)) for bl in range(self.num_outputs)]
driver_pins = [self.wordline_buf_inst.get_pin("in_{}".format(bl)) for bl in range(self.num_outputs)] driver_pins = [self.wordline_buf_inst.get_pin("in_{}".format(bl)) for bl in range(self.num_outputs)]
route_pins = array_pins + driver_pins route_pins = array_pins + driver_pins
self.connect_row_pins(self.output_layer, route_pins, round=True) self.connect_row_pins(self.inv_route_layer, route_pins, round=True)
def connect_inputs(self): def connect_inputs(self):

View File

@ -35,17 +35,19 @@ class rom_poly_tap(design):
def create_layout(self): def create_layout(self):
self.place_via() self.place_via()
self.add_boundary()
# self.extend_poly() # self.extend_poly()
if self.add_tap or self.place_poly: if self.add_tap or self.place_poly:
self.place_active_tap() self.place_active_tap()
self.add_boundary()
def add_boundary(self): def add_boundary(self):
contact_width = self.poly_contact.width contact_width = self.poly_contact.width
self.height = self.dummy.height self.height = self.dummy.height
self.width = contact_width + self.pitch_offset self.width = contact_width + self.pitch_offset
print("pitch off", self.pitch_offset)
super().add_boundary() super().add_boundary()
def place_via(self): def place_via(self):
@ -60,14 +62,9 @@ class rom_poly_tap(design):
contact_x = contact_width * 0.5 + self.contact_x_offset contact_x = contact_width * 0.5 + self.contact_x_offset
self.contact_offset = vector(contact_x, contact_y) self.contact_offset = vector(contact_x, contact_y)
if OPTS.tech_name == "sky130":
directions="pref"
else:
directions="nonpref"
self.via = self.add_via_stack_center(from_layer="poly", self.via = self.add_via_stack_center(from_layer="poly",
to_layer=self.strap_layer, to_layer=self.strap_layer,
offset=self.contact_offset, offset=self.contact_offset)
directions=directions)
self.add_layout_pin_rect_center("poly_tap", self.strap_layer, self.contact_offset) self.add_layout_pin_rect_center("poly_tap", self.strap_layer, self.contact_offset)
def extend_poly(self): def extend_poly(self):

View File

@ -17,24 +17,17 @@ class rom_precharge_array(design):
""" """
An array of inverters to create the inverted address lines for the rom decoder An array of inverters to create the inverted address lines for the rom decoder
""" """
def __init__(self, cols, name="", bitline_layer="m2", strap_spacing=None, strap_layer="m3", tap_direction="row"): def __init__(self, cols, name="", bitline_layer="m2", strap_spacing=0, strap_layer="m3", tap_direction="row"):
self.cols = cols self.cols = cols
self.strap_layer = strap_layer self.strap_layer = strap_layer
self.bitline_layer = bitline_layer self.bitline_layer = bitline_layer
self.tap_direction = tap_direction self.tap_direction = tap_direction
self.strap_spacing = strap_spacing
if "li" in layer: if "li" in layer:
self.supply_layer = "li" self.supply_layer = "li"
else: else:
self.supply_layer = "m1" self.supply_layer = "m1"
if strap_spacing != None:
self.strap_spacing = strap_spacing
else:
self.strap_spacing = 0
if strap_spacing != 0: if strap_spacing != 0:
self.num_straps = ceil(self.cols / self.strap_spacing) self.num_straps = ceil(self.cols / self.strap_spacing)
self.array_col_size = self.cols + self.num_straps self.array_col_size = self.cols + self.num_straps
@ -158,11 +151,17 @@ class rom_precharge_array(design):
self.add_segment_center(layer="poly", start=offset_start, end=offset_end) self.add_segment_center(layer="poly", start=offset_start, end=offset_end)
self.add_segment_center(layer="poly", start=self.pmos_insts[-1].get_pin("G").center(), end=offset_end) self.add_segment_center(layer="poly", start=self.pmos_insts[-1].get_pin("G").center(), end=offset_end)
gate_y = self.pmos_insts[0].get_pin('G').cy()
start = vector( self.get_pin("gate").lx(), gate_y)
end = vector( self.get_pin("precharge_r").rx(), gate_y )
self.add_segment_center(layer="poly", start=start, end=end)
def extend_well(self): def extend_well(self):
self.well_offset = self.pmos.tap_offset self.well_offset = self.pmos.tap_offset
well_y = self.pmos_insts[0].get_pin("vdd").cy() - 0.5 * self.nwell_width
well_y = self.get_pin("vdd").cy() - 0.5 * self.nwell_width well_y = self.get_pin("vdd").by() - self.nwell_enclose_active
well_ll = vector(0, well_y) well_ll = vector(0, well_y)
self.add_rect("nwell", well_ll, self.width , self.height - well_y) self.add_rect("nwell", well_ll, self.width , self.height - well_y)

View File

@ -214,7 +214,8 @@ class rom_wordline_driver_array(design):
directions="nonpref") directions="nonpref")
self.add_via_stack_center(offset=offset, self.add_via_stack_center(offset=offset,
from_layer=self.active_stack[2], from_layer=self.active_stack[2],
to_layer=self.supply_layer) to_layer=self.supply_layer,
directions="nonpref")
if well_type == "p": if well_type == "p":
pin = "gnd_tap" pin = "gnd_tap"
self.gnd_taps.append(self.add_layout_pin_rect_center(text=pin, layer=self.supply_layer, offset=offset)) self.gnd_taps.append(self.add_layout_pin_rect_center(text=pin, layer=self.supply_layer, offset=offset))

View File

@ -26,7 +26,7 @@ class precharge_test(openram_test):
debug.info(2, "Testing rom precharge bitcell") debug.info(2, "Testing rom precharge bitcell")
tx = factory.create(module_type="rom_precharge_cell", module_name="precharge_cell", bitline_layer="m2", supply_layer="m1") tx = factory.create(module_type="rom_precharge_array", module_name="rom_precharge_array", cols=8, strap_spacing=2, tap_direction="col")
self.local_check(tx) self.local_check(tx)
openram.end_openram() openram.end_openram()

View File

@ -25,9 +25,11 @@ class rom_array_test(openram_test):
debug.info(2, "Testing 4x4 array for rom cell") debug.info(2, "Testing 4x4 array for rom cell")
data = [[1, 0, 0, 1, 0, 0, 1, 1, 0], [0, 1, 0, 0, 1, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 1], [0, 1, 0, 0, 1, 1, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0], [1, 0, 0, 1, 0, 0, 0, 1, 0]] # data = [[1, 0, 0, 1, 0, 0, 1, 1, 0], [0, 1, 0, 0, 1, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 1], [0, 1, 0, 0, 1, 1, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0], [1, 0, 0, 1, 0, 0, 0, 1, 0]]
a = factory.create(module_type="rom_base_array", cols=9, rows=8, bitmap=data, strap_spacing=4, pitch_match=True)
data = [[1, 0, 0], [1, 1, 1], [0,1, 0]]
a = factory.create(module_type="rom_base_array", cols=3, rows=3, bitmap=data, strap_spacing=1, pitch_match=True)
self.local_check(a) self.local_check(a)
a.sp_write(OPTS.openram_temp + 'simulation_file.sp') a.sp_write(OPTS.openram_temp + 'simulation_file.sp')

View File

@ -1,162 +1,165 @@
magic magic
tech gf180mcuD tech gf180mcuD
magscale 1 10 magscale 1 10
timestamp 1694492972 timestamp 1694553776
<< nwell >> << nwell >>
rect 675 -40 1355 640 rect 675 -30 1355 650
<< nmos >> << nmos >>
rect 211 300 381 360 rect 211 310 381 370
rect 211 190 381 250 rect 211 200 381 260
<< pmos >> << pmos >>
rect 765 330 1106 390 rect 765 340 1106 400
rect 765 160 1106 220 rect 765 170 1106 230
<< ndiff >> << ndiff >>
rect 211 438 381 460 rect 211 448 381 470
rect 211 392 273 438 rect 211 402 273 448
rect 319 392 381 438 rect 319 402 381 448
rect 211 360 381 392 rect 211 370 381 402
rect 211 250 381 300 rect 211 260 381 310
rect 211 158 381 190 rect 211 168 381 200
rect 211 112 273 158 rect 211 122 273 168
rect 319 112 381 158 rect 319 122 381 168
rect 211 90 381 112 rect 211 100 381 122
<< pdiff >> << pdiff >>
rect 765 468 1106 490 rect 765 478 1106 500
rect 765 422 818 468 rect 765 432 818 478
rect 1052 422 1106 468 rect 1052 432 1106 478
rect 765 390 1106 422 rect 765 400 1106 432
rect 765 298 1106 330 rect 765 308 1106 340
rect 765 252 818 298 rect 765 262 818 308
rect 1052 252 1106 298 rect 1052 262 1106 308
rect 765 220 1106 252 rect 765 230 1106 262
rect 765 128 1106 160 rect 765 138 1106 170
rect 765 82 818 128 rect 765 92 818 138
rect 1052 82 1106 128 rect 1052 92 1106 138
rect 765 60 1106 82 rect 765 70 1106 92
<< ndiffc >> << ndiffc >>
rect 273 392 319 438 rect 273 402 319 448
rect 273 112 319 158 rect 273 122 319 168
<< pdiffc >> << pdiffc >>
rect 818 422 1052 468 rect 818 432 1052 478
rect 818 252 1052 298 rect 818 262 1052 308
rect 818 82 1052 128 rect 818 92 1052 138
<< psubdiff >> << psubdiff >>
rect 74 23 181 40 rect 74 33 181 50
rect 74 -23 114 23 rect 74 -13 114 33
rect 160 -23 181 23 rect 160 -13 181 33
rect 74 -40 181 -23 rect 74 -30 181 -13
<< nsubdiff >> << nsubdiff >>
rect 1172 107 1252 144 rect 1172 117 1252 154
rect 1172 61 1189 107 rect 1172 71 1189 117
rect 1235 61 1252 107 rect 1235 71 1252 117
rect 1172 37 1252 61 rect 1172 47 1252 71
<< psubdiffcont >> << psubdiffcont >>
rect 114 -23 160 23 rect 114 -13 160 33
<< nsubdiffcont >> << nsubdiffcont >>
rect 1189 61 1235 107 rect 1189 71 1235 117
<< polysilicon >> << polysilicon >>
rect 88 373 171 400 rect 88 383 171 410
rect 88 327 104 373 rect 88 337 104 383
rect 150 360 171 373 rect 150 370 171 383
rect 431 360 765 390 rect 431 370 765 400
rect 150 327 211 360 rect 150 337 211 370
rect 88 300 211 327 rect 88 310 211 337
rect 381 330 765 360 rect 381 340 765 370
rect 1106 330 1156 390 rect 1106 340 1156 400
rect 381 300 471 330 rect 381 310 471 340
rect 88 234 211 250 rect 88 244 211 260
rect 88 188 104 234 rect 88 198 104 244
rect 150 190 211 234 rect 150 200 211 244
rect 381 220 471 250 rect 381 230 471 260
rect 381 190 765 220 rect 381 200 765 230
rect 150 188 171 190 rect 150 198 171 200
rect 88 150 171 188 rect 88 160 171 198
rect 431 160 765 190 rect 431 170 765 200
rect 1106 160 1156 220 rect 1106 170 1156 230
<< polycontact >> << polycontact >>
rect 104 327 150 373 rect 104 337 150 383
rect 104 188 150 234 rect 104 198 150 244
<< metal1 >> << metal1 >>
rect 211 438 451 440 rect 260 448 630 450
rect 101 373 153 425 rect 101 383 153 435
rect 211 392 273 438 rect 260 402 273 448
rect 319 392 451 438 rect 319 402 630 448
rect 807 422 818 468 rect 807 432 818 478
rect 1052 422 1064 468 rect 1052 432 1064 478
rect 903 416 915 422 rect 903 426 915 432
rect 967 416 979 422 rect 967 426 979 432
rect 211 390 451 392 rect 260 400 630 402
rect 101 327 104 373 rect 101 337 104 383
rect 150 327 153 373 rect 150 337 153 383
rect 101 313 153 327 rect 101 323 153 337
rect 401 300 451 390 rect 580 310 630 400
rect 1130 300 1182 463 rect 580 308 1182 310
rect 401 298 1182 300 rect 580 262 818 308
rect 401 252 818 298 rect 1052 262 1182 308
rect 1052 252 1182 298 rect 580 260 1182 262
rect 401 250 1182 252 rect 101 244 153 258
rect 101 234 153 248 rect 101 198 104 244
rect 101 188 104 234 rect 150 198 153 244
rect 150 188 153 234 rect 101 139 153 198
rect 101 129 153 188 rect 241 116 273 168
rect 241 106 273 158 rect 325 116 348 168
rect 325 106 348 158 rect 903 138 915 144
rect 903 128 915 134 rect 967 138 979 144
rect 967 128 979 134 rect 241 110 348 116
rect 241 100 348 106 rect 807 92 818 138
rect 807 82 818 128 rect 1052 92 1064 138
rect 1052 82 1064 128 rect 1139 68 1186 120
rect 1139 58 1186 110 rect 1238 68 1250 120
rect 1238 58 1250 110 rect 80 36 179 46
rect 80 26 179 36 rect 80 -16 111 36
rect 80 -26 111 26 rect 163 -16 179 36
rect 163 -26 179 26 rect 80 -24 179 -16
rect 80 -34 179 -26
<< via1 >> << via1 >>
rect 915 422 967 468 rect 915 432 967 478
rect 915 416 967 422 rect 915 426 967 432
rect 273 112 319 158 rect 273 122 319 168
rect 319 112 325 158 rect 319 122 325 168
rect 273 106 325 112 rect 273 116 325 122
rect 915 128 967 134 rect 915 138 967 144
rect 915 82 967 128 rect 915 92 967 138
rect 1186 107 1238 110 rect 1186 117 1238 120
rect 1186 61 1189 107 rect 1186 71 1189 117
rect 1189 61 1235 107 rect 1189 71 1235 117
rect 1235 61 1238 107 rect 1235 71 1238 117
rect 1186 58 1238 61 rect 1186 68 1238 71
rect 111 23 163 26 rect 111 33 163 36
rect 111 -23 114 23 rect 111 -13 114 33
rect 114 -23 160 23 rect 114 -13 160 33
rect 160 -23 163 23 rect 160 -13 163 33
rect 111 -26 163 -23 rect 111 -16 163 -13
<< metal2 >> << metal2 >>
rect 271 158 327 520 rect 271 168 327 530
rect 271 106 273 158 rect 271 116 273 168
rect 325 106 327 158 rect 325 116 327 168
rect 271 28 327 106 rect 271 38 327 116
rect 89 26 327 28 rect 89 36 327 38
rect 89 -26 111 26 rect 89 -16 111 36
rect 163 -26 327 26 rect 163 -16 327 36
rect 913 468 969 520 rect 913 478 969 530
rect 913 416 915 468 rect 913 426 915 478
rect 967 416 969 468 rect 967 426 969 478
rect 913 134 969 416 rect 913 144 969 426
rect 913 82 915 134 rect 913 92 915 144
rect 967 112 969 134 rect 967 122 969 144
rect 967 110 1250 112 rect 967 120 1250 122
rect 967 82 1186 110 rect 967 92 1186 120
rect 913 58 1186 82 rect 913 68 1186 92
rect 1238 58 1250 110 rect 1238 68 1250 120
rect 913 56 1250 58 rect 913 66 1250 68
rect 913 8 969 56 rect 913 18 969 66
rect 89 -28 327 -26 rect 89 -18 327 -16
<< labels >> << labels >>
rlabel metal1 s 1156 439 1156 439 4 Y rlabel metal2 s 271 38 327 530 4 GND
rlabel metal1 s 127 211 127 211 4 B port 1 nsew
rlabel metal1 s 127 350 127 350 4 A rlabel metal2 s 941 43 941 43 4 VDD
rlabel metal2 s 941 33 941 33 4 VDD flabel metal1 s 605 425 605 425 2 FreeSans 368 0 0 0 Z
rlabel metal2 s 300 56 300 56 4 GND port 2 nsew
flabel metal1 s 127 360 127 360 2 FreeSans 368 0 0 0 A
port 3 nsew
flabel metal1 s 127 221 127 221 2 FreeSans 368 0 0 0 B
port 4 nsew
<< properties >> << properties >>
string FIXED_BBOX -17 0 1373 522 string FIXED_BBOX -17 0 1373 542
<< end >> << end >>

View File

@ -1,6 +1,6 @@
.subckt gf180mcu_3v3__nand2_1_dec A B Y VDD GND .subckt gf180mcu_3v3__nand2_1_dec A B Z VDD GND
X0 VDD B Y VDD pfet_03p3 w=1.7u l=0.3u X0 VDD B Z VDD pfet_03v3 w=1.7u l=0.3u
X1 Y A VDD VDD pfet_03p3 w=1.7u l=0.3u X1 Z A VDD VDD pfet_03v3 w=1.7u l=0.3u
X2 a_28_21# A Y GND nfet_03p3 w=0.85u l=0.3u X2 a_28_21# A Z GND nfet_03v3 w=0.85u l=0.3u
X3 VSS B a_28_21# GND nfet_03p3 w=0.85u l=0.3u X3 GND B a_28_21# GND nfet_03v3 w=0.85u l=0.3u
.ends .ends

View File

@ -52,7 +52,7 @@ cell_properties.bitcell_1port.gnd_layer = "m1"
cell_properties.nand2_dec.port_order = ['A', 'B', 'Z', 'vdd', 'gnd'] cell_properties.nand2_dec.port_order = ['A', 'B', 'Z', 'vdd', 'gnd']
cell_properties.nand2_dec.port_map = {'A': 'A', cell_properties.nand2_dec.port_map = {'A': 'A',
'B': 'B', 'B': 'B',
'Z': 'Y', 'Z': 'Z',
'vdd': 'VDD', 'vdd': 'VDD',
'gnd': 'GND'} 'gnd': 'GND'}
@ -96,6 +96,8 @@ active_stack = ("active", "contact", "m1")
m1_stack = ("m1", "via1", "m2") m1_stack = ("m1", "via1", "m2")
m2_stack = ("m2", "via2", "m3") m2_stack = ("m2", "via2", "m3")
m3_stack = ("m3", "via3", "m4") m3_stack = ("m3", "via3", "m4")
m4_stack = ("m4", "via4", "m5")
layer_indices = {"poly": 0, layer_indices = {"poly": 0,
"active": 0, "active": 0,
@ -104,7 +106,8 @@ layer_indices = {"poly": 0,
"m1": 1, "m1": 1,
"m2": 2, "m2": 2,
"m3": 3, "m3": 3,
"m4": 4} "m4": 4,
"m5": 5}
# The FEOL stacks get us up to m1 # The FEOL stacks get us up to m1
feol_stacks = [poly_stack, feol_stacks = [poly_stack,
@ -113,22 +116,24 @@ feol_stacks = [poly_stack,
# The BEOL stacks are m1 and up # The BEOL stacks are m1 and up
beol_stacks = [m1_stack, beol_stacks = [m1_stack,
m2_stack, m2_stack,
m3_stack] m3_stack,
m4_stack]
layer_stacks = feol_stacks + beol_stacks layer_stacks = feol_stacks + beol_stacks
preferred_directions = {"poly": "V", preferred_directions = {"poly": "V",
"active": "V", "active": "V",
"m1": "H", "m1": "V",
"m2": "V", "m2": "H",
"m3": "H", "m3": "V",
"m4": "V"} "m4": "H",
"m5": "V"}
################################################### ###################################################
# Power grid # Power grid
################################################### ###################################################
# Use M3/M4 # Use M3/M4
power_grid = m3_stack power_grid = m4_stack
################################################### ###################################################
##GDS Layer Map ##GDS Layer Map
@ -201,8 +206,8 @@ drc = d.design_rules("gf180")
drc["grid"] = 0.005 drc["grid"] = 0.005
# minwidth_tx with contact (no dog bone transistors) # minwidth_tx with contact (no dog bone transistors)
drc["minwidth_tx"] = 0.5 drc["minwidth_tx"] = 0.57
# PL.2 Min gate width/channel length for 6V pmos (0.7 for 6V nmos) # PL.2 Min gate width/channel length for 3V3 pmos
drc["minlength_channel"] = 0.28 drc["minlength_channel"] = 0.28
drc["minlength_channel_pmos"] = 0.55 drc["minlength_channel_pmos"] = 0.55
@ -305,7 +310,7 @@ drc.add_enclosure("m1",
drc.add_enclosure("m1", drc.add_enclosure("m1",
layer="via1", layer="via1",
enclosure=0, enclosure=0,
extension=0.205) extension=0.15)
drc.add_layer("via1", drc.add_layer("via1",
width=0.26, width=0.26,
@ -362,6 +367,23 @@ drc.add_enclosure("m4",
layer="via4", layer="via4",
enclosure=0.06) enclosure=0.06)
drc.add_layer("via4",
width=0.26,
spacing=0.26)
# Magic wants 0.36um width but PDK says 0.28
drc.add_layer("m5",
width=0.36,
spacing=0.28,
area=0.1444)
drc.add_enclosure("m5",
layer="via4",
enclosure=0.06)
drc.add_enclosure("m5",
layer="via5",
enclosure=0.06)
drc.add_layer("via5", drc.add_layer("via5",
width=0.26, width=0.26,