Add dummy bitcell module.

Modify bitcell logic to guess if bitcell is not "bitcell"
No longer need to specify replica (and dummy) bitcell explicitly
Add support for 1 or 2 port replica array.
This commit is contained in:
mrg
2019-07-05 12:58:52 -07:00
parent f542613d78
commit b9d993c88b
12 changed files with 208 additions and 76 deletions
+15 -23
View File
@@ -148,11 +148,12 @@ class bank(design.design):
# The center point for these cells are the upper-right corner of
# the bitcell array.
# The decoder/driver logic is placed on the right and mirrored on Y-axis.
# The write/sense/precharge/mux is placed on the top and mirrored on the X-axis.
# The port address decoder/driver logic is placed on the right and mirrored on X- and Y-axis.
# The port data write/sense/precharge/mux is placed on the top and mirrored on the X-axis.
self.bitcell_array_top = self.bitcell_array.height
self.bitcell_array_right = self.bitcell_array.width + self.m1_width + self.m2_gap
self.bitcell_array_right = self.bitcell_array.width + self.m1_width + self.m2_gap
# Offset past the dummy/RBL column
self.bitcell_array_left = 2*self.bitcell.width
self.compute_instance_port0_offsets()
if len(self.all_ports)==2:
@@ -161,7 +162,7 @@ class bank(design.design):
def compute_instance_port0_offsets(self):
"""
Compute the instance offsets for port0.
Compute the instance offsets for port0 on the left/bottom of the bank.
"""
port = 0
@@ -172,17 +173,15 @@ class bank(design.design):
# LOWER RIGHT QUADRANT
# Below the bitcell array
self.port_data_offsets[port] = vector(0,0)
self.port_data_offsets[port] = vector(self.bitcell_array_left,0)
# UPPER LEFT QUADRANT
# To the left of the bitcell array
# The wordline driver is placed to the right of the main decoder width.
x_offset = self.m2_gap + self.port_address.width
self.port_address_offsets[port] = vector(-x_offset,0)
# LOWER LEFT QUADRANT
# Place the col decoder left aligned with wordline driver plus halfway under row decoder
# Place the col decoder left aligned with row decoder (x_offset doesn't change)
# Place the col decoder left aligned with wordline driver
# Below the bitcell array with well spacing
x_offset = self.central_bus_width[port] + self.port_address.wordline_driver.width
if self.col_addr_size > 0:
@@ -204,7 +203,7 @@ class bank(design.design):
def compute_instance_port1_offsets(self):
"""
Compute the instance offsets for port1 on the top of the bank.
Compute the instance offsets for port1 on the right/top of the bank.
"""
port=1
@@ -218,12 +217,11 @@ class bank(design.design):
# LOWER RIGHT QUADRANT
# To the left of the bitcell array
# The wordline driver is placed to the right of the main decoder width.
x_offset = self.bitcell_array_right + self.port_address.width + self.m2_gap
self.port_address_offsets[port] = vector(x_offset,0)
# UPPER RIGHT QUADRANT
# Place the col decoder right aligned with wordline driver plus halfway under row decoder
# Place the col decoder right aligned with wordline driver
# Above the bitcell array with a well spacing
x_offset = self.bitcell_array_right + self.central_bus_width[port] + self.port_address.wordline_driver.width
if self.col_addr_size > 0:
@@ -247,16 +245,12 @@ class bank(design.design):
self.compute_instance_offsets()
# UPPER RIGHT QUADRANT
self.place_bitcell_array(self.bitcell_array_offset)
# LOWER RIGHT QUADRANT
self.place_port_data(self.port_data_offsets)
# UPPER LEFT QUADRANT
self.place_port_address(self.port_address_offsets)
# LOWER LEFT QUADRANT
self.place_column_decoder(self.column_decoder_offsets)
self.place_bank_select(self.bank_select_offsets)
@@ -274,11 +268,6 @@ class bank(design.design):
debug.check(self.num_rows*self.num_cols==self.word_size*self.num_words,"Invalid bank sizes.")
debug.check(self.addr_size==self.col_addr_size + self.row_addr_size,"Invalid address break down.")
# Width for the vdd/gnd rails
self.supply_rail_width = 4*self.m2_width
# FIXME: This spacing should be width dependent...
self.supply_rail_pitch = self.supply_rail_width + 4*self.m2_space
# The order of the control signals on the control bus:
self.input_control_signals = []
port_num = 0
@@ -328,7 +317,7 @@ class bank(design.design):
self.wl_names = self.bitcell.list_all_wl_names()
self.bitline_names = self.bitcell.list_all_bitline_names()
self.bitcell_array = factory.create(module_type="bitcell_array",
self.bitcell_array = factory.create(module_type="replica_bitcell_array",
cols=self.num_cols,
rows=self.num_rows)
self.add_mod(self.bitcell_array)
@@ -358,11 +347,14 @@ class bank(design.design):
self.bitcell_array_inst=self.add_inst(name="bitcell_array",
mod=self.bitcell_array)
print(self.bitcell_array.pins)
temp = []
for col in range(self.num_cols):
for bitline in self.bitline_names:
temp.append(bitline+"_{0}".format(col))
for col in range(2):
for bitline in self.bitline_names:
temp.append("replica_"+bitline+"_{0}".format(col))
for row in range(self.num_rows):
for wordline in self.wl_names:
temp.append(wordline+"_{0}".format(row))
+47 -30
View File
@@ -22,13 +22,18 @@ class replica_bitcell_array(design.design):
Dummy are the outside columns/rows with WL and BL tied to gnd.
Requires a regular bitcell array, replica bitcell, and dummy bitcell (Bl/BR disconnected).
"""
def __init__(self, cols, rows, name):
def __init__(self, cols, rows, num_ports, name):
design.design.__init__(self, name)
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols))
self.add_comment("rows: {0} cols: {1}".format(rows, cols))
self.column_size = cols
self.row_size = rows
self.num_ports = num_ports
# Two dummy rows/cols plus replica for each port
self.extra_rows = 2 + self.num_ports
self.extra_cols = 2 + self.num_ports
self.create_netlist()
if not OPTS.netlist_only:
@@ -80,19 +85,20 @@ class replica_bitcell_array(design.design):
# Replica bitline
self.replica_column = factory.create(module_type="replica_column",
rows=self.row_size + 4)
rows=self.row_size + self.extra_rows,
num_ports = self.num_ports)
self.add_mod(self.replica_column)
# Dummy row
self.dummy_row = factory.create(module_type="dummy_array",
rows=1,
cols=self.column_size)
cols=self.column_size,
rows=1)
self.add_mod(self.dummy_row)
# Dummy col
self.dummy_col = factory.create(module_type="dummy_array",
cols=1,
rows=self.row_size + 4)
rows=self.row_size + self.extra_rows)
self.add_mod(self.dummy_col)
@@ -103,27 +109,33 @@ class replica_bitcell_array(design.design):
self.bl_names = [x for x in self.bitcell_array.pins if x.startswith("b")]
# top/bottom rows (in the middle)
self.replica_wl_names = ["replica_"+x for x in self.cell.pins if x.startswith("w")]
self.dummy_wl_names = ["dummy_"+x for x in self.cell.pins if x.startswith("w")]
self.dummy_bl_names = ["dummy_"+x for x in self.cell.pins if x.startswith("b")]
self.replica_wl_names = ["replica_"+x for x in self.cell.list_all_wl_names()]
self.dummy_wl_names = ["dummy_"+x for x in self.cell.list_all_wl_names()]
self.dummy_bl_names = ["dummy_"+x for x in self.cell.list_all_bitline_names()]
self.dummy_row_bl_names = self.bl_names
# dummy row and replica on each side of the bitcell rows
self.replica_col_wl_names = [x+"_0" for x in self.dummy_wl_names] \
+ ["replica_"+x+"_0" for x in self.cell.list_all_wl_names()] \
+ self.wl_names \
+ ["replica_"+x+"_1" for x in self.cell.list_all_wl_names()] \
+ [x+"_1" for x in self.dummy_wl_names]
self.replica_bl_names = ["replica_"+x for x in self.cell.pins if x.startswith("b")]
+ self.wl_names
if self.num_ports==2:
self.replica_col_wl_names.extend(["replica_"+x+"_1" for x in self.cell.list_all_wl_names()])
self.replica_col_wl_names.extend([x+"_1" for x in self.dummy_wl_names])
self.replica_bl_names = ["replica_"+x for x in self.cell.list_all_bitline_names()]
self.replica_bl0_names = [x+"_0" for x in self.replica_bl_names]
self.replica_bl1_names = [x+"_1" for x in self.replica_bl_names]
# left/right rows
self.dummy_col_wl_names = self.replica_col_wl_names
self.add_pin_list(self.bl_names)
self.add_pin_list([x+"_0" for x in self.replica_bl_names])
self.add_pin_list([x+"_1" for x in self.replica_bl_names])
self.add_pin_list([x for x in self.replica_col_wl_names if not x.startswith("dummy")])
self.add_pin_list(self.replica_bl0_names)
if self.num_ports==2:
self.add_pin_list(self.replica_bl1_names)
self.add_pin_list(self.wl_names)
self.add_pin_list(self.replica_wl_names)
#self.add_pin_list([x for x in self.replica_col_wl_names if not x.startswith("dummy")])
self.add_pin("vdd")
self.add_pin("gnd")
@@ -142,10 +154,11 @@ class replica_bitcell_array(design.design):
self.replica_col_left_inst=self.add_inst(name="replica_col_left",
mod=self.replica_column)
self.connect_inst([x+"_0" for x in self.replica_bl_names] + self.replica_col_wl_names + supplies)
self.replica_col_right_inst=self.add_inst(name="replica_col_right",
mod=self.replica_column)
self.connect_inst([x+"_1" for x in self.replica_bl_names] + self.replica_col_wl_names[::-1] + supplies)
if self.num_ports==2:
self.replica_col_right_inst=self.add_inst(name="replica_col_right",
mod=self.replica_column)
self.connect_inst([x+"_1" for x in self.replica_bl_names] + self.replica_col_wl_names[::-1] + supplies)
# Replica rows with replica bitcell
self.dummy_row_bottop_inst=self.add_inst(name="dummy_row_bottop",
@@ -177,16 +190,17 @@ class replica_bitcell_array(design.design):
def create_layout(self):
self.height = (self.row_size+4)*self.dummy_row.height
self.width = (self.column_size+4)*self.replica_column.width
self.height = (self.row_size+self.extra_rows)*self.dummy_row.height
self.width = (self.column_size+self.extra_cols)*self.replica_column.width
# This is a bitcell x bitcell offset to scale
offset = vector(self.replica_column.width, self.dummy_row.height)
self.bitcell_array_inst.place(offset=[0,0])
self.replica_col_left_inst.place(offset=offset.scale(-1,-2))
self.replica_col_right_inst.place(offset=offset.scale(0,2)+self.bitcell_array_inst.ur(),
mirror="MX")
if self.num_ports==2:
self.replica_col_right_inst.place(offset=offset.scale(0,2)+self.bitcell_array_inst.ur(),
mirror="MX")
self.dummy_row_toptop_inst.place(offset=offset.scale(0,2)+self.bitcell_array_inst.ul(),
mirror="MX")
@@ -196,7 +210,11 @@ class replica_bitcell_array(design.design):
self.dummy_row_botbot_inst.place(offset=offset.scale(0,-2))
self.dummy_col_left_inst.place(offset=offset.scale(-2,-2))
self.dummy_col_right_inst.place(offset=offset.scale(1,-2)+self.bitcell_array_inst.lr())
if self.num_ports==2:
self.dummy_col_right_inst.place(offset=offset.scale(1,-2)+self.bitcell_array_inst.lr())
else:
self.dummy_col_right_inst.place(offset=offset.scale(0,-2)+self.bitcell_array_inst.lr())
self.translate_all(offset.scale(-2,-2))
@@ -246,7 +264,10 @@ class replica_bitcell_array(design.design):
height=pin.height())
# Replica columns
for index,side in enumerate(["left","right"]):
replica_sides = ["left"]
if self.num_ports==2:
replica_sides.append("right")
for index,side in enumerate(replica_sides):
inst = getattr(self, "replica_col_{}_inst".format(side))
pin_names = inst.mod.get_pin_names()
for pin_name in pin_names:
@@ -262,11 +283,7 @@ class replica_bitcell_array(design.design):
for pin_name in ["vdd","gnd"]:
for inst in [self.bitcell_array_inst,
self.replica_col_left_inst, self.replica_col_right_inst,
self.dummy_col_left_inst, self.dummy_col_right_inst,
self.dummy_row_toptop_inst, self.dummy_row_topbot_inst,
self.dummy_row_bottop_inst, self.dummy_row_botbot_inst]:
for inst in self.insts:
pin_list = inst.get_pins(pin_name)
for pin in pin_list:
self.add_power_pin(name=pin_name, loc=pin.center(), vertical=True, start_layer=pin.layer)
+3 -2
View File
@@ -16,10 +16,11 @@ class replica_column(design.design):
Generate a replica bitline column for the replica array.
"""
def __init__(self, name, rows):
def __init__(self, name, rows, num_ports):
design.design.__init__(self, name)
self.row_size = rows
self.num_ports = num_ports
self.create_netlist()
if not OPTS.netlist_only:
@@ -64,7 +65,7 @@ class replica_column(design.design):
self.cell_inst = {}
for row in range(self.row_size):
name="rbc_{0}".format(row)
if row>0 and row<self.row_size-2:
if row>0 and row<self.row_size - self.num_ports:
self.cell_inst[row]=self.add_inst(name=name,
mod=self.replica_cell)
else: