diff --git a/LICENSE b/LICENSE index 761f6e8b..75c009a8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2019 Regents of the University of California and The Board +Copyright (c) 2018-2019 Regents of the University of California and The Board of Regents for the Oklahoma Agricultural and Mechanical College (acting for and on behalf of Oklahoma State University) All rights reserved. diff --git a/compiler/base/hierarchy_design.py b/compiler/base/hierarchy_design.py index 5b45abe1..6a6003a2 100644 --- a/compiler/base/hierarchy_design.py +++ b/compiler/base/hierarchy_design.py @@ -37,12 +37,17 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): return inst_map - def DRC_LVS(self, final_verification=False): + def DRC_LVS(self, final_verification=False, top_level=False): """Checks both DRC and LVS for a module""" + + # Final verification option does not allow nets to be connected by label. # Unit tests will check themselves. + if OPTS.is_unit_test: + return + if not OPTS.check_lvsdrc: + return # Do not run if disabled in options. - - if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)): + if (OPTS.inline_lvsdrc or top_level): global total_drc_errors global total_lvs_errors diff --git a/compiler/example_configs/example_config_1rw_1r_scn4m_subm.py b/compiler/example_configs/example_config_1rw_1r_scn4m_subm.py index 8703967b..5dad0207 100644 --- a/compiler/example_configs/example_config_1rw_1r_scn4m_subm.py +++ b/compiler/example_configs/example_config_1rw_1r_scn4m_subm.py @@ -10,6 +10,9 @@ process_corners = ["TT"] supply_voltages = [5.0] temperatures = [25] +route_supplies = True +check_lvsdrc = True + output_path = "temp" output_name = "sram_1rw_1r_{0}_{1}_{2}".format(word_size,num_words,tech_name) diff --git a/compiler/example_configs/example_config_1w_1r_scn4m_subm.py b/compiler/example_configs/example_config_1w_1r_scn4m_subm.py index 56f6edfd..c698a035 100644 --- a/compiler/example_configs/example_config_1w_1r_scn4m_subm.py +++ b/compiler/example_configs/example_config_1w_1r_scn4m_subm.py @@ -10,6 +10,9 @@ process_corners = ["TT"] supply_voltages = [5.0] temperatures = [25] +route_supplies = True +check_lvsdrc = True + output_path = "temp" output_name = "sram_1w_1r_{0}_{1}_{2}".format(word_size,num_words,tech_name) diff --git a/compiler/example_configs/example_config_freepdk45.py b/compiler/example_configs/example_config_freepdk45.py index ac02e514..73e15b6d 100644 --- a/compiler/example_configs/example_config_freepdk45.py +++ b/compiler/example_configs/example_config_freepdk45.py @@ -6,6 +6,9 @@ process_corners = ["TT"] supply_voltages = [1.0] temperatures = [25] +route_supplies = True +check_lvsdrc = True + output_path = "temp" output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name) diff --git a/compiler/example_configs/example_config_scn4m_subm.py b/compiler/example_configs/example_config_scn4m_subm.py index 7fafeb08..cf973225 100644 --- a/compiler/example_configs/example_config_scn4m_subm.py +++ b/compiler/example_configs/example_config_scn4m_subm.py @@ -6,6 +6,9 @@ process_corners = ["TT"] supply_voltages = [5.0] temperatures = [25] +route_supplies = True +check_lvsdrc = True + output_path = "temp" output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name) diff --git a/compiler/globals.py b/compiler/globals.py index 590fc97f..3d4b2129 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -79,10 +79,6 @@ def print_banner(): debug.print_raw("|=========" + "Computer Science and Engineering Department".center(60) + "=========|") debug.print_raw("|=========" + "University of California Santa Cruz".center(60) + "=========|") debug.print_raw("|=========" + " ".center(60) + "=========|") - debug.print_raw("|=========" + "VLSI Computer Architecture Research Group".center(60) + "=========|") - debug.print_raw("|=========" + "Electrical and Computer Engineering Department".center(60) + "=========|") - debug.print_raw("|=========" + "Oklahoma State University".center(60) + "=========|") - debug.print_raw("|=========" + " ".center(60) + "=========|") user_info = "Usage help: openram-user-group@ucsc.edu" debug.print_raw("|=========" + user_info.center(60) + "=========|") dev_info = "Development help: openram-dev-group@ucsc.edu" @@ -478,11 +474,14 @@ def report_status(): OPTS.num_r_ports, OPTS.num_w_ports)) if OPTS.netlist_only: - debug.print_raw("Netlist only mode (no physical design is being done).") + debug.print_raw("Netlist only mode (no physical design is being done, netlist_only=False to disable).") + if not OPTS.route_supplies: + debug.print_raw("Design supply routing skipped for run-time (incomplete GDS will not be saved, route_supplies=True to enable).") + if not OPTS.inline_lvsdrc: - debug.print_raw("DRC/LVS/PEX is only run on the top-level design.") + debug.print_raw("DRC/LVS/PEX is only run on the top-level design to save run-time (inline_lvsdrc=True to enable).") if not OPTS.check_lvsdrc: - debug.print_raw("DRC/LVS/PEX is completely disabled.") + debug.print_raw("DRC/LVS/PEX is disabled (check_lvsdrc=True to enable).") diff --git a/compiler/openram.py b/compiler/openram.py index 0fe3f7cd..555f2c8e 100755 --- a/compiler/openram.py +++ b/compiler/openram.py @@ -48,8 +48,13 @@ debug.print_raw("Words per row: {}".format(c.words_per_row)) #from parser import * output_extensions = ["sp","v","lib","py","html","log"] +# Only output lef/gds if back-end if not OPTS.netlist_only: - output_extensions.extend(["gds","lef"]) + output_extensions.extend(["lef"]) + # Only output gds if final routing + if OPTS.route_supplies: + output_extensions.extend(["gds"]) + output_files = ["{0}{1}.{2}".format(OPTS.output_path,OPTS.output_name,x) for x in output_extensions] debug.print_raw("Output files are: ") for path in output_files: diff --git a/compiler/options.py b/compiler/options.py index f3410f86..a6e5726a 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -8,10 +8,41 @@ class options(optparse.Values): that is the sole required command-line positional argument for openram.py. """ + ################### + # Configuration options + ################### # This is the technology directory. openram_tech = "" + # This is the name of the technology. tech_name = "" + + # Port configuration (1-2 ports allowed) + num_rw_ports = 1 + num_r_ports = 0 + num_w_ports = 0 + + # These will get initialized by the user or the tech file + supply_voltages = "" + temperatures = "" + process_corners = "" + + # Size parameters must be specified by user in config file. + #num_words = 0 + #word_size = 0 + # You can manually specify banks, but it is better to auto-detect it. + num_banks = 1 + + ################### + # Optimization options + ################### + # Uses the delay chain size in the tech.py file rather automatic sizing. + use_tech_delay_chain_size = False + + + ################### + # Debug options. + ################### # This is the temp directory where all intermediate results are stored. try: # If user defined the temporary location in their environment, use it @@ -22,12 +53,29 @@ class options(optparse.Values): # This is the verbosity level to control debug information. 0 is none, 1 # is minimal, etc. debug_level = 0 + + ################### + # Run-time vs accuracy options. + # Default, sacrifice accuracy/completeness for speed. + # Must turn on options for verification, final routing, etc. + ################### # When enabled, layout is not generated (and no DRC or LVS are performed) netlist_only = False + # Whether we should do the final power routing + route_supplies = False # This determines whether LVS and DRC is checked at all. - check_lvsdrc = True + check_lvsdrc = False # This determines whether LVS and DRC is checked for every submodule. inline_lvsdrc = False + # Remove noncritical memory cells for characterization speed-up + trim_netlist = True + # Run with extracted parasitics + use_pex = False + + + ################### + # Tool options + ################### # Variable to select the variant of spice spice_name = "" # The spice executable being used which is derived from the user PATH. @@ -40,12 +88,9 @@ class options(optparse.Values): drc_exe = None lvs_exe = None pex_exe = None + # Should we print out the banner at startup print_banner = True - # Run with extracted parasitics - use_pex = False - # Remove noncritical memory cells for characterization speed-up - trim_netlist = True # Use detailed LEF blockages detailed_blockages = True # Define the output file paths @@ -57,28 +102,10 @@ class options(optparse.Values): # Purge the temp directory after a successful run (doesn't purge on errors, anyhow) purge_temp = True - # These are the configuration parameters - 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 - #word_size = 0 - - # You can manually specify banks, but it is better to auto-detect it. - num_banks = 1 - - #Uses the delay chain size in the tech.py file rather automatic sizing. - use_tech_delay_chain_size = False - + ################### # These are the default modules that can be over-riden + ################### bank_select = "bank_select" bitcell_array = "bitcell_array" bitcell = "bitcell" diff --git a/compiler/sram.py b/compiler/sram.py index 5ff28d47..d2234d92 100644 --- a/compiler/sram.py +++ b/compiler/sram.py @@ -62,19 +62,22 @@ class sram(): """ Save all the output files while reporting time to do it as well. """ if not OPTS.netlist_only: - # Write the layout - start_time = datetime.datetime.now() - gdsname = OPTS.output_path + self.s.name + ".gds" - debug.print_raw("GDS: Writing to {0}".format(gdsname)) - self.gds_write(gdsname) - print_time("GDS", datetime.datetime.now(), start_time) - # Create a LEF physical model start_time = datetime.datetime.now() lefname = OPTS.output_path + self.s.name + ".lef" debug.print_raw("LEF: Writing to {0}".format(lefname)) self.lef_write(lefname) print_time("LEF", datetime.datetime.now(), start_time) + + if OPTS.route_supplies: + # Write the layout + start_time = datetime.datetime.now() + gdsname = OPTS.output_path + self.s.name + ".gds" + debug.print_raw("GDS: Writing to {0}".format(gdsname)) + self.gds_write(gdsname) + print_time("GDS", datetime.datetime.now(), start_time) + + # Save the spice file start_time = datetime.datetime.now() diff --git a/compiler/sram_base.py b/compiler/sram_base.py index 611900e4..22f1c354 100644 --- a/compiler/sram_base.py +++ b/compiler/sram_base.py @@ -110,7 +110,8 @@ class sram_base(design, verilog, lef): self.height = highest_coord[1] start_time = datetime.now() - self.DRC_LVS(final_verification=True) + # We only enable final verification if we have routed the design + self.DRC_LVS(final_verification=OPTS.route_supplies, top_level=True) if not OPTS.is_unit_test: print_time("Verification",datetime.now(), start_time) @@ -120,6 +121,10 @@ class sram_base(design, verilog, lef): def route_supplies(self): """ Route the supply grid and connect the pins to them. """ + # Do not route the power supply + if not OPTS.route_supplies: + return + for inst in self.insts: self.copy_power_pins(inst,"vdd") self.copy_power_pins(inst,"gnd") diff --git a/compiler/tests/27_worst_case_delay_test.py b/compiler/tests/27_worst_case_delay_test.py index 0b208f62..da632862 100755 --- a/compiler/tests/27_worst_case_delay_test.py +++ b/compiler/tests/27_worst_case_delay_test.py @@ -22,7 +22,6 @@ class worst_case_timing_sram_test(openram_test): OPTS.analytical_delay = False OPTS.netlist_only = True OPTS.trim_netlist = False - OPTS.check_lvsdrc = True # This is a hack to reload the characterizer __init__ with the spice version diff --git a/compiler/tests/config_freepdk45.py b/compiler/tests/config_freepdk45.py index aaaa4c37..7a1da315 100755 --- a/compiler/tests/config_freepdk45.py +++ b/compiler/tests/config_freepdk45.py @@ -6,4 +6,6 @@ process_corners = ["TT"] supply_voltages = [1.0] temperatures = [25] +route_supplies = True +check_lvsdrc = True diff --git a/compiler/tests/config_scn3me_subm.py b/compiler/tests/config_freepdk45_front_end.py similarity index 59% rename from compiler/tests/config_scn3me_subm.py rename to compiler/tests/config_freepdk45_front_end.py index 330d463b..81da24e8 100755 --- a/compiler/tests/config_scn3me_subm.py +++ b/compiler/tests/config_freepdk45_front_end.py @@ -1,8 +1,11 @@ word_size = 1 num_words = 16 -tech_name = "scn3me_subm" +tech_name = "freepdk45" process_corners = ["TT"] -supply_voltages = [5.0] +supply_voltages = [1.0] temperatures = [25] + + + diff --git a/compiler/tests/config_scn4m_subm.py b/compiler/tests/config_scn4m_subm.py index e847745b..adb1c99d 100755 --- a/compiler/tests/config_scn4m_subm.py +++ b/compiler/tests/config_scn4m_subm.py @@ -6,6 +6,9 @@ process_corners = ["TT"] supply_voltages = [5.0] temperatures = [25] +route_supplies = True +check_lvsdrc = True + drc_name = "magic" lvs_name = "netgen" pex_name = "magic" diff --git a/compiler/tests/config_scn4m_subm_front_end.py b/compiler/tests/config_scn4m_subm_front_end.py new file mode 100755 index 00000000..e847745b --- /dev/null +++ b/compiler/tests/config_scn4m_subm_front_end.py @@ -0,0 +1,12 @@ +word_size = 1 +num_words = 16 + +tech_name = "scn4m_subm" +process_corners = ["TT"] +supply_voltages = [5.0] +temperatures = [25] + +drc_name = "magic" +lvs_name = "netgen" +pex_name = "magic" + diff --git a/compiler/verify/magic.py b/compiler/verify/magic.py index 7db9a5c2..5c5a65da 100644 --- a/compiler/verify/magic.py +++ b/compiler/verify/magic.py @@ -347,8 +347,7 @@ def run_pex(name, gds_name, sp_name, output=None, final_verification=False): out_errors = len(stdouterrors) - assert(os.path.isfile(output)) - #correct_port(name, output, sp_name) + debug.check(os.path.isfile(output),"Couldn't find PEX extracted output.") return out_errors