diff --git a/compiler/bitcells/bitcell.py b/compiler/bitcells/bitcell.py index f18bf700..96432cea 100644 --- a/compiler/bitcells/bitcell.py +++ b/compiler/bitcells/bitcell.py @@ -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 diff --git a/compiler/bitcells/bitcell_1rw_1r.py b/compiler/bitcells/bitcell_1rw_1r.py index 68619184..f627a4ac 100644 --- a/compiler/bitcells/bitcell_1rw_1r.py +++ b/compiler/bitcells/bitcell_1rw_1r.py @@ -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 diff --git a/compiler/bitcells/bitcell_1w_1r.py b/compiler/bitcells/bitcell_1w_1r.py index c58ceb9d..b36c38bf 100644 --- a/compiler/bitcells/bitcell_1w_1r.py +++ b/compiler/bitcells/bitcell_1w_1r.py @@ -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 diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py index 01306f7f..7ed748ec 100644 --- a/compiler/bitcells/pbitcell.py +++ b/compiler/bitcells/pbitcell.py @@ -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 diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index a9a47ec6..5c08df30 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -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())) diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index 293d3e08..4b8ac212 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -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] \ No newline at end of file + return inst_name+'.x'+self.cell_inst[row,col].name, self.cell_inst[row,col] diff --git a/compiler/modules/dummy_array.py b/compiler/modules/dummy_array.py index e175e732..10007106 100644 --- a/compiler/modules/dummy_array.py +++ b/compiler/modules/dummy_array.py @@ -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: diff --git a/compiler/modules/port_data.py b/compiler/modules/port_data.py index 89020a2b..0b93b66d 100644 --- a/compiler/modules/port_data.py +++ b/compiler/modules/port_data.py @@ -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 """ diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 12401301..ba92240e 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -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)] diff --git a/compiler/modules/replica_column.py b/compiler/modules/replica_column.py index 42903e7c..cf2a910a 100644 --- a/compiler/modules/replica_column.py +++ b/compiler/modules/replica_column.py @@ -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") diff --git a/compiler/tests/05_replica_bitcell_1rw_1r_array_test.py b/compiler/tests/05_replica_bitcell_1rw_1r_array_test.py index ddf6be60..bae7edde 100755 --- a/compiler/tests/05_replica_bitcell_1rw_1r_array_test.py +++ b/compiler/tests/05_replica_bitcell_1rw_1r_array_test.py @@ -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() diff --git a/compiler/tests/05_replica_bitcell_array_test.py b/compiler/tests/05_replica_bitcell_array_test.py index 00c14953..2b446758 100755 --- a/compiler/tests/05_replica_bitcell_array_test.py +++ b/compiler/tests/05_replica_bitcell_array_test.py @@ -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 diff --git a/compiler/tests/05_replica_pbitcell_array_test.py b/compiler/tests/05_replica_pbitcell_array_test.py index a31e392c..b7bce868 100755 --- a/compiler/tests/05_replica_pbitcell_array_test.py +++ b/compiler/tests/05_replica_pbitcell_array_test.py @@ -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()