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. Create a 2:4 or 3:8 column address decoder.
""" """
# Height is a multiple of DFF so that it can be staggered self.dff =factory.create(module_type="dff")
# and rows do not align with the control logic module
self.dff = factory.create(module_type="dff")
if self.col_addr_size == 0: if self.col_addr_size == 0:
return return
elif self.col_addr_size == 1: 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: 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: 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: else:
# No error checking before? # No error checking before?
debug.error("Invalid column decoder?", -1) 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. # For specific technologies, there is no vdd via within the bitcell. Instead vdd is connect via end caps.
try: try:
bitcell_no_vdd_pin = cell_properties.bitcell.no_vdd_via end_caps_enabled = cell_properties.bitcell.end_caps
except AttributeError: except AttributeError:
bitcell_no_vdd_pin = False end_caps_enabled = False
# Add vdd/gnd via stacks # Add vdd/gnd via stacks
for row in range(self.row_size): if not end_caps_enabled:
for col in range(self.column_size): for row in range(self.row_size):
inst = self.cell_inst[row,col] for col in range(self.column_size):
for pin_name in ["vdd", "gnd"]: inst = self.cell_inst[row, col]
for pin in inst.get_pins(pin_name): for pin_name in ["vdd", "gnd"]:
if not (pin_name == "vdd" and bitcell_no_vdd_pin): for pin in inst.get_pins(pin_name):
self.add_power_pin(name=pin_name, self.add_power_pin(name=pin_name,
loc=pin.center(), loc=pin.center(),
directions=bitcell_power_pin_directions, directions=bitcell_power_pin_directions,

View File

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

View File

@ -20,11 +20,16 @@ class hierarchical_predecode(design.design):
def __init__(self, name, input_number, height=None): def __init__(self, name, input_number, height=None):
self.number_of_inputs = input_number self.number_of_inputs = input_number
b = factory.create(module_type="bitcell")
if not height: if not height:
b = factory.create(module_type="bitcell")
self.cell_height = b.height self.cell_height = b.height
else: self.column_decoder = False
elif height != b.height:
self.cell_height = 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)) self.number_of_outputs = int(math.pow(2, self.number_of_inputs))
design.design.__init__(self, name) design.design.__init__(self, name)
@ -40,21 +45,21 @@ class hierarchical_predecode(design.design):
def add_modules(self): def add_modules(self):
""" Add the INV and AND gate modules """ """ Add the INV and AND gate modules """
if self.number_of_inputs == 2: debug.check(self.number_of_inputs < 4,
self.and_mod = factory.create(module_type="and2_dec", "Invalid number of predecode inputs: {}".format(self.number_of_inputs))
height=self.cell_height)
elif self.number_of_inputs == 3: if self.column_decoder:
self.and_mod = factory.create(module_type="and3_dec", and_type = "pand{}".format(self.number_of_inputs)
height=self.cell_height) inv_type = "pinv"
elif self.number_of_inputs == 4:
self.and_mod = factory.create(module_type="and4_dec",
height=self.cell_height)
else: 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) self.add_mod(self.and_mod)
# This uses the pinv_dec parameterized cell # 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, height=self.cell_height,
size=1) size=1)
self.add_mod(self.inv) self.add_mod(self.inv)
@ -80,7 +85,7 @@ class hierarchical_predecode(design.design):
# Outputs from cells are on output layer # Outputs from cells are on output layer
if OPTS.tech_name == "sky130": if OPTS.tech_name == "sky130":
self.bus_layer = "m1" self.bus_layer = "m1"
self.bus_directions = None self.bus_directions = "nonpref"
self.bus_pitch = self.m1_pitch self.bus_pitch = self.m1_pitch
self.bus_space = 1.5 * self.m1_space self.bus_space = 1.5 * self.m1_space
self.input_layer = "m2" self.input_layer = "m2"
@ -88,7 +93,7 @@ class hierarchical_predecode(design.design):
self.output_layer_pitch = self.li_pitch self.output_layer_pitch = self.li_pitch
else: else:
self.bus_layer = "m2" self.bus_layer = "m2"
self.bus_directions = None self.bus_directions = "pref"
self.bus_pitch = self.m2_pitch self.bus_pitch = self.m2_pitch
self.bus_space = self.m2_space self.bus_space = self.m2_space
# This requires a special jog to ensure to conflicts with the output layers # 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 # 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 # since this is where the p/n devices are and there are no
# pins in the and gates. # pins in the and gates.
if OPTS.tech_name == "sky130": inv_out_pos = inv_out_pin.rc()
inv_out_pos = inv_out_pin.lr()
else:
inv_out_pos = inv_out_pin.rc()
y_offset = (inv_num + 1) * self.inv.height - self.output_layer_pitch 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) 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) 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. """ """ 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 # 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"]: for n in ["vdd", "gnd"]:
# This makes a wire from top to bottom for both inv and and gates # This makes a wire from top to bottom for both inv and and gates
for i in [self.inv_inst, self.and_inst]: 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. # For specific technologies, there is no vdd via within the bitcell. Instead vdd is connect via end caps.
try: 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: except AttributeError:
bitcell_no_vdd_pin = False supply_insts = self.insts
for pin_name in ["vdd", "gnd"]: for pin_name in ["vdd", "gnd"]:
for inst in self.insts: for inst in supply_insts:
pin_list = inst.get_pins(pin_name) pin_list = inst.get_pins(pin_name)
for pin in pin_list: for pin in pin_list:
if not (pin_name == "vdd" and bitcell_no_vdd_pin): self.add_power_pin(name=pin_name,
self.add_power_pin(name=pin_name, loc=pin.center(),
loc=pin.center(), directions=("V", "V"),
directions=("V", "V"), start_layer=pin.layer)
start_layer=pin.layer)
def get_rbl_wl_name(self, port): def get_rbl_wl_name(self, port):
""" Return the WL for the given RBL port """ """ Return the WL for the given RBL port """

View File

@ -183,11 +183,16 @@ class replica_column(design.design):
width=self.width, width=self.width,
height=wl_pin.height()) height=wl_pin.height())
# For every second row and column, add a via for gnd and vdd # For specific technologies, there is no vdd via within the bitcell. Instead vdd is connect via end caps.
for row in range(row_range_min, row_range_max): if end_caps_enabled:
inst = self.cell_inst[row] 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"]: 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): def get_bitcell_pins(self, col, row):
""" Creates a list of connections in the bitcell, """ Creates a list of connections in the bitcell,