Merge branch 'add_wmask' of github.com:VLSIDA/PrivateRAM into add_wmask

This commit is contained in:
Matt Guthaus 2019-08-21 10:18:59 -07:00
commit c39b09c736
1 changed files with 60 additions and 78 deletions

View File

@ -44,11 +44,11 @@ class sram_1bank(sram_base):
if self.col_addr_dff: if self.col_addr_dff:
self.col_addr_dff_insts = self.create_col_addr_dff() self.col_addr_dff_insts = self.create_col_addr_dff()
self.data_dff_insts = self.create_data_dff()
if self.write_size is not None: if self.write_size is not None:
self.wmask_dff_insts = self.create_wmask_dff() self.wmask_dff_insts = self.create_wmask_dff()
self.data_dff_insts = self.create_data_dff()
else:
self.data_dff_insts = self.create_data_dff()
def place_instances(self): def place_instances(self):
""" """
@ -67,8 +67,8 @@ class sram_1bank(sram_base):
control_pos = [None]*len(self.all_ports) control_pos = [None]*len(self.all_ports)
row_addr_pos = [None]*len(self.all_ports) row_addr_pos = [None]*len(self.all_ports)
col_addr_pos = [None]*len(self.all_ports) col_addr_pos = [None]*len(self.all_ports)
data_pos = [None]*len(self.all_ports)
wmask_pos = [None]*len(self.all_ports) wmask_pos = [None]*len(self.all_ports)
data_pos = [None]*len(self.all_ports)
# This is M2 pitch even though it is on M1 to help stem via spacings on the trunk # This is M2 pitch even though it is on M1 to help stem via spacings on the trunk
# The M1 pitch is for supply rail spacings # The M1 pitch is for supply rail spacings
@ -77,6 +77,22 @@ class sram_1bank(sram_base):
# Port 0 # Port 0
port = 0 port = 0
if self.write_size is not None:
if port in self.write_ports:
# Add the write mask flops below the write mask AND array.
wmask_pos[port] = vector(self.bank.bank_array_ll.x,
- max_gap_size - self.dff.height)
self.wmask_dff_insts[port].place(wmask_pos[port])
# Add the data flops below the write mask flops.
data_pos[port] = vector(self.bank.bank_array_ll.x,
-2*max_gap_size - 2*self.dff.height)
self.data_dff_insts[port].place(data_pos[port])
else:
wmask_pos[port] = vector(self.bank.bank_array_ll.x, 0)
data_pos[port] = vector(self.bank.bank_array_ll.x,0)
else:
# Add the data flops below the bank to the right of the lower-left of bank array # Add the data flops below the bank to the right of the lower-left of bank array
# This relies on the lower-left of the array of the bank # This relies on the lower-left of the array of the bank
# decoder in upper left, bank in upper right, sensing in lower right. # decoder in upper left, bank in upper right, sensing in lower right.
@ -90,15 +106,6 @@ class sram_1bank(sram_base):
else: else:
data_pos[port] = vector(self.bank.bank_array_ll.x,0) data_pos[port] = vector(self.bank.bank_array_ll.x,0)
# Add the write mask flops below the din flops.
if self.write_size is not None:
if port in self.write_ports:
wmask_pos[port] = vector(self.bank.bank_array_ll.x,
- 1.5*max_gap_size - 2*self.dff.height)
self.wmask_dff_insts[port].place(wmask_pos[port])
else:
wmask_pos[port] = vector(self.bank.bank_array_ll.x, 0)
# Add the col address flops below the bank to the left of the lower-left of bank array # Add the col address flops below the bank to the left of the lower-left of bank array
if self.col_addr_dff: if self.col_addr_dff:
col_addr_pos[port] = vector(self.bank.bank_array_ll.x - self.col_addr_dff_insts[port].width - self.bank.m2_gap, col_addr_pos[port] = vector(self.bank.bank_array_ll.x - self.col_addr_dff_insts[port].width - self.bank.m2_gap,
@ -125,47 +132,33 @@ class sram_1bank(sram_base):
-max_gap_size - self.col_addr_dff_insts[port].height) -max_gap_size - self.col_addr_dff_insts[port].height)
self.col_addr_dff_insts[port].place(col_addr_pos[port]) self.col_addr_dff_insts[port].place(col_addr_pos[port])
# Add the data flops below the bank to the right of the lower-left of bank array
# This relies on the lower-left of the array of the bank
# decoder in upper left, bank in upper right, sensing in lower right.
# These flops go below the sensing and leave a gap to channel route to the
# sense amps.
if port in self.write_ports:
data_pos[port] = vector(self.bank.bank_array_ll.x,
-max_gap_size - self.data_dff_insts[port].height)
self.data_dff_insts[port].place(data_pos[port])
if len(self.all_ports)>1: if len(self.all_ports)>1:
# Port 1 # Port 1
port = 1 port = 1
if port in self.write_ports:
if self.write_size is not None:
# 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,
self.bank.height + max_gap_size + self.dff.height)
self.wmask_dff_insts[port].place(wmask_pos[port], mirror="MX")
# Add the data flops below the write mask flops
data_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
self.bank.height + 2*max_gap_size + 2*self.dff.height)
self.data_dff_insts[port].place(data_pos[port], mirror="MX")
else:
# Add the data flops above the bank to the left of the upper-right of bank array # Add the data flops above the bank to the left of the upper-right of bank array
# This relies on the upper-right of the array of the bank # This relies on the upper-right of the array of the bank
# decoder in upper left, bank in upper right, sensing in lower right. # decoder in upper left, bank in upper right, sensing in lower right.
# These flops go below the sensing and leave a gap to channel route to the # These flops go below the sensing and leave a gap to channel route to the
# sense amps. # sense amps.
if port in self.write_ports:
data_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width, data_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
self.bank.height + max_gap_size + self.dff.height) self.bank.height + max_gap_size + self.dff.height)
self.data_dff_insts[port].place(data_pos[port], mirror="MX") self.data_dff_insts[port].place(data_pos[port], mirror="MX")
# Add the write mask flops below the din flops.
if self.write_size is not None:
if port in self.write_ports:
wmask_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
self.bank.height + 1.5*max_gap_size + 2*self.dff.height)
self.wmask_dff_insts[port].place(wmask_pos[port], mirror="MX")
# Add the write mask flops to the left of the din flops.
if self.write_size is not None:
if port in self.write_ports:
wmask_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
self.bank.height + max_gap_size + self.data_dff_insts[port].height)
self.wmask_dff_insts[port].place(wmask_pos[port], mirror="MX")
else:
data_pos[port] = self.bank_inst.ur()
# Add the col address flops above the bank to the right of the upper-right of bank array # Add the col address flops above the bank to the right of the upper-right of bank array
if self.col_addr_dff: if self.col_addr_dff:
col_addr_pos[port] = vector(self.bank.bank_array_ur.x + self.bank.m2_gap, col_addr_pos[port] = vector(self.bank.bank_array_ur.x + self.bank.m2_gap,
@ -189,15 +182,6 @@ class sram_1bank(sram_base):
row_addr_pos[port] = vector(x_offset, y_offset) row_addr_pos[port] = vector(x_offset, y_offset)
self.row_addr_dff_insts[port].place(row_addr_pos[port], mirror="XY") self.row_addr_dff_insts[port].place(row_addr_pos[port], mirror="XY")
# Add the data flops above the bank to the left of the upper-right of bank array
# This relies on the upper-right of the array of the bank
# decoder in upper left, bank in upper right, sensing in lower right.
# These flops go below the sensing and leave a gap to channel route to the
# sense amps.
if port in self.write_ports:
data_pos[port] = vector(self.bank.bank_array_ur.x - self.data_dff_insts[port].width,
self.bank.height + max_gap_size + self.dff.height)
self.data_dff_insts[port].place(data_pos[port], mirror="MX")
def add_layout_pins(self): def add_layout_pins(self):
""" """
@ -376,12 +360,24 @@ class sram_1bank(sram_base):
dff_names = ["dout_{}".format(x) for x in range(self.word_size)] 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] dff_pins = [self.data_dff_insts[port].get_pin(x) for x in dff_names]
for x in dff_names:
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=self.data_dff_insts[port].get_pin(x).center())
self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=self.data_dff_insts[port].get_pin(x).center())
bank_names = ["din{0}_{1}".format(port,x) for x in range(self.word_size)] bank_names = ["din{0}_{1}".format(port,x) for x in range(self.word_size)]
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names] bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
for x in bank_names:
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=self.bank_inst.get_pin(x).bc())
self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=self.bank_inst.get_pin(x).bc())
route_map = list(zip(bank_pins, dff_pins)) route_map = list(zip(bank_pins, dff_pins))
self.create_horizontal_channel_route(route_map, offset) self.create_horizontal_channel_route(netlist=route_map,
offset=offset,
layer_stack=("metal3", "via3", "metal4"))
def route_wmask_dff(self): def route_wmask_dff(self):
""" Connect the output of the wmask flops to the write mask AND array """ """ Connect the output of the wmask flops to the write mask AND array """
@ -395,25 +391,11 @@ class sram_1bank(sram_base):
dff_names = ["dout_{}".format(x) for x in range(self.num_wmasks)] dff_names = ["dout_{}".format(x) for x in range(self.num_wmasks)]
dff_pins = [self.wmask_dff_insts[port].get_pin(x) for x in dff_names] dff_pins = [self.wmask_dff_insts[port].get_pin(x) for x in dff_names]
for x in dff_names:
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=self.wmask_dff_insts[port].get_pin(x).center())
self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=self.wmask_dff_insts[port].get_pin(x).center())
bank_names = ["bank_wmask{0}_{1}".format(port, x) for x in range(self.num_wmasks)] bank_names = ["bank_wmask{0}_{1}".format(port, x) for x in range(self.num_wmasks)]
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names] bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
for x in bank_names:
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=self.bank_inst.get_pin(x).center())
self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=self.bank_inst.get_pin(x).center())
route_map = list(zip(bank_pins, dff_pins)) route_map = list(zip(bank_pins, dff_pins))
self.create_horizontal_channel_route(netlist=route_map, self.create_horizontal_channel_route(route_map,offset)
offset=offset,
layer_stack=("metal3", "via3", "metal4"))
def add_lvs_correspondence_points(self): def add_lvs_correspondence_points(self):