Add option to remove wells. Save area in pgates with redundant wells.

This commit is contained in:
mrg 2020-05-13 14:46:42 -07:00
parent 848241a3ad
commit 617bf302d1
17 changed files with 35 additions and 31 deletions

View File

@ -15,14 +15,14 @@ class pand2(pgate.pgate):
"""
This is a simple buffer used for driving loads.
"""
def __init__(self, name, size=1, height=None, vertical=False):
def __init__(self, name, size=1, height=None, vertical=False, add_wells=True):
debug.info(1, "Creating pand2 {}".format(name))
self.add_comment("size: {}".format(size))
self.vertical = vertical
self.size = size
pgate.pgate.__init__(self, name)
pgate.pgate.__init__(self, name, height, add_wells)
def create_netlist(self):
self.add_pins()
@ -31,12 +31,15 @@ class pand2(pgate.pgate):
def create_modules(self):
self.nand = factory.create(module_type="pnand2",
height=self.height)
self.add_mod(self.nand)
height=self.height,
add_wells=False)
self.inv = factory.create(module_type="pdriver",
size_list=[self.size],
height=self.height)
height=self.height,
add_wells=self.add_wells)
self.add_mod(self.nand)
self.add_mod(self.inv)
def create_layout(self):

View File

@ -15,7 +15,7 @@ class pand3(pgate.pgate):
"""
This is a simple buffer used for driving loads.
"""
def __init__(self, name, size=1, height=None, vertical=False):
def __init__(self, name, size=1, height=None, vertical=False, add_wells=True):
debug.info(1, "Creating pand3 {}".format(name))
self.add_comment("size: {}".format(size))
@ -23,7 +23,7 @@ class pand3(pgate.pgate):
self.size = size
# Creates the netlist and layout
pgate.pgate.__init__(self, name, height)
pgate.pgate.__init__(self, name, height, add_wells)
def create_netlist(self):
self.add_pins()
@ -33,12 +33,17 @@ class pand3(pgate.pgate):
def create_modules(self):
# Shield the cap, but have at least a stage effort of 4
self.nand = factory.create(module_type="pnand3",
height=self.height)
self.add_mod(self.nand)
height=self.height,
add_wells=False)
# Add the well tap to the inverter because when stacked
# vertically it is sometimes narrower
self.inv = factory.create(module_type="pdriver",
size_list=[self.size],
height=self.height)
height=self.height,
add_wells=self.add_wells)
self.add_mod(self.nand)
self.add_mod(self.inv)
def create_layout(self):

View File

