Still working on array refactor

This commit is contained in:
mrg 2020-08-25 11:50:44 -07:00
parent 8dee5520e0
commit 28bd93bf51
11 changed files with 167 additions and 175 deletions

View File

@ -68,7 +68,7 @@ class bank(design.design):
self.route_layout() self.route_layout()
# Can remove the following, but it helps for debug! # Can remove the following, but it helps for debug!
# self.add_lvs_correspondence_points() self.add_lvs_correspondence_points()
# Remember the bank center for further placement # Remember the bank center for further placement
self.bank_array_ll = self.offset_all_coordinates().scale(-1, -1) self.bank_array_ll = self.offset_all_coordinates().scale(-1, -1)
@ -83,7 +83,7 @@ class bank(design.design):
for bit in range(self.word_size + self.num_spare_cols): for bit in range(self.word_size + self.num_spare_cols):
self.add_pin("dout{0}_{1}".format(port, bit), "OUTPUT") self.add_pin("dout{0}_{1}".format(port, bit), "OUTPUT")
for port in self.all_ports: for port in self.all_ports:
self.add_pin_list(self.bitcell_array.get_rbl_bitline_names(port), "OUTPUT") self.add_pin("rbl_bl_{0}_{0}".format(port), "OUTPUT")
for port in self.write_ports: for port in self.write_ports:
for bit in range(self.word_size + self.num_spare_cols): for bit in range(self.word_size + self.num_spare_cols):
self.add_pin("din{0}_{1}".format(port, bit), "INPUT") self.add_pin("din{0}_{1}".format(port, bit), "INPUT")
@ -145,7 +145,7 @@ class bank(design.design):
to_layer="m3", to_layer="m3",
offset=pin_offset) offset=pin_offset)
self.add_path(bl_pin.layer, [pin_offset, pin_pos]) self.add_path(bl_pin.layer, [pin_offset, pin_pos])
self.add_layout_pin_segment_center(text="rbl_bl{0}".format(port), self.add_layout_pin_segment_center(text="rbl_bl_{0}_{0}".format(port),
layer="m3", layer="m3",
start=left_right_offset, start=left_right_offset,
end=pin_offset) end=pin_offset)
@ -357,13 +357,6 @@ class bank(design.design):
def add_modules(self): def add_modules(self):
""" Add all the modules using the class loader """ """ Add all the modules using the class loader """
# create arrays of bitline and bitline_bar names for read, write, or all ports
self.bitcell = factory.create(module_type="bitcell")
self.bl_names = self.bitcell.get_all_bl_names()
self.br_names = self.bitcell.get_all_br_names()
self.wl_names = self.bitcell.get_all_wl_names()
self.bitline_names = self.bitcell.get_all_bitline_names()
self.port_data = [] self.port_data = []
for port in self.all_ports: for port in self.all_ports:
temp_pre = factory.create(module_type="port_data", temp_pre = factory.create(module_type="port_data",
@ -401,30 +394,34 @@ class bank(design.design):
# gnd # gnd
temp = [] temp = []
# Replace RBL wordline with wl_en#
wordline_names = self.bitcell_array.get_wordline_names()
rbl_wl_names = [] temp.extend(self.bitcell_array.get_dummy_bitline_names(0))
for port in self.all_ports: temp.extend(self.bitcell_array.get_rbl_bitline_names(0))
rbl_wl_names.append(self.bitcell_array.get_rbl_wordline_names(port)) temp.extend(self.bitcell_array.get_bitline_names())
if len(self.all_ports) > 1:
temp.extend(self.bitcell_array.get_rbl_bitline_names(1))
temp.extend(self.bitcell_array.get_dummy_bitline_names(1))
wordline_names = self.bitcell_array.get_dummy_wordline_names(0)
wordline_names.extend(self.bitcell_array.get_rbl_wordline_names(0))
wordline_names.extend(self.bitcell_array.get_wordline_names())
if len(self.all_ports) > 1:
wordline_names.extend(self.bitcell_array.get_rbl_wordline_names(1))
wordline_names.extend(self.bitcell_array.get_dummy_wordline_names(1))
# Rename the RBL WL to the enable name # Rename the RBL WL to the enable name
for port in self.all_ports: for port in self.all_ports:
wordline_names = [x.replace(rbl_wl_names[port], "wl_en{0}".format(port)) for x in wordline_names] rbl_wl_name = self.bitcell_array.get_rbl_wordline_names(port)
wordline_names = [x.replace(rbl_wl_name[port], "wl_en{0}".format(port)) for x in wordline_names]
# Connect the other RBL WL to gnd # Connect the other RBL WL to gnd
wordline_names = ["gnd" if x.startswith("rbl_wl") else x for x in wordline_names] wordline_names = ["gnd" if x.startswith("rbl_wl") else x for x in wordline_names]
# Connect the dummy WL to gnd # Connect the dummy WL to gnd
wordline_names = ["gnd" if x.startswith("dummy") else x for x in wordline_names] wordline_names = ["gnd" if x.startswith("dummy") else x for x in wordline_names]
temp.extend(wordline_names) temp.extend(wordline_names)
rbl_names = self.bitcell_array.get_rbl_bitline_names()
temp.extend(rbl_names)
bitline_names = self.bitcell_array.get_bitline_names()
temp.extend(bitline_names)
temp.append("vdd") temp.append("vdd")
temp.append("gnd") temp.append("gnd")
import pdb; pdb.set_trace()
self.connect_inst(temp) self.connect_inst(temp)
def place_bitcell_array(self, offset): def place_bitcell_array(self, offset):
@ -433,17 +430,15 @@ class bank(design.design):
def create_port_data(self): def create_port_data(self):
""" Creating Port Data """ """ Creating Port Data """
self.port_data_inst = [None] * len(self.all_ports) self.port_data_inst = [None] * len(self.all_ports)
for port in self.all_ports: for port in self.all_ports:
self.port_data_inst[port]=self.add_inst(name="port_data{}".format(port), self.port_data_inst[port]=self.add_inst(name="port_data{}".format(port),
mod=self.port_data[port]) mod=self.port_data[port])
temp = [] temp = []
rbl_bl_names = self.bitcell_array.get_rbl_bitline_names(port) temp.extend(["rbl_bl_{0}_{0}".format(port), "rbl_br_{0}_{0}".format(port)])
temp.extend(rbl_bl_names) temp.extend(self.bitcell_array.get_bitline_names(port))
for col in range(self.num_cols + self.num_spare_cols):
temp.append("{0}_{1}".format(self.bl_names[port], col))
temp.append("{0}_{1}".format(self.br_names[port], col))
if port in self.read_ports: if port in self.read_ports:
for bit in range(self.word_size + self.num_spare_cols): for bit in range(self.word_size + self.num_spare_cols):
temp.append("dout{0}_{1}".format(port, bit)) temp.append("dout{0}_{1}".format(port, bit))
@ -488,8 +483,7 @@ class bank(design.design):
for bit in range(self.row_addr_size): for bit in range(self.row_addr_size):
temp.append("addr{0}_{1}".format(port, bit + self.col_addr_size)) temp.append("addr{0}_{1}".format(port, bit + self.col_addr_size))
temp.append("wl_en{}".format(port)) temp.append("wl_en{}".format(port))
for row in range(self.num_rows): temp.extend(self.bitcell_array.get_wordline_names(port))
temp.append("{0}_{1}".format(self.wl_names[port], row))
temp.extend(["vdd", "gnd"]) temp.extend(["vdd", "gnd"])
self.connect_inst(temp) self.connect_inst(temp)
@ -707,27 +701,28 @@ class bank(design.design):
# Connect the regular bitlines # Connect the regular bitlines
inst2 = self.port_data_inst[port] inst2 = self.port_data_inst[port]
inst1 = self.bitcell_array_inst inst1 = self.bitcell_array_inst
inst1_bl_name = self.bl_names[port] + "_{}" inst1_bl_name = [x for x in self.bitcell_array.get_bitline_names(port) if "bl" in x]
inst1_br_name = self.br_names[port] + "_{}" inst1_br_name = [x for x in self.bitcell_array.get_bitline_names(port) if "br" in x]
inst2_bl_name = inst2.mod.get_bl_names() + "_{}" inst2_bl_name = []
inst2_br_name = inst2.mod.get_br_names() + "_{}" inst2_br_name = []
for col in range(self.num_cols):
inst2_bl_name.append(inst2.mod.get_bl_names() + "_{}".format(col))
inst2_br_name.append(inst2.mod.get_br_names() + "_{}".format(col))
for col in range(self.num_spare_cols):
inst2_bl_name.append("spare" + inst2.mod.get_bl_names() + "_{}".format(col))
inst2_br_name.append("spare" + inst2.mod.get_br_names() + "_{}".format(col))
self.connect_bitlines(inst1=inst1, self.connect_bitlines(inst1=inst1,
inst2=inst2, inst2=inst2,
num_bits=self.num_cols,
inst1_bl_name=inst1_bl_name, inst1_bl_name=inst1_bl_name,
inst1_br_name=inst1_br_name, inst1_br_name=inst1_br_name,
inst2_bl_name=inst2_bl_name, inst2_bl_name=inst2_bl_name,
inst2_br_name=inst2_br_name) inst2_br_name=inst2_br_name)
# connect spare bitlines
for i in range(self.num_spare_cols):
self.connect_bitline(inst1, inst2, inst1_bl_name.format(self.num_cols + i), "spare" + inst2_bl_name.format(i))
self.connect_bitline(inst1, inst2, inst1_br_name.format(self.num_cols + i), "spare" + inst2_br_name.format(i))
# Connect the replica bitlines # Connect the replica bitlines
rbl_bl_names = self.bitcell_array.get_rbl_bitline_names(port) rbl_bl_names = self.bitcell_array.get_rbl_bitline_names(port)[2 * port: 2 * port + 2]
for (array_name, data_name) in zip(rbl_bl_names, ["rbl_bl", "rbl_br"]): for (array_name, data_name) in zip(rbl_bl_names, ["rbl_bl", "rbl_br"]):
self.connect_bitline(inst1, inst2, array_name, data_name) self.connect_bitline(inst1, inst2, array_name, data_name)
@ -826,16 +821,16 @@ class bank(design.design):
vector(top_loc.x, yoffset), vector(top_loc.x, yoffset),
top_loc]) top_loc])
def connect_bitlines(self, inst1, inst2, num_bits, def connect_bitlines(self, inst1, inst2,
inst1_bl_name, inst1_br_name, inst1_bl_name, inst1_br_name,
inst2_bl_name, inst2_br_name): inst2_bl_name, inst2_br_name):
""" """
Connect the bl and br of two modules. Connect the bl and br of two modules.
""" """
for (name1, name2) in zip(inst1_bl_name, inst2_bl_name):
for col in range(num_bits): self.connect_bitline(inst1, inst2, name1, name2)
self.connect_bitline(inst1, inst2, inst1_bl_name.format(col), inst2_bl_name.format(col)) for (name1, name2) in zip(inst1_br_name, inst2_br_name):
self.connect_bitline(inst1, inst2, inst1_br_name.format(col), inst2_br_name.format(col)) self.connect_bitline(inst1, inst2, name1, name2)
def route_port_address(self, port): def route_port_address(self, port):
""" Connect Wordline driver to bitcell array wordline """ """ Connect Wordline driver to bitcell array wordline """
@ -850,11 +845,12 @@ class bank(design.design):
def route_port_address_left(self, port): def route_port_address_left(self, port):
""" Connecting Wordline driver output to Bitcell WL connection """ """ Connecting Wordline driver output to Bitcell WL connection """
for row in range(self.num_rows): driver_names = ["wl_{}".format(x) for x in range(self.num_rows)]
for (driver_name, array_name) in zip(driver_names, self.bitcell_array.get_wordline_names(port)):
# The mid guarantees we exit the input cell to the right. # The mid guarantees we exit the input cell to the right.
driver_wl_pin = self.port_address_inst[port].get_pin("wl_{}".format(row)) driver_wl_pin = self.port_address_inst[port].get_pin(driver_name)
driver_wl_pos = driver_wl_pin.rc() driver_wl_pos = driver_wl_pin.rc()
bitcell_wl_pin = self.bitcell_array_inst.get_pin(self.wl_names[port] + "_{}".format(row)) bitcell_wl_pin = self.bitcell_array_inst.get_pin(array_name)
bitcell_wl_pos = bitcell_wl_pin.lc() bitcell_wl_pos = bitcell_wl_pin.lc()
mid1 = driver_wl_pos.scale(0, 1) + vector(0.5 * self.port_address_inst[port].rx() + 0.5 * self.bitcell_array_inst.lx(), 0) mid1 = driver_wl_pos.scale(0, 1) + vector(0.5 * self.port_address_inst[port].rx() + 0.5 * self.bitcell_array_inst.lx(), 0)
mid2 = mid1.scale(1, 0) + bitcell_wl_pos.scale(0.5, 1) mid2 = mid1.scale(1, 0) + bitcell_wl_pos.scale(0.5, 1)
@ -867,11 +863,12 @@ class bank(design.design):
def route_port_address_right(self, port): def route_port_address_right(self, port):
""" Connecting Wordline driver output to Bitcell WL connection """ """ Connecting Wordline driver output to Bitcell WL connection """
for row in range(self.num_rows): driver_names = ["wl_{}".format(x) for x in range(self.num_rows)]
for (driver_name, array_name) in zip(driver_names, self.bitcell_array.get_wordline_names(port)):
# The mid guarantees we exit the input cell to the right. # The mid guarantees we exit the input cell to the right.
driver_wl_pin = self.port_address_inst[port].get_pin("wl_{}".format(row)) driver_wl_pin = self.port_address_inst[port].get_pin(driver_name)
driver_wl_pos = driver_wl_pin.lc() driver_wl_pos = driver_wl_pin.lc()
bitcell_wl_pin = self.bitcell_array_inst.get_pin(self.wl_names[port] + "_{}".format(row)) bitcell_wl_pin = self.bitcell_array_inst.get_pin(array_name)
bitcell_wl_pos = bitcell_wl_pin.rc() bitcell_wl_pos = bitcell_wl_pin.rc()
mid1 = driver_wl_pos.scale(0, 1) + vector(0.5 * self.port_address_inst[port].lx() + 0.5 * self.bitcell_array_inst.rx(), 0) mid1 = driver_wl_pos.scale(0, 1) + vector(0.5 * self.port_address_inst[port].lx() + 0.5 * self.bitcell_array_inst.rx(), 0)
mid2 = mid1.scale(1, 0) + bitcell_wl_pos.scale(0, 1) mid2 = mid1.scale(1, 0) + bitcell_wl_pos.scale(0, 1)
@ -932,26 +929,29 @@ class bank(design.design):
These should probably be turned off by default though, since extraction These should probably be turned off by default though, since extraction
will show these as ports in the extracted netlist. will show these as ports in the extracted netlist.
""" """
# Add the wordline names
for i in range(self.num_rows):
wl_name = "wl_{}".format(i)
wl_pin = self.bitcell_array_inst.get_pin(wl_name)
self.add_label(text=wl_name,
layer="m1",
offset=wl_pin.center())
# Add the bitline names for pin_name in self.bitcell_array.get_all_bitline_names():
for i in range(self.num_cols): self.copy_layout_pin(self.bitcell_array, pin_name)
bl_name = "bl_{}".format(i) # Add the wordline names
br_name = "br_{}".format(i) # for i in range(self.num_rows):
bl_pin = self.bitcell_array_inst.get_pin(bl_name) # wl_name = "wl_{}".format(i)
br_pin = self.bitcell_array_inst.get_pin(br_name) # wl_pin = self.bitcell_array_inst.get_pin(wl_name)
self.add_label(text=bl_name, # self.add_label(text=wl_name,
layer="m2", # layer="m1",
offset=bl_pin.center()) # offset=wl_pin.center())
self.add_label(text=br_name,
layer="m2", # # Add the bitline names
offset=br_pin.center()) # for i in range(self.num_cols):
# bl_name = "bl_{}".format(i)
# br_name = "br_{}".format(i)
# bl_pin = self.bitcell_array_inst.get_pin(bl_name)
# br_pin = self.bitcell_array_inst.get_pin(br_name)
# self.add_label(text=bl_name,
# layer="m2",
# offset=bl_pin.center())
# self.add_label(text=br_name,
# layer="m2",
# offset=br_pin.center())
# # Add the data output names to the sense amp output # # Add the data output names to the sense amp output
# for i in range(self.word_size): # for i in range(self.word_size):
@ -962,24 +962,27 @@ class bank(design.design):
# offset=data_pin.center()) # offset=data_pin.center())
# Add labels on the decoder # Add labels on the decoder
for port in self.write_ports: # for port in self.write_ports:
for i in range(self.word_size): # for i in range(self.word_size):
data_name = "dec_out_{}".format(i) # data_name = "dec_out_{}".format(i)
pin_name = "in_{}".format(i) # pin_name = "in_{}".format(i)
data_pin = self.wordline_driver_inst[port].get_pin(pin_name) # data_pin = self.wordline_driver_inst[port].get_pin(pin_name)
self.add_label(text=data_name, # self.add_label(text=data_name,
layer="m1", # layer="m1",
offset=data_pin.center()) # offset=data_pin.center())
def route_unused_wordlines(self): def route_unused_wordlines(self):
""" Connect the unused RBL and dummy wordlines to gnd """ """ Connect the unused RBL and dummy wordlines to gnd """
gnd_wl_names = [] gnd_wl_names = []
# Connect unused RBL WL to gnd # Connect unused RBL WL to gnd
array_rbl_names = set([x for x in self.bitcell_array.get_all_wordline_names() if x.startswith("rbl")]) # All RBL WL names
dummy_rbl_names = set([x for x in self.bitcell_array.get_all_wordline_names() if x.startswith("dummy")]) array_rbl_names = set(self.bitcell_array.get_rbl_wordline_names())
rbl_wl_names = set([self.bitcell_array.get_rbl_wordline_names(x) for x in self.all_ports]) dummy_rbl_names = set(self.bitcell_array.get_dummy_wordline_names())
# List of used RBL WL names
rbl_wl_names = set()
for port in self.all_ports:
rbl_wl_names.add(self.bitcell_array.get_rbl_wordline_names(port)[port])
gnd_wl_names = list((array_rbl_names - rbl_wl_names) | dummy_rbl_names) gnd_wl_names = list((array_rbl_names - rbl_wl_names) | dummy_rbl_names)
for wl_name in gnd_wl_names: for wl_name in gnd_wl_names:
@ -1012,7 +1015,7 @@ class bank(design.design):
rbl_wl_name = self.bitcell_array.get_rbl_wordline_names(port) rbl_wl_name = self.bitcell_array.get_rbl_wordline_names(port)
connection.append((self.prefix + "wl_en{}".format(port), connection.append((self.prefix + "wl_en{}".format(port),
self.bitcell_array_inst.get_pin(rbl_wl_name))) self.bitcell_array_inst.get_pin(rbl_wl_name[port])))
if port in self.write_ports: if port in self.write_ports:
connection.append((self.prefix + "w_en{}".format(port), connection.append((self.prefix + "w_en{}".format(port),

View File

@ -31,7 +31,7 @@ class bitcell_base_array(design.design):
self.create_all_wordline_names() self.create_all_wordline_names()
def get_all_bitline_names(self, prefix=""): def get_all_bitline_names(self, prefix=""):
return [prefix + x for x in self.bitline_names] return [prefix + x for x in self.all_bitline_names]
def create_all_bitline_names(self): def create_all_bitline_names(self):
self.bitline_names = [[] for port in self.all_ports] self.bitline_names = [[] for port in self.all_ports]
@ -40,10 +40,10 @@ class bitcell_base_array(design.design):
self.bitline_names[port].extend(["bl_{0}_{1}".format(port, col), self.bitline_names[port].extend(["bl_{0}_{1}".format(port, col),
"br_{0}_{1}".format(port, col)]) "br_{0}_{1}".format(port, col)])
# Make a flat list too # Make a flat list too
self.all_bitline_names = [x for sl in self.bitline_names for x in sl] self.all_bitline_names = [x for sl in zip(*self.bitline_names) for x in sl]
def get_all_wordline_names(self, prefix=""): def get_all_wordline_names(self, prefix=""):
return [prefix + x for x in self.wordline_names] return [prefix + x for x in self.all_wordline_names]
def create_all_wordline_names(self): def create_all_wordline_names(self):
self.wordline_names = [[] for port in self.all_ports] self.wordline_names = [[] for port in self.all_ports]
@ -76,8 +76,8 @@ class bitcell_base_array(design.design):
""" Creates a list of connections in the bitcell, """ Creates a list of connections in the bitcell,
indexed by column and row, for instance use in bitcell_array """ indexed by column and row, for instance use in bitcell_array """
bitcell_pins = [] bitcell_pins = []
bitcell_pins.extend([x for x in self.all_bitline_names if x.endswith("_{0}".format(col))]) for port in self.all_ports:
# wordlines bitcell_pins.extend([x for x in self.get_bitline_names(port) if x.endswith("_{0}".format(col))])
bitcell_pins.extend([x for x in self.all_wordline_names if x.endswith("_{0}".format(row))]) bitcell_pins.extend([x for x in self.all_wordline_names if x.endswith("_{0}".format(row))])
bitcell_pins.append("vdd") bitcell_pins.append("vdd")
bitcell_pins.append("gnd") bitcell_pins.append("gnd")

View File

@ -70,7 +70,6 @@ class global_bitcell_array(design.design):
self.add_mod(la) self.add_mod(la)
self.local_mods.append(la) self.local_mods.append(la)
import pdb; pdb.set_trace()
def add_pins(self): def add_pins(self):
return return

View File

@ -110,7 +110,6 @@ class local_bitcell_array(bitcell_base_array.bitcell_base_array):
self.all_array_wordline_inputs = [x + "i" if x not in self.gnd_wl_names else "gnd" for x in self.bitcell_array.get_wordline_names()] self.all_array_wordline_inputs = [x + "i" if x not in self.gnd_wl_names else "gnd" for x in self.bitcell_array.get_wordline_names()]
self.bitline_names = self.bitcell_array.bitline_names self.bitline_names = self.bitcell_array.bitline_names
import pdb; pdb.set_trace()
# Arrays are always: # Arrays are always:
# word lines (bottom to top) # word lines (bottom to top)

View File

@ -53,18 +53,10 @@ class port_data(design.design):
return self.precharge.get_br_names() return self.precharge.get_br_names()
def get_bl_name(self, port=0): def get_bl_name(self, port=0):
bl_name = "bl" return "bl_{}".format(port)
if len(self.all_ports) == 1:
return bl_name
else:
return bl_name + "{}".format(port)
def get_br_name(self, port=0): def get_br_name(self, port=0):
br_name = "br" return "br_{}".format(port)
if len(self.all_ports) == 1:
return br_name
else:
return br_name + "{}".format(port)
def create_netlist(self): def create_netlist(self):
self.precompute_constants() self.precompute_constants()
@ -110,15 +102,11 @@ class port_data(design.design):
self.add_pin("rbl_bl", "INOUT") self.add_pin("rbl_bl", "INOUT")
self.add_pin("rbl_br", "INOUT") self.add_pin("rbl_br", "INOUT")
for bit in range(self.num_cols): for bit in range(self.num_cols):
bl_name = self.get_bl_name(self.port) self.add_pin("bl_{0}".format(bit), "INOUT")
br_name = self.get_br_name(self.port) self.add_pin("br_{0}".format(bit), "INOUT")
self.add_pin("{0}_{1}".format(bl_name, bit), "INOUT")
self.add_pin("{0}_{1}".format(br_name, bit), "INOUT")
for bit in range(self.num_spare_cols): for bit in range(self.num_spare_cols):
bl_name = self.get_bl_name(self.port) self.add_pin("sparebl_{0}".format(bit), "INOUT")
br_name = self.get_br_name(self.port) self.add_pin("sparebr_{0}".format(bit), "INOUT")
self.add_pin("spare{0}_{1}".format(bl_name, bit), "INOUT")
self.add_pin("spare{0}_{1}".format(br_name, bit), "INOUT")
if self.port in self.read_ports: if self.port in self.read_ports:
for bit in range(self.word_size + self.num_spare_cols): for bit in range(self.word_size + self.num_spare_cols):
@ -274,21 +262,18 @@ class port_data(design.design):
self.precharge_array_inst = self.add_inst(name="precharge_array{}".format(self.port), self.precharge_array_inst = self.add_inst(name="precharge_array{}".format(self.port),
mod=self.precharge_array) mod=self.precharge_array)
bl_name = self.get_bl_name(self.port)
br_name = self.get_br_name(self.port)
temp = [] temp = []
# Use left BLs for RBL # Use left BLs for RBL
if self.port==0: if self.port==0:
temp.append("rbl_bl") temp.append("rbl_bl")
temp.append("rbl_br") temp.append("rbl_br")
for bit in range(self.num_cols): for bit in range(self.num_cols):
temp.append("{0}_{1}".format(bl_name, bit)) temp.append("bl_{0}".format(bit))
temp.append("{0}_{1}".format(br_name, bit)) temp.append("br_{0}".format(bit))
for bit in range(self.num_spare_cols): for bit in range(self.num_spare_cols):
temp.append("spare{0}_{1}".format(bl_name, bit)) temp.append("sparebl_{0}".format(bit))
temp.append("spare{0}_{1}".format(br_name, bit)) temp.append("sparebr_{0}".format(bit))
# Use right BLs for RBL # Use right BLs for RBL
if self.port==1: if self.port==1:
@ -308,17 +293,15 @@ class port_data(design.design):
self.column_mux_array_inst = self.add_inst(name="column_mux_array{}".format(self.port), self.column_mux_array_inst = self.add_inst(name="column_mux_array{}".format(self.port),
mod=self.column_mux_array) mod=self.column_mux_array)
bl_name = self.get_bl_name(self.port)
br_name = self.get_br_name(self.port)
temp = [] temp = []
for col in range(self.num_cols): for col in range(self.num_cols):
temp.append("{0}_{1}".format(bl_name, col)) temp.append("bl_{0}".format(col))
temp.append("{0}_{1}".format(br_name, col)) temp.append("br_{0}".format(col))
for word in range(self.words_per_row): for word in range(self.words_per_row):
temp.append("sel_{}".format(word)) temp.append("sel_{}".format(word))
for bit in range(self.word_size): for bit in range(self.word_size):
temp.append("{0}_out_{1}".format(bl_name, bit)) temp.append("bl_out_{0}".format(bit))
temp.append("{0}_out_{1}".format(br_name, bit)) temp.append("br_out_{0}".format(bit))
temp.append("gnd") temp.append("gnd")
self.connect_inst(temp) self.connect_inst(temp)
@ -335,22 +318,20 @@ class port_data(design.design):
self.sense_amp_array_inst = self.add_inst(name="sense_amp_array{}".format(self.port), self.sense_amp_array_inst = self.add_inst(name="sense_amp_array{}".format(self.port),
mod=self.sense_amp_array) mod=self.sense_amp_array)
bl_name = self.get_bl_name(self.port)
br_name = self.get_br_name(self.port)
temp = [] temp = []
for bit in range(self.word_size): for bit in range(self.word_size):
temp.append("dout_{}".format(bit)) temp.append("dout_{}".format(bit))
if self.words_per_row == 1: if self.words_per_row == 1:
temp.append("{0}_{1}".format(bl_name, bit)) temp.append("bl_{0}".format(bit))
temp.append("{0}_{1}".format(br_name, bit)) temp.append("br_{0}".format(bit))
else: else:
temp.append("{0}_out_{1}".format(bl_name, bit)) temp.append("bl_out_{0}".format(bit))
temp.append("{0}_out_{1}".format(br_name, bit)) temp.append("br_out_{0}".format(bit))
for bit in range(self.num_spare_cols): for bit in range(self.num_spare_cols):
temp.append("dout_{}".format(self.word_size + bit)) temp.append("dout_{}".format(self.word_size + bit))
temp.append("spare{0}_{1}".format(bl_name, bit)) temp.append("sparebl_{0}".format(bit))
temp.append("spare{0}_{1}".format(br_name, bit)) temp.append("sparebr_{0}".format(bit))
temp.append("s_en") temp.append("s_en")
temp.extend(["vdd", "gnd"]) temp.extend(["vdd", "gnd"])
@ -364,24 +345,21 @@ class port_data(design.design):
""" Creating Write Driver """ """ Creating Write Driver """
self.write_driver_array_inst = self.add_inst(name="write_driver_array{}".format(self.port), self.write_driver_array_inst = self.add_inst(name="write_driver_array{}".format(self.port),
mod=self.write_driver_array) mod=self.write_driver_array)
bl_name = self.get_bl_name(self.port)
br_name = self.get_br_name(self.port)
temp = [] temp = []
for bit in range(self.word_size + self.num_spare_cols): for bit in range(self.word_size + self.num_spare_cols):
temp.append("din_{}".format(bit)) temp.append("din_{}".format(bit))
for bit in range(self.word_size): for bit in range(self.word_size):
if (self.words_per_row == 1): if (self.words_per_row == 1):
temp.append("{0}_{1}".format(bl_name, bit)) temp.append("bl_{0}".format(bit))
temp.append("{0}_{1}".format(br_name, bit)) temp.append("br_{0}".format(bit))
else: else:
temp.append("{0}_out_{1}".format(bl_name, bit)) temp.append("bl_out_{0}".format(bit))
temp.append("{0}_out_{1}".format(br_name, bit)) temp.append("br_out_{0}".format(bit))
for bit in range(self.num_spare_cols): for bit in range(self.num_spare_cols):
temp.append("spare{0}_{1}".format(bl_name, bit)) temp.append("sparebl_{0}".format(bit))
temp.append("spare{0}_{1}".format(br_name, bit)) temp.append("sparebr_{0}".format(bit))
if self.write_size is not None: if self.write_size is not None:
for i in range(self.num_wmasks): for i in range(self.num_wmasks):

View File

@ -165,6 +165,8 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
def add_pins(self): def add_pins(self):
# Arrays are always: # Arrays are always:
# bitlines (column first then port order)
# word lines (row first then port order)
# dummy wordlines # dummy wordlines
# replica wordlines # replica wordlines
# regular wordlines (bottom to top) # regular wordlines (bottom to top)
@ -175,8 +177,8 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
# vdd # vdd
# gnd # gnd
self.add_wordline_pins()
self.add_bitline_pins() self.add_bitline_pins()
self.add_wordline_pins()
self.add_pin("vdd", "POWER") self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND") self.add_pin("gnd", "GROUND")
@ -193,7 +195,6 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
for port in self.all_ports: for port in self.all_ports:
bitline_names = ["dummy_{0}_{1}".format(x, loc) for x in self.row_cap_left.get_bitline_names(port)] bitline_names = ["dummy_{0}_{1}".format(x, loc) for x in self.row_cap_left.get_bitline_names(port)]
self.dummy_col_bitline_names[-1].extend(bitline_names) self.dummy_col_bitline_names[-1].extend(bitline_names)
self.add_pin_list(bitline_names, "INOUT")
self.all_dummy_col_bitline_names = [x for sl in self.dummy_col_bitline_names for x in sl] self.all_dummy_col_bitline_names = [x for sl in self.dummy_col_bitline_names for x in sl]
for port in range(self.add_left_rbl + self.add_right_rbl): for port in range(self.add_left_rbl + self.add_right_rbl):
@ -201,16 +202,22 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
right_names=["rbl_br_{0}_{1}".format(x, port) for x in self.all_ports] right_names=["rbl_br_{0}_{1}".format(x, port) for x in self.all_ports]
bitline_names = [x for t in zip(left_names, right_names) for x in t] bitline_names = [x for t in zip(left_names, right_names) for x in t]
self.rbl_bitline_names.append(bitline_names) self.rbl_bitline_names.append(bitline_names)
self.add_pin_list(bitline_names, "INOUT")
# Make a flat list too # Make a flat list too
self.all_rbl_bitline_names = [x for sl in self.rbl_bitline_names for x in sl] self.all_rbl_bitline_names = [x for sl in self.rbl_bitline_names for x in sl]
for port in self.all_ports: for port in self.all_ports:
bitline_names = self.bitcell_array.get_bitline_names(port) bitline_names = self.bitcell_array.get_bitline_names(port)
self.bitline_names.append(bitline_names) self.bitline_names.append(bitline_names)
self.add_pin_list(bitline_names, "INOUT")
# Make a flat list too # Make a flat list too
self.all_bitline_names = [x for sl in self.bitline_names for x in sl] self.all_bitline_names = [x for sl in zip(*self.bitline_names) for x in sl]
self.add_pin_list(self.dummy_col_bitline_names[0], "INOUT")
for port in range(self.add_left_rbl):
self.add_pin_list(self.rbl_bitline_names[port], "INOUT")
self.add_pin_list(self.all_bitline_names, "INOUT")
for port in range(self.add_left_rbl, self.add_left_rbl + self.add_right_rbl):
self.add_pin_list(self.rbl_bitline_names[port], "INOUT")
self.add_pin_list(self.dummy_col_bitline_names[1], "INOUT")
def add_wordline_pins(self): def add_wordline_pins(self):
@ -225,19 +232,16 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
for loc in ["bot", "top"]: for loc in ["bot", "top"]:
wordline_names = ["{0}_{1}".format(wl_name, loc) for wl_name in dummy_row_wordline_names] wordline_names = ["{0}_{1}".format(wl_name, loc) for wl_name in dummy_row_wordline_names]
self.dummy_row_wordline_names.append(wordline_names) self.dummy_row_wordline_names.append(wordline_names)
self.add_pin_list(wordline_names, "INPUT")
self.all_dummy_row_wordline_names = [x for sl in self.dummy_row_wordline_names for x in sl] self.all_dummy_row_wordline_names = [x for sl in self.dummy_row_wordline_names for x in sl]
for port in range(self.left_rbl + self.right_rbl): for port in range(self.left_rbl + self.right_rbl):
wordline_names=["rbl_wl_{0}_{1}".format(x, port) for x in self.all_ports] wordline_names=["rbl_wl_{0}_{1}".format(x, port) for x in self.all_ports]
self.rbl_wordline_names.append(wordline_names) self.rbl_wordline_names.append(wordline_names)
self.add_pin_list(wordline_names, "INPUT")
self.all_rbl_wordline_names = [x for sl in self.rbl_wordline_names for x in sl] self.all_rbl_wordline_names = [x for sl in self.rbl_wordline_names for x in sl]
for port in self.all_ports: for port in self.all_ports:
wordline_names = self.bitcell_array.get_wordline_names(port) wordline_names = self.bitcell_array.get_wordline_names(port)
self.wordline_names.append(wordline_names) self.wordline_names.append(wordline_names)
self.add_pin_list(wordline_names, "INPUT")
self.all_wordline_names = [x for sl in zip(*self.wordline_names) for x in sl] self.all_wordline_names = [x for sl in zip(*self.wordline_names) for x in sl]
# All wordlines including dummy and RBL # All wordlines including dummy and RBL
@ -250,6 +254,14 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
self.replica_array_wordline_names.extend(self.rbl_wordline_names[p]) self.replica_array_wordline_names.extend(self.rbl_wordline_names[p])
self.replica_array_wordline_names.extend(self.dummy_row_wordline_names[1]) self.replica_array_wordline_names.extend(self.dummy_row_wordline_names[1])
self.add_pin_list(self.dummy_row_wordline_names[0], "INPUT")
for port in range(self.left_rbl):
self.add_pin_list(self.rbl_wordline_names[port], "INPUT")
self.add_pin_list(self.all_wordline_names)
for port in range(self.left_rbl, self.left_rbl + self.right_rbl):
self.add_pin_list(self.rbl_wordline_names[port], "INPUT")
self.add_pin_list(self.dummy_row_wordline_names[1], "INPUT")
def create_instances(self): def create_instances(self):
""" Create the module instances used in this design """ """ Create the module instances used in this design """
@ -447,37 +459,39 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
Inactive will be set to gnd. Inactive will be set to gnd.
""" """
if port == None: if port == None:
temp = [] return self.all_rbl_wordline_names
for port in self.all_ports:
temp.extend(self.replica_wordline_names[port])
return temp
else: else:
wl_names = self.replica_wordline_names[port] return self.rbl_wordline_names[port]
return wl_names[port]
def get_rbl_bitline_names(self, port=None): def get_rbl_bitline_names(self, port=None):
""" Return the BL for the given RBL port """ """ Return the BL for the given RBL port """
if port == None: if port == None:
temp = [] return self.all_rbl_bitline_names
for port in self.all_ports:
temp.extend(self.replica_bitline_names[port])
return temp
else: else:
bl_names = self.replica_bitline_names[port] return self.rbl_bitline_names[port]
return bl_names[2 * port:2 * port + 2]
def get_wordline_names(self, port=None): def get_bitline_names(self, port=None):
""" Return the wordline names """ """ Return the BL for the given RBL port """
if port == None: if port == None:
return self.wordline_names return self.all_bitline_names
else: else:
wl_name = self.cell.get_all_wl_names()[port] return self.bitline_names[port]
temp = [x for x in self.wordline_names if wl_name in x]
return temp
def get_bitline_names(self): def get_dummy_wordline_names(self, port=None):
""" Return the bitline names """ """
return self.bitline_names Return the ACTIVE WL for the given dummy port.
"""
if port == None:
return self.all_dummy_row_wordline_names
else:
return self.dummy_row_wordline_names[port]
def get_dummy_bitline_names(self, port=None):
""" Return the BL for the given dummy port """
if port == None:
return self.all_dummy_col_bitline_names
else:
return self.dummy_col_bitline_names[port]
def analytical_power(self, corner, load): def analytical_power(self, corner, load):
"""Power of Bitcell array and bitline in nW.""" """Power of Bitcell array and bitline in nW."""

View File

@ -554,7 +554,7 @@ class sram_1bank(sram_base):
for port in self.all_ports: for port in self.all_ports:
# Only input (besides pins) is the replica bitline # Only input (besides pins) is the replica bitline
src_pin = self.control_logic_insts[port].get_pin("rbl_bl") src_pin = self.control_logic_insts[port].get_pin("rbl_bl")
dest_pin = self.bank_inst.get_pin("rbl_bl{}".format(port)) dest_pin = self.bank_inst.get_pin("rbl_bl_{0}_{0}".format(port))
self.add_wire(self.m2_stack[::-1], self.add_wire(self.m2_stack[::-1],
[src_pin.center(), vector(src_pin.cx(), dest_pin.cy()), dest_pin.rc()]) [src_pin.center(), vector(src_pin.cx(), dest_pin.cy()), dest_pin.rc()])
self.add_via_stack_center(from_layer=src_pin.layer, self.add_via_stack_center(from_layer=src_pin.layer,

View File

@ -346,7 +346,6 @@ class sram_base(design, verilog, lef):
temp.append("dout{0}[{1}]".format(port, bit)) temp.append("dout{0}[{1}]".format(port, bit))
for port in self.all_ports: for port in self.all_ports:
temp.append("rbl_bl{0}".format(port)) temp.append("rbl_bl{0}".format(port))
temp.append("rbl_br{0}".format(port))
for port in self.write_ports: for port in self.write_ports:
for bit in range(self.word_size + self.num_spare_cols): for bit in range(self.word_size + self.num_spare_cols):
temp.append("bank_din{0}[{1}]".format(port, bit)) temp.append("bank_din{0}[{1}]".format(port, bit))

View File

@ -15,7 +15,7 @@ from sram_factory import factory
import debug import debug
# @unittest.skip("SKIPPING 05_global_bitcell_array_test") @unittest.skip("SKIPPING 05_global_bitcell_array_test")
class global_bitcell_array_test(openram_test): class global_bitcell_array_test(openram_test):
def runTest(self): def runTest(self):

View File

@ -15,7 +15,7 @@ from sram_factory import factory
import debug import debug
#@unittest.skip("SKIPPING 05_local_bitcell_array_test") @unittest.skip("SKIPPING 05_local_bitcell_array_test")
class local_bitcell_array_1rw_1r_test(openram_test): class local_bitcell_array_1rw_1r_test(openram_test):
def runTest(self): def runTest(self):

View File

@ -15,7 +15,7 @@ from sram_factory import factory
import debug import debug
#@unittest.skip("SKIPPING 05_local_bitcell_array_test") @unittest.skip("SKIPPING 05_local_bitcell_array_test")
class local_bitcell_array_test(openram_test): class local_bitcell_array_test(openram_test):
def runTest(self): def runTest(self):