Merge remote-tracking branch 'origin/dev' into rbl_revamp

This commit is contained in:
mrg
2019-07-12 11:10:07 -07:00
20 changed files with 772 additions and 143 deletions
+1 -4
View File
@@ -34,7 +34,6 @@ class sram():
start_time = datetime.datetime.now()
self.name = name
if self.num_banks == 1:
from sram_1bank import sram_1bank as sram
@@ -84,8 +83,6 @@ class sram():
self.gds_write(gdsname)
print_time("GDS", datetime.datetime.now(), start_time)
# Save the spice file
start_time = datetime.datetime.now()
spname = OPTS.output_path + self.s.name + ".sp"
@@ -133,4 +130,4 @@ class sram():
vname = OPTS.output_path + self.s.name + ".v"
debug.print_raw("Verilog: Writing to {0}".format(vname))
self.verilog_write(vname)
print_time("Verilog", datetime.datetime.now(), start_time)
print_time("Verilog", datetime.datetime.now(), start_time)
+40 -3
View File
@@ -46,6 +46,9 @@ class sram_1bank(sram_base):
self.data_dff_insts = self.create_data_dff()
if (self.write_size != self.word_size):
self.wmask_dff_insts = self.create_wmask_dff()
def place_instances(self):
"""
@@ -65,6 +68,7 @@ class sram_1bank(sram_base):
row_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)
# 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
@@ -105,6 +109,29 @@ class sram_1bank(sram_base):
row_addr_pos[port] = vector(x_offset, y_offset)
self.row_addr_dff_insts[port].place(row_addr_pos[port])
# Add the col address flops below the bank to the left of the lower-left of bank array
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,
-max_gap_size - self.col_addr_dff_insts[port].height)
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])
# Add the write mask flops to the left of the din flops.
if (self.write_size != self.word_size):
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")
if len(self.all_ports)>1:
# Port 1
@@ -119,6 +146,13 @@ class sram_1bank(sram_base):
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")
# Add the write mask flops to the left of the din flops.
if (self.write_size != self.word_size):
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()
@@ -143,7 +177,7 @@ class sram_1bank(sram_base):
self.row_addr_dff_insts[port].place(row_addr_pos[port], mirror="XY")
def add_layout_pins(self):
"""
Add the top-level pins for a single bank SRAM with control.
@@ -326,10 +360,13 @@ class sram_1bank(sram_base):
offset=pin.center())
def graph_exclude_data_dff(self):
"""Removes data dff from search graph. """
#Data dffs are only for writing so are not useful for evaluating read delay.
"""Removes data dff and wmask dff (if applicable) from search graph. """
#Data dffs and wmask dffs are only for writing so are not useful for evaluating read delay.
for inst in self.data_dff_insts:
self.graph_inst_exclude.add(inst)
if (self.write_size != self.word_size):
for inst in self.wmask_dff_insts:
self.graph_inst_exclude.add(inst)
def graph_exclude_addr_dff(self):
"""Removes data dff from search graph. """
+34 -6
View File
@@ -68,7 +68,10 @@ class sram_base(design, verilog, lef):
self.add_pin("web{}".format(port),"INPUT")
for port in self.all_ports:
self.add_pin("clk{}".format(port),"INPUT")
# add the optional write mask pins
if self.word_size != self.write_size:
for port in self.write_ports:
self.add_pin("wmask{}".format(port),"INPUT")
for port in self.read_ports:
for bit in range(self.word_size):
self.add_pin("DOUT{0}[{1}]".format(port,bit),"OUTPUT")
@@ -150,9 +153,6 @@ class sram_base(design, verilog, lef):
rtr.route()
def compute_bus_sizes(self):
""" Compute the independent bus widths shared between two and four bank SRAMs """
@@ -278,7 +278,9 @@ class sram_base(design, verilog, lef):
self.data_dff = dff_array(name="data_dff", rows=1, columns=self.word_size)
self.add_mod(self.data_dff)
self.wmask_dff = dff_array(name="wmask_dff", rows=1, columns=int(self.word_size/self.write_size))
self.add_mod(self.wmask_dff)
# Create the bank module (up to four are instantiated)
from bank import bank
@@ -303,6 +305,7 @@ class sram_base(design, verilog, lef):
self.control_logic_rw = self.mod_control_logic(num_rows=self.num_rows,
words_per_row=self.words_per_row,
word_size=self.word_size,
write_size = self.write_size,
sram=self,
port_type="rw")
self.add_mod(self.control_logic_rw)
@@ -310,6 +313,7 @@ class sram_base(design, verilog, lef):
self.control_logic_w = self.mod_control_logic(num_rows=self.num_rows,
words_per_row=self.words_per_row,
word_size=self.word_size,
write_size=self.write_size,
sram=self,
port_type="w")
self.add_mod(self.control_logic_w)
@@ -317,7 +321,8 @@ class sram_base(design, verilog, lef):
self.control_logic_r = self.mod_control_logic(num_rows=self.num_rows,
words_per_row=self.words_per_row,
word_size=self.word_size,
sram=self,
write_size=self.write_size,
sram=self,
port_type="r")
self.add_mod(self.control_logic_r)
@@ -448,6 +453,29 @@ class sram_base(design, verilog, lef):
return insts
def create_wmask_dff(self):
""" Add and place all wmask flops """
num_wmask = int(self.word_size/self.write_size)
insts = []
for port in self.all_ports:
if port in self.write_ports:
insts.append(self.add_inst(name="wmask_dff{}".format(port),
mod=self.wmask_dff))
else:
insts.append(None)
continue
# inputs, outputs/output/bar
inputs = []
outputs = []
for bit in range(num_wmask):
inputs.append("wmask{}[{}]".format(port, bit))
outputs.append("BANK_WMASK{}[{}]".format(port, bit))
self.connect_inst(inputs + outputs + ["clk_buf{}".format(port), "vdd", "gnd"])
return insts
def create_control_logic(self):
""" Add control logic instances """
+6 -2
View File
@@ -14,16 +14,20 @@ from sram_factory import factory
class sram_config:
""" This is a structure that is used to hold the SRAM configuration options. """
def __init__(self, word_size, num_words, num_banks=1, words_per_row=None):
def __init__(self, word_size, num_words, write_size = None, num_banks=1, words_per_row=None):
self.word_size = word_size
self.num_words = num_words
self.write_size = write_size
self.num_banks = num_banks
# This will get over-written when we determine the organization
self.words_per_row = words_per_row
if self.write_size == None:
self.write_size = self.word_size
self.compute_sizes()
def set_local_config(self, module):
""" Copy all of the member variables to the given module for convenience """