From a346bddd880ae172a642a4aa2f9b66a40312743c Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 4 Sep 2018 10:47:24 -0700 Subject: [PATCH 1/8] Cleanup some items with new sram_config. Update unit tests accordingly. --- compiler/globals.py | 52 ++++++++---- compiler/modules/bank.py | 4 + compiler/modules/hierarchical_decoder.py | 2 +- compiler/openram.py | 9 +- compiler/options.py | 8 +- compiler/pgates/pbitcell.py | 18 ++-- compiler/sram.py | 9 +- compiler/sram_1bank.py | 5 +- compiler/sram_2bank.py | 4 +- compiler/sram_4bank.py | 4 +- compiler/sram_base.py | 83 ++----------------- compiler/sram_config.py | 100 ++++++++++++++++++----- compiler/tests/04_pbitcell_test.py | 53 +++++++++--- compiler/tests/19_psingle_bank_test.py | 1 - compiler/tests/20_sram_1bank_test.py | 9 +- compiler/tests/20_sram_2bank_test.py | 9 +- compiler/tests/20_sram_4bank_test.py | 8 +- compiler/tests/21_hspice_delay_test.py | 2 +- compiler/tests/21_ngspice_delay_test.py | 2 +- compiler/tests/23_lib_sram_model_test.py | 3 +- compiler/tests/23_lib_sram_prune_test.py | 2 +- compiler/tests/23_lib_sram_test.py | 2 +- compiler/tests/24_lef_sram_test.py | 2 +- compiler/tests/25_verilog_sram_test.py | 2 +- 24 files changed, 222 insertions(+), 171 deletions(-) diff --git a/compiler/globals.py b/compiler/globals.py index 991ec1ad..3bdc5f92 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -116,6 +116,11 @@ def init_openram(config_file, is_unit_test=True): import_tech() + init_paths() + + # This depends on the tech, so do it after tech is loaded + init_config() + # Reset the static duplicate name checker for unit tests. import hierarchy_design hierarchy_design.hierarchy_design.name_map=[] @@ -229,15 +234,6 @@ def read_config(config_file, is_unit_test=True): OPTS.num_r_ports, OPTS.tech_name) - # Don't delete the output dir, it may have other files! - # make the directory if it doesn't exist - try: - os.makedirs(OPTS.output_path, 0o750) - except OSError as e: - if e.errno == 17: # errno.EEXIST - os.chmod(OPTS.output_path, 0o750) - except: - debug.error("Unable to make output directory.",-1) def end_openram(): @@ -299,12 +295,6 @@ def setup_paths(): cleanup_paths() - # make the directory if it doesn't exist - try: - os.makedirs(OPTS.openram_temp, 0o750) - except OSError as e: - if e.errno == 17: # errno.EEXIST - os.chmod(OPTS.openram_temp, 0o750) def is_exe(fpath): @@ -320,7 +310,37 @@ def find_exe(check_exe): if is_exe(exe): return exe return None - + +def init_paths(): + """ Create the temp and output directory if it doesn't exist """ + + # make the directory if it doesn't exist + try: + os.makedirs(OPTS.openram_temp, 0o750) + except OSError as e: + if e.errno == 17: # errno.EEXIST + os.chmod(OPTS.openram_temp, 0o750) + + # Don't delete the output dir, it may have other files! + # make the directory if it doesn't exist + try: + os.makedirs(OPTS.output_path, 0o750) + except OSError as e: + if e.errno == 17: # errno.EEXIST + os.chmod(OPTS.output_path, 0o750) + except: + debug.error("Unable to make output directory.",-1) + +def init_config(): + """ Initialize the SRAM configurations. """ + # Create the SRAM configuration + from sram_config import sram_config + OPTS.sram_config = sram_config(OPTS.word_size, + OPTS.num_words, + OPTS.num_banks) + + + # imports correct technology directories for testing def import_tech(): global OPTS diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index f39fb424..3af935a3 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -29,6 +29,10 @@ class bank(design.design): design.design.__init__(self, name) debug.info(2, "create sram of size {0} with {1} words".format(self.word_size,self.num_words)) + + self.total_write = OPTS.num_rw_ports + OPTS.num_w_ports + self.total_read = OPTS.num_rw_ports + OPTS.num_r_ports + self.total_ports = OPTS.num_rw_ports + OPTS.num_w_ports + OPTS.num_r_ports # The local control signals are gated when we have bank select logic, # so this prefix will be added to all of the input signals to create diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 38136b62..7c90b1f1 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -130,7 +130,7 @@ class hierarchical_decoder(design.design): self.total_number_of_predecoder_outputs = 4*self.no_of_pre2x4 + 8*self.no_of_pre3x8 else: self.total_number_of_predecoder_outputs = 0 - debug.error("Not enough rows for a hierarchical decoder. Non-hierarchical not supported yet.",-1) + debug.error("Not enough rows ({}) for a hierarchical decoder. Non-hierarchical not supported yet.".format(self.num_inputs),-1) # Calculates height and width of pre-decoder, if self.no_of_pre3x8 > 0: diff --git a/compiler/openram.py b/compiler/openram.py index a6db154d..e4ab593e 100755 --- a/compiler/openram.py +++ b/compiler/openram.py @@ -52,14 +52,13 @@ print(*output_files,sep="\n") start_time = datetime.datetime.now() print_time("Start",start_time) +# Configure the SRAM organization c = sram_config(word_size=OPTS.word_size, - num_words=OPTS.num_words, - num_rw_ports=OPTS.num_rw_ports, - num_w_ports=OPTS.num_w_ports, - num_r_ports=OPTS.num_r_ports) + num_words=OPTS.num_words) # import SRAM test generation -s = sram(c, OPTS.output_name) +s = sram(sram_config=c, + name=OPTS.output_name) # Output the files for the resulting SRAM s.save() diff --git a/compiler/options.py b/compiler/options.py index a81f7fae..5298c00f 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -55,11 +55,17 @@ class options(optparse.Values): num_rw_ports = 1 num_r_ports = 0 num_w_ports = 0 + # These will get initialized by the the file supply_voltages = "" temperatures = "" process_corners = "" - + + # These are the main configuration parameters that should be over-ridden + # in a configuration file. + #num_words = 0 + #num_banks = 1 + #word_size = 0 # These are the default modules that can be over-riden decoder = "hierarchical_decoder" diff --git a/compiler/pgates/pbitcell.py b/compiler/pgates/pbitcell.py index 0b2ec27d..3ac0fa74 100644 --- a/compiler/pgates/pbitcell.py +++ b/compiler/pgates/pbitcell.py @@ -16,18 +16,18 @@ class pbitcell(pgate.pgate): width = None height = None - def __init__(self, num_rw_ports=OPTS.num_rw_ports, num_w_ports=OPTS.num_w_ports, num_r_ports=OPTS.num_r_ports): + def __init__(self): - name = "pbitcell_{0}RW_{1}W_{2}R".format(num_rw_ports, num_w_ports, num_r_ports) + self.num_rw_ports = OPTS.num_rw_ports + self.num_w_ports = OPTS.num_w_ports + self.num_r_ports = OPTS.num_r_ports + + name = "pbitcell_{0}RW_{1}W_{2}R".format(self.num_rw_ports, self.num_w_ports, self.num_r_ports) pgate.pgate.__init__(self, name) - debug.info(2, "create a multi-port bitcell with {0} rw ports, {1} w ports and {2} r ports".format(num_rw_ports, - num_w_ports, - num_r_ports)) + debug.info(2, "create a multi-port bitcell with {0} rw ports, {1} w ports and {2} r ports".format(self.num_rw_ports, + self.num_w_ports, + self.num_r_ports)) - self.num_rw_ports = num_rw_ports - self.num_w_ports = num_w_ports - self.num_r_ports = num_r_ports - self.create_netlist() if not OPTS.netlist_only: self.create_layout() diff --git a/compiler/sram.py b/compiler/sram.py index 3891150b..0feea1b3 100644 --- a/compiler/sram.py +++ b/compiler/sram.py @@ -12,8 +12,9 @@ class sram(): results. We can later add visualizer and other high-level functions as needed. """ - def __init__(self, sram_config, name="sram"): + def __init__(self, sram_config, name): + sram_config.compute_sizes() sram_config.set_local_config(self) # reset the static duplicate name checker for unit tests @@ -27,6 +28,8 @@ class sram(): start_time = datetime.datetime.now() self.name = name + + if self.num_banks == 1: from sram_1bank import sram_1bank as sram elif self.num_banks == 2: @@ -35,8 +38,8 @@ class sram(): from sram_4bank import sram_4bank as sram else: debug.error("Invalid number of banks.",-1) - - self.s = sram(sram_config, name) + + self.s = sram(name, sram_config) self.s.create_netlist() if not OPTS.netlist_only: self.s.create_layout() diff --git a/compiler/sram_1bank.py b/compiler/sram_1bank.py index 20dab3c7..e27eb2b3 100644 --- a/compiler/sram_1bank.py +++ b/compiler/sram_1bank.py @@ -18,12 +18,11 @@ class sram_1bank(sram_base): """ Procedures specific to a one bank SRAM. """ - def __init__(self, sram_config, name): - sram_base.__init__(self, sram_config, name) + def __init__(self, name, sram_config): + sram_base.__init__(self, name, sram_config) def create_netlist(self): - self.compute_sizes() sram_base.create_netlist(self) self.create_modules() diff --git a/compiler/sram_2bank.py b/compiler/sram_2bank.py index ff0d7868..daf02563 100644 --- a/compiler/sram_2bank.py +++ b/compiler/sram_2bank.py @@ -16,8 +16,8 @@ class sram_2bank(sram_base): """ Procedures specific to a two bank SRAM. """ - def __init__(self, sram_config, name): - sram_base.__init__(self, sram_config, name) + def __init__(self, name, sram_config): + sram_base.__init__(self, name, sram_config) def compute_bank_offsets(self): """ Compute the overall offsets for a two bank SRAM """ diff --git a/compiler/sram_4bank.py b/compiler/sram_4bank.py index 64163e9f..44b8ba87 100644 --- a/compiler/sram_4bank.py +++ b/compiler/sram_4bank.py @@ -16,8 +16,8 @@ class sram_4bank(sram_base): """ Procedures specific to a four bank SRAM. """ - def __init__(self, sram_config, name): - sram_base.__init__(self, sram_config, name) + def __init__(self, name, sram_config): + sram_base.__init__(self, name, sram_config) def compute_bank_offsets(self): """ Compute the overall offsets for a four bank SRAM """ diff --git a/compiler/sram_base.py b/compiler/sram_base.py index 7ead2e48..af21d704 100644 --- a/compiler/sram_base.py +++ b/compiler/sram_base.py @@ -3,7 +3,6 @@ import datetime import getpass import debug from importlib import reload -from math import log,sqrt,ceil from vector import vector from globals import OPTS, print_time @@ -14,85 +13,14 @@ class sram_base(design): Dynamically generated SRAM by connecting banks to control logic. The number of banks should be 1 , 2 or 4 """ - def __init__(self, sram_config, name): + def __init__(self, name, sram_config): design.__init__(self, name) - - # This is used to compute the sizes of the SRAM - # and must be loaded before netlist creation - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell = self.mod_bitcell() - - self.sram_config = sram_config - self.sram_config.set_local_config(self) + self.sram_config = sram_config + sram_config.set_local_config(self) + self.bank_insts = [] - def compute_sizes(self): - """ Computes the organization of the memory using bitcell size by trying to make it square.""" - - debug.check(self.num_banks in [1,2,4], "Valid number of banks are 1 , 2 and 4.") - - self.num_words_per_bank = self.num_words/self.num_banks - self.num_bits_per_bank = self.word_size*self.num_words_per_bank - - # If this was hard coded, don't dynamically compute it! - if self.sram_config.words_per_row: - self.words_per_row = self.sram_config.words_per_row - else: - # Compute the area of the bitcells and estimate a square bank (excluding auxiliary circuitry) - self.bank_area = self.bitcell.width*self.bitcell.height*self.num_bits_per_bank - self.bank_side_length = sqrt(self.bank_area) - - # Estimate the words per row given the height of the bitcell and the square side length - self.tentative_num_cols = int(self.bank_side_length/self.bitcell.width) - self.words_per_row = self.estimate_words_per_row(self.tentative_num_cols, self.word_size) - - # Estimate the number of rows given the tentative words per row - self.tentative_num_rows = self.num_bits_per_bank / (self.words_per_row*self.word_size) - self.words_per_row = self.amend_words_per_row(self.tentative_num_rows, self.words_per_row) - - # Fix the number of columns and rows - self.num_cols = int(self.words_per_row*self.word_size) - self.num_rows = int(self.num_words_per_bank/self.words_per_row) - - # Compute the address and bank sizes - self.row_addr_size = int(log(self.num_rows, 2)) - self.col_addr_size = int(log(self.words_per_row, 2)) - self.bank_addr_size = self.col_addr_size + self.row_addr_size - self.addr_size = self.bank_addr_size + int(log(self.num_banks, 2)) - - self.sram_config.words_per_row = self.words_per_row - debug.info(1,"Words per row: {}".format(self.words_per_row)) - - def estimate_words_per_row(self,tentative_num_cols, word_size): - """ - This provides a heuristic rounded estimate for the number of words - per row. - """ - - if tentative_num_cols < 1.5*word_size: - return 1 - elif tentative_num_cols > 3*word_size: - return 4 - else: - return 2 - - def amend_words_per_row(self,tentative_num_rows, words_per_row): - """ - This picks the number of words per row more accurately by limiting - it to a minimum and maximum. - """ - # Recompute the words per row given a hard max - if(tentative_num_rows > 512): - debug.check(tentative_num_rows*words_per_row <= 2048, "Number of words exceeds 2048") - return int(words_per_row*tentative_num_rows/512) - # Recompute the words per row given a hard min - if(tentative_num_rows < 16): - debug.check(tentative_num_rows*words_per_row >= 16, "Minimum number of rows is 16, but given {0}".format(tentative_num_rows)) - return int(words_per_row*tentative_num_rows/16) - - return words_per_row def add_pins(self): """ Add pins for entire SRAM. """ @@ -270,6 +198,9 @@ class sram_base(design): def add_modules(self): """ Create all the modules that will be used """ + c = reload(__import__(OPTS.bitcell)) + self.mod_bitcell = getattr(c, OPTS.bitcell) + self.bitcell = self.mod_bitcell() c = reload(__import__(OPTS.control_logic)) self.mod_control_logic = getattr(c, OPTS.control_logic) diff --git a/compiler/sram_config.py b/compiler/sram_config.py index e7c58905..e7c80fd8 100644 --- a/compiler/sram_config.py +++ b/compiler/sram_config.py @@ -1,36 +1,96 @@ +import debug +from math import log,sqrt,ceil +from importlib import reload from globals import OPTS 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, num_rw_ports=OPTS.num_rw_ports, num_w_ports=OPTS.num_w_ports, num_r_ports=OPTS.num_r_ports): + def __init__(self, word_size, num_words, num_banks=1): self.word_size = word_size self.num_words = num_words self.num_banks = num_banks - self.num_rw_ports = num_rw_ports - self.num_w_ports = num_w_ports - self.num_r_ports = num_r_ports # This will get over-written when we determine the organization - self.num_banks = 1 self.words_per_row = None - - self.total_write = num_rw_ports + num_w_ports - self.total_read = num_rw_ports + num_r_ports - self.total_ports = num_rw_ports + num_w_ports + num_r_ports + # Move the module names to this? + def set_local_config(self, module): - module.word_size = self.word_size - module.num_words = self.num_words - module.num_banks = self.num_banks - module.num_rw_ports = self.num_rw_ports - module.num_w_ports = self.num_w_ports - module.num_r_ports = self.num_r_ports + """ Copy all of the member variables to the given module for convenience """ - module.words_per_row = self.words_per_row - - module.total_write = self.total_write - module.total_read = self.total_read - module.total_ports = self.total_ports + members = [attr for attr in dir(self) if not callable(getattr(self, attr)) and not attr.startswith("__")] + # Copy all the variables to the local module + for member in members: + setattr(module,member,getattr(self,member)) + + def compute_sizes(self): + """ Computes the organization of the memory using bitcell size by trying to make it square.""" + + c = reload(__import__(OPTS.bitcell)) + self.mod_bitcell = getattr(c, OPTS.bitcell) + # pass a copy of myself for the port numbers + self.bitcell = self.mod_bitcell() + + + debug.check(self.num_banks in [1,2,4], "Valid number of banks are 1 , 2 and 4.") + + self.num_words_per_bank = self.num_words/self.num_banks + self.num_bits_per_bank = self.word_size*self.num_words_per_bank + + # If this was hard coded, don't dynamically compute it! + if not self.words_per_row: + # Compute the area of the bitcells and estimate a square bank (excluding auxiliary circuitry) + self.bank_area = self.bitcell.width*self.bitcell.height*self.num_bits_per_bank + self.bank_side_length = sqrt(self.bank_area) + + # Estimate the words per row given the height of the bitcell and the square side length + self.tentative_num_cols = int(self.bank_side_length/self.bitcell.width) + self.words_per_row = self.estimate_words_per_row(self.tentative_num_cols, self.word_size) + + # Estimate the number of rows given the tentative words per row + self.tentative_num_rows = self.num_bits_per_bank / (self.words_per_row*self.word_size) + self.words_per_row = self.amend_words_per_row(self.tentative_num_rows, self.words_per_row) + + # Fix the number of columns and rows + self.num_cols = int(self.words_per_row*self.word_size) + self.num_rows = int(self.num_words_per_bank/self.words_per_row) + + # Compute the address and bank sizes + self.row_addr_size = int(log(self.num_rows, 2)) + self.col_addr_size = int(log(self.words_per_row, 2)) + self.bank_addr_size = self.col_addr_size + self.row_addr_size + self.addr_size = self.bank_addr_size + int(log(self.num_banks, 2)) + + debug.info(1,"Words per row: {}".format(self.words_per_row)) + + def estimate_words_per_row(self,tentative_num_cols, word_size): + """ + This provides a heuristic rounded estimate for the number of words + per row. + """ + + if tentative_num_cols < 1.5*word_size: + return 1 + elif tentative_num_cols > 3*word_size: + return 4 + else: + return 2 + + def amend_words_per_row(self,tentative_num_rows, words_per_row): + """ + This picks the number of words per row more accurately by limiting + it to a minimum and maximum. + """ + # Recompute the words per row given a hard max + if(not OPTS.is_unit_test and tentative_num_rows > 512): + debug.check(tentative_num_rows*words_per_row <= 2048, "Number of words exceeds 2048") + return int(words_per_row*tentative_num_rows/512) + # Recompute the words per row given a hard min + if(not OPTS.is_unit_test and tentative_num_rows < 16): + debug.check(tentative_num_rows*words_per_row >= 16, "Minimum number of rows is 16, but given {0}".format(tentative_num_rows)) + return int(words_per_row*tentative_num_rows/16) + + return words_per_row diff --git a/compiler/tests/04_pbitcell_test.py b/compiler/tests/04_pbitcell_test.py index 070637f9..70f51a99 100755 --- a/compiler/tests/04_pbitcell_test.py +++ b/compiler/tests/04_pbitcell_test.py @@ -18,47 +18,76 @@ class pbitcell_test(openram_test): def runTest(self): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) - import pbitcell + from pbitcell import pbitcell import tech - + OPTS.sram_config.num_rw_ports=1 + OPTS.sram_config.num_w_ports=1 + OPTS.sram_config.num_r_ports=1 debug.info(2, "Bitcell with 1 of each port: read/write, write, and read") - tx = pbitcell.pbitcell(num_rw_ports=1,num_w_ports=1,num_r_ports=1) + tx = pbitcell() self.local_check(tx) + OPTS.sram_config.num_rw_ports=0 + OPTS.sram_config.num_w_ports=1 + OPTS.sram_config.num_r_ports=1 debug.info(2, "Bitcell with 0 read/write ports") - tx = pbitcell.pbitcell(num_rw_ports=0,num_w_ports=1,num_r_ports=1) + tx = pbitcell() self.local_check(tx) + OPTS.sram_config.num_rw_ports=1 + OPTS.sram_config.num_w_ports=0 + OPTS.sram_config.num_r_ports=1 debug.info(2, "Bitcell with 0 write ports") - tx = pbitcell.pbitcell(num_rw_ports=1,num_w_ports=0,num_r_ports=1) + tx = pbitcell() self.local_check(tx) + OPTS.sram_config.num_rw_ports=1 + OPTS.sram_config.num_w_ports=1 + OPTS.sram_config.num_r_ports=0 debug.info(2, "Bitcell with 0 read ports") - tx = pbitcell.pbitcell(num_rw_ports=1,num_w_ports=1,num_r_ports=0) + tx = pbitcell() self.local_check(tx) + OPTS.sram_config.num_rw_ports=1 + OPTS.sram_config.num_w_ports=0 + OPTS.sram_config.num_r_ports=0 debug.info(2, "Bitcell with 0 read ports and 0 write ports") - tx = pbitcell.pbitcell(num_rw_ports=1,num_w_ports=0,num_r_ports=0) + tx = pbitcell() self.local_check(tx) + OPTS.sram_config.num_rw_ports=2 + OPTS.sram_config.num_w_ports=2 + OPTS.sram_config.num_r_ports=2 debug.info(2, "Bitcell with 2 of each port: read/write, write, and read") - tx = pbitcell.pbitcell(num_rw_ports=2,num_w_ports=2,num_r_ports=2) + tx = pbitcell() self.local_check(tx) + OPTS.sram_config.num_rw_ports=0 + OPTS.sram_config.num_w_ports=2 + OPTS.sram_config.num_r_ports=2 debug.info(2, "Bitcell with 0 read/write ports") - tx = pbitcell.pbitcell(num_rw_ports=0,num_w_ports=2,num_r_ports=2) + tx = pbitcell() self.local_check(tx) + OPTS.sram_config.num_rw_ports=2 + OPTS.sram_config.num_w_ports=0 + OPTS.sram_config.num_r_ports=2 debug.info(2, "Bitcell with 0 write ports") - tx = pbitcell.pbitcell(num_rw_ports=2,num_w_ports=0,num_r_ports=2) + tx = pbitcell() self.local_check(tx) + OPTS.sram_config.num_rw_ports=2 + OPTS.sram_config.num_w_ports=2 + OPTS.sram_config.num_r_ports=0 debug.info(2, "Bitcell with 0 read ports") - tx = pbitcell.pbitcell(num_rw_ports=2,num_w_ports=2,num_r_ports=0) + tx = pbitcell() self.local_check(tx) + OPTS.sram_config.num_rw_ports=2 + OPTS.sram_config.num_w_ports=0 + OPTS.sram_config.num_r_ports=0 debug.info(2, "Bitcell with 0 read ports and 0 write ports") - tx = pbitcell.pbitcell(num_rw_ports=2,num_w_ports=0,num_r_ports=0) + tx = pbitcell() self.local_check(tx) globals.end_openram() diff --git a/compiler/tests/19_psingle_bank_test.py b/compiler/tests/19_psingle_bank_test.py index b98c2ff1..fd68409a 100755 --- a/compiler/tests/19_psingle_bank_test.py +++ b/compiler/tests/19_psingle_bank_test.py @@ -29,7 +29,6 @@ class psingle_bank_test(openram_test): OPTS.num_r_ports = 1 c = sram_config(word_size=4, num_words=16) - c.words_per_row=1 debug.info(1, "No column mux") name = "bank1_{0}rw_{1}w_{2}r_single".format(c.num_rw_ports, c.num_w_ports, c.num_r_ports) diff --git a/compiler/tests/20_sram_1bank_test.py b/compiler/tests/20_sram_1bank_test.py index ad5732a6..ce482b6d 100755 --- a/compiler/tests/20_sram_1bank_test.py +++ b/compiler/tests/20_sram_1bank_test.py @@ -21,27 +21,28 @@ class sram_1bank_test(openram_test): num_words=16, num_banks=1) + c.words_per_row=1 debug.info(1, "Single bank, no column mux with control logic") - a = sram(c, name="sram1") + a = sram(c, "sram1") self.local_check(a, final_verification=True) c.num_words=32 c.words_per_row=2 debug.info(1, "Single bank two way column mux with control logic") - a = sram(c, name="sram2") + a = sram(c, "sram2") self.local_check(a, final_verification=True) c.num_words=64 c.words_per_row=4 debug.info(1, "Single bank, four way column mux with control logic") - a = sram(c, name="sram3") + a = sram(c, "sram3") self.local_check(a, final_verification=True) c.word_size=2 c.num_words=128 c.words_per_row=8 debug.info(1, "Single bank, eight way column mux with control logic") - a = sram(c, name="sram4") + a = sram(c, "sram4") self.local_check(a, final_verification=True) globals.end_openram() diff --git a/compiler/tests/20_sram_2bank_test.py b/compiler/tests/20_sram_2bank_test.py index fd701860..ff9fbaea 100755 --- a/compiler/tests/20_sram_2bank_test.py +++ b/compiler/tests/20_sram_2bank_test.py @@ -22,27 +22,28 @@ class sram_2bank_test(openram_test): num_words=32, num_banks=2) + c.words_per_row=1 debug.info(1, "Two bank, no column mux with control logic") - a = sram(c, name="sram1") + a = sram(c, "sram1") self.local_check(a, final_verification=True) c.num_words=64 c.words_per_row=2 debug.info(1, "Two bank two way column mux with control logic") - a = sram(c, name="sram2") + a = sram(c, "sram2") self.local_check(a, final_verification=True) c.num_words=128 c.words_per_row=4 debug.info(1, "Two bank, four way column mux with control logic") - a = sram(c, name="sram3") + a = sram(c, "sram3") self.local_check(a, final_verification=True) c.word_size=2 c.num_words=256 c.words_per_row=8 debug.info(1, "Two bank, eight way column mux with control logic") - a = sram(c, name="sram4") + a = sram(c, "sram4") self.local_check(a, final_verification=True) globals.end_openram() diff --git a/compiler/tests/20_sram_4bank_test.py b/compiler/tests/20_sram_4bank_test.py index 19937d04..fb34d3b0 100755 --- a/compiler/tests/20_sram_4bank_test.py +++ b/compiler/tests/20_sram_4bank_test.py @@ -23,26 +23,26 @@ class sram_4bank_test(openram_test): num_banks=4) debug.info(1, "Four bank, no column mux with control logic") - a = sram(c, name="sram1") + a = sram(c, "sram1") self.local_check(a, final_verification=True) c.num_words=128 c.words_per_row=2 debug.info(1, "Four bank two way column mux with control logic") - a = sram(c, name="sram2") + a = sram(c, "sram2") self.local_check(a, final_verification=True) c.num_words=256 c.words_per_row=4 debug.info(1, "Four bank, four way column mux with control logic") - a = sram(word_size=16, num_words=256, num_banks=4, name="sram3") + a = sram(c, "sram3") self.local_check(a, final_verification=True) c.word_size=2 c.num_words=256 c.words_per_row=8 debug.info(1, "Four bank, eight way column mux with control logic") - a = sram.sram(word_size=2, num_words=256, num_banks=4, name="sram4") + a = sram.sram(c, "sram4") self.local_check(a, final_verification=True) globals.end_openram() diff --git a/compiler/tests/21_hspice_delay_test.py b/compiler/tests/21_hspice_delay_test.py index cfcf3173..93fc8413 100755 --- a/compiler/tests/21_hspice_delay_test.py +++ b/compiler/tests/21_hspice_delay_test.py @@ -32,7 +32,7 @@ class timing_sram_test(openram_test): c = sram_config(word_size=1, num_words=16, num_banks=1) - + c.words_per_row=1 debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank") s = sram(c, name="sram1") diff --git a/compiler/tests/21_ngspice_delay_test.py b/compiler/tests/21_ngspice_delay_test.py index 02557d96..d54cdf54 100755 --- a/compiler/tests/21_ngspice_delay_test.py +++ b/compiler/tests/21_ngspice_delay_test.py @@ -32,7 +32,7 @@ class timing_sram_test(openram_test): c = sram_config(word_size=1, num_words=16, num_banks=1) - + c.words_per_row=1 debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank") s = sram(c, name="sram1") diff --git a/compiler/tests/23_lib_sram_model_test.py b/compiler/tests/23_lib_sram_model_test.py index cec8b85a..8d5064d5 100755 --- a/compiler/tests/23_lib_sram_model_test.py +++ b/compiler/tests/23_lib_sram_model_test.py @@ -22,10 +22,9 @@ class lib_test(openram_test): c = sram_config(word_size=2, num_words=16, num_banks=1) - + c.words_per_row=1 debug.info(1, "Testing analytical timing for sample 2 bit, 16 words SRAM with 1 bank") s = sram(c, "sram_2_16_1_{0}".format(OPTS.tech_name)) - tempspice = OPTS.openram_temp + "temp.sp" s.sp_write(tempspice) diff --git a/compiler/tests/23_lib_sram_prune_test.py b/compiler/tests/23_lib_sram_prune_test.py index 37974bf7..952072aa 100755 --- a/compiler/tests/23_lib_sram_prune_test.py +++ b/compiler/tests/23_lib_sram_prune_test.py @@ -31,7 +31,7 @@ class lib_test(openram_test): c = sram_config(word_size=2, num_words=16, num_banks=1) - + c.words_per_row=1 debug.info(1, "Testing pruned timing for sample 2 bit, 16 words SRAM with 1 bank") s = sram(c, "sram_2_16_1_{0}".format(OPTS.tech_name)) diff --git a/compiler/tests/23_lib_sram_test.py b/compiler/tests/23_lib_sram_test.py index 5e6aa060..1b2d317c 100755 --- a/compiler/tests/23_lib_sram_test.py +++ b/compiler/tests/23_lib_sram_test.py @@ -31,7 +31,7 @@ class lib_test(openram_test): c = sram_config(word_size=2, num_words=16, num_banks=1) - + c.words_per_row=1 debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank") s = sram(c, "sram_2_16_1_{0}".format(OPTS.tech_name)) diff --git a/compiler/tests/24_lef_sram_test.py b/compiler/tests/24_lef_sram_test.py index b2566b84..f66104b6 100755 --- a/compiler/tests/24_lef_sram_test.py +++ b/compiler/tests/24_lef_sram_test.py @@ -22,7 +22,7 @@ class lef_test(openram_test): c = sram_config(word_size=2, num_words=16, num_banks=1) - + c.words_per_row=1 debug.info(1, "Testing LEF for sample 2 bit, 16 words SRAM with 1 bank") s = sram(c, "sram_2_16_1_{0}".format(OPTS.tech_name)) diff --git a/compiler/tests/25_verilog_sram_test.py b/compiler/tests/25_verilog_sram_test.py index 9412e8e8..48ba29e8 100755 --- a/compiler/tests/25_verilog_sram_test.py +++ b/compiler/tests/25_verilog_sram_test.py @@ -21,7 +21,7 @@ class verilog_test(openram_test): c = sram_config(word_size=2, num_words=16, num_banks=1) - + c.words_per_row=1 debug.info(1, "Testing Verilog for sample 2 bit, 16 words SRAM with 1 bank") s = sram(c, "sram_2_16_1_{0}".format(OPTS.tech_name)) From de6f22aa3c1f6ea0bb750ccaaa10183d3e393bac Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 4 Sep 2018 10:48:37 -0700 Subject: [PATCH 2/8] Fix unit test permissions --- compiler/tests/08_wordline_driver_test.py | 0 compiler/tests/09_sense_amp_array_test.py | 0 compiler/tests/10_write_driver_array_test.py | 0 compiler/tests/19_psingle_bank_test.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 compiler/tests/08_wordline_driver_test.py mode change 100644 => 100755 compiler/tests/09_sense_amp_array_test.py mode change 100644 => 100755 compiler/tests/10_write_driver_array_test.py mode change 100644 => 100755 compiler/tests/19_psingle_bank_test.py diff --git a/compiler/tests/08_wordline_driver_test.py b/compiler/tests/08_wordline_driver_test.py old mode 100644 new mode 100755 diff --git a/compiler/tests/09_sense_amp_array_test.py b/compiler/tests/09_sense_amp_array_test.py old mode 100644 new mode 100755 diff --git a/compiler/tests/10_write_driver_array_test.py b/compiler/tests/10_write_driver_array_test.py old mode 100644 new mode 100755 diff --git a/compiler/tests/19_psingle_bank_test.py b/compiler/tests/19_psingle_bank_test.py old mode 100644 new mode 100755 From 0adfe664296ccf8087689709c8d1291bb5bde62a Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 4 Sep 2018 11:15:18 -0700 Subject: [PATCH 3/8] Add total_ port variables to sram base class. --- compiler/sram_base.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/sram_base.py b/compiler/sram_base.py index 23412f05..ca3351b5 100644 --- a/compiler/sram_base.py +++ b/compiler/sram_base.py @@ -19,6 +19,10 @@ class sram_base(design): self.sram_config = sram_config sram_config.set_local_config(self) + self.total_write = OPTS.num_rw_ports + OPTS.num_w_ports + self.total_read = OPTS.num_rw_ports + OPTS.num_r_ports + self.total_ports = OPTS.num_rw_ports + OPTS.num_w_ports + OPTS.num_r_ports + self.bank_insts = [] From 6963a1092f2074fae0b2b27a7d9e2b109f626ede Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 4 Sep 2018 11:55:22 -0700 Subject: [PATCH 4/8] Make bitcell width/height not static. Update modules to use it for pbitcell. --- compiler/modules/delay_chain.py | 5 ----- compiler/modules/hierarchical_decoder.py | 3 ++- compiler/modules/sense_amp_array.py | 3 ++- compiler/modules/wordline_driver.py | 12 +++++++----- compiler/modules/write_driver_array.py | 5 +++-- compiler/pgates/pbitcell.py | 17 ++++++----------- compiler/pgates/pgate.py | 11 ++++++++++- compiler/pgates/pinv.py | 8 ++------ compiler/pgates/pinvbuf.py | 8 ++------ compiler/pgates/pnand2.py | 9 ++------- compiler/pgates/pnand3.py | 10 ++-------- compiler/pgates/pnor2.py | 9 ++------- compiler/pgates/single_level_column_mux.py | 2 ++ compiler/tests/19_psingle_bank_test.py | 2 +- 14 files changed, 43 insertions(+), 61 deletions(-) diff --git a/compiler/modules/delay_chain.py b/compiler/modules/delay_chain.py index b8a57f15..90175743 100644 --- a/compiler/modules/delay_chain.py +++ b/compiler/modules/delay_chain.py @@ -53,11 +53,6 @@ class delay_chain(design.design): self.add_pin("gnd") def add_modules(self): - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell = self.mod_bitcell() - self.inv = pinv(route_output=False) self.add_mod(self.inv) diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 7c90b1f1..0b44c8fc 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -24,7 +24,8 @@ class hierarchical_decoder(design.design): from importlib import reload c = reload(__import__(OPTS.bitcell)) self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell_height = self.mod_bitcell.height + b = self.mod_bitcell() + self.bitcell_height = b.height self.NAND_FORMAT = "DEC_NAND[{0}]" self.INV_FORMAT = "DEC_INV_[{0}]" diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index a02ffd9d..c48d280d 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -57,10 +57,11 @@ class sense_amp_array(design.design): self.amp = self.mod_sense_amp("sense_amp") self.add_mod(self.amp) + # This is just used for measurements, + # so don't add the module c = reload(__import__(OPTS.bitcell)) self.mod_bitcell = getattr(c, OPTS.bitcell) self.bitcell = self.mod_bitcell() - self.add_mod(self.bitcell) def create_sense_amp_array(self): self.local_insts = [] diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index 87b0430e..3deac4e1 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -50,6 +50,13 @@ class wordline_driver(design.design): def add_modules(self): + # This is just used for measurements, + # so don't add the module + from importlib import reload + c = reload(__import__(OPTS.bitcell)) + self.mod_bitcell = getattr(c, OPTS.bitcell) + self.bitcell = self.mod_bitcell() + self.inv = pinv() self.add_mod(self.inv) @@ -59,11 +66,6 @@ class wordline_driver(design.design): self.nand2 = pnand2() self.add_mod(self.nand2) - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - self.mod_bitcell = getattr(c, OPTS.bitcell) - self.bitcell = self.mod_bitcell() - self.add_mod(self.bitcell) def route_vdd_gnd(self): """ Add a pin for each row of vdd/gnd which are must-connects next level up. """ diff --git a/compiler/modules/write_driver_array.py b/compiler/modules/write_driver_array.py index 88d40c86..eff0c8d8 100644 --- a/compiler/modules/write_driver_array.py +++ b/compiler/modules/write_driver_array.py @@ -58,11 +58,12 @@ class write_driver_array(design.design): self.mod_write_driver = getattr(c, OPTS.write_driver) self.driver = self.mod_write_driver("write_driver") self.add_mod(self.driver) - + + # This is just used for measurements, + # so don't add the module c = reload(__import__(OPTS.bitcell)) self.mod_bitcell = getattr(c, OPTS.bitcell) self.bitcell = self.mod_bitcell() - self.add_mod(self.bitcell) def create_write_array(self): self.driver_insts = {} diff --git a/compiler/pgates/pbitcell.py b/compiler/pgates/pbitcell.py index 3ac0fa74..6f579c06 100644 --- a/compiler/pgates/pbitcell.py +++ b/compiler/pgates/pbitcell.py @@ -1,5 +1,4 @@ import contact -import pgate import design import debug from tech import drc, parameter, spice @@ -7,14 +6,11 @@ from vector import vector from ptx import ptx from globals import OPTS -class pbitcell(pgate.pgate): +class pbitcell(design.design): """ This module implements a parametrically sized multi-port bitcell, with a variable number of read/write, write, and read ports """ - - width = None - height = None def __init__(self): @@ -23,18 +19,17 @@ class pbitcell(pgate.pgate): self.num_r_ports = OPTS.num_r_ports name = "pbitcell_{0}RW_{1}W_{2}R".format(self.num_rw_ports, self.num_w_ports, self.num_r_ports) - pgate.pgate.__init__(self, name) + # This is not a pgate because pgates depend on the bitcell height! + design.design.__init__(self, name) debug.info(2, "create a multi-port bitcell with {0} rw ports, {1} w ports and {2} r ports".format(self.num_rw_ports, self.num_w_ports, self.num_r_ports)) self.create_netlist() - if not OPTS.netlist_only: - self.create_layout() + # We must always create the bitcell layout because + # some transistor sizes in the other netlists depend on it + self.create_layout() - # FIXME: Why is this static set here? - pbitcell.width = self.width - pbitcell.height = self.height def create_netlist(self): self.add_pins() diff --git a/compiler/pgates/pgate.py b/compiler/pgates/pgate.py index 4e47934d..ec3bed0c 100644 --- a/compiler/pgates/pgate.py +++ b/compiler/pgates/pgate.py @@ -11,10 +11,19 @@ class pgate(design.design): This is a module that implements some shared functions for parameterized gates. """ - def __init__(self, name): + def __init__(self, name, height=None): """ Creates a generic cell """ design.design.__init__(self, name) + if height: + self.height = height + elif not height: + from importlib import reload + c = reload(__import__(OPTS.bitcell)) + bitcell = getattr(c, OPTS.bitcell) + b = bitcell() + self.height = b.height + def connect_pin_to_rail(self,inst,pin,supply): """ Conencts a ptx pin to a supply rail. """ diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index e2e87053..f0df378d 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -17,26 +17,22 @@ class pinv(pgate.pgate): from center of rail to rail.. The route_output will route the output to the right side of the cell for easier access. """ - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - bitcell = getattr(c, OPTS.bitcell) unique_id = 1 - def __init__(self, size=1, beta=parameter["beta"], height=bitcell.height, route_output=True): + def __init__(self, size=1, beta=parameter["beta"], height=None, route_output=True): # We need to keep unique names because outputting to GDSII # will use the last record with a given name. I.e., you will # over-write a design in GDS if one has and the other doesn't # have poly connected, for example. name = "pinv_{}".format(pinv.unique_id) pinv.unique_id += 1 - pgate.pgate.__init__(self, name) + pgate.pgate.__init__(self, name, height) debug.info(2, "create pinv structure {0} with size of {1}".format(name, size)) self.nmos_size = size self.pmos_size = beta*size self.beta = beta - self.height = height # Maybe minimize height if not defined in future? self.route_output = False diff --git a/compiler/pgates/pinvbuf.py b/compiler/pgates/pinvbuf.py index e55fb649..328836dc 100644 --- a/compiler/pgates/pinvbuf.py +++ b/compiler/pgates/pinvbuf.py @@ -11,13 +11,9 @@ class pinvbuf(design.design): This is a simple inverter/buffer used for driving loads. It is used in the column decoder for 1:2 decoding and as the clock buffer. """ - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - bitcell = getattr(c, OPTS.bitcell) - unique_id = 1 - def __init__(self, driver_size=4, height=bitcell.height, name=""): + def __init__(self, driver_size=4, height=None, name=""): self.stage_effort = 4 self.row_height = height @@ -32,7 +28,7 @@ class pinvbuf(design.design): name = "pinvbuf_{0}_{1}_{2}".format(self.predriver_size, self.driver_size, pinvbuf.unique_id) pinvbuf.unique_id += 1 - design.design.__init__(self, name) + design.design.__init__(self, name) debug.info(1, "Creating {}".format(self.name)) self.create_netlist() diff --git a/compiler/pgates/pnand2.py b/compiler/pgates/pnand2.py index 99ae9f02..d38c7de4 100644 --- a/compiler/pgates/pnand2.py +++ b/compiler/pgates/pnand2.py @@ -12,24 +12,19 @@ class pnand2(pgate.pgate): This model use ptx to generate a 2-input nand within a cetrain height. """ - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - bitcell = getattr(c, OPTS.bitcell) - unique_id = 1 - def __init__(self, size=1, height=bitcell.height): + def __init__(self, size=1, height=None): """ Creates a cell for a simple 2 input nand """ name = "pnand2_{0}".format(pnand2.unique_id) pnand2.unique_id += 1 - pgate.pgate.__init__(self, name) + pgate.pgate.__init__(self, name, height) debug.info(2, "create pnand2 structure {0} with size of {1}".format(name, size)) self.nmos_size = 2*size self.pmos_size = parameter["beta"]*size self.nmos_width = self.nmos_size*drc["minwidth_tx"] self.pmos_width = self.pmos_size*drc["minwidth_tx"] - self.height = height # FIXME: Allow these to be sized debug.check(size==1,"Size 1 pnand2 is only supported now.") diff --git a/compiler/pgates/pnand3.py b/compiler/pgates/pnand3.py index 984ee417..b4e11b32 100644 --- a/compiler/pgates/pnand3.py +++ b/compiler/pgates/pnand3.py @@ -12,18 +12,13 @@ class pnand3(pgate.pgate): This model use ptx to generate a 2-input nand within a cetrain height. """ - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - mod_bitcell = getattr(c, OPTS.bitcell) - bitcell = mod_bitcell() - unique_id = 1 - def __init__(self, size=1, height=bitcell.height): + def __init__(self, size=1, height=None): """ Creates a cell for a simple 3 input nand """ name = "pnand3_{0}".format(pnand3.unique_id) pnand3.unique_id += 1 - pgate.pgate.__init__(self, name) + pgate.pgate.__init__(self, name, height) debug.info(2, "create pnand3 structure {0} with size of {1}".format(name, size)) # We have trouble pitch matching a 3x sizes to the bitcell... @@ -32,7 +27,6 @@ class pnand3(pgate.pgate): self.pmos_size = parameter["beta"]*size self.nmos_width = self.nmos_size*drc["minwidth_tx"] self.pmos_width = self.pmos_size*drc["minwidth_tx"] - self.height = height # FIXME: Allow these to be sized debug.check(size==1,"Size 1 pnand3 is only supported now.") diff --git a/compiler/pgates/pnor2.py b/compiler/pgates/pnor2.py index e19f03cf..8f7dcea4 100644 --- a/compiler/pgates/pnor2.py +++ b/compiler/pgates/pnor2.py @@ -12,17 +12,13 @@ class pnor2(pgate.pgate): This model use ptx to generate a 2-input nor within a cetrain height. """ - from importlib import reload - c = reload(__import__(OPTS.bitcell)) - bitcell = getattr(c, OPTS.bitcell) - unique_id = 1 - def __init__(self, size=1, height=bitcell.height): + def __init__(self, size=1, height=None): """ Creates a cell for a simple 2 input nor """ name = "pnor2_{0}".format(pnor2.unique_id) pnor2.unique_id += 1 - pgate.pgate.__init__(self, name) + pgate.pgate.__init__(self, name, height) debug.info(2, "create pnor2 structure {0} with size of {1}".format(name, size)) self.nmos_size = size @@ -30,7 +26,6 @@ class pnor2(pgate.pgate): self.pmos_size = 1.5*parameter["beta"]*size self.nmos_width = self.nmos_size*drc["minwidth_tx"] self.pmos_width = self.pmos_size*drc["minwidth_tx"] - self.height = height # FIXME: Allow these to be sized debug.check(size==1,"Size 1 pnor2 is only supported now.") diff --git a/compiler/pgates/single_level_column_mux.py b/compiler/pgates/single_level_column_mux.py index 604c9312..015b434a 100644 --- a/compiler/pgates/single_level_column_mux.py +++ b/compiler/pgates/single_level_column_mux.py @@ -39,6 +39,8 @@ class single_level_column_mux(design.design): self.add_wells() def add_modules(self): + # This is just used for measurements, + # so don't add the module from importlib import reload c = reload(__import__(OPTS.bitcell)) self.mod_bitcell = getattr(c, OPTS.bitcell) diff --git a/compiler/tests/19_psingle_bank_test.py b/compiler/tests/19_psingle_bank_test.py index bdb64f9e..f377a3db 100755 --- a/compiler/tests/19_psingle_bank_test.py +++ b/compiler/tests/19_psingle_bank_test.py @@ -11,7 +11,7 @@ import globals from globals import OPTS import debug -@unittest.skip("SKIPPING 19_psingle_bank_test") +#@unittest.skip("SKIPPING 19_psingle_bank_test") class psingle_bank_test(openram_test): def runTest(self): From 4fc9278b73c654e01d65ef8b2ff15fabe41766e9 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 4 Sep 2018 13:05:21 -0700 Subject: [PATCH 5/8] Convert bounding box layer for SCMOS to bb, gds layer 63. --- technology/scn3me_subm/gds_lib/cell_6t.gds | Bin 6144 -> 5916 bytes technology/scn3me_subm/gds_lib/dff.gds | Bin 16622 -> 16622 bytes technology/scn3me_subm/gds_lib/ms_flop.gds | Bin 18934 -> 18934 bytes .../scn3me_subm/gds_lib/replica_cell_6t.gds | Bin 6060 -> 6060 bytes technology/scn3me_subm/gds_lib/sense_amp.gds | Bin 10240 -> 8312 bytes technology/scn3me_subm/gds_lib/tri_gate.gds | Bin 4576 -> 4576 bytes .../scn3me_subm/gds_lib/write_driver.gds | Bin 11804 -> 11804 bytes technology/scn3me_subm/mag_lib/cell_6t.gds | Bin 5916 -> 0 bytes technology/scn3me_subm/mag_lib/cell_6t.mag | 10 +++++----- technology/scn3me_subm/mag_lib/dff.mag | 4 ++-- technology/scn3me_subm/mag_lib/ms_flop.mag | 4 ++-- .../scn3me_subm/mag_lib/replica_cell_6t.mag | 10 +++++----- technology/scn3me_subm/mag_lib/sense_amp.mag | 4 ++-- technology/scn3me_subm/mag_lib/tri_gate.mag | 4 ++-- .../scn3me_subm/mag_lib/write_driver.mag | 4 ++-- .../scn3me_subm/tech/SCN3ME_SUBM.30.tech | 12 +++++++++++- technology/scn3me_subm/tech/tech.py | 4 ++-- technology/scn3me_subm/tf/layers.map | 2 +- 18 files changed, 34 insertions(+), 24 deletions(-) delete mode 100644 technology/scn3me_subm/mag_lib/cell_6t.gds diff --git a/technology/scn3me_subm/gds_lib/cell_6t.gds b/technology/scn3me_subm/gds_lib/cell_6t.gds index ec9264568959cc70edee2dc6cb55ac528ede4993..20e5367ece732f8208aab30adb0584859e15655f 100644 GIT binary patch literal 5916 zcmbuDJ#3X_6vq#@x0eD1+sa2v3e;4PmQo5-sUJ~H*kEvAAcjPvH8M1Y7=w%q4w^79 zFqp`|K%xVK149Rg4#qGtI5;pcFgQ3k5EnnL=XcNh_kHfg^Eya!`Q84X=YP)g{XX}# zjm;Skaf7Cs`A`(Y&VefnCKU(|EW)Da1h0klg@@43vw=MB^yT89> zw&h*3iH(|jE{869dE&p>;U~X{A6?A-F+SvA{KT0Dp^L7k{U;ATts6)m z(8U4&k$V2k4qh`mdBbdespiV*&_ypV^B4YZ_s?(4j$DlWBQ8D)U39(CPwv)*XahWQ zQE`J_p7_mnjD?T=OB_f$(8VS{`-FOU#l=Ul|3uf*{P^+izgm+xid&VZe#Rev`N5Aa zdRgL+@gWD}Chor)y6Af1k33Zydw%tW{PYRt{>Z}~9lI2J74Di0UG(xa|F-q0J9bHo zIK+%kPfz{RGf|IrQy+4Mpo>lUr)MHBdyTcso*|CnR^?^>rE>oqx@)%lUF>!7)J`*W z(e>0n`q*szrr9&E)qM6BGj!3*Q~$nm;X81rCO&jA_jkL0{TR77Ez}&p8M^3gOY_rD z+Rj-g(jRoO$v^s7Z4k|93;hrF^fdpzbKyI1M+_hR$6u8v{_wERs4E`57rN+r;*UP# zqp#x8d!dU>{=HAaM|<%@eCT46pK->=_>1_^#oQnLBp3Y`HKwBLY5&QCkNhHiKoR^s@|M}w>t-Tx6c@Ul`q?);x1T>>lf3BS!1KE=Kl9ER ziC-ihy6AeEpL*P%cb}gU;A&NcJEK13G>=D#mL`O3Ls?wAX7 z(aX#HCkETkbC3EW&pp~N4m|$~f1E$`oAXCJcrA2sp#OzG&KZ2{d69AB{1Kb{Bg>I% z>vb{O!kEyesyyxgn8ulz6`=wg$fb~4wTlOnOuMc0%5$N2DD zf$SvF$=NWgAexr-7r+(Hcdmg_? zobpU@J@s?Oa_6W0BK<%YT~GbAlX~PAX$QLKdZVAb+}lOsC@yTu&pKn?87qYny$)|{ETt< z%illv8T(+by!4;!Kfl7?x*(eA+zK}N>-Ot+AY;aR2ihNO_OtFdC%7|+_|QeyllI4+ zp`WZD5g&U%bUpR|zwu+8#kkEciIJCeNB*k3mwzS%hzz-2i|@8^VVa1 LTE*Jzy=dFtRZEf{ literal 6144 zcmd6rJ&YAq6vxlL_jY)=&*kk3>@HaZf(ZKoEbJ+D^l^W4=FiNmo_WT~O_m?|-}9ey?#J9a zcP+D)Wi~s~vPo;(4x6x!_0#`HZQRDJXQ!;!%2qGE{l*7t@0)FJkG}BYrzc+e@vHmK zon1eA^UK%H*z9P7H_P6-w6^y8v&q}(nq`l-Y~Hf*mYFT~+k?UHH_i4va6bQo*|C#m zqV#3e0q-bysheADE(%$dk2F*zlLUG>t=g@5~b&C@OwP|9n)s> zOC@<;@!Zfqw(fa|<+p!Xl-`uT7L(`4PaXaowb#b4*8c-n&1Puz?`5WULz=Uewf>9ODQ9=zjZ?UP@Wo*3l!+KHo9eAFOHALb_>KjTGyQF>ySpKlKG zK;rp!5T(cYecTS-apGg#MCrr)a~=0nH~B^B>3P-qkCgN8=Ue-lbM&sCU!wH(waCx6 zr>}R&S@_heC3zo;_8`CS735>jU<{{kl$4$r`nxNhAMQMB_Sk17$zQZL`tcFR8sK|V zl%Ck=CmuhwvyY0>6GK0-`Xx7hQF>zNXOCr!A>&WYqV&W@Kk@ikugsq)Ju&oiUJwsi zclbr=iJ@QP23hyapGg0U_C`PP#F3ZtMwFgd^&c(QzrQbdd2h(goQcvCLqF#Obwa*@ zm^)GWrunPopWN`h4>I1=A+jeI?Roy5-~WzTwv+o`HZ{V(yZE=)Z~NYnYRzV{kJf4x zCx>o~^w8gSddk-_JEl{5&T5Zq{w-aP+tPI(HzoZ2%hH?t9y5B^$w>2+FG}C^#@F(* zQxN}8JBIYcuzp6DTLt9ngZ!fO#L&;|(r3tQF@B=-#6~~y_?ZLV98r2==&#;#iRaA~ z$zQaGepV&@zZrj#=M?Q>{j59UAvZ++FG^1g{p>WvL2jyyzbL)Quezab zx+4CfJ;?9lrkgc&Gk&797Nw`>Rr4RO?qAb4{MN(z^;@ne{cks}n!mf^ zaqRB+*)yEdoBhl&J2PYsIb}rYi9!9IWB(y1K5~oFW51sW+>9nS%(yA>E{W20W9s>d zu^gQk{I%!!DksL9?|H?;9DGw1j^d0N=3t+G=2z>^WFM}srbCLqL=N-t<&b`o=bd-| zttWSE@^l~dzdZjAT=libm}}iRrRS{9UmCyC{~ylJnx8$AcLtJ|^Fx%L80Kfc;eCVn z*#AW7o8F&V{_6RSkMqLm{V&>s{KV+jebkJiAjZC#{S8>rt#U<^C;c Lt)$oMfBf?h%e|6$ diff --git a/technology/scn3me_subm/gds_lib/dff.gds b/technology/scn3me_subm/gds_lib/dff.gds index b96235c7500aba5314ed95369b44d5000c60b5ff..07c37298b1293dad95cbcfb12e4c3222dddffa7f 100644 GIT binary patch delta 96 zcmaFY$oQ_2QHg<#fr){cL57iup^Sl(frWvGL6Jca&NgHan5d+zj#YwzgN-dEEscSJ ag@b{CjhBhRe)1c8i;XD__LEf{P5}Txb`Avq delta 93 zcmaFY$oQ_2QHg<#fr){cL57iup$y0pVBlvEXAnkWi%nEgmcc5)z`@3rl9sk{VY594 T2Ll5eFB3!X#2kysDh{UrF7FL_ diff --git a/technology/scn3me_subm/gds_lib/ms_flop.gds b/technology/scn3me_subm/gds_lib/ms_flop.gds index 0e06e5328c1ef9dfee97b69b81905929d2c06d86..e1c071bea7fc0075f13ae6143e1c4c103f6f6f98 100644 GIT binary patch delta 100 zcmex1nep3XMkNL|1||k(1{p>shB5|D1{MY$21N!fINOjxcA}EHHdYA+9yYez;`p?j e`~n6B77hjmHeMzM`^hC977KGcHm~vUVgvxOLl2Yy delta 98 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 diff --git a/technology/scn3me_subm/mag_lib/cell_6t.gds b/technology/scn3me_subm/mag_lib/cell_6t.gds deleted file mode 100644 index c6fdb0e8208d82752b8df1f873200eaf17b8e3c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5916 zcmbuDJ&cr96owD8v$G?tIJ@q`E?Hm=g6uE5>?-R|3>rGNFiIjZB$~KJ3SuY>p`@_T zgo1*?L<$NLEhsD~wy>ZuhLXatL*4ElH_cx7%WQR{=IcL(E_!=&%uN2det+~` z-4KbRxUly<^)J(9TeJ}DJIx0pS#jV=Y{EKz{!ZX)2o18KeSqthS zx?c3Z^ouX<_h#Z;Q*nc?XZ&Wnw!=q${2B*3L&6mqKo_zqPab@FZXk0&7YFz&;MqI zE_!>`zkf4)2XEEHhc4#*-R?g>NA4YqHOH=pF8bKA`I#qU=d2T%54u?Lk3P~EL^H<1 z{DVC`n}7di_zvC@!^iybSM3>pc-Uw36_@UWF1nua$DHvoS8?f1=wivg?{WATFMfy* zT`c*jGd}7s;zJkn{+K7Zn7^o+imqqpPab^a7nuXPIN)DS_fLC0ysS4dAn$E-(e*U{ zQ~s$NW;?H%iNsM{=z7-AzTv(7;+dM{MHdI&-+lR6cg{%sBJt2g*R%QQ$NhQFshY%5 z+^Rk6XU=@6waD4UchSFR{nUs11AY;2Rkt1o?hk$QrypY{mq;ANt=fzEx%aYuB5@QK z4%~nH@^i)wKZyB?oZsl8>)HI&p1iD|Nd3{peExW641E#r9dY_z=yt~u2W*yjv=;FZo_vI&Fx>l?mYk@9$dz%0F;P`p((O=}f$N0s8 z_g~_V^M`qJ{)mUKgf0%uKk>&ogO5EgQa8>YvE*;BN3NY$#TW}UVN6wfcK%a0!ng0S z7(Uhnf7PD)SL^!4bMo~4JM@i{Puh!q?mX%JdF`5fL2u9aVYnn{EU;e=A0CXg)X|DnSa!WzZIyTc;t5IqU#xdb8NbLp&_&m? ze#S{Z@{5cEU39(ZColJQkvNJAOZj=uSa)hAvVJ-{s`hMt-ZSalgSzRxBYJzrAI}-@ zE%J+;Mf@!y4!pmT^TTYU9evZkpLmu>+VMs(e=#uW6v;8o*xk(dq8wO>;HfC<2j4E z&98`&m*> rect -8 29 42 51 << pwell >> @@ -105,13 +105,13 @@ rect 6 2 10 48 rect 24 -2 28 48 rect 32 33 36 48 rect 32 -2 36 29 -<< m3p >> +<< bb >> rect 0 0 34 46 << labels >> rlabel metal2 0 0 0 0 1 gnd rlabel metal2 34 0 34 0 1 gnd rlabel m2contact 17 46 17 46 5 vdd -rlabel metal1 4 7 4 7 1 WL -rlabel metal2 8 43 8 43 1 BL -rlabel metal2 26 43 26 43 1 BR +rlabel metal2 8 43 8 43 1 bl +rlabel metal2 26 43 26 43 1 br +rlabel metal1 4 7 4 7 1 wl << end >> diff --git a/technology/scn3me_subm/mag_lib/dff.mag b/technology/scn3me_subm/mag_lib/dff.mag index 19825153..46d22c84 100644 --- a/technology/scn3me_subm/mag_lib/dff.mag +++ b/technology/scn3me_subm/mag_lib/dff.mag @@ -1,6 +1,6 @@ magic tech scmos -timestamp 1518823399 +timestamp 1536089597 << nwell >> rect 0 48 109 103 << pwell >> @@ -266,7 +266,7 @@ rect 6 30 10 50 rect 22 20 26 57 rect 70 44 74 70 rect 70 20 74 40 -<< m3p >> +<< bb >> rect 0 0 109 100 << labels >> rlabel m2contact 15 34 15 34 4 clk diff --git a/technology/scn3me_subm/mag_lib/ms_flop.mag b/technology/scn3me_subm/mag_lib/ms_flop.mag index 8b3b1d40..713d264f 100644 --- a/technology/scn3me_subm/mag_lib/ms_flop.mag +++ b/technology/scn3me_subm/mag_lib/ms_flop.mag @@ -1,6 +1,6 @@ magic tech scmos -timestamp 1523479368 +timestamp 1536089622 << nwell >> rect -2 0 18 200 << pwell >> @@ -280,7 +280,7 @@ rect 14 8 20 9 rect 14 4 15 8 rect 19 4 20 8 rect 14 3 20 4 -<< m3p >> +<< bb >> rect 0 0 34 200 << labels >> rlabel metal1 0 8 0 8 2 clk diff --git a/technology/scn3me_subm/mag_lib/replica_cell_6t.mag b/technology/scn3me_subm/mag_lib/replica_cell_6t.mag index 52dd6265..d0dc472f 100644 --- a/technology/scn3me_subm/mag_lib/replica_cell_6t.mag +++ b/technology/scn3me_subm/mag_lib/replica_cell_6t.mag @@ -1,6 +1,6 @@ magic tech scmos -timestamp 1521677136 +timestamp 1536091380 << nwell >> rect -8 29 42 51 << pwell >> @@ -106,13 +106,13 @@ rect 6 2 10 48 rect 24 -2 28 48 rect 32 33 36 48 rect 32 -2 36 29 -<< m3p >> +<< bb >> rect 0 0 34 46 << labels >> rlabel metal2 0 0 0 0 1 gnd rlabel metal2 34 0 34 0 1 gnd rlabel m2contact 17 46 17 46 5 vdd -rlabel metal1 4 7 4 7 1 WL -rlabel metal2 8 43 8 43 1 BL -rlabel metal2 26 43 26 43 1 BR +rlabel metal2 8 43 8 43 1 bl +rlabel metal2 26 43 26 43 1 br +rlabel metal1 4 7 4 7 1 wl << end >> diff --git a/technology/scn3me_subm/mag_lib/sense_amp.mag b/technology/scn3me_subm/mag_lib/sense_amp.mag index b29f7da0..e5fa4373 100644 --- a/technology/scn3me_subm/mag_lib/sense_amp.mag +++ b/technology/scn3me_subm/mag_lib/sense_amp.mag @@ -1,6 +1,6 @@ magic tech scmos -timestamp 1524065550 +timestamp 1536089670 << nwell >> rect 0 0 40 102 << pwell >> @@ -122,7 +122,7 @@ rect 20 44 22 48 rect 3 0 7 11 rect 10 0 14 44 rect 20 0 24 44 -<< m3p >> +<< bb >> rect 0 0 34 163 << labels >> flabel metal1 0 149 0 149 4 FreeSans 26 0 0 0 en diff --git a/technology/scn3me_subm/mag_lib/tri_gate.mag b/technology/scn3me_subm/mag_lib/tri_gate.mag index a393074b..bda635c7 100644 --- a/technology/scn3me_subm/mag_lib/tri_gate.mag +++ b/technology/scn3me_subm/mag_lib/tri_gate.mag @@ -1,6 +1,6 @@ magic tech scmos -timestamp 1524499924 +timestamp 1536089695 << nwell >> rect -2 45 38 73 << pwell >> @@ -86,7 +86,7 @@ rect 24 19 28 23 << metal2 >> rect 15 34 25 38 rect 15 0 19 34 -<< m3p >> +<< bb >> rect 0 0 34 73 << labels >> rlabel metal1 0 12 0 12 3 en diff --git a/technology/scn3me_subm/mag_lib/write_driver.mag b/technology/scn3me_subm/mag_lib/write_driver.mag index 80e09d11..ab2014aa 100644 --- a/technology/scn3me_subm/mag_lib/write_driver.mag +++ b/technology/scn3me_subm/mag_lib/write_driver.mag @@ -1,6 +1,6 @@ magic tech scmos -timestamp 1524499497 +timestamp 1536089714 << nwell >> rect -3 101 37 138 rect -3 0 37 51 @@ -209,7 +209,7 @@ rect 10 196 14 202 rect 20 193 24 202 rect 20 177 24 189 rect 15 0 19 6 -<< m3p >> +<< bb >> rect 0 0 34 202 << labels >> rlabel metal2 15 1 15 1 1 din diff --git a/technology/scn3me_subm/tech/SCN3ME_SUBM.30.tech b/technology/scn3me_subm/tech/SCN3ME_SUBM.30.tech index bf6ce64b..be511001 100644 --- a/technology/scn3me_subm/tech/SCN3ME_SUBM.30.tech +++ b/technology/scn3me_subm/tech/SCN3ME_SUBM.30.tech @@ -276,6 +276,11 @@ cifoutput style lambda=0.30(p) scalefactor 30 15 + # This is a custom section to add bounding boxes in OpenRAM + layer BB bb + labels bb + calma 63 0 + layer CWN nwell,rnw bloat-or pdiff,rpd,pdc/a,pfet * 180 bloat-or nsd,nsc/a * 90 @@ -1506,7 +1511,12 @@ cifinput style lambda=0.30(p) scalefactor 30 - layer nwell CWN + # This is a custom section to add bounding boxes in OpenRAM + layer bb BB + labels BB + calma 63 0 + +layer nwell CWN and-not CWNR and-not CTA labels CWN diff --git a/technology/scn3me_subm/tech/tech.py b/technology/scn3me_subm/tech/tech.py index d69a7d7f..4998c5b6 100755 --- a/technology/scn3me_subm/tech/tech.py +++ b/technology/scn3me_subm/tech/tech.py @@ -39,8 +39,8 @@ layer["via1"] = 50 layer["metal2"] = 51 layer["via2"] = 61 layer["metal3"] = 62 -layer["text"] = 83 -layer["boundary"] = 83 +layer["text"] = 63 +layer["boundary"] = 63 ################################################### ##END GDS Layer Map diff --git a/technology/scn3me_subm/tf/layers.map b/technology/scn3me_subm/tf/layers.map index d10d5f2d..b5440f23 100644 --- a/technology/scn3me_subm/tf/layers.map +++ b/technology/scn3me_subm/tf/layers.map @@ -13,4 +13,4 @@ Metal2 drawing 51 0 Via2 drawing 61 0 Metal3 drawing 62 0 Glass drawing 52 0 -text drawing 83 0 +comment drawing 63 0 From 763f1e8deea8eef0169903842df1dc0255a4ae69 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 4 Sep 2018 14:03:15 -0700 Subject: [PATCH 6/8] Finish renaming replica bitcell and bitline pin names. --- compiler/modules/replica_bitcell.py | 2 +- compiler/modules/replica_bitline.py | 4 ++-- .../scn3me_subm/gds_lib/replica_cell_6t.gds | Bin 6060 -> 6060 bytes 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/modules/replica_bitcell.py b/compiler/modules/replica_bitcell.py index 5ec524f4..7bbdbe06 100644 --- a/compiler/modules/replica_bitcell.py +++ b/compiler/modules/replica_bitcell.py @@ -10,7 +10,7 @@ class replica_bitcell(design.design): is a hand-made cell, so the layout and netlist should be available in the technology library. """ - pin_names = ["BL", "BR", "WL", "vdd", "gnd"] + pin_names = ["bl", "br", "wl", "vdd", "gnd"] (width,height) = utils.get_libcell_size("replica_cell_6t", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "replica_cell_6t", GDS["unit"], layer["boundary"]) diff --git a/compiler/modules/replica_bitline.py b/compiler/modules/replica_bitline.py index b15f4515..6ca4a829 100644 --- a/compiler/modules/replica_bitline.py +++ b/compiler/modules/replica_bitline.py @@ -228,7 +228,7 @@ class replica_bitline(design.design): # 3. Route the contact of previous route to the bitcell WL # route bend of previous net to bitcell WL - wl_offset = self.rbc_inst.get_pin("WL").lc() + wl_offset = self.rbc_inst.get_pin("wl").lc() xmid_point= 0.5*(wl_offset.x+contact_offset.x) wl_mid1 = vector(xmid_point,contact_offset.y) wl_mid2 = vector(xmid_point,wl_offset.y) @@ -247,7 +247,7 @@ class replica_bitline(design.design): # Route the connection of the source route to the RBL bitline (left) # Via will go halfway down from the bitcell - bl_offset = self.rbc_inst.get_pin("BL").bc() + bl_offset = self.rbc_inst.get_pin("bl").bc() # Route down a pitch so we can use M2 routing bl_down_offset = bl_offset - vector(0, self.m2_pitch) self.add_path("metal2",[source_offset, bl_down_offset, bl_offset]) diff --git a/technology/scn3me_subm/gds_lib/replica_cell_6t.gds b/technology/scn3me_subm/gds_lib/replica_cell_6t.gds index 4336cc246d4c6955adf6e0190585cb91226ba027..12d97796c04c2045340cafe3ef594d99adef8042 100644 GIT binary patch delta 25 ccmZ3Zzeaz8EGr)aBLn|LC3^^CW15>d07_v65C8xG delta 25 ccmZ3Zzeaz8EGsVqGXvX1C3^^CW15>d07=OO00000 From d721fae5b0014de292080610180f2aa17872565e Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 4 Sep 2018 14:33:14 -0700 Subject: [PATCH 7/8] Change labels in replica cell for freepdk45 too --- .../freepdk45/gds_lib/replica_cell_6t.gds | Bin 20480 -> 20480 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/technology/freepdk45/gds_lib/replica_cell_6t.gds b/technology/freepdk45/gds_lib/replica_cell_6t.gds index 9b301c08ae8f2b857d6cbdef1795cc73b82ea61a..2881a883709d5f4b04a8632ed039b1c2e7e61b9c 100644 GIT binary patch delta 961 zcmYLGPiPZa9G*9wPA6&Fnl@>gKWemC-6en8Ce|iRXWmT5aio)O+3kWXi(pX?Qe=^p zJrwE?N*WJJ>nDilK`7qDgQH#w5<;0q@F3!0PagCt9;A3FEc@FY*2Bm9e((2v-}}Ay z+(*oP#Ma}d1A-*<3TYuLghct`rOOwtFa0S9k&aF^z5U?vr(eF6j{Y8dTYd6YNOg*& z>=tApC`5&EpD@AS1h8@VIU}uVNaUF zYiSyFX$EH{QcEV@kj@eFn|pl>%YC!IVOsb$5gCNnx37%!sw_oc)>ZY^I33iK;$Z# znt__eVQA_dqAgX0s~Rv=4w2BBrq;BJR>eiFLcC(Y)GJ<7cNtvWggL`K>C8V2Elc(I z=^EQ?=?tPtvYA(2OQ-Q%o$?5h{v%#GS)7`S!LR;-r&SYI2qT1#&L~!#dE^KmX6JF6 VkaG^;x7p(UIyjs1=H{NUe*s1~O0@t0 delta 949 zcmYjNU1%It7@a#iJDuHRH`#QPY&MCpR*Tte_h;Oul%_D6t zu4`#+L^HLdHmTX#1eO14_cmXKsh`22=%6oJxFDK)(Z_o`HdbO1Pj%kvxA8D$qaAaR zj4M1aByJmZct#5eqk&;;^`G*?afut_9eCtuY!`2hZNVH(i(GOWQNlqlq2MLxXVK5vhGj86CebIXW4rjw+(tkC zJ60w*YGwmJW*X>a=%4uzPkDDZ(Loe{1vl~%EBV(jny(|8p?=1NKU0UrILi6>Bv*r% zqbK8s(>3&`CA?`LS;o;6>!*BNnX18>YGG&cCag)$on?LY2+?uA6W($5DP-_dsf@#X z3cZqp;anP*OE!!W|FL)#wbRS`n?9Zt+qhP^f_~9~S?nTO;#Zfrszq*esfnn-HiafU za)N9X1IpQMk!xB|VKo1dK=0H5)+x^Mk_^4)ga|L3yeVLvbi(0_F@c>E9P>o5AI%Fy z3mkFb|Jr%ZGfzVznq%`h=46u`&9Zow#k1Tad6+N3E*J4=Wfp&yQeoF-b7?E+HMu`H ztD}3?IauzB{jM!As7c-*{a56|u$#DFZK7LsAgdHrTex3gUSVEgUMbSOfX&k;9+$_T zb^4;5)YWAa%XMA(_^s5&xAHu$%U9t_2ZLq+Md(e5fg{l+6rno~jv5Nx2A#=zgYR_* zL0v)BoxAlj`0nC4Y+ZZ1)oxs;*<8C{%7}v_23R zc8XZu$l>;Y;GqdKO!L Date: Wed, 5 Sep 2018 10:59:41 -0700 Subject: [PATCH 8/8] Change options in pbitcell test to be global again. --- compiler/tests/04_pbitcell_test.py | 60 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/compiler/tests/04_pbitcell_test.py b/compiler/tests/04_pbitcell_test.py index 70f51a99..0b6bd8f5 100755 --- a/compiler/tests/04_pbitcell_test.py +++ b/compiler/tests/04_pbitcell_test.py @@ -20,72 +20,72 @@ class pbitcell_test(openram_test): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) from pbitcell import pbitcell import tech - OPTS.sram_config.num_rw_ports=1 - OPTS.sram_config.num_w_ports=1 - OPTS.sram_config.num_r_ports=1 + OPTS.num_rw_ports=1 + OPTS.num_w_ports=1 + OPTS.num_r_ports=1 debug.info(2, "Bitcell with 1 of each port: read/write, write, and read") tx = pbitcell() self.local_check(tx) - OPTS.sram_config.num_rw_ports=0 - OPTS.sram_config.num_w_ports=1 - OPTS.sram_config.num_r_ports=1 + OPTS.num_rw_ports=0 + OPTS.num_w_ports=1 + OPTS.num_r_ports=1 debug.info(2, "Bitcell with 0 read/write ports") tx = pbitcell() self.local_check(tx) - OPTS.sram_config.num_rw_ports=1 - OPTS.sram_config.num_w_ports=0 - OPTS.sram_config.num_r_ports=1 + OPTS.num_rw_ports=1 + OPTS.num_w_ports=0 + OPTS.num_r_ports=1 debug.info(2, "Bitcell with 0 write ports") tx = pbitcell() self.local_check(tx) - OPTS.sram_config.num_rw_ports=1 - OPTS.sram_config.num_w_ports=1 - OPTS.sram_config.num_r_ports=0 + OPTS.num_rw_ports=1 + OPTS.num_w_ports=1 + OPTS.num_r_ports=0 debug.info(2, "Bitcell with 0 read ports") tx = pbitcell() self.local_check(tx) - OPTS.sram_config.num_rw_ports=1 - OPTS.sram_config.num_w_ports=0 - OPTS.sram_config.num_r_ports=0 + OPTS.num_rw_ports=1 + OPTS.num_w_ports=0 + OPTS.num_r_ports=0 debug.info(2, "Bitcell with 0 read ports and 0 write ports") tx = pbitcell() self.local_check(tx) - OPTS.sram_config.num_rw_ports=2 - OPTS.sram_config.num_w_ports=2 - OPTS.sram_config.num_r_ports=2 + OPTS.num_rw_ports=2 + OPTS.num_w_ports=2 + OPTS.num_r_ports=2 debug.info(2, "Bitcell with 2 of each port: read/write, write, and read") tx = pbitcell() self.local_check(tx) - OPTS.sram_config.num_rw_ports=0 - OPTS.sram_config.num_w_ports=2 - OPTS.sram_config.num_r_ports=2 + OPTS.num_rw_ports=0 + OPTS.num_w_ports=2 + OPTS.num_r_ports=2 debug.info(2, "Bitcell with 0 read/write ports") tx = pbitcell() self.local_check(tx) - OPTS.sram_config.num_rw_ports=2 - OPTS.sram_config.num_w_ports=0 - OPTS.sram_config.num_r_ports=2 + OPTS.num_rw_ports=2 + OPTS.num_w_ports=0 + OPTS.num_r_ports=2 debug.info(2, "Bitcell with 0 write ports") tx = pbitcell() self.local_check(tx) - OPTS.sram_config.num_rw_ports=2 - OPTS.sram_config.num_w_ports=2 - OPTS.sram_config.num_r_ports=0 + OPTS.num_rw_ports=2 + OPTS.num_w_ports=2 + OPTS.num_r_ports=0 debug.info(2, "Bitcell with 0 read ports") tx = pbitcell() self.local_check(tx) - OPTS.sram_config.num_rw_ports=2 - OPTS.sram_config.num_w_ports=0 - OPTS.sram_config.num_r_ports=0 + OPTS.num_rw_ports=2 + OPTS.num_w_ports=0 + OPTS.num_r_ports=0 debug.info(2, "Bitcell with 0 read ports and 0 write ports") tx = pbitcell() self.local_check(tx)