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.base import vector
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")
A_in = self.inv_inst.get_pin("A")
vdd_rail = self.addr_nand.get_pin("vdd")
# Find the center of the pmos poly/gate
poly_right = clk1_pin.cx() + self.poly_enclose_contact + 0.5 * self.contact_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())
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
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())

View File

@ -88,6 +88,8 @@ class rom_base_array(bitcell_base_array):
else:
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)
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",
cols=self.column_size,
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))
def add_pins(self):
print(self.get_wordline_names())
for bl_name in self.get_bitline_names():
self.add_pin(bl_name, "OUTPUT")
for wl_name in self.get_wordline_names():
@ -215,7 +218,7 @@ class rom_base_array(bitcell_base_array):
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))]
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
min_x = float('inf')
@ -246,7 +249,6 @@ class rom_base_array(bitcell_base_array):
self.cell_pos = {}
self.strap_pos = {}
pitch_offset = 0
for row in range(self.row_size + 1):
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:
output_layer = "m3"
rail_y = self.precharge_inst.get_pins("vdd")[0].cy()
print("cols ", self.bitline_names[0])
for bl in range(self.column_size):
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))]
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.base import vector, design
from openram import OPTS
from openram.tech import drc
from openram.tech import drc, layer
class rom_decoder(design):
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
# bit lines in the base array become the word lines/rows in the decoder
# 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.num_outputs = num_outputs
self.num_inputs = ceil(log(num_outputs, 2))
@ -28,8 +32,6 @@ class rom_decoder(design):
b = factory.create(module_type=OPTS.bitcell)
self.cell_height = b.height
self.route_layer = route_layer
self.output_layer = output_layer
self.inv_route_layer = "m2"
self.fanout=fanout
self.invert_outputs=invert_outputs
self.create_netlist()
@ -203,13 +205,12 @@ class rom_decoder(design):
for j in range(self.num_outputs):
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)]
driver_pins = [self.wordline_buf_inst.get_pin("in_{}".format(bl)) for bl in range(self.num_outputs)]
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):

View File

@ -35,17 +35,19 @@ class rom_poly_tap(design):
def create_layout(self):
self.place_via()
self.add_boundary()
# self.extend_poly()
if self.add_tap or self.place_poly:
self.place_active_tap()
self.add_boundary()
def add_boundary(self):
contact_width = self.poly_contact.width
self.height = self.dummy.height
self.width = contact_width + self.pitch_offset
print("pitch off", self.pitch_offset)
super().add_boundary()
def place_via(self):
@ -60,14 +62,9 @@ class rom_poly_tap(design):
contact_x = contact_width * 0.5 + self.contact_x_offset
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",
to_layer=self.strap_layer,
offset=self.contact_offset,
directions=directions)
offset=self.contact_offset)
self.add_layout_pin_rect_center("poly_tap", self.strap_layer, self.contact_offset)
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
"""
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.strap_layer = strap_layer
self.bitline_layer = bitline_layer
self.tap_direction = tap_direction
self.strap_spacing = strap_spacing
if "li" in layer:
self.supply_layer = "li"
else:
self.supply_layer = "m1"
if strap_spacing != None:
self.strap_spacing = strap_spacing
else:
self.strap_spacing = 0
if strap_spacing != 0:
self.num_straps = ceil(self.cols / self.strap_spacing)
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=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):
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)
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")
self.add_via_stack_center(offset=offset,
from_layer=self.active_stack[2],
to_layer=self.supply_layer)
to_layer=self.supply_layer,
directions="nonpref")
if well_type == "p":
pin = "gnd_tap"
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")
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)
openram.end_openram()

View File

@ -25,9 +25,11 @@ class rom_array_test(openram_test):
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)
a.sp_write(OPTS.openram_temp + 'simulation_file.sp')

View File

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

View File

@ -1,6 +1,6 @@
.subckt gf180mcu_3v3__nand2_1_dec A B Y VDD GND
X0 VDD B Y VDD pfet_03p3 w=1.7u l=0.3u
X1 Y A VDD VDD pfet_03p3 w=1.7u l=0.3u
X2 a_28_21# A Y GND nfet_03p3 w=0.85u l=0.3u
X3 VSS B a_28_21# GND nfet_03p3 w=0.85u l=0.3u
.ends
.subckt gf180mcu_3v3__nand2_1_dec A B Z VDD GND
X0 VDD B Z VDD pfet_03v3 w=1.7u l=0.3u
X1 Z A VDD VDD pfet_03v3 w=1.7u l=0.3u
X2 a_28_21# A Z GND nfet_03v3 w=0.85u l=0.3u
X3 GND B a_28_21# GND nfet_03v3 w=0.85u l=0.3u
.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_map = {'A': 'A',
'B': 'B',
'Z': 'Y',
'Z': 'Z',
'vdd': 'VDD',
'gnd': 'GND'}
@ -96,6 +96,8 @@ active_stack = ("active", "contact", "m1")
m1_stack = ("m1", "via1", "m2")
m2_stack = ("m2", "via2", "m3")
m3_stack = ("m3", "via3", "m4")
m4_stack = ("m4", "via4", "m5")
layer_indices = {"poly": 0,
"active": 0,
@ -104,7 +106,8 @@ layer_indices = {"poly": 0,
"m1": 1,
"m2": 2,
"m3": 3,
"m4": 4}
"m4": 4,
"m5": 5}
# The FEOL stacks get us up to m1
feol_stacks = [poly_stack,
@ -113,22 +116,24 @@ feol_stacks = [poly_stack,
# The BEOL stacks are m1 and up
beol_stacks = [m1_stack,
m2_stack,
m3_stack]
m3_stack,
m4_stack]
layer_stacks = feol_stacks + beol_stacks
preferred_directions = {"poly": "V",
"active": "V",
"m1": "H",
"m2": "V",
"m3": "H",
"m4": "V"}
"m1": "V",
"m2": "H",
"m3": "V",
"m4": "H",
"m5": "V"}
###################################################
# Power grid
###################################################
# Use M3/M4
power_grid = m3_stack
power_grid = m4_stack
###################################################
##GDS Layer Map
@ -201,8 +206,8 @@ drc = d.design_rules("gf180")
drc["grid"] = 0.005
# minwidth_tx with contact (no dog bone transistors)
drc["minwidth_tx"] = 0.5
# PL.2 Min gate width/channel length for 6V pmos (0.7 for 6V nmos)
drc["minwidth_tx"] = 0.57
# PL.2 Min gate width/channel length for 3V3 pmos
drc["minlength_channel"] = 0.28
drc["minlength_channel_pmos"] = 0.55
@ -305,7 +310,7 @@ drc.add_enclosure("m1",
drc.add_enclosure("m1",
layer="via1",
enclosure=0,
extension=0.205)
extension=0.15)
drc.add_layer("via1",
width=0.26,
@ -362,6 +367,23 @@ drc.add_enclosure("m4",
layer="via4",
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",
width=0.26,