@ -17,7 +17,7 @@ class pdriver(pgate.pgate):
sized for driving a load.
"""
def __init__(self, name, neg_polarity=False, fanout=0, size_list=None, height=None):
def __init__(self, name, neg_polarity=False, fanout=0, size_list=None, height=None, add_wells=True):
debug.info(1, "creating pdriver {}".format(name))
@ -35,7 +35,7 @@ class pdriver(pgate.pgate):
debug.error("Cannot specify both size_list and neg_polarity.", -1)
# Creates the netlist and layout
pgate.pgate.__init__(self, name, height)
pgate.pgate.__init__(self, name, height, add_wells)
def compute_sizes(self):
# size_list specified
@ -73,9 +73,9 @@ class pdriver(pgate.pgate):
self.place_modules()
self.route_wires()
self.add_layout_pins()
self.width = self.inv_inst_list[-1].rx()
self.height = self.inv_inst_list[0].height
self.extend_wells()
self.route_supply_rails()
self.add_boundary()
@ -87,7 +87,7 @@ class pdriver(pgate.pgate):
def add_modules(self):
self.inv_list = []
add_well = True
add_well = self.add_wells
for size in self.size_list:
temp_inv = factory.create(module_type="pinv",
size=size,

View File

@ -162,12 +162,12 @@ class pgate(design.design):
nwell_height = nwell_max_offset - self.nwell_y_offset
self.add_rect(layer="nwell",
offset=nwell_position,
width=self.well_width,
width=self.width + 2 * self.well_extend_active,
height=nwell_height)
if "vtg" in layer:
self.add_rect(layer="vtg",
offset=nwell_position,
width=self.well_width,
width=self.width + 2 * self.well_extend_active,
height=nwell_height)
# Start this half a rail width below the cell
@ -178,12 +178,12 @@ class pgate(design.design):
pwell_height = self.nwell_y_offset - pwell_position.y
self.add_rect(layer="pwell",
offset=pwell_position,
width=self.well_width,
width=self.width + 2 * self.well_extend_active,
height=pwell_height)
if "vtg" in layer:
self.add_rect(layer="vtg",
offset=pwell_position,
width=self.well_width,
width=self.width + 2 * self.well_extend_active,
height=pwell_height)
def add_nwell_contact(self, pmos, pmos_pos):
@ -304,16 +304,17 @@ class pgate(design.design):
def determine_width(self):
""" Determine the width based on the well contacts (assumed to be on the right side) """
# It was already set or is left as default (minimum)
# Width is determined by well contact and spacing and allowing a supply via between each cell
if self.add_wells:
self.width = max(self.nwell_contact.rx(), self.pwell_contact.rx()) + self.m1_space + 0.5 * contact.m1_via.width
width = max(self.nwell_contact.rx(), self.pwell_contact.rx()) + self.m1_space + 0.5 * contact.m1_via.width
# Height is an input parameter, so it is not recomputed.
else:
max_active_xoffset = self.find_highest_layer_coords("active").x
max_route_xoffset = self.find_highest_layer_coords(self.route_layer).x + 0.5 * self.m1_space
self.width = max(max_active_xoffset, max_route_xoffset)
self.well_width = self.width + 2 * self.nwell_enclose_active
width = max(max_active_xoffset, max_route_xoffset)
self.width = width
@staticmethod
def bin_width(tx_type, target_width):

View File

@ -60,14 +60,14 @@ class pinv(pgate.pgate):
self.add_well_contacts()
self.determine_width()
self.extend_wells()
self.route_supply_rails()
self.connect_rails()
self.route_input_gate(self.pmos_inst,
self.nmos_inst,
self.output_pos.y,
"A",
position="farleft")
self.route_outputs()
self.route_supply_rails()
self.connect_rails()
self.add_boundary()
def add_pins(self):

View File

@ -5,7 +5,6 @@
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import contact
import pgate
import debug
from tech import drc, parameter, spice

View File

@ -50,7 +50,7 @@ class single_level_column_mux(pgate.pgate):
self.connect_poly()
self.add_bitline_pins()
self.connect_bitlines()
self.add_wells()
self.add_pn_wells()
def add_modules(self):
self.bitcell = factory.create(module_type="bitcell")
@ -218,7 +218,7 @@ class single_level_column_mux(pgate.pgate):
self.add_path(self.col_mux_stack[2],
[br_pin.bc(), mid1, mid2, nmos_lower_d_pin.center()])
def add_wells(self):
def add_pn_wells(self):
"""
Add a well and implant over the whole cell. Also, add the
pwell contact (if it exists)

View File

@ -25,10 +25,6 @@ class pnor2_test(openram_test):
tx = factory.create(module_type="pnor2", size=1)
self.local_check(tx)
debug.info(2, "Checking 2-input nor gate")
tx = factory.create(module_type="pnor2", size=1, add_wells=False)
self.local_drc_check(tx)
globals.end_openram()
# run the test from the command line

View File

0
compiler/tests/05_replica_bitcell_array_test.py Normal file → Executable file
View File

View File

0
compiler/tests/08_wordline_driver_pbitcell_test.py Normal file → Executable file
View File

0
compiler/tests/09_sense_amp_array_test_pbitcell.py Normal file → Executable file
View File

0
compiler/tests/10_write_driver_array_pbitcell_test.py Normal file → Executable file
View File

View File

View File

0
compiler/tests/19_bank_select_pbitcell_test.py Normal file → Executable file
View File