SRAM with RBL integration in array.

This commit is contained in:
mrg
2019-07-16 09:04:58 -07:00
parent 37c15937e2
commit bea07c2319
4 changed files with 109 additions and 79 deletions
+13 -9
View File
@@ -54,8 +54,8 @@ class bank(design.design):
def create_netlist(self):
self.compute_sizes()
self.add_pins()
self.add_modules()
self.add_pins() # Must create the replica bitcell array first
self.create_instances()
@@ -78,9 +78,10 @@ class bank(design.design):
for port in self.read_ports:
for bit in range(self.word_size):
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.read_ports:
self.add_pin(self.bitcell_array.get_rbl_bl_name(port),"OUT")
for port in self.read_ports:
self.add_pin(self.bitcell_array.get_rbl_wl_name(port),"IN")
for port in self.write_ports:
for bit in range(self.word_size):
self.add_pin("din{0}_{1}".format(port,bit),"IN")
@@ -247,7 +248,7 @@ class bank(design.design):
# LOWER RIGHT QUADRANT
# To the left of the bitcell array
x_offset = self.bitcell_array_right + self.port_address.width + self.m2_gap
x_offset = self.bitcell_array_right + self.port_address.width
self.port_address_offsets[port] = vector(x_offset,self.main_bitcell_array_bottom)
# UPPER RIGHT QUADRANT
@@ -684,11 +685,12 @@ class bank(design.design):
control_bus_length = self.max_y_offset - self.main_bitcell_array_top - 2*self.m1_pitch
control_bus_offset = vector(self.bitcell_array_right,
self.max_y_offset - control_bus_length)
# The bus for the right port is reversed so that the rbl_wl is closest to the array
self.bus_xoffset[1] = self.create_bus(layer="metal2",
pitch=self.m2_pitch,
offset=control_bus_offset,
names=self.control_signals[1],
names=list(reversed(self.control_signals[1])),
length=control_bus_length,
vertical=True,
make_pins=(self.num_banks==1))
@@ -950,13 +952,15 @@ class bank(design.design):
if port in self.read_ports:
connection.append((self.prefix+"s_en{}".format(port), self.port_data_inst[port].get_pin("s_en").lc()))
for (control_signal, pin_pos) in connection:
control_mid_pos = self.bus_xoffset[port][control_signal]
control_pos = vector(self.bus_xoffset[port][control_signal].x ,pin_pos.y)
self.add_path("metal1", [control_pos, pin_pos])
self.add_wire(("metal1","via1","metal2"), [control_mid_pos, control_pos, pin_pos])
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=control_pos)
# clk to wordline_driver
control_signal = self.prefix+"wl_en{}".format(port)
if port%2:
+39 -24
View File
@@ -95,6 +95,18 @@ class control_logic(design.design):
size=4,
height=dff_height)
self.add_mod(self.and2)
if self.port_type=="rw":
self.rbl_driver = factory.create(module_type="pand2",
size=self.num_cols,
height=dff_height)
self.add_mod(self.rbl_driver)
elif self.port_type=="r":
self.rbl_driver = factory.create(module_type="pbuf",
size=self.num_cols,
height=dff_height)
self.add_mod(self.rbl_driver)
# clk_buf drives a flop for every address and control bit
# plus about 5 fanouts for the control logic
@@ -131,12 +143,14 @@ class control_logic(design.design):
height=dff_height)
self.add_mod(self.inv)
# p_en_bar drives every column in the bicell array
# p_en_bar drives every column in the bitcell array
self.p_en_bar_driver = factory.create(module_type="pdriver",
neg_polarity=True,
fanout=self.num_cols,
height=dff_height)
self.add_mod(self.p_en_bar_driver)
# if (self.port_type == "rw") or (self.port_type == "r"):
# from importlib import reload
@@ -366,11 +380,13 @@ class control_logic(design.design):
self.create_wlen_row()
if (self.port_type == "rw") or (self.port_type == "w"):
self.create_wen_row()
if (self.port_type == "rw") or (self.port_type == "r"):
if (self.port_type == "rw") or (self.port_type == "r"):
self.create_rbl_row()
self.create_pen_row()
self.create_sen_row()
self.create_delay()
if (self.port_type == "rw") or (self.port_type == "r") or self.words_per_row>1:
self.create_pen_row()
def place_instances(self):
@@ -400,9 +416,10 @@ class control_logic(design.design):
height = self.w_en_inst.uy()
control_center_y = self.w_en_inst.uy()
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
if (self.port_type == "rw") or (self.port_type == "r") or self.words_per_row>1:
self.place_pen_row(row)
row += 1
self.place_sen_row(row)
@@ -431,8 +448,9 @@ class control_logic(design.design):
self.route_wen()
if (self.port_type == "rw") or (self.port_type == "r"):
self.route_rbl()
self.route_pen()
self.route_sen()
if (self.port_type == "rw") or (self.port_type == "r") or self.words_per_row>1:
self.route_pen()
self.route_clk_buf()
self.route_gated_clk_bar()
self.route_gated_clk_buf()
@@ -451,8 +469,8 @@ class control_logic(design.design):
# Add the RBL above the rows
# Add to the right of the control rows and routing channel
offset = vector(0, y_off)
self.delay_inst.place(offset)
offset = vector(self.delay_chain.width, y_off)
self.delay_inst.place(offset, mirror="MY")
def create_clk_buf_row(self):
@@ -589,11 +607,15 @@ class control_logic(design.design):
self.connect_output(self.wl_en_inst, "Z", "wl_en")
def create_rbl_row(self):
# input: gated_clk_bar, we_bar, output: rbl_in
self.rbl_inst=self.add_inst(name="and2_rbl",
mod=self.and2)
self.connect_inst(["gated_clk_bar", "we_bar", "rbl_wl", "vdd", "gnd"])
self.rbl_inst=self.add_inst(name="rbl_driver",
mod=self.rbl_driver)
if self.port_type == "rw":
# input: gated_clk_bar, we_bar, output: rbl_wl
self.connect_inst(["gated_clk_bar", "we_bar", "rbl_wl", "vdd", "gnd"])
elif self.port_type == "r":
# 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
@@ -608,20 +630,14 @@ class control_logic(design.design):
""" Connect the logic for the rbl_in generation """
if self.port_type == "rw":
input_name = "we_bar"
# Connect the NAND gate inputs to the bus
rbl_in_map = zip(["A", "B"], ["gated_clk_bar", "we_bar"])
self.connect_vertical_bus(rbl_in_map, self.rbl_inst, self.rail_offsets)
# Connect the output of the precharge enable to the RBL input
#if self.port_type == "rw":
# out_pos = self.rbl_in_inst.get_pin("Z").center()
#else:
# out_pos = vector(self.rail_offsets["gated_clk_bar"].x, self.rbl_inst.by()-3*self.m2_pitch)
self.copy_layout_pin(self.rbl_inst, "Z", "rbl_wl")
else:
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):
@@ -727,7 +743,6 @@ class control_logic(design.design):
self.row_end_inst.append(self.w_en_inst)
def route_wen(self):
if self.port_type == "rw":
input_name = "we"
else: