mirror of https://github.com/VLSIDA/OpenRAM.git
Changed routing to allow for 2 write port with write mask.
This commit is contained in:
parent
01bdea23ae
commit
dd67490823
|
|
@ -74,7 +74,9 @@ class bank(design.design):
|
|||
# Remember the bank center for further placement
|
||||
self.bank_array_ll = self.offset_all_coordinates().scale(-1,-1)
|
||||
self.bank_array_ur = self.bitcell_array_inst.ur()
|
||||
|
||||
self.bank_array_ul = self.bitcell_array_inst.ul()
|
||||
|
||||
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@ class port_data(design.design):
|
|||
|
||||
sram_config.set_local_config(self)
|
||||
self.port = port
|
||||
if self.write_size:
|
||||
if self.write_size is not None:
|
||||
self.num_wmasks = int(self.word_size/self.write_size)
|
||||
else:
|
||||
self.num_wmasks = 0
|
||||
|
||||
|
||||
if name == "":
|
||||
name = "port_data_{0}".format(self.port)
|
||||
design.design.__init__(self, name)
|
||||
|
|
@ -58,7 +58,7 @@ class port_data(design.design):
|
|||
|
||||
if self.write_driver_array:
|
||||
self.create_write_driver_array()
|
||||
if self.write_size:
|
||||
if self.write_size is not None:
|
||||
self.create_write_mask_and_array()
|
||||
else:
|
||||
self.write_mask_and_array_inst = None
|
||||
|
|
@ -70,9 +70,9 @@ class port_data(design.design):
|
|||
self.create_column_mux_array()
|
||||
else:
|
||||
self.column_mux_array_inst = None
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def create_layout(self):
|
||||
self.compute_instance_offsets()
|
||||
self.place_instances()
|
||||
|
|
@ -81,7 +81,7 @@ class port_data(design.design):
|
|||
|
||||
def add_pins(self):
|
||||
""" Adding pins for port address module"""
|
||||
|
||||
|
||||
self.add_pin("rbl_bl","INOUT")
|
||||
self.add_pin("rbl_br","INOUT")
|
||||
for bit in range(self.num_cols):
|
||||
|
|
@ -107,7 +107,7 @@ class port_data(design.design):
|
|||
self.add_pin("vdd","POWER")
|
||||
self.add_pin("gnd","GROUND")
|
||||
|
||||
|
||||
|
||||
def route_layout(self):
|
||||
""" Create routing among the modules """
|
||||
self.route_data_lines()
|
||||
|
|
@ -118,15 +118,15 @@ class port_data(design.design):
|
|||
""" Add the pins """
|
||||
self.route_bitline_pins()
|
||||
self.route_control_pins()
|
||||
|
||||
|
||||
def route_data_lines(self):
|
||||
""" Route the bitlines depending on the port type rw, w, or r. """
|
||||
|
||||
|
||||
if self.port in self.readwrite_ports:
|
||||
# (write_mask_and ->) write_driver -> sense_amp -> (column_mux ->) precharge -> bitcell_array
|
||||
self.route_write_mask_and_array_in(self.port)
|
||||
self.route_write_mask_and_array_to_write_driver(self.port)
|
||||
self.route_write_driver_in(self.port)
|
||||
self.route_write_driver_in(self.port)
|
||||
self.route_sense_amp_out(self.port)
|
||||
self.route_write_driver_to_sense_amp(self.port)
|
||||
self.route_sense_amp_to_column_mux_or_precharge_array(self.port)
|
||||
|
|
@ -142,15 +142,15 @@ class port_data(design.design):
|
|||
self.route_write_mask_and_array_to_write_driver(self.port)
|
||||
self.route_write_driver_in(self.port)
|
||||
self.route_write_driver_to_column_mux_or_precharge_array(self.port)
|
||||
self.route_column_mux_to_precharge_array(self.port)
|
||||
|
||||
self.route_column_mux_to_precharge_array(self.port)
|
||||
|
||||
def route_supplies(self):
|
||||
""" Propagate all vdd/gnd pins up to this level for all modules """
|
||||
|
||||
|
||||
for inst in self.insts:
|
||||
self.copy_power_pins(inst,"vdd")
|
||||
self.copy_power_pins(inst,"gnd")
|
||||
|
||||
|
||||
def add_modules(self):
|
||||
|
||||
# Extra column +1 is for RBL
|
||||
|
|
@ -163,23 +163,23 @@ class port_data(design.design):
|
|||
|
||||
if self.port in self.read_ports:
|
||||
self.sense_amp_array = factory.create(module_type="sense_amp_array",
|
||||
word_size=self.word_size,
|
||||
word_size=self.word_size,
|
||||
words_per_row=self.words_per_row)
|
||||
self.add_mod(self.sense_amp_array)
|
||||
else:
|
||||
self.sense_amp_array = None
|
||||
|
||||
|
||||
|
||||
if self.col_addr_size > 0:
|
||||
self.column_mux_array = factory.create(module_type="column_mux_array",
|
||||
columns=self.num_cols,
|
||||
columns=self.num_cols,
|
||||
word_size=self.word_size,
|
||||
bitcell_bl=self.bl_names[self.port],
|
||||
bitcell_br=self.br_names[self.port])
|
||||
self.add_mod(self.column_mux_array)
|
||||
else:
|
||||
self.column_mux_array = None
|
||||
|
||||
|
||||
|
||||
if self.port in self.write_ports:
|
||||
self.write_driver_array = factory.create(module_type="write_driver_array",
|
||||
|
|
@ -187,11 +187,12 @@ class port_data(design.design):
|
|||
word_size=self.word_size,
|
||||
write_size=self.write_size)
|
||||
self.add_mod(self.write_driver_array)
|
||||
if self.write_size:
|
||||
if self.write_size is not None:
|
||||
self.write_mask_and_array = factory.create(module_type="write_mask_and_array",
|
||||
columns=self.num_cols,
|
||||
word_size=self.word_size,
|
||||
write_size=self.write_size)
|
||||
write_size=self.write_size,
|
||||
port = self.port)
|
||||
self.add_mod(self.write_mask_and_array)
|
||||
else:
|
||||
self.write_mask_and_array = None
|
||||
|
|
@ -207,8 +208,8 @@ class port_data(design.design):
|
|||
if self.col_addr_size>0:
|
||||
self.num_col_addr_lines = 2**self.col_addr_size
|
||||
else:
|
||||
self.num_col_addr_lines = 0
|
||||
|
||||
self.num_col_addr_lines = 0
|
||||
|
||||
|
||||
# A space for wells or jogging m2 between modules
|
||||
self.m2_gap = max(2*drc("pwell_to_nwell") + drc("well_enclosure_active"),
|
||||
|
|
@ -216,7 +217,7 @@ 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.bitcell = factory.create(module_type="bitcell")
|
||||
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()
|
||||
|
|
@ -226,7 +227,7 @@ class port_data(design.design):
|
|||
if not self.precharge_array:
|
||||
self.precharge_array_inst = None
|
||||
return
|
||||
|
||||
|
||||
self.precharge_array_inst = self.add_inst(name="precharge_array{}".format(self.port),
|
||||
mod=self.precharge_array)
|
||||
|
||||
|
|
@ -245,16 +246,16 @@ class port_data(design.design):
|
|||
temp.extend(["p_en_bar", "vdd"])
|
||||
self.connect_inst(temp)
|
||||
|
||||
|
||||
|
||||
def place_precharge_array(self, offset):
|
||||
""" Placing Precharge """
|
||||
|
||||
|
||||
self.precharge_array_inst.place(offset=offset, mirror="MX")
|
||||
|
||||
|
||||
|
||||
def create_column_mux_array(self):
|
||||
""" Creating Column Mux when words_per_row > 1 . """
|
||||
|
||||
|
||||
self.column_mux_array_inst = self.add_inst(name="column_mux_array{}".format(self.port),
|
||||
mod=self.column_mux_array)
|
||||
|
||||
|
|
@ -270,15 +271,15 @@ class port_data(design.design):
|
|||
temp.append("gnd")
|
||||
self.connect_inst(temp)
|
||||
|
||||
|
||||
|
||||
def place_column_mux_array(self, offset):
|
||||
""" Placing Column Mux when words_per_row > 1 . """
|
||||
if self.col_addr_size == 0:
|
||||
return
|
||||
|
||||
|
||||
self.column_mux_array_inst.place(offset=offset, mirror="MX")
|
||||
|
||||
|
||||
|
||||
def create_sense_amp_array(self):
|
||||
""" Creating Sense amp """
|
||||
self.sense_amp_array_inst = self.add_inst(name="sense_amp_array{}".format(self.port),
|
||||
|
|
@ -293,11 +294,11 @@ class port_data(design.design):
|
|||
else:
|
||||
temp.append(self.bl_names[self.port]+"_out_{0}".format(bit))
|
||||
temp.append(self.br_names[self.port]+"_out_{0}".format(bit))
|
||||
|
||||
|
||||
temp.extend(["s_en", "vdd", "gnd"])
|
||||
self.connect_inst(temp)
|
||||
|
||||
|
||||
|
||||
def place_sense_amp_array(self, offset):
|
||||
""" Placing Sense amp """
|
||||
self.sense_amp_array_inst.place(offset=offset, mirror="MX")
|
||||
|
|
@ -320,7 +321,7 @@ class port_data(design.design):
|
|||
temp.append(self.bl_names[self.port] + "_out_{0}".format(bit))
|
||||
temp.append(self.br_names[self.port] + "_out_{0}".format(bit))
|
||||
|
||||
if self.write_size:
|
||||
if self.write_size is not None:
|
||||
for i in range(self.num_wmasks):
|
||||
temp.append("wdriver_sel_{}".format(i))
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class write_mask_and_array(design.design):
|
|||
The write mask AND array goes between the write driver array and the sense amp array.
|
||||
"""
|
||||
|
||||
def __init__(self, name, columns, word_size, write_size):
|
||||
def __init__(self, name, columns, word_size, write_size, port):
|
||||
design.design.__init__(self, name)
|
||||
debug.info(1, "Creating {0}".format(self.name))
|
||||
self.add_comment("columns: {0}".format(columns))
|
||||
|
|
@ -30,6 +30,7 @@ class write_mask_and_array(design.design):
|
|||
self.columns = columns
|
||||
self.word_size = word_size
|
||||
self.write_size = write_size
|
||||
self.port = port
|
||||
self.words_per_row = int(columns / word_size)
|
||||
self.num_wmasks = int(word_size / write_size)
|
||||
|
||||
|
|
@ -106,13 +107,24 @@ class write_mask_and_array(design.design):
|
|||
self.nand2 = factory.create(module_type="pnand2")
|
||||
supply_pin=self.nand2.get_pin("vdd")
|
||||
|
||||
|
||||
# Create the enable pin that connects all write mask AND array's B pins
|
||||
beg_en_pin = self.and2_insts[0].get_pin("B")
|
||||
end_en_pin = self.and2_insts[self.num_wmasks-1].get_pin("B")
|
||||
self.add_layout_pin(text="en",
|
||||
layer="metal3",
|
||||
offset=beg_en_pin.bc(),
|
||||
width = end_en_pin.cx() - beg_en_pin.cx())
|
||||
if self.port == 0:
|
||||
self.add_layout_pin(text="en",
|
||||
layer="metal3",
|
||||
offset=beg_en_pin.bc(),
|
||||
width=end_en_pin.cx() - beg_en_pin.cx())
|
||||
else:
|
||||
en_to_edge = self.and2.width - beg_en_pin.cx()
|
||||
self.add_layout_pin(text="en",
|
||||
layer="metal3",
|
||||
offset=beg_en_pin.bc(),
|
||||
width=end_en_pin.cx() - beg_en_pin.cx() + en_to_edge)
|
||||
self.add_via_center(layers=("metal2", "via2", "metal3"),
|
||||
offset=vector(end_en_pin.cx() + en_to_edge, end_en_pin.cy()))
|
||||
|
||||
|
||||
for i in range(self.num_wmasks):
|
||||
# Copy remaining layout pins
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ class sram_1bank(sram_base):
|
|||
if port in self.write_ports:
|
||||
if self.write_size:
|
||||
# Add the write mask flops below the write mask AND array.
|
||||
wmask_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
|
||||
wmask_pos[port] = vector(self.bank.bank_array_ur.x - self.wmask_dff_insts[port].width,
|
||||
self.bank.height + max_gap_size_wmask + self.dff.height)
|
||||
self.wmask_dff_insts[port].place(wmask_pos[port], mirror="MX")
|
||||
|
||||
|
|
@ -355,11 +355,16 @@ class sram_1bank(sram_base):
|
|||
""" Connect the output of the data flops to the write driver """
|
||||
# This is where the channel will start (y-dimension at least)
|
||||
for port in self.write_ports:
|
||||
if port%2:
|
||||
offset = self.data_dff_insts[port].ll() - vector(0, (self.word_size+2)*self.m1_pitch)
|
||||
if self.write_size:
|
||||
if port % 2:
|
||||
offset = self.data_dff_insts[port].ll() - vector(0, (self.word_size + 2)*self.m3_pitch)
|
||||
else:
|
||||
offset = self.data_dff_insts[port].ul() + vector(0, 2 * self.m3_pitch)
|
||||
else:
|
||||
offset = self.data_dff_insts[port].ul() + vector(0, 2*self.m1_pitch)
|
||||
|
||||
if port%2:
|
||||
offset = self.data_dff_insts[port].ll() - vector(0, (self.word_size+2)*self.m1_pitch)
|
||||
else:
|
||||
offset = self.data_dff_insts[port].ul() + vector(0, 2*self.m1_pitch)
|
||||
|
||||
dff_names = ["dout_{}".format(x) for x in range(self.word_size)]
|
||||
dff_pins = [self.data_dff_insts[port].get_pin(x) for x in dff_names]
|
||||
|
|
@ -399,7 +404,7 @@ class sram_1bank(sram_base):
|
|||
# This is where the channel will start (y-dimension at least)
|
||||
for port in self.write_ports:
|
||||
if port % 2:
|
||||
offset = self.wmask_dff_insts[port].ll() - vector(0, (self.word_size + 2) * self.m1_pitch)
|
||||
offset = self.wmask_dff_insts[port].ll() - vector(0, (self.num_wmasks+2) * self.m1_pitch)
|
||||
else:
|
||||
offset = self.wmask_dff_insts[port].ul() + vector(0, 2 * self.m1_pitch)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue