mirror of https://github.com/VLSIDA/OpenRAM.git
Port name maps between bank and replica array working.
This commit is contained in:
parent
2271946eef
commit
e550d6ff10
|
|
@ -42,22 +42,22 @@ class bitcell(design.design):
|
|||
cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file.
|
||||
return logical_effort.logical_effort('bitline', size, cin, load, parasitic_delay, False)
|
||||
|
||||
def list_all_wl_names(self):
|
||||
def get_all_wl_names(self):
|
||||
""" Creates a list of all wordline pin names """
|
||||
row_pins = ["wl"]
|
||||
return row_pins
|
||||
|
||||
def list_all_bitline_names(self):
|
||||
def get_all_bitline_names(self):
|
||||
""" Creates a list of all bitline pin names (both bl and br) """
|
||||
column_pins = ["bl", "br"]
|
||||
return column_pins
|
||||
|
||||
def list_all_bl_names(self):
|
||||
def get_all_bl_names(self):
|
||||
""" Creates a list of all bl pins names """
|
||||
column_pins = ["bl"]
|
||||
return column_pins
|
||||
|
||||
def list_all_br_names(self):
|
||||
def get_all_br_names(self):
|
||||
""" Creates a list of all br pins names """
|
||||
column_pins = ["br"]
|
||||
return column_pins
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class bitcell_1rw_1r(design.design):
|
|||
read_port_load = 0.5 #min size NMOS gate load
|
||||
return logical_effort.logical_effort('bitline', size, cin, load+read_port_load, parasitic_delay, False)
|
||||
|
||||
def list_bitcell_pins(self, col, row):
|
||||
def get_bitcell_pins(self, col, row):
|
||||
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
|
||||
bitcell_pins = ["bl0_{0}".format(col),
|
||||
"br0_{0}".format(col),
|
||||
|
|
@ -55,42 +55,42 @@ class bitcell_1rw_1r(design.design):
|
|||
"gnd"]
|
||||
return bitcell_pins
|
||||
|
||||
def list_all_wl_names(self):
|
||||
def get_all_wl_names(self):
|
||||
""" Creates a list of all wordline pin names """
|
||||
row_pins = ["wl0", "wl1"]
|
||||
return row_pins
|
||||
|
||||
def list_all_bitline_names(self):
|
||||
def get_all_bitline_names(self):
|
||||
""" Creates a list of all bitline pin names (both bl and br) """
|
||||
column_pins = ["bl0", "br0", "bl1", "br1"]
|
||||
return column_pins
|
||||
|
||||
def list_all_bl_names(self):
|
||||
def get_all_bl_names(self):
|
||||
""" Creates a list of all bl pins names """
|
||||
column_pins = ["bl0", "bl1"]
|
||||
return column_pins
|
||||
|
||||
def list_all_br_names(self):
|
||||
def get_all_br_names(self):
|
||||
""" Creates a list of all br pins names """
|
||||
column_pins = ["br0", "br1"]
|
||||
return column_pins
|
||||
|
||||
def list_read_bl_names(self):
|
||||
def get_read_bl_names(self):
|
||||
""" Creates a list of bl pin names associated with read ports """
|
||||
column_pins = ["bl0", "bl1"]
|
||||
return column_pins
|
||||
|
||||
def list_read_br_names(self):
|
||||
def get_read_br_names(self):
|
||||
""" Creates a list of br pin names associated with read ports """
|
||||
column_pins = ["br0", "br1"]
|
||||
return column_pins
|
||||
|
||||
def list_write_bl_names(self):
|
||||
def get_write_bl_names(self):
|
||||
""" Creates a list of bl pin names associated with write ports """
|
||||
column_pins = ["bl0"]
|
||||
return column_pins
|
||||
|
||||
def list_write_br_names(self):
|
||||
def get_write_br_names(self):
|
||||
""" Creates a list of br pin names asscociated with write ports"""
|
||||
column_pins = ["br0"]
|
||||
return column_pins
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class bitcell_1w_1r(design.design):
|
|||
read_port_load = 0.5 #min size NMOS gate load
|
||||
return logical_effort.logical_effort('bitline', size, cin, load+read_port_load, parasitic_delay, False)
|
||||
|
||||
def list_bitcell_pins(self, col, row):
|
||||
def get_bitcell_pins(self, col, row):
|
||||
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
|
||||
bitcell_pins = ["bl0_{0}".format(col),
|
||||
"br0_{0}".format(col),
|
||||
|
|
@ -55,42 +55,42 @@ class bitcell_1w_1r(design.design):
|
|||
"gnd"]
|
||||
return bitcell_pins
|
||||
|
||||
def list_all_wl_names(self):
|
||||
def get_all_wl_names(self):
|
||||
""" Creates a list of all wordline pin names """
|
||||
row_pins = ["wl0", "wl1"]
|
||||
return row_pins
|
||||
|
||||
def list_all_bitline_names(self):
|
||||
def get_all_bitline_names(self):
|
||||
""" Creates a list of all bitline pin names (both bl and br) """
|
||||
column_pins = ["bl0", "br0", "bl1", "br1"]
|
||||
return column_pins
|
||||
|
||||
def list_all_bl_names(self):
|
||||
def get_all_bl_names(self):
|
||||
""" Creates a list of all bl pins names """
|
||||
column_pins = ["bl0", "bl1"]
|
||||
return column_pins
|
||||
|
||||
def list_all_br_names(self):
|
||||
def get_all_br_names(self):
|
||||
""" Creates a list of all br pins names """
|
||||
column_pins = ["br0", "br1"]
|
||||
return column_pins
|
||||
|
||||
def list_read_bl_names(self):
|
||||
def get_read_bl_names(self):
|
||||
""" Creates a list of bl pin names associated with read ports """
|
||||
column_pins = ["bl0", "bl1"]
|
||||
return column_pins
|
||||
|
||||
def list_read_br_names(self):
|
||||
def get_read_br_names(self):
|
||||
""" Creates a list of br pin names associated with read ports """
|
||||
column_pins = ["br0", "br1"]
|
||||
return column_pins
|
||||
|
||||
def list_write_bl_names(self):
|
||||
def get_write_bl_names(self):
|
||||
""" Creates a list of bl pin names associated with write ports """
|
||||
column_pins = ["bl0"]
|
||||
return column_pins
|
||||
|
||||
def list_write_br_names(self):
|
||||
def get_write_br_names(self):
|
||||
""" Creates a list of br pin names asscociated with write ports"""
|
||||
column_pins = ["br0"]
|
||||
return column_pins
|
||||
|
|
|
|||
|
|
@ -851,7 +851,7 @@ class pbitcell(design.design):
|
|||
implant_type="n",
|
||||
well_type="n")
|
||||
|
||||
def list_bitcell_pins(self, col, row):
|
||||
def get_bitcell_pins(self, col, row):
|
||||
""" Creates a list of connections in the bitcell, indexed by column and row, for instance use in bitcell_array """
|
||||
bitcell_pins = []
|
||||
for port in range(self.total_ports):
|
||||
|
|
@ -863,12 +863,12 @@ class pbitcell(design.design):
|
|||
bitcell_pins.append("gnd")
|
||||
return bitcell_pins
|
||||
|
||||
def list_all_wl_names(self):
|
||||
def get_all_wl_names(self):
|
||||
""" Creates a list of all wordline pin names """
|
||||
wordline_names = self.rw_wl_names + self.w_wl_names + self.r_wl_names
|
||||
return wordline_names
|
||||
|
||||
def list_all_bitline_names(self):
|
||||
def get_all_bitline_names(self):
|
||||
""" Creates a list of all bitline pin names (both bl and br) """
|
||||
bitline_pins = []
|
||||
for port in range(self.total_ports):
|
||||
|
|
@ -876,12 +876,12 @@ class pbitcell(design.design):
|
|||
bitline_pins.append("br{0}".format(port))
|
||||
return bitline_pins
|
||||
|
||||
def list_all_bl_names(self):
|
||||
def get_all_bl_names(self):
|
||||
""" Creates a list of all bl pins names """
|
||||
bl_pins = self.rw_bl_names + self.w_bl_names + self.r_bl_names
|
||||
return bl_pins
|
||||
|
||||
def list_all_br_names(self):
|
||||
def get_all_br_names(self):
|
||||
""" Creates a list of all br pins names """
|
||||
br_pins = self.rw_br_names + self.w_br_names + self.r_br_names
|
||||
return br_pins
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ class bank(design.design):
|
|||
""" Route the rbl_bl and rbl_wl """
|
||||
|
||||
if self.port_data[port].has_rbl():
|
||||
bl_name = self.bitcell.get_bl_name(port)
|
||||
bl_pin = self.bitcell_array_inst.get_pin("rbl_{0}_{1}".format(bl_name,port))
|
||||
bl_pin_name = self.bitcell_array.get_rbl_bl_name(self.port_rbl_map[port])
|
||||
bl_pin = self.bitcell_array_inst.get_pin(bl_pin_name)
|
||||
self.add_layout_pin(text="rbl_bl{0}".format(port),
|
||||
layer=bl_pin.layer,
|
||||
offset=bl_pin.ll(),
|
||||
|
|
@ -342,10 +342,10 @@ class bank(design.design):
|
|||
|
||||
# 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.list_all_bl_names()
|
||||
self.br_names = self.bitcell.list_all_br_names()
|
||||
self.wl_names = self.bitcell.list_all_wl_names()
|
||||
self.bitline_names = self.bitcell.list_all_bitline_names()
|
||||
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 = []
|
||||
for port in self.all_ports:
|
||||
|
|
@ -363,26 +363,35 @@ class bank(design.design):
|
|||
|
||||
|
||||
# The number of replica lines depends on the port configuration
|
||||
rbl_num = [self.read_ports.count(p) for p in self.all_ports]
|
||||
if len(rbl_num)<2:
|
||||
rbl_num.append(0)
|
||||
self.num_rbl = sum(rbl_num)
|
||||
# The indices always start at 0
|
||||
self.rbl_indices = []
|
||||
rbl_counts = [self.read_ports.count(p) for p in self.all_ports]
|
||||
self.num_rbl = sum(rbl_counts)
|
||||
|
||||
# The replica array indices always start at 0, so this will map them to
|
||||
# the correct SRAM port
|
||||
# (e.g. if port 0 is w, then port 1 will use RBL 0 in replica bitcell array
|
||||
# because write ports don't use an RBL)
|
||||
self.port_rbl_map = {}
|
||||
index = 0
|
||||
for num in rbl_num:
|
||||
for (i,num) in enumerate(rbl_counts):
|
||||
if num>0:
|
||||
self.rbl_indices.append(index)
|
||||
self.port_rbl_map[i]=index
|
||||
index += 1
|
||||
else:
|
||||
self.rbl_indices.append(-1)
|
||||
|
||||
if len(rbl_counts)<2:
|
||||
rbl_counts.append(0)
|
||||
|
||||
|
||||
# Which bitcell port should be used in the RBL
|
||||
# For now (since only 2 ports), if port 0 is not a read port, skip it in the RBLs
|
||||
bitcell_ports=list(range(len(self.read_ports)))
|
||||
if 0 not in self.read_ports:
|
||||
bitcell_ports = [x+1 for x in bitcell_ports]
|
||||
|
||||
self.bitcell_array = factory.create(module_type="replica_bitcell_array",
|
||||
cols=self.num_cols,
|
||||
rows=self.num_rows,
|
||||
left_rbl=rbl_num[0],
|
||||
right_rbl=rbl_num[1])
|
||||
left_rbl=rbl_counts[0],
|
||||
right_rbl=rbl_counts[1],
|
||||
bitcell_ports=bitcell_ports)
|
||||
self.add_mod(self.bitcell_array)
|
||||
|
||||
|
||||
|
|
@ -402,14 +411,16 @@ class bank(design.design):
|
|||
for bitline in self.bitline_names:
|
||||
temp.append("{0}_{1}".format(bitline,col))
|
||||
for rbl in range(self.num_rbl):
|
||||
for bitline in self.bitline_names:
|
||||
temp.append("rbl_{0}_{1}".format(bitline,rbl))
|
||||
rbl_bl_name=self.bitcell_array.get_rbl_bl_name(rbl)
|
||||
temp.append(rbl_bl_name)
|
||||
rbl_br_name=self.bitcell_array.get_rbl_br_name(rbl)
|
||||
temp.append(rbl_br_name)
|
||||
for row in range(self.num_rows):
|
||||
for wordline in self.wl_names:
|
||||
temp.append("{0}_{1}".format(wordline,row))
|
||||
for rbl in range(self.num_rbl):
|
||||
for wordline in self.wl_names:
|
||||
temp.append("rbl_{0}_{1}".format(wordline,rbl))
|
||||
rbl_wl_name=self.bitcell_array.get_rbl_wl_name(rbl)
|
||||
temp.append(rbl_wl_name)
|
||||
temp.append("vdd")
|
||||
temp.append("gnd")
|
||||
self.connect_inst(temp)
|
||||
|
|
@ -430,8 +441,10 @@ class bank(design.design):
|
|||
|
||||
temp = []
|
||||
if self.port_data[port].has_rbl():
|
||||
temp.append("rbl_{0}_{1}".format(self.bl_names[port],self.rbl_indices[port]))
|
||||
temp.append("rbl_{0}_{1}".format(self.br_names[port],self.rbl_indices[port]))
|
||||
rbl_bl_name=self.bitcell_array.get_rbl_bl_name(self.port_rbl_map[port])
|
||||
rbl_br_name=self.bitcell_array.get_rbl_br_name(self.port_rbl_map[port])
|
||||
temp.append(rbl_bl_name)
|
||||
temp.append(rbl_br_name)
|
||||
for col in range(self.num_cols):
|
||||
temp.append("{0}_{1}".format(self.bl_names[port],col))
|
||||
temp.append("{0}_{1}".format(self.br_names[port],col))
|
||||
|
|
@ -695,8 +708,10 @@ class bank(design.design):
|
|||
|
||||
# Connect the replica bitlines
|
||||
if self.port_data[port].has_rbl():
|
||||
self.connect_bitline(inst1, inst2, "rbl_{0}_{1}".format(self.bitcell.get_bl_name(port),self.rbl_indices[port]), "rbl_bl")
|
||||
self.connect_bitline(inst1, inst2, "rbl_{0}_{1}".format(self.bitcell.get_br_name(port),self.rbl_indices[port]), "rbl_br")
|
||||
rbl_bl_name=self.bitcell_array.get_rbl_bl_name(self.port_rbl_map[port])
|
||||
rbl_br_name=self.bitcell_array.get_rbl_br_name(self.port_rbl_map[port])
|
||||
self.connect_bitline(inst1, inst2, rbl_bl_name, "rbl_bl")
|
||||
self.connect_bitline(inst1, inst2, rbl_br_name, "rbl_br")
|
||||
|
||||
|
||||
|
||||
|
|
@ -927,7 +942,8 @@ class bank(design.design):
|
|||
connection.append((self.prefix+"p_en_bar{}".format(port), self.port_data_inst[port].get_pin("p_en_bar").lc()))
|
||||
|
||||
if port in self.read_ports:
|
||||
connection.append((self.prefix+"rbl_wl{}".format(port), self.bitcell_array_inst.get_pin("rbl_{0}_{1}".format(self.bitcell.get_wl_name(port),port)).lc()))
|
||||
rbl_wl_name = self.bitcell_array.get_rbl_wl_name(self.port_rbl_map[port])
|
||||
connection.append((self.prefix+"rbl_wl{}".format(port), self.bitcell_array_inst.get_pin(rbl_wl_name).lc()))
|
||||
|
||||
if port in self.write_ports:
|
||||
connection.append((self.prefix+"w_en{}".format(port), self.port_data_inst[port].get_pin("w_en").lc()))
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ class bitcell_array(design.design):
|
|||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
row_list = self.cell.list_all_wl_names()
|
||||
column_list = self.cell.list_all_bitline_names()
|
||||
row_list = self.cell.get_all_wl_names()
|
||||
column_list = self.cell.get_all_bitline_names()
|
||||
for col in range(self.column_size):
|
||||
for cell_column in column_list:
|
||||
self.add_pin(cell_column+"_{0}".format(col))
|
||||
|
|
@ -89,16 +89,16 @@ class bitcell_array(design.design):
|
|||
self.cell = factory.create(module_type="bitcell")
|
||||
self.add_mod(self.cell)
|
||||
|
||||
def list_bitcell_pins(self, col, row):
|
||||
def get_bitcell_pins(self, col, row):
|
||||
""" Creates a list of connections in the bitcell,
|
||||
indexed by column and row, for instance use in bitcell_array """
|
||||
|
||||
bitcell_pins = []
|
||||
|
||||
pin_names = self.cell.list_all_bitline_names()
|
||||
pin_names = self.cell.get_all_bitline_names()
|
||||
for pin in pin_names:
|
||||
bitcell_pins.append(pin+"_{0}".format(col))
|
||||
pin_names = self.cell.list_all_wl_names()
|
||||
pin_names = self.cell.get_all_wl_names()
|
||||
for pin in pin_names:
|
||||
bitcell_pins.append(pin+"_{0}".format(row))
|
||||
bitcell_pins.append("vdd")
|
||||
|
|
@ -115,13 +115,13 @@ class bitcell_array(design.design):
|
|||
name = "bit_r{0}_c{1}".format(row, col)
|
||||
self.cell_inst[row,col]=self.add_inst(name=name,
|
||||
mod=self.cell)
|
||||
self.connect_inst(self.list_bitcell_pins(col, row))
|
||||
self.connect_inst(self.get_bitcell_pins(col, row))
|
||||
|
||||
def add_layout_pins(self):
|
||||
""" Add the layout pins """
|
||||
|
||||
row_list = self.cell.list_all_wl_names()
|
||||
column_list = self.cell.list_all_bitline_names()
|
||||
row_list = self.cell.get_all_wl_names()
|
||||
column_list = self.cell.get_all_bitline_names()
|
||||
|
||||
for col in range(self.column_size):
|
||||
for cell_column in column_list:
|
||||
|
|
@ -224,4 +224,4 @@ class bitcell_array(design.design):
|
|||
|
||||
def get_cell_name(self, inst_name, row, col):
|
||||
"""Gets the spice name of the target bitcell."""
|
||||
return inst_name+'.x'+self.cell_inst[row,col].name, self.cell_inst[row,col]
|
||||
return inst_name+'.x'+self.cell_inst[row,col].name, self.cell_inst[row,col]
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ class dummy_array(design.design):
|
|||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
row_list = self.cell.list_all_wl_names()
|
||||
column_list = self.cell.list_all_bitline_names()
|
||||
row_list = self.cell.get_all_wl_names()
|
||||
column_list = self.cell.get_all_bitline_names()
|
||||
for col in range(self.column_size):
|
||||
for cell_column in column_list:
|
||||
self.add_pin(cell_column+"_{0}".format(col))
|
||||
|
|
@ -84,16 +84,16 @@ class dummy_array(design.design):
|
|||
|
||||
self.cell = factory.create(module_type="bitcell")
|
||||
|
||||
def list_bitcell_pins(self, col, row):
|
||||
def get_bitcell_pins(self, col, row):
|
||||
""" Creates a list of connections in the bitcell,
|
||||
indexed by column and row, for instance use in bitcell_array """
|
||||
|
||||
bitcell_pins = []
|
||||
|
||||
pin_names = self.cell.list_all_bitline_names()
|
||||
pin_names = self.cell.get_all_bitline_names()
|
||||
for pin in pin_names:
|
||||
bitcell_pins.append(pin+"_{0}".format(col))
|
||||
pin_names = self.cell.list_all_wl_names()
|
||||
pin_names = self.cell.get_all_wl_names()
|
||||
for pin in pin_names:
|
||||
bitcell_pins.append(pin+"_{0}".format(row))
|
||||
bitcell_pins.append("vdd")
|
||||
|
|
@ -110,13 +110,13 @@ class dummy_array(design.design):
|
|||
name = "bit_r{0}_c{1}".format(row, col)
|
||||
self.cell_inst[row,col]=self.add_inst(name=name,
|
||||
mod=self.dummy_cell)
|
||||
self.connect_inst(self.list_bitcell_pins(col, row))
|
||||
self.connect_inst(self.get_bitcell_pins(col, row))
|
||||
|
||||
def add_layout_pins(self):
|
||||
""" Add the layout pins """
|
||||
|
||||
row_list = self.cell.list_all_wl_names()
|
||||
column_list = self.cell.list_all_bitline_names()
|
||||
row_list = self.cell.get_all_wl_names()
|
||||
column_list = self.cell.get_all_bitline_names()
|
||||
|
||||
for col in range(self.column_size):
|
||||
for cell_column in column_list:
|
||||
|
|
|
|||
|
|
@ -201,9 +201,9 @@ class port_data(design.design):
|
|||
|
||||
# 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.list_all_bl_names()
|
||||
self.br_names = self.bitcell.list_all_br_names()
|
||||
self.wl_names = self.bitcell.list_all_wl_names()
|
||||
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()
|
||||
|
||||
def create_precharge_array(self):
|
||||
""" Creating Precharge """
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@ import dummy_array
|
|||
|
||||
class replica_bitcell_array(design.design):
|
||||
"""
|
||||
Creates a bitcell arrow of cols x rows and then adds the replica and dummy columns
|
||||
and rows for one or two read ports. Replica columns are on the left and right, respectively.
|
||||
Creates a bitcell arrow of cols x rows and then adds the replica
|
||||
and dummy columns and rows. Replica columns are on the left and
|
||||
right, respectively and connected to the given bitcell ports.
|
||||
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).
|
||||
Requires a regular bitcell array, replica bitcell, and dummy
|
||||
bitcell (Bl/BR disconnected).
|
||||
"""
|
||||
def __init__(self, cols, rows, left_rbl, right_rbl, name):
|
||||
def __init__(self, cols, rows, left_rbl, right_rbl, bitcell_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))
|
||||
|
|
@ -31,8 +33,10 @@ class replica_bitcell_array(design.design):
|
|||
self.row_size = rows
|
||||
self.left_rbl = left_rbl
|
||||
self.right_rbl = right_rbl
|
||||
self.bitcell_ports = bitcell_ports
|
||||
|
||||
debug.check(left_rbl+right_rbl==len(self.read_ports),"Invalid number of RBLs for port configuration.")
|
||||
debug.check(left_rbl+right_rbl==len(self.bitcell_ports),"Bitcell ports must match total RBLs.")
|
||||
|
||||
# Two dummy rows/cols plus replica for each port
|
||||
self.extra_rows = 2 + left_rbl + right_rbl
|
||||
|
|
@ -122,15 +126,14 @@ class replica_bitcell_array(design.design):
|
|||
self.bitcell_array_bl_names = [x for x in self.bitcell_array.pins if x.startswith("b")]
|
||||
|
||||
# These are the non-indexed names
|
||||
self.dummy_cell_wl_names = ["dummy_"+x for x in self.cell.list_all_wl_names()]
|
||||
self.dummy_cell_bl_names = ["dummy_"+x for x in self.cell.list_all_bitline_names()]
|
||||
self.dummy_cell_wl_names = ["dummy_"+x for x in self.cell.get_all_wl_names()]
|
||||
self.dummy_cell_bl_names = ["dummy_"+x for x in self.cell.get_all_bitline_names()]
|
||||
self.dummy_row_bl_names = self.bitcell_array_bl_names
|
||||
|
||||
self.rbl_bl_names = []
|
||||
self.rbl_wl_names = []
|
||||
for port in range(self.left_rbl+self.right_rbl):
|
||||
self.rbl_bl_names.append("rbl_bl{}".format(port))
|
||||
self.rbl_wl_names.append("rbl_wl{}".format(port))
|
||||
# A dictionary because some ports may have nothing
|
||||
self.rbl_bl_names = {}
|
||||
self.rbl_br_names = {}
|
||||
self.rbl_wl_names = {}
|
||||
|
||||
# Create the full WL names include dummy, replica, and regular bit cells
|
||||
self.replica_col_wl_names = []
|
||||
|
|
@ -138,18 +141,18 @@ class replica_bitcell_array(design.design):
|
|||
# Left port WLs (one dummy for each port when we allow >1 port)
|
||||
for port in range(self.left_rbl):
|
||||
# Make names for all RBLs
|
||||
wl_names = ["rbl_{0}_{1}".format(x,port) for x in self.cell.list_all_wl_names()]
|
||||
# Rename the one we will use
|
||||
wl_names[port] = self.rbl_wl_names[port]
|
||||
wl_names=["rbl_{0}_{1}".format(self.cell.get_wl_name(x),port) for x in range(len(self.all_ports))]
|
||||
# Keep track of the pin that is the RBL
|
||||
self.rbl_wl_names[port]=wl_names[self.bitcell_ports[port]]
|
||||
self.replica_col_wl_names.extend(wl_names)
|
||||
# Regular WLs
|
||||
self.replica_col_wl_names.extend(self.bitcell_array_wl_names)
|
||||
# Right port WLs (one dummy for each port when we allow >1 port)
|
||||
for port in range(self.left_rbl,self.left_rbl+self.right_rbl):
|
||||
# Make names for all RBLs
|
||||
wl_names = ["rbl_{0}_{1}".format(x,port) for x in self.cell.list_all_wl_names()]
|
||||
# Rename the one we will use
|
||||
wl_names[port] = self.rbl_wl_names[port]
|
||||
wl_names=["rbl_{0}_{1}".format(self.cell.get_wl_name(x),port) for x in range(len(self.all_ports))]
|
||||
# Keep track of the pin that is the RBL
|
||||
self.rbl_wl_names[port]=wl_names[self.bitcell_ports[port]]
|
||||
self.replica_col_wl_names.extend(wl_names)
|
||||
self.replica_col_wl_names.extend(["{0}_top".format(x) for x in self.dummy_cell_wl_names])
|
||||
|
||||
|
|
@ -162,26 +165,33 @@ class replica_bitcell_array(design.design):
|
|||
self.replica_wl_names = {}
|
||||
# Array of all port bitline names
|
||||
for port in range(self.left_rbl+self.right_rbl):
|
||||
left_names = ["rbl_{0}_{1}".format(x,port) for x in self.cell.list_all_bl_names()]
|
||||
right_names = ["rbl_{0}_{1}".format(x,port) for x in self.cell.list_all_br_names()]
|
||||
left_names[port] = self.rbl_bl_names[port]
|
||||
left_names=["rbl_{0}_{1}".format(self.cell.get_bl_name(x),port) for x in range(len(self.all_ports))]
|
||||
right_names=["rbl_{0}_{1}".format(self.cell.get_br_name(x),port) for x in range(len(self.all_ports))]
|
||||
# Keep track of the left pins that are the RBL
|
||||
self.rbl_bl_names[port]=left_names[self.bitcell_ports[port]]
|
||||
self.rbl_br_names[port]=right_names[self.bitcell_ports[port]]
|
||||
# Interleave the left and right lists
|
||||
bl_names = [x for t in zip(left_names, right_names) for x in t]
|
||||
self.replica_bl_names[port] = bl_names
|
||||
|
||||
wl_names = ["rbl_{0}_{1}".format(x,port) for x in self.cell.list_all_wl_names()]
|
||||
wl_names[port] = "rbl_wl{}".format(port)
|
||||
wl_names = ["rbl_{0}_{1}".format(x,port) for x in self.cell.get_all_wl_names()]
|
||||
#wl_names[port] = "rbl_wl{}".format(port)
|
||||
self.replica_wl_names[port] = wl_names
|
||||
|
||||
|
||||
# External pins
|
||||
self.add_pin_list(self.bitcell_array_bl_names, "INOUT")
|
||||
for port in range(self.left_rbl+self.right_rbl):
|
||||
self.add_pin("rbl_bl{}".format(port),"INPUT")
|
||||
# Need to sort by port order since dictionary values may not be in order
|
||||
bl_names = [self.rbl_bl_names[x] for x in sorted(self.rbl_bl_names.keys())]
|
||||
br_names = [self.rbl_br_names[x] for x in sorted(self.rbl_br_names.keys())]
|
||||
for (bl_name,br_name) in zip(bl_names,br_names):
|
||||
self.add_pin(bl_name,"INPUT")
|
||||
self.add_pin(br_name,"INPUT")
|
||||
self.add_pin_list(self.bitcell_array_wl_names, "INPUT")
|
||||
for port in range(self.left_rbl+self.right_rbl):
|
||||
self.add_pin("rbl_wl{}".format(port),"OUTPUT")
|
||||
|
||||
# Need to sort by port order since dictionary values may not be in order
|
||||
wl_names = [self.rbl_wl_names[x] for x in sorted(self.rbl_wl_names.keys())]
|
||||
for pin_name in wl_names:
|
||||
self.add_pin(pin_name,"INPUT")
|
||||
self.add_pin("vdd", "POWER")
|
||||
self.add_pin("gnd", "GROUND")
|
||||
|
||||
|
|
@ -310,7 +320,7 @@ class replica_bitcell_array(design.design):
|
|||
# Replica wordlines
|
||||
for port in range(self.left_rbl+self.right_rbl):
|
||||
inst = self.replica_col_inst[port]
|
||||
for (pin_name,wl_name) in zip(self.cell.list_all_wl_names(),self.replica_wl_names[port]):
|
||||
for (pin_name,wl_name) in zip(self.cell.get_all_wl_names(),self.replica_wl_names[port]):
|
||||
# +1 for dummy row
|
||||
pin_bit = port+1
|
||||
# +row_size if above the array
|
||||
|
|
@ -319,7 +329,7 @@ class replica_bitcell_array(design.design):
|
|||
|
||||
pin_name += "_{}".format(pin_bit)
|
||||
pin = inst.get_pin(pin_name)
|
||||
if wl_name in self.rbl_wl_names:
|
||||
if wl_name in self.rbl_wl_names.values():
|
||||
self.add_layout_pin(text=wl_name,
|
||||
layer=pin.layer,
|
||||
offset=pin.ll().scale(0,1),
|
||||
|
|
@ -330,15 +340,17 @@ class replica_bitcell_array(design.design):
|
|||
# Replica bitlines
|
||||
for port in range(self.left_rbl+self.right_rbl):
|
||||
inst = self.replica_col_inst[port]
|
||||
for (pin_name, bl_name) in zip(self.cell.list_all_bitline_names(),self.replica_bl_names[port]):
|
||||
for (pin_name, bl_name) in zip(self.cell.get_all_bitline_names(),self.replica_bl_names[port]):
|
||||
pin = inst.get_pin(pin_name)
|
||||
name = "rbl_{0}_{1}".format(pin_name,port)
|
||||
if bl_name in self.rbl_bl_names:
|
||||
self.add_layout_pin(text=name,
|
||||
layer=pin.layer,
|
||||
offset=pin.ll().scale(1,0),
|
||||
width=pin.width(),
|
||||
height=self.height)
|
||||
if bl_name in self.rbl_bl_names or bl_name in self.rbl_br_names:
|
||||
name = bl_name
|
||||
else:
|
||||
name = "rbl_{0}_{1}".format(pin_name,port)
|
||||
self.add_layout_pin(text=name,
|
||||
layer=pin.layer,
|
||||
offset=pin.ll().scale(1,0),
|
||||
width=pin.width(),
|
||||
height=self.height)
|
||||
|
||||
|
||||
for pin_name in ["vdd","gnd"]:
|
||||
|
|
@ -350,7 +362,17 @@ class replica_bitcell_array(design.design):
|
|||
|
||||
|
||||
|
||||
def get_rbl_wl_name(self, port):
|
||||
""" Return the WL for the given RBL port """
|
||||
return self.rbl_wl_names[port]
|
||||
|
||||
def get_rbl_bl_name(self, port):
|
||||
""" Return the BL for the given RBL port """
|
||||
return self.rbl_bl_names[port]
|
||||
|
||||
def get_rbl_br_name(self, port):
|
||||
""" Return the BR for the given RBL port """
|
||||
return self.rbl_br_names[port]
|
||||
|
||||
def analytical_delay(self, corner, slew, load):
|
||||
"""Returns relative delay of the bitline in the bitcell array"""
|
||||
|
|
@ -358,7 +380,7 @@ class replica_bitcell_array(design.design):
|
|||
#The load being driven/drained is mostly the bitline but could include the sense amp or the column mux.
|
||||
#The load from the bitlines is due to the drain capacitances from all the other bitlines and wire parasitics.
|
||||
drain_load = logical_effort.convert_farad_to_relative_c(parameter['bitcell_drain_cap'])
|
||||
wire_unit_load = .05 * drain_load #Wires add 5% to this.
|
||||
wire_unit_load = 0.05 * drain_load #Wires add 5% to this.
|
||||
bitline_load = (drain_load+wire_unit_load)*self.row_size
|
||||
return [self.cell.analytical_delay(corner, slew, load+bitline_load)]
|
||||
|
||||
|
|
|
|||
|
|
@ -53,10 +53,10 @@ class replica_column(design.design):
|
|||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
column_list = self.cell.list_all_bitline_names()
|
||||
column_list = self.cell.get_all_bitline_names()
|
||||
for cell_column in column_list:
|
||||
self.add_pin("{0}_{1}".format(cell_column,0))
|
||||
row_list = self.cell.list_all_wl_names()
|
||||
row_list = self.cell.get_all_wl_names()
|
||||
for row in range(self.total_size):
|
||||
for cell_row in row_list:
|
||||
self.add_pin("{0}_{1}".format(cell_row,row))
|
||||
|
|
@ -88,7 +88,7 @@ class replica_column(design.design):
|
|||
else:
|
||||
self.cell_inst[row]=self.add_inst(name=name,
|
||||
mod=self.dummy_cell)
|
||||
self.connect_inst(self.list_bitcell_pins(0, row))
|
||||
self.connect_inst(self.get_bitcell_pins(0, row))
|
||||
|
||||
def place_instances(self):
|
||||
|
||||
|
|
@ -112,8 +112,8 @@ class replica_column(design.design):
|
|||
def add_layout_pins(self):
|
||||
""" Add the layout pins """
|
||||
|
||||
row_list = self.cell.list_all_wl_names()
|
||||
column_list = self.cell.list_all_bitline_names()
|
||||
row_list = self.cell.get_all_wl_names()
|
||||
column_list = self.cell.get_all_bitline_names()
|
||||
|
||||
for cell_column in column_list:
|
||||
bl_pin = self.cell_inst[0].get_pin(cell_column)
|
||||
|
|
@ -138,16 +138,16 @@ class replica_column(design.design):
|
|||
for pin_name in ["vdd", "gnd"]:
|
||||
self.copy_layout_pin(inst, pin_name)
|
||||
|
||||
def list_bitcell_pins(self, col, row):
|
||||
def get_bitcell_pins(self, col, row):
|
||||
""" Creates a list of connections in the bitcell,
|
||||
indexed by column and row, for instance use in bitcell_array """
|
||||
|
||||
bitcell_pins = []
|
||||
|
||||
pin_names = self.cell.list_all_bitline_names()
|
||||
pin_names = self.cell.get_all_bitline_names()
|
||||
for pin in pin_names:
|
||||
bitcell_pins.append(pin+"_{0}".format(col))
|
||||
pin_names = self.cell.list_all_wl_names()
|
||||
pin_names = self.cell.get_all_wl_names()
|
||||
for pin in pin_names:
|
||||
bitcell_pins.append(pin+"_{0}".format(row))
|
||||
bitcell_pins.append("vdd")
|
||||
|
|
|
|||
|
|
@ -26,7 +26,11 @@ class replica_bitcell_array_test(openram_test):
|
|||
OPTS.num_w_ports = 0
|
||||
|
||||
debug.info(2, "Testing 4x4 array for cell_1rw_1r")
|
||||
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=1)
|
||||
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=2, right_rbl=0, bitcell_ports=[0,1])
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(2, "Testing 4x4 array for cell_1rw_1r")
|
||||
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=1, bitcell_ports=[0,1])
|
||||
self.local_check(a)
|
||||
|
||||
globals.end_openram()
|
||||
|
|
|
|||
|
|
@ -19,13 +19,9 @@ class replica_bitcell_array_test(openram_test):
|
|||
globals.init_openram("config_{0}".format(OPTS.tech_name))
|
||||
|
||||
debug.info(2, "Testing 4x4 array for 6t_cell")
|
||||
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=0)
|
||||
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=0, bitcell_ports=[0])
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(2, "Testing 4x4 array for 6t_cell")
|
||||
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=0, right_rbl=1)
|
||||
self.local_check(a)
|
||||
|
||||
globals.end_openram()
|
||||
|
||||
# run the test from the command line
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class replica_bitcell_array_test(openram_test):
|
|||
OPTS.num_w_ports = 0
|
||||
|
||||
debug.info(2, "Testing 4x4 array for pbitcell")
|
||||
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=1)
|
||||
a = factory.create(module_type="replica_bitcell_array", cols=4, rows=4, left_rbl=1, right_rbl=1, bitcell_ports=[0,1])
|
||||
self.local_check(a)
|
||||
|
||||
globals.end_openram()
|
||||
|
|
|
|||
Loading…
Reference in New Issue