mirror of https://github.com/VLSIDA/OpenRAM.git
Combine rbl_wl and wl_en. Size p_en_bar slower than wl_en.
This commit is contained in:
parent
ad35f8745e
commit
a2f81aeae4
|
|
@ -84,8 +84,6 @@ class bank(design.design):
|
|||
self.add_pin("dout{0}_{1}".format(port,bit),"OUTPUT")
|
||||
for port in self.read_ports:
|
||||
self.add_pin(self.bitcell_array.get_rbl_bl_name(self.port_rbl_map[port]),"OUTPUT")
|
||||
for port in self.read_ports:
|
||||
self.add_pin(self.bitcell_array.get_rbl_wl_name(self.port_rbl_map[port]),"INPUT")
|
||||
for port in self.write_ports:
|
||||
for bit in range(self.word_size):
|
||||
self.add_pin("din{0}_{1}".format(port,bit),"INPUT")
|
||||
|
|
@ -306,13 +304,13 @@ class bank(design.design):
|
|||
self.input_control_signals = []
|
||||
port_num = 0
|
||||
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), "rbl_wl{}".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)])
|
||||
port_num += 1
|
||||
for port in range(OPTS.num_w_ports):
|
||||
self.input_control_signals.append(["wl_en{}".format(port_num), "w_en{}".format(port_num), "p_en_bar{}".format(port_num)])
|
||||
port_num += 1
|
||||
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), "rbl_wl{}".format(port_num)])
|
||||
self.input_control_signals.append(["wl_en{}".format(port_num), "s_en{}".format(port_num), "p_en_bar{}".format(port_num)])
|
||||
port_num += 1
|
||||
|
||||
# Number of control lines in the bus for each port
|
||||
|
|
@ -422,9 +420,9 @@ class bank(design.design):
|
|||
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):
|
||||
rbl_wl_name=self.bitcell_array.get_rbl_wl_name(rbl)
|
||||
temp.append(rbl_wl_name)
|
||||
for port in self.all_ports:
|
||||
if self.port_data[port].has_rbl():
|
||||
temp.append("wl_en{0}".format(port))
|
||||
temp.append("vdd")
|
||||
temp.append("gnd")
|
||||
self.connect_inst(temp)
|
||||
|
|
@ -947,7 +945,7 @@ class bank(design.design):
|
|||
|
||||
if port in self.read_ports:
|
||||
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()))
|
||||
connection.append((self.prefix+"wl_en{}".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()))
|
||||
|
|
@ -967,10 +965,10 @@ class bank(design.design):
|
|||
control_signal = self.prefix+"wl_en{}".format(port)
|
||||
if port%2:
|
||||
pin_pos = self.port_address_inst[port].get_pin("wl_en").uc()
|
||||
mid_pos = pin_pos + vector(0,self.m2_gap) # to route down to the top of the bus
|
||||
mid_pos = pin_pos + vector(0,2*self.m2_gap) # to route down to the top of the bus
|
||||
else:
|
||||
pin_pos = self.port_address_inst[port].get_pin("wl_en").bc()
|
||||
mid_pos = pin_pos - vector(0,self.m2_gap) # to route down to the top of the bus
|
||||
mid_pos = pin_pos - vector(0,2*self.m2_gap) # to route down to the top of the bus
|
||||
control_x_offset = self.bus_xoffset[port][control_signal].x
|
||||
control_pos = vector(control_x_offset, mid_pos.y)
|
||||
self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos])
|
||||
|
|
|
|||
|
|
@ -101,20 +101,26 @@ class control_logic(design.design):
|
|||
self.add_mod(self.rbl_driver)
|
||||
|
||||
|
||||
# clk_buf drives a flop for every address and control bit
|
||||
# clk_buf drives a flop for every address
|
||||
addr_flops = math.log(self.num_words,2) + math.log(self.words_per_row,2)
|
||||
# plus data flops and control flops
|
||||
num_flops = addr_flops + self.word_size + self.num_control_signals
|
||||
# each flop internally has a FO 5 approximately
|
||||
# plus about 5 fanouts for the control logic
|
||||
# each flop internally has a FO 4 approximately
|
||||
clock_fanout = 4*(math.log(self.num_words,2) + math.log(self.words_per_row,2) \
|
||||
+ self.num_control_signals) + 5
|
||||
clock_fanout = 5*num_flops + 5
|
||||
self.clk_buf_driver = factory.create(module_type="pdriver",
|
||||
fanout=clock_fanout,
|
||||
height=dff_height)
|
||||
|
||||
self.add_mod(self.clk_buf_driver)
|
||||
|
||||
# We will use the maximum since this same value is used to size the wl_en
|
||||
# and the p_en_bar drivers
|
||||
max_fanout = max(self.num_rows,self.num_cols)
|
||||
|
||||
# wl_en drives every row in the bank
|
||||
self.wl_en_driver = factory.create(module_type="pdriver",
|
||||
fanout=self.num_rows,
|
||||
fanout=max_fanout,
|
||||
height=dff_height)
|
||||
self.add_mod(self.wl_en_driver)
|
||||
|
||||
|
|
@ -137,9 +143,11 @@ class control_logic(design.design):
|
|||
self.add_mod(self.inv)
|
||||
|
||||
# p_en_bar drives every column in the bitcell array
|
||||
# but it is sized the same as the wl_en driver with
|
||||
# prepended 3 inverter stages to guarantee it is slower and odd polarity
|
||||
driver_size_list = [1,1,1,*self.wl_en_driver.get_sizes()]
|
||||
self.p_en_bar_driver = factory.create(module_type="pdriver",
|
||||
neg_polarity=True,
|
||||
fanout=self.num_cols,
|
||||
size_list=driver_size_list,
|
||||
height=dff_height)
|
||||
self.add_mod(self.p_en_bar_driver)
|
||||
|
||||
|
|
@ -346,9 +354,9 @@ class control_logic(design.design):
|
|||
|
||||
# Outputs to the bank
|
||||
if self.port_type == "rw":
|
||||
self.output_list = ["rbl_wl", "s_en", "w_en"]
|
||||
self.output_list = ["s_en", "w_en"]
|
||||
elif self.port_type == "r":
|
||||
self.output_list = ["rbl_wl", "s_en"]
|
||||
self.output_list = ["s_en"]
|
||||
else:
|
||||
self.output_list = ["w_en"]
|
||||
self.output_list.append("p_en_bar")
|
||||
|
|
@ -376,7 +384,6 @@ class control_logic(design.design):
|
|||
if (self.port_type == "rw") or (self.port_type == "w"):
|
||||
self.create_wen_row()
|
||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||
self.create_rbl_row()
|
||||
self.create_sen_row()
|
||||
self.create_delay()
|
||||
self.create_pen_row()
|
||||
|
|
@ -410,9 +417,6 @@ class control_logic(design.design):
|
|||
height = self.w_en_gate_inst.uy()
|
||||
control_center_y = self.w_en_gate_inst.uy()
|
||||
row += 1
|
||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||
self.place_rbl_row(row)
|
||||
row += 1
|
||||
self.place_pen_row(row)
|
||||
row += 1
|
||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||
|
|
@ -441,7 +445,6 @@ class control_logic(design.design):
|
|||
if (self.port_type == "rw") or (self.port_type == "w"):
|
||||
self.route_wen()
|
||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||
self.route_rbl()
|
||||
self.route_sen()
|
||||
self.route_pen()
|
||||
self.route_clk_buf()
|
||||
|
|
@ -597,41 +600,14 @@ class control_logic(design.design):
|
|||
def route_wlen(self):
|
||||
wlen_map = zip(["A"], ["gated_clk_bar"])
|
||||
self.connect_vertical_bus(wlen_map, self.wl_en_inst, self.rail_offsets)
|
||||
|
||||
self.connect_output(self.wl_en_inst, "Z", "wl_en")
|
||||
|
||||
def create_rbl_row(self):
|
||||
|
||||
self.rbl_inst=self.add_inst(name="rbl_driver",
|
||||
mod=self.rbl_driver)
|
||||
# input: gated_clk_bar, output: rbl_wl
|
||||
self.connect_inst(["gated_clk_bar", "rbl_wl", "vdd", "gnd"])
|
||||
|
||||
def place_rbl_row(self,row):
|
||||
x_off = self.control_x_offset
|
||||
(y_off,mirror)=self.get_offset(row)
|
||||
|
||||
offset = vector(x_off, y_off)
|
||||
self.rbl_inst.place(offset, mirror)
|
||||
|
||||
self.row_end_inst.append(self.rbl_inst)
|
||||
|
||||
def route_rbl(self):
|
||||
""" Connect the logic for the rbl_in generation """
|
||||
|
||||
rbl_in_map = zip(["A"], ["gated_clk_bar"])
|
||||
self.connect_vertical_bus(rbl_in_map, self.rbl_inst, self.rail_offsets)
|
||||
self.connect_output(self.rbl_inst, "Z", "rbl_wl")
|
||||
|
||||
# Input from RBL goes to the delay line for futher delay
|
||||
self.copy_layout_pin(self.delay_inst, "in", "rbl_bl")
|
||||
|
||||
def create_pen_row(self):
|
||||
input_name = "gated_clk_buf"
|
||||
|
||||
# input: pre_p_en, output: p_en_bar
|
||||
# input: gated_clk_bar, output: p_en_bar
|
||||
self.p_en_bar_inst=self.add_inst(name="inv_p_en_bar",
|
||||
mod=self.p_en_bar_driver)
|
||||
self.connect_inst([input_name, "p_en_bar", "vdd", "gnd"])
|
||||
self.connect_inst(["gated_clk_buf", "p_en_bar", "vdd", "gnd"])
|
||||
|
||||
|
||||
def place_pen_row(self,row):
|
||||
|
|
@ -691,6 +667,10 @@ class control_logic(design.design):
|
|||
|
||||
self.connect_output(self.s_en_gate_inst, "Z", "s_en")
|
||||
|
||||
# Input from RBL goes to the delay line for futher delay
|
||||
self.copy_layout_pin(self.delay_inst, "in", "rbl_bl")
|
||||
|
||||
|
||||
|
||||
def create_wen_row(self):
|
||||
# input: we (or cs) output: w_en
|
||||
|
|
|
|||
|
|
@ -341,8 +341,6 @@ class sram_base(design, verilog, lef):
|
|||
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 bit in range(self.word_size):
|
||||
temp.append("BANK_DIN{0}[{1}]".format(port,bit))
|
||||
|
|
@ -506,9 +504,6 @@ class sram_base(design, verilog, lef):
|
|||
temp.append("rbl_bl{}".format(port))
|
||||
|
||||
# Ouputs
|
||||
if port in self.read_ports:
|
||||
temp.append("rbl_wl{}".format(port))
|
||||
|
||||
if port in self.read_ports:
|
||||
temp.append("s_en{}".format(port))
|
||||
if port in self.write_ports:
|
||||
|
|
@ -530,7 +525,10 @@ class sram_base(design, verilog, lef):
|
|||
in_pos = src_pin.rc()
|
||||
else:
|
||||
in_pos = src_pin.lc()
|
||||
out_pos = dest_pin.center()
|
||||
if src_pin.cy() < dest_pin.cy():
|
||||
out_pos = dest_pin.bc()
|
||||
else:
|
||||
out_pos = dest_pin.uc()
|
||||
|
||||
# move horizontal first
|
||||
self.add_wire(("metal3","via2","metal2"),[in_pos, vector(out_pos.x,in_pos.y),out_pos])
|
||||
|
|
|
|||
Loading…
Reference in New Issue