mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-08-29 17:39:02 +02:00
SRAM with RBL integration in array.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user