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
+8 -5
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):
+10 -5
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):
+4 -4
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,
+9 -8
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):
+2 -2
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):
-1
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
+2 -2
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)
-4
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
View File
View File
View File
View File
View File
View File
View File
View File