Single bank passing.

Parameterized gate column mux of dff height.
End-cap only supply option instead of no vdd in bitcell.
This commit is contained in:
mrg 2020-06-25 14:03:59 -07:00
parent ee0a003298
commit f84ee04fa9
6 changed files with 61 additions and 51 deletions

View File

@ -497,18 +497,20 @@ class bank(design.design):
Create a 2:4 or 3:8 column address decoder.
"""
# Height is a multiple of DFF so that it can be staggered
# and rows do not align with the control logic module
self.dff = factory.create(module_type="dff")
self.dff =factory.create(module_type="dff")
if self.col_addr_size == 0:
return
elif self.col_addr_size == 1:
self.column_decoder = factory.create(module_type="pinvbuf", height=self.dff.height)
self.column_decoder = factory.create(module_type="pinvbuf",
height=self.dff.height)
elif self.col_addr_size == 2:
self.column_decoder = factory.create(module_type="hierarchical_predecode2x4", height=self.dff.height)
self.column_decoder = factory.create(module_type="hierarchical_predecode2x4",
height=self.dff.height)
elif self.col_addr_size == 3:
self.column_decoder = factory.create(module_type="hierarchical_predecode3x8", height=self.dff.height)
self.column_decoder = factory.create(module_type="hierarchical_predecode3x8",
height=self.dff.height)
else:
# No error checking before?
debug.error("Invalid column decoder?", -1)

View File

@ -110,17 +110,17 @@ class bitcell_base_array(design.design):
# For specific technologies, there is no vdd via within the bitcell. Instead vdd is connect via end caps.
try:
bitcell_no_vdd_pin = cell_properties.bitcell.no_vdd_via
end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError:
bitcell_no_vdd_pin = False
end_caps_enabled = False
# Add vdd/gnd via stacks
for row in range(self.row_size):
for col in range(self.column_size):
inst = self.cell_inst[row,col]
for pin_name in ["vdd", "gnd"]:
for pin in inst.get_pins(pin_name):
if not (pin_name == "vdd" and bitcell_no_vdd_pin):
if not end_caps_enabled:
for row in range(self.row_size):
for col in range(self.column_size):
inst = self.cell_inst[row, col]
for pin_name in ["vdd", "gnd"]:
for pin in inst.get_pins(pin_name):
self.add_power_pin(name=pin_name,
loc=pin.center(),
directions=bitcell_power_pin_directions,

View File

@ -78,12 +78,10 @@ class hierarchical_decoder(design.design):
def add_decoders(self):
""" Create the decoders based on the number of pre-decodes """
self.pre2_4 = factory.create(module_type="hierarchical_predecode2x4",
height=self.cell_height)
self.pre2_4 = factory.create(module_type="hierarchical_predecode2x4")
self.add_mod(self.pre2_4)
self.pre3_8 = factory.create(module_type="hierarchical_predecode3x8",
height=self.cell_height)
self.pre3_8 = factory.create(module_type="hierarchical_predecode3x8")
self.add_mod(self.pre3_8)
def determine_predecodes(self, num_inputs):

View File

@ -20,12 +20,17 @@ class hierarchical_predecode(design.design):
def __init__(self, name, input_number, height=None):
self.number_of_inputs = input_number
b = factory.create(module_type="bitcell")
if not height:
b = factory.create(module_type="bitcell")
self.cell_height = b.height
else:
self.column_decoder = False
elif height != b.height:
self.cell_height = height
self.column_decoder = True
else:
self.cell_height = b.height
self.column_decoder = False
self.number_of_outputs = int(math.pow(2, self.number_of_inputs))
design.design.__init__(self, name)
@ -40,21 +45,21 @@ class hierarchical_predecode(design.design):
def add_modules(self):
""" Add the INV and AND gate modules """
if self.number_of_inputs == 2:
self.and_mod = factory.create(module_type="and2_dec",
height=self.cell_height)
elif self.number_of_inputs == 3:
self.and_mod = factory.create(module_type="and3_dec",
height=self.cell_height)
elif self.number_of_inputs == 4:
self.and_mod = factory.create(module_type="and4_dec",
height=self.cell_height)
debug.check(self.number_of_inputs < 4,
"Invalid number of predecode inputs: {}".format(self.number_of_inputs))
if self.column_decoder:
and_type = "pand{}".format(self.number_of_inputs)
inv_type = "pinv"
else:
debug.error("Invalid number of predecode inputs: {}".format(self.number_of_inputs), -1)
and_type = "and{}_dec".format(self.number_of_inputs)
inv_type = "inv_dec"
self.and_mod = factory.create(module_type=and_type,
height=self.cell_height)
self.add_mod(self.and_mod)
# This uses the pinv_dec parameterized cell
self.inv = factory.create(module_type="inv_dec",
self.inv = factory.create(module_type=inv_type,
height=self.cell_height,
size=1)
self.add_mod(self.inv)
@ -80,7 +85,7 @@ class hierarchical_predecode(design.design):
# Outputs from cells are on output layer
if OPTS.tech_name == "sky130":
self.bus_layer = "m1"
self.bus_directions = None
self.bus_directions = "nonpref"
self.bus_pitch = self.m1_pitch
self.bus_space = 1.5 * self.m1_space
self.input_layer = "m2"
@ -88,7 +93,7 @@ class hierarchical_predecode(design.design):
self.output_layer_pitch = self.li_pitch
else:
self.bus_layer = "m2"
self.bus_directions = None
self.bus_directions = "pref"
self.bus_pitch = self.m2_pitch
self.bus_space = self.m2_space
# This requires a special jog to ensure to conflicts with the output layers
@ -238,10 +243,7 @@ class hierarchical_predecode(design.design):
# add output so that it is just below the vdd or gnd rail
# since this is where the p/n devices are and there are no
# pins in the and gates.
if OPTS.tech_name == "sky130":
inv_out_pos = inv_out_pin.lr()
else:
inv_out_pos = inv_out_pin.rc()
inv_out_pos = inv_out_pin.rc()
y_offset = (inv_num + 1) * self.inv.height - self.output_layer_pitch
right_pos = inv_out_pos + vector(self.inv.width - self.inv.get_pin("Z").rx(), 0)
rail_pos = vector(self.decode_rails[out_pin].cx(), y_offset)
@ -309,7 +311,7 @@ class hierarchical_predecode(design.design):
""" Add a pin for each row of vdd/gnd which are must-connects next level up. """
# In sky130, we use hand-made decoder cells with vertical power
if OPTS.tech_name == "sky130":
if not self.column_decoder:
for n in ["vdd", "gnd"]:
# This makes a wire from top to bottom for both inv and and gates
for i in [self.inv_inst, self.and_inst]:

View File

@ -380,19 +380,22 @@ class replica_bitcell_array(design.design):
# For specific technologies, there is no vdd via within the bitcell. Instead vdd is connect via end caps.
try:
bitcell_no_vdd_pin = cell_properties.bitcell.no_vdd_via
if cell_properties.bitcell.end_caps_enabled:
supply_insts = [self.dummy_col_left_inst, self.dummy_col_right_inst,
self.dummy_row_top_inst, self.dummy_row_bot_inst] + list(self.replica_col_inst.values())
else:
supply_insts = self.insts
except AttributeError:
bitcell_no_vdd_pin = False
supply_insts = self.insts
for pin_name in ["vdd", "gnd"]:
for inst in self.insts:
for inst in supply_insts:
pin_list = inst.get_pins(pin_name)
for pin in pin_list:
if not (pin_name == "vdd" and bitcell_no_vdd_pin):
self.add_power_pin(name=pin_name,
loc=pin.center(),
directions=("V", "V"),
start_layer=pin.layer)
self.add_power_pin(name=pin_name,
loc=pin.center(),
directions=("V", "V"),
start_layer=pin.layer)
def get_rbl_wl_name(self, port):
""" Return the WL for the given RBL port """

View File

@ -183,11 +183,16 @@ class replica_column(design.design):
width=self.width,
height=wl_pin.height())
# For every second row and column, add a via for gnd and vdd
for row in range(row_range_min, row_range_max):
inst = self.cell_inst[row]
# For specific technologies, there is no vdd via within the bitcell. Instead vdd is connect via end caps.
if end_caps_enabled:
supply_insts = [self.cell_inst[0], self.cell_inst[self.total_size - 1]]
else:
supply_insts = self.cell_inst.values()
for inst in supply_insts:
for pin_name in ["vdd", "gnd"]:
self.copy_layout_pin(inst, pin_name)
if pin_name in inst.mod.pins:
self.copy_layout_pin(inst, pin_name)
def get_bitcell_pins(self, col, row):
""" Creates a list of connections in the bitcell,