Functional tests working with new RBL.

This commit is contained in:
mrg 2019-07-12 08:42:36 -07:00
parent 0b13225913
commit 043018e8ba
18 changed files with 152 additions and 113 deletions

View File

@ -71,7 +71,12 @@ class bitcell(design.design):
"""Get bl name""" """Get bl name"""
debug.check(port==0,"One port for bitcell only.") debug.check(port==0,"One port for bitcell only.")
return "br" return "br"
def get_wl_name(self, port=0):
"""Get wl name"""
debug.check(port==0,"One port for bitcell only.")
return "wl"
def analytical_power(self, corner, load): def analytical_power(self, corner, load):
"""Bitcell power in nW. Only characterizes leakage.""" """Bitcell power in nW. Only characterizes leakage."""
from tech import spice from tech import spice

View File

@ -104,6 +104,11 @@ class bitcell_1rw_1r(design.design):
"""Get bl name by port""" """Get bl name by port"""
debug.check(port<2,"Two ports for bitcell_1rw_1r only.") debug.check(port<2,"Two ports for bitcell_1rw_1r only.")
return "br{}".format(port) return "br{}".format(port)
def get_wl_name(self, port=0):
"""Get wl name by port"""
debug.check(port<2,"Two ports for bitcell_1rw_1r only.")
return "wl{}".format(port)
def analytical_power(self, corner, load): def analytical_power(self, corner, load):
"""Bitcell power in nW. Only characterizes leakage.""" """Bitcell power in nW. Only characterizes leakage."""

View File

@ -103,6 +103,11 @@ class bitcell_1w_1r(design.design):
"""Get bl name by port""" """Get bl name by port"""
return "br{}".format(port) return "br{}".format(port)
def get_wl_name(self, port=0):
"""Get wl name by port"""
debug.check(port<2,"Two ports for bitcell_1rw_1r only.")
return "wl{}".format(port)
def analytical_power(self, corner, load): def analytical_power(self, corner, load):
"""Bitcell power in nW. Only characterizes leakage.""" """Bitcell power in nW. Only characterizes leakage."""
from tech import spice from tech import spice

View File

@ -902,7 +902,13 @@ class pbitcell(design.design):
def get_br_name(self, port=0): def get_br_name(self, port=0):
"""Get bl name by port""" """Get bl name by port"""
return "br{}".format(port) return "br{}".format(port)
def get_wl_name(self, port=0):
"""Get wl name by port"""
debug.check(port<2,"Two ports for bitcell_1rw_1r only.")
return "wl{}".format(port)
def analytical_delay(self, corner, slew, load=0, swing = 0.5): def analytical_delay(self, corner, slew, load=0, swing = 0.5):
parasitic_delay = 1 parasitic_delay = 1

View File

@ -78,6 +78,9 @@ class bank(design.design):
for port in self.read_ports: for port in self.read_ports:
for bit in range(self.word_size): for bit in range(self.word_size):
self.add_pin("dout{0}_{1}".format(port,bit),"OUT") self.add_pin("dout{0}_{1}".format(port,bit),"OUT")
self.add_pin("rbl_bl{0}_{0}".format(port),"OUT")
for port in self.read_ports:
self.add_pin("rbl_wl{0}_{0}".format(port),"IN")
for port in self.write_ports: for port in self.write_ports:
for bit in range(self.word_size): for bit in range(self.word_size):
self.add_pin("din{0}_{1}".format(port,bit),"IN") self.add_pin("din{0}_{1}".format(port,bit),"IN")
@ -108,6 +111,7 @@ class bank(design.design):
for port in self.all_ports: for port in self.all_ports:
self.route_bitlines(port) self.route_bitlines(port)
self.route_rbl(port)
self.route_port_address(port) self.route_port_address(port)
self.route_column_address_lines(port) self.route_column_address_lines(port)
self.route_control_lines(port) self.route_control_lines(port)
@ -116,6 +120,20 @@ class bank(design.design):
self.route_supplies() self.route_supplies()
def route_rbl(self,port):
""" 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))
self.add_layout_pin(text="rbl_bl{0}".format(port),
layer=bl_pin.layer,
offset=bl_pin.ll(),
height=bl_pin.height(),
width=bl_pin.width())
def route_bitlines(self, port): def route_bitlines(self, port):
""" Route the bitlines depending on the port type rw, w, or r. """ """ Route the bitlines depending on the port type rw, w, or r. """
@ -281,13 +299,13 @@ class bank(design.design):
self.input_control_signals = [] self.input_control_signals = []
port_num = 0 port_num = 0
for port in range(OPTS.num_rw_ports): for port in range(OPTS.num_rw_ports):
self.input_control_signals.append(["wl_en{}".format(port_num), "w_en{}".format(port_num), "s_en{}".format(port_num), "p_en_bar{}".format(port_num)]) self.input_control_signals.append(["wl_en{}".format(port_num), "w_en{}".format(port_num), "s_en{}".format(port_num), "p_en_bar{}".format(port_num), "rbl_wl{}".format(port_num)])
port_num += 1 port_num += 1
for port in range(OPTS.num_w_ports): for port in range(OPTS.num_w_ports):
self.input_control_signals.append(["wl_en{}".format(port_num), "w_en{}".format(port_num)]) self.input_control_signals.append(["wl_en{}".format(port_num), "w_en{}".format(port_num)])
port_num += 1 port_num += 1
for port in range(OPTS.num_r_ports): for port in range(OPTS.num_r_ports):
self.input_control_signals.append(["wl_en{}".format(port_num), "s_en{}".format(port_num), "p_en_bar{}".format(port_num)]) self.input_control_signals.append(["wl_en{}".format(port_num), "s_en{}".format(port_num), "p_en_bar{}".format(port_num), "rbl_wl{}".format(port_num)])
port_num += 1 port_num += 1
# Number of control lines in the bus for each port # Number of control lines in the bus for each port
@ -904,7 +922,10 @@ class bank(design.design):
connection = [] connection = []
if port in self.read_ports: if port in self.read_ports:
connection.append((self.prefix+"p_en_bar{}".format(port), self.port_data_inst[port].get_pin("p_en_bar").lc())) 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()))
if port in self.write_ports: if port in self.write_ports:
connection.append((self.prefix+"w_en{}".format(port), self.port_data_inst[port].get_pin("w_en").lc())) connection.append((self.prefix+"w_en{}".format(port), self.port_data_inst[port].get_pin("w_en").lc()))

View File

@ -39,7 +39,7 @@ class control_logic(design.design):
self.num_cols = word_size*words_per_row self.num_cols = word_size*words_per_row
self.num_words = num_rows*words_per_row self.num_words = num_rows*words_per_row
self.enable_delay_chain_resizing = True self.enable_delay_chain_resizing = False
self.inv_parasitic_delay = logical_effort.logical_effort.pinv self.inv_parasitic_delay = logical_effort.logical_effort.pinv
#Determines how much larger the sen delay should be. Accounts for possible error in model. #Determines how much larger the sen delay should be. Accounts for possible error in model.
@ -73,10 +73,8 @@ class control_logic(design.design):
def add_pins(self): def add_pins(self):
""" Add the pins to the control logic module. """ """ Add the pins to the control logic module. """
for pin in self.input_list + ["clk"]: self.add_pin_list(self.input_list + ["clk"] + self.rbl_list, "INPUT")
self.add_pin(pin,"INPUT") self.add_pin_list(self.output_list,"OUTPUT")
for pin in self.output_list:
self.add_pin(pin,"OUTPUT")
self.add_pin("vdd","POWER") self.add_pin("vdd","POWER")
self.add_pin("gnd","GROUND") self.add_pin("gnd","GROUND")
@ -139,46 +137,48 @@ class control_logic(design.design):
height=dff_height) height=dff_height)
self.add_mod(self.p_en_bar_driver) self.add_mod(self.p_en_bar_driver)
if (self.port_type == "rw") or (self.port_type == "r"): # if (self.port_type == "rw") or (self.port_type == "r"):
from importlib import reload # from importlib import reload
self.delay_chain_resized = False # self.delay_chain_resized = False
c = reload(__import__(OPTS.replica_bitline)) # c = reload(__import__(OPTS.replica_bitline))
replica_bitline = getattr(c, OPTS.replica_bitline) # replica_bitline = getattr(c, OPTS.replica_bitline)
bitcell_loads = int(math.ceil(self.num_rows * OPTS.rbl_delay_percentage)) # bitcell_loads = int(math.ceil(self.num_rows * OPTS.rbl_delay_percentage))
#Use a model to determine the delays with that heuristic # #Use a model to determine the delays with that heuristic
if OPTS.use_tech_delay_chain_size: #Use tech parameters if set. # if OPTS.use_tech_delay_chain_size: #Use tech parameters if set.
fanout_list = OPTS.delay_chain_stages*[OPTS.delay_chain_fanout_per_stage] # fanout_list = OPTS.delay_chain_stages*[OPTS.delay_chain_fanout_per_stage]
debug.info(1, "Using tech parameters to size delay chain: fanout_list={}".format(fanout_list)) # debug.info(1, "Using tech parameters to size delay chain: fanout_list={}".format(fanout_list))
self.replica_bitline = factory.create(module_type="replica_bitline", # self.replica_bitline = factory.create(module_type="replica_bitline",
delay_fanout_list=fanout_list, # delay_fanout_list=fanout_list,
bitcell_loads=bitcell_loads) # bitcell_loads=bitcell_loads)
if self.sram != None: #Calculate model value even for specified sizes # if self.sram != None: #Calculate model value even for specified sizes
self.set_sen_wl_delays() # self.set_sen_wl_delays()
else: #Otherwise, use a heuristic and/or model based sizing. # else: #Otherwise, use a heuristic and/or model based sizing.
#First use a heuristic # #First use a heuristic
delay_stages_heuristic, delay_fanout_heuristic = self.get_heuristic_delay_chain_size() # delay_stages_heuristic, delay_fanout_heuristic = self.get_heuristic_delay_chain_size()
self.replica_bitline = factory.create(module_type="replica_bitline", # self.replica_bitline = factory.create(module_type="replica_bitline",
delay_fanout_list=[delay_fanout_heuristic]*delay_stages_heuristic, # delay_fanout_list=[delay_fanout_heuristic]*delay_stages_heuristic,
bitcell_loads=bitcell_loads) # bitcell_loads=bitcell_loads)
#Resize if necessary, condition depends on resizing method # #Resize if necessary, condition depends on resizing method
if self.sram != None and self.enable_delay_chain_resizing and not self.does_sen_rise_fall_timing_match(): # if self.sram != None and self.enable_delay_chain_resizing and not self.does_sen_rise_fall_timing_match():
#This resizes to match fall and rise delays, can make the delay chain weird sizes. # #This resizes to match fall and rise delays, can make the delay chain weird sizes.
stage_list = self.get_dynamic_delay_fanout_list(delay_stages_heuristic, delay_fanout_heuristic) # stage_list = self.get_dynamic_delay_fanout_list(delay_stages_heuristic, delay_fanout_heuristic)
self.replica_bitline = factory.create(module_type="replica_bitline", # self.replica_bitline = factory.create(module_type="replica_bitline",
delay_fanout_list=stage_list, # delay_fanout_list=stage_list,
bitcell_loads=bitcell_loads) # bitcell_loads=bitcell_loads)
#This resizes based on total delay. # #This resizes based on total delay.
# delay_stages, delay_fanout = self.get_dynamic_delay_chain_size(delay_stages_heuristic, delay_fanout_heuristic) # # delay_stages, delay_fanout = self.get_dynamic_delay_chain_size(delay_stages_heuristic, delay_fanout_heuristic)
# self.replica_bitline = factory.create(module_type="replica_bitline", # # self.replica_bitline = factory.create(module_type="replica_bitline",
# delay_fanout_list=[delay_fanout]*delay_stages, # # delay_fanout_list=[delay_fanout]*delay_stages,
# bitcell_loads=bitcell_loads) # # bitcell_loads=bitcell_loads)
self.sen_delay_rise,self.sen_delay_fall = self.get_delays_to_sen() #get the new timing # self.sen_delay_rise,self.sen_delay_fall = self.get_delays_to_sen() #get the new timing
self.delay_chain_resized = True # self.delay_chain_resized = True
self.add_mod(self.replica_bitline) self.delay_chain=factory.create(module_type="delay_chain",
fanout_list = OPTS.delay_chain_stages*[OPTS.delay_chain_fanout_per_stage])
self.add_mod(self.delay_chain)
def get_heuristic_delay_chain_size(self): def get_heuristic_delay_chain_size(self):
"""Use a basic heuristic to determine the size of the delay chain used for the Sense Amp Enable """ """Use a basic heuristic to determine the size of the delay chain used for the Sense Amp Enable """
@ -312,8 +312,13 @@ class control_logic(design.design):
# List of input control signals # List of input control signals
if self.port_type == "rw": if self.port_type == "rw":
self.input_list = ["csb", "web"] self.input_list = ["csb", "web"]
self.rbl_list = ["rbl_bl"]
elif self.port_type == "r":
self.input_list = ["csb"]
self.rbl_list = ["rbl_bl"]
else: else:
self.input_list = ["csb"] self.input_list = ["csb"]
self.rbl_list = []
if self.port_type == "rw": if self.port_type == "rw":
self.dff_output_list = ["cs_bar", "cs", "we_bar", "we"] self.dff_output_list = ["cs_bar", "cs", "we_bar", "we"]
@ -332,9 +337,9 @@ class control_logic(design.design):
# Outputs to the bank # Outputs to the bank
if self.port_type == "rw": if self.port_type == "rw":
self.output_list = ["s_en", "w_en", "p_en_bar"] self.output_list = ["rbl_wl", "s_en", "w_en", "p_en_bar"]
elif self.port_type == "r": elif self.port_type == "r":
self.output_list = ["s_en", "p_en_bar"] self.output_list = ["rbl_wl", "s_en", "p_en_bar"]
else: else:
self.output_list = ["w_en"] self.output_list = ["w_en"]
self.output_list.append("wl_en") self.output_list.append("wl_en")
@ -361,11 +366,11 @@ class control_logic(design.design):
if (self.port_type == "rw") or (self.port_type == "w"): if (self.port_type == "rw") or (self.port_type == "w"):
self.create_wen_row() self.create_wen_row()
if self.port_type == "rw": if self.port_type == "rw":
self.create_rbl_in_row() self.create_rbl_row()
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
self.create_pen_row() self.create_pen_row()
self.create_sen_row() self.create_sen_row()
self.create_rbl() self.create_delay()
def place_instances(self): def place_instances(self):
@ -395,17 +400,16 @@ class control_logic(design.design):
height = self.w_en_inst.uy() height = self.w_en_inst.uy()
control_center_y = self.w_en_inst.uy() control_center_y = self.w_en_inst.uy()
row += 1 row += 1
if self.port_type == "rw":
self.place_rbl_in_row(row)
row += 1
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
self.place_rbl_row(row)
row += 1
self.place_pen_row(row) self.place_pen_row(row)
row += 1 row += 1
self.place_sen_row(row) self.place_sen_row(row)
row += 1 row += 1
self.place_rbl(row) self.place_delay(row)
height = self.rbl_inst.uy() height = self.delay_inst.uy()
control_center_y = self.rbl_inst.by() control_center_y = self.delay_inst.by()
# This offset is used for placement of the control logic in the SRAM level. # This offset is used for placement of the control logic in the SRAM level.
self.control_logic_center = vector(self.ctrl_dff_inst.rx(), control_center_y) self.control_logic_center = vector(self.ctrl_dff_inst.rx(), control_center_y)
@ -415,7 +419,7 @@ class control_logic(design.design):
# Max of modules or logic rows # Max of modules or logic rows
self.width = max([inst.rx() for inst in self.row_end_inst]) self.width = max([inst.rx() for inst in self.row_end_inst])
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
self.width = max(self.rbl_inst.rx() , self.width) self.width = max(self.delay_inst.rx() , self.width)
self.width += self.m2_pitch self.width += self.m2_pitch
def route_all(self): def route_all(self):
@ -426,7 +430,7 @@ class control_logic(design.design):
if (self.port_type == "rw") or (self.port_type == "w"): if (self.port_type == "rw") or (self.port_type == "w"):
self.route_wen() self.route_wen()
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
self.route_rbl_in() self.route_rbl()
self.route_pen() self.route_pen()
self.route_sen() self.route_sen()
self.route_clk_buf() self.route_clk_buf()
@ -435,24 +439,20 @@ class control_logic(design.design):
self.route_supply() self.route_supply()
def create_rbl(self): def create_delay(self):
""" Create the replica bitline """ """ Create the replica bitline """
if self.port_type == "r": self.delay_inst=self.add_inst(name="delay_chain",
input_name = "gated_clk_bar" mod=self.delay_chain)
else: self.connect_inst(["rbl_bl", "pre_s_en", "vdd", "gnd"])
input_name = "rbl_in"
self.rbl_inst=self.add_inst(name="replica_bitline",
mod=self.replica_bitline)
self.connect_inst([input_name, "pre_s_en", "vdd", "gnd"])
def place_rbl(self,row): def place_delay(self,row):
""" Place the replica bitline """ """ Place the replica bitline """
y_off = row * self.and2.height + 2*self.m1_pitch y_off = row * self.and2.height + 2*self.m1_pitch
# Add the RBL above the rows # Add the RBL above the rows
# Add to the right of the control rows and routing channel # Add to the right of the control rows and routing channel
offset = vector(0, y_off) offset = vector(0, y_off)
self.rbl_inst.place(offset) self.delay_inst.place(offset)
def create_clk_buf_row(self): def create_clk_buf_row(self):
@ -588,44 +588,41 @@ class control_logic(design.design):
self.connect_vertical_bus(wlen_map, self.wl_en_inst, self.rail_offsets) self.connect_vertical_bus(wlen_map, self.wl_en_inst, self.rail_offsets)
self.connect_output(self.wl_en_inst, "Z", "wl_en") self.connect_output(self.wl_en_inst, "Z", "wl_en")
def create_rbl_in_row(self): def create_rbl_row(self):
# input: gated_clk_bar, we_bar, output: rbl_in # input: gated_clk_bar, we_bar, output: rbl_in
self.rbl_in_inst=self.add_inst(name="and2_rbl_in", self.rbl_inst=self.add_inst(name="and2_rbl",
mod=self.and2) mod=self.and2)
self.connect_inst(["gated_clk_bar", "we_bar", "rbl_in", "vdd", "gnd"]) self.connect_inst(["gated_clk_bar", "we_bar", "rbl_wl", "vdd", "gnd"])
def place_rbl_in_row(self,row): def place_rbl_row(self,row):
x_off = self.control_x_offset x_off = self.control_x_offset
(y_off,mirror)=self.get_offset(row) (y_off,mirror)=self.get_offset(row)
offset = vector(x_off, y_off) offset = vector(x_off, y_off)
self.rbl_in_inst.place(offset, mirror) self.rbl_inst.place(offset, mirror)
self.row_end_inst.append(self.rbl_in_inst) self.row_end_inst.append(self.rbl_inst)
def route_rbl_in(self): def route_rbl(self):
""" Connect the logic for the rbl_in generation """ """ Connect the logic for the rbl_in generation """
if self.port_type == "rw": if self.port_type == "rw":
input_name = "we_bar" input_name = "we_bar"
# Connect the NAND gate inputs to the bus # Connect the NAND gate inputs to the bus
rbl_in_map = zip(["A", "B"], ["gated_clk_bar", "we_bar"]) rbl_in_map = zip(["A", "B"], ["gated_clk_bar", "we_bar"])
self.connect_vertical_bus(rbl_in_map, self.rbl_in_inst, self.rail_offsets) self.connect_vertical_bus(rbl_in_map, self.rbl_inst, self.rail_offsets)
# Connect the output of the precharge enable to the RBL input # Connect the output of the precharge enable to the RBL input
if self.port_type == "rw": #if self.port_type == "rw":
out_pos = self.rbl_in_inst.get_pin("Z").center() # out_pos = self.rbl_in_inst.get_pin("Z").center()
else: #else:
out_pos = vector(self.rail_offsets["gated_clk_bar"].x, self.rbl_inst.by()-3*self.m2_pitch) # out_pos = vector(self.rail_offsets["gated_clk_bar"].x, self.rbl_inst.by()-3*self.m2_pitch)
in_pos = self.rbl_inst.get_pin("en").center()
mid1 = vector(in_pos.x,out_pos.y) self.copy_layout_pin(self.rbl_inst, "Z", "rbl_wl")
self.add_wire(("metal3","via2","metal2"),[out_pos, mid1, in_pos])
self.add_via_center(layers=("metal1","via1","metal2"), self.copy_layout_pin(self.delay_inst, "in", "rbl_bl")
offset=out_pos)
self.add_via_center(layers=("metal2","via2","metal3"),
offset=out_pos)
def create_pen_row(self): def create_pen_row(self):
if self.port_type == "rw": if self.port_type == "rw":
@ -698,7 +695,7 @@ class control_logic(design.design):
def route_sen(self): def route_sen(self):
out_pos = self.rbl_inst.get_pin("out").bc() out_pos = self.delay_inst.get_pin("out").bc()
in_pos = self.s_en_inst.get_pin("A").lc() in_pos = self.s_en_inst.get_pin("A").lc()
mid1 = vector(out_pos.x,in_pos.y) mid1 = vector(out_pos.x,in_pos.y)
self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos]) self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos])
@ -817,8 +814,8 @@ class control_logic(design.design):
self.add_path("metal1", [row_loc, pin_loc]) self.add_path("metal1", [row_loc, pin_loc])
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
self.copy_layout_pin(self.rbl_inst,"gnd") self.copy_layout_pin(self.delay_inst,"gnd")
self.copy_layout_pin(self.rbl_inst,"vdd") self.copy_layout_pin(self.delay_inst,"vdd")
self.copy_layout_pin(self.ctrl_dff_inst,"gnd") self.copy_layout_pin(self.ctrl_dff_inst,"gnd")
self.copy_layout_pin(self.ctrl_dff_inst,"vdd") self.copy_layout_pin(self.ctrl_dff_inst,"vdd")
@ -844,7 +841,7 @@ class control_logic(design.design):
# height=pin.height(), # height=pin.height(),
# width=pin.width()) # width=pin.width())
pin=self.rbl_inst.get_pin("out") pin=self.delay_inst.get_pin("out")
self.add_label_pin(text="out", self.add_label_pin(text="out",
layer=pin.layer, layer=pin.layer,
offset=pin.ll(), offset=pin.ll(),

View File

@ -427,3 +427,8 @@ class replica_bitcell_array(design.design):
bitcell_wl_cin = self.cell.get_wl_cin() bitcell_wl_cin = self.cell.get_wl_cin()
total_cin = bitcell_wl_cin * self.column_size total_cin = bitcell_wl_cin * self.column_size
return total_cin return total_cin
def graph_exclude_bits(self, targ_row, targ_col):
"""Excludes bits in column from being added to graph except target"""
self.bitcell_array.graph_exclude_bits(targ_row, targ_col)

View File

@ -43,11 +43,11 @@ class options(optparse.Values):
################### ###################
# Optimization options # Optimization options
################### ###################
rbl_delay_percentage = .5 #Approximate percentage of delay compared to bitlines rbl_delay_percentage = 0.5 #Approximate percentage of delay compared to bitlines
# Allow manual adjustment of the delay chain over automatic # Allow manual adjustment of the delay chain over automatic
use_tech_delay_chain_size = False use_tech_delay_chain_size = False
delay_chain_stages = 4 delay_chain_stages = 5
delay_chain_fanout_per_stage = 3 delay_chain_fanout_per_stage = 3

View File

@ -243,6 +243,8 @@ class sram_1bank(sram_base):
# The clock gets routed separately and is not a part of the bank # The clock gets routed separately and is not a part of the bank
if "clk" in signal: if "clk" in signal:
continue continue
if signal.startswith("rbl"):
continue
src_pin = self.control_logic_insts[port].get_pin(signal) src_pin = self.control_logic_insts[port].get_pin(signal)
dest_pin = self.bank_inst.get_pin(signal+"{}".format(port)) dest_pin = self.bank_inst.get_pin(signal+"{}".format(port))
self.connect_rail_from_left_m2m3(src_pin, dest_pin) self.connect_rail_from_left_m2m3(src_pin, dest_pin)
@ -364,4 +366,4 @@ class sram_1bank(sram_base):
#Sanity check in case it was forgotten #Sanity check in case it was forgotten
if inst_name.find('x') != 0: if inst_name.find('x') != 0:
inst_name = 'x'+inst_name inst_name = 'x'+inst_name
return self.bank_inst.mod.get_cell_name(inst_name+'.x'+self.bank_inst.name, row, col) return self.bank_inst.mod.get_cell_name(inst_name+'.x'+self.bank_inst.name, row, col)

View File

@ -283,8 +283,7 @@ class sram_base(design, verilog, lef):
# Create the bank module (up to four are instantiated) # Create the bank module (up to four are instantiated)
from bank import bank from bank import bank
self.bank = bank(self.sram_config, self.bank = bank(self.sram_config,
name="bank", name="bank")
num_ports=len(self.all_ports))
self.add_mod(self.bank) self.add_mod(self.bank)
# Create bank decoder # Create bank decoder
@ -331,6 +330,10 @@ class sram_base(design, verilog, lef):
for port in self.read_ports: for port in self.read_ports:
for bit in range(self.word_size): for bit in range(self.word_size):
temp.append("DOUT{0}[{1}]".format(port,bit)) temp.append("DOUT{0}[{1}]".format(port,bit))
for port in self.read_ports:
temp.append("rbl_bl{0}".format(port))
for port in self.read_ports:
temp.append("rbl_wl{0}".format(port))
for port in self.write_ports: for port in self.write_ports:
for bit in range(self.word_size): for bit in range(self.word_size):
temp.append("BANK_DIN{0}[{1}]".format(port,bit)) temp.append("BANK_DIN{0}[{1}]".format(port,bit))
@ -465,8 +468,12 @@ class sram_base(design, verilog, lef):
if port in self.readwrite_ports: if port in self.readwrite_ports:
temp.append("web{}".format(port)) temp.append("web{}".format(port))
temp.append("clk{}".format(port)) temp.append("clk{}".format(port))
if port in self.read_ports:
temp.append("rbl_bl{}".format(port))
# Ouputs # Ouputs
if port in self.read_ports:
temp.append("rbl_wl{}".format(port))
if port in self.read_ports: if port in self.read_ports:
temp.append("s_en{}".format(port)) temp.append("s_en{}".format(port))
if port in self.write_ports: if port in self.write_ports:

View File

@ -53,8 +53,6 @@ class psram_1bank_2mux_1rw_1r_1w_func_test(openram_test):
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
f = functional(s.s, tempspice, corner) f = functional(s.s, tempspice, corner)
d = delay(s.s, tempspice, corner)
feasible_period = self.find_feasible_test_period(d, s.s, f.load, f.slew)
f.num_cycles = 10 f.num_cycles = 10
(fail, error) = f.run() (fail, error) = f.run()

View File

@ -53,8 +53,6 @@ class psram_1bank_4mux_func_test(openram_test):
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
f = functional(s.s, tempspice, corner) f = functional(s.s, tempspice, corner)
d = delay(s.s, tempspice, corner)
feasible_period = self.find_feasible_test_period(d, s.s, f.load, f.slew)
f.num_cycles = 10 f.num_cycles = 10
(fail, error) = f.run() (fail, error) = f.run()

View File

@ -53,8 +53,6 @@ class psram_1bank_8mux_func_test(openram_test):
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
f = functional(s.s, tempspice, corner) f = functional(s.s, tempspice, corner)
d = delay(s.s, tempspice, corner)
feasible_period = self.find_feasible_test_period(d, s.s, f.load, f.slew)
f.num_cycles = 10 f.num_cycles = 10
(fail, error) = f.run() (fail, error) = f.run()

View File

@ -53,8 +53,6 @@ class psram_1bank_nomux_func_test(openram_test):
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
f = functional(s.s, tempspice, corner) f = functional(s.s, tempspice, corner)
d = delay(s.s, tempspice, corner)
feasible_period = self.find_feasible_test_period(d, s.s, f.load, f.slew)
f.num_cycles = 10 f.num_cycles = 10
(fail, error) = f.run() (fail, error) = f.run()

View File

@ -45,11 +45,9 @@ class sram_1bank_2mux_func_test(openram_test):
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
f = functional(s.s, tempspice, corner) f = functional(s.s, tempspice, corner)
d = delay(s.s, tempspice, corner)
feasible_period = self.find_feasible_test_period(d, s.s, f.load, f.slew)
f.num_cycles = 10 f.num_cycles = 10
(fail, error) = f.run(feasible_period) (fail, error) = f.run()
self.assertTrue(fail,error) self.assertTrue(fail,error)
globals.end_openram() globals.end_openram()

View File

@ -45,8 +45,6 @@ class sram_1bank_4mux_func_test(openram_test):
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
f = functional(s.s, tempspice, corner) f = functional(s.s, tempspice, corner)
d = delay(s.s, tempspice, corner)
feasible_period = self.find_feasible_test_period(d, s.s, f.load, f.slew)
f.num_cycles = 10 f.num_cycles = 10
(fail, error) = f.run() (fail, error) = f.run()

View File

@ -48,8 +48,6 @@ class sram_1bank_8mux_func_test(openram_test):
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
f = functional(s.s, tempspice, corner) f = functional(s.s, tempspice, corner)
d = delay(s.s, tempspice, corner)
feasible_period = self.find_feasible_test_period(d, s.s, f.load, f.slew)
f.num_cycles = 10 f.num_cycles = 10
(fail, error) = f.run() (fail, error) = f.run()

View File

@ -61,7 +61,7 @@ class openram_test(unittest.TestCase):
self.fail("LVS mismatch: {}".format(a.name)) self.fail("LVS mismatch: {}".format(a.name))
# For debug... # For debug...
#import pdb; pdb.set_trace() import pdb; pdb.set_trace()
if OPTS.purge_temp: if OPTS.purge_temp:
self.cleanup() self.cleanup()