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. 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)) debug.info(1, "Creating pand2 {}".format(name))
self.add_comment("size: {}".format(size)) self.add_comment("size: {}".format(size))
self.vertical = vertical self.vertical = vertical
self.size = size self.size = size
pgate.pgate.__init__(self, name) pgate.pgate.__init__(self, name, height, add_wells)
def create_netlist(self): def create_netlist(self):
self.add_pins() self.add_pins()
@ -31,12 +31,15 @@ class pand2(pgate.pgate):
def create_modules(self): def create_modules(self):
self.nand = factory.create(module_type="pnand2", self.nand = factory.create(module_type="pnand2",
height=self.height) height=self.height,
self.add_mod(self.nand) add_wells=False)
self.inv = factory.create(module_type="pdriver", self.inv = factory.create(module_type="pdriver",
size_list=[self.size], 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) self.add_mod(self.inv)
def create_layout(self): def create_layout(self):

View File

@ -15,7 +15,7 @@ class pand3(pgate.pgate):
""" """
This is a simple buffer used for driving loads. 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)) debug.info(1, "Creating pand3 {}".format(name))
self.add_comment("size: {}".format(size)) self.add_comment("size: {}".format(size))
@ -23,7 +23,7 @@ class pand3(pgate.pgate):
self.size = size self.size = size
# Creates the netlist and layout # Creates the netlist and layout
pgate.pgate.__init__(self, name, height) pgate.pgate.__init__(self, name, height, add_wells)
def create_netlist(self): def create_netlist(self):
self.add_pins() self.add_pins()
@ -33,12 +33,17 @@ class pand3(pgate.pgate):
def create_modules(self): def create_modules(self):
# Shield the cap, but have at least a stage effort of 4 # Shield the cap, but have at least a stage effort of 4
self.nand = factory.create(module_type="pnand3", self.nand = factory.create(module_type="pnand3",
height=self.height) height=self.height,
self.add_mod(self.nand) 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", self.inv = factory.create(module_type="pdriver",
size_list=[self.size], 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) self.add_mod(self.inv)
def create_layout(self): def create_layout(self):

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,10 +25,6 @@ class pnor2_test(openram_test):
tx = factory.create(module_type="pnor2", size=1) tx = factory.create(module_type="pnor2", size=1)
self.local_check(tx) 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() globals.end_openram()
# run the test from the command line # 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