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.
|
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)
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,17 @@ 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]:
|
||||||
|
|
|
||||||
|
|
@ -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 """
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue