mirror of https://github.com/VLSIDA/OpenRAM.git
fixing contact placement for gf180 in rom
This commit is contained in:
parent
b279791762
commit
75f7a5847f
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -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 >>
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue