mirror of https://github.com/VLSIDA/OpenRAM.git
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:
parent
ee0a003298
commit
f84ee04fa9
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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]:
|
||||
|
|
|
|||
|
|
@ -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 """
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue