From 2833b706c7adaeec0e7602ebd989ea7c3fb93b92 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Fri, 29 Jun 2018 09:23:23 -0700 Subject: [PATCH 1/3] Fix duplicate name check for some modules by checking if name is a substring. Allows pbitcell to pass. --- compiler/base/design.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/base/design.py b/compiler/base/design.py index c1c976c5..794bb79a 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -40,10 +40,12 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout): 'hierarchical_predecode3x8'] if name not in design.name_map: design.name_map.append(name) - elif self.__class__.__name__ in ok_list: - pass else: - debug.error("Duplicate layout reference name {0} of class {1}. GDS2 requires names be unique.".format(name,self.__class__),-1) + for ok_names in ok_list: + if ok_names in self.__class__.__name__: + break + else: + debug.error("Duplicate layout reference name {0} of class {1}. GDS2 requires names be unique.".format(name,self.__class__),-1) def setup_drc_constants(self): """ These are some DRC constants used in many places in the compiler.""" From 8cee26bc8c6cabcb1df58a2ad924a38e628b17d4 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Fri, 29 Jun 2018 09:23:43 -0700 Subject: [PATCH 2/3] Allow python 3.5. Make easier to revise required version. --- compiler/globals.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/globals.py b/compiler/globals.py index 58922e52..86d091b1 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -89,11 +89,13 @@ def print_banner(): def check_versions(): """ Run some checks of required software versions. """ - # Now require python >=3.6 + # Now require python >=3.5 major_python_version = sys.version_info.major minor_python_version = sys.version_info.minor - if not (major_python_version == 3 and minor_python_version >= 6): - debug.error("Python 3.6 or greater is required.",-1) + major_required = 3 + minor_required = 5 + if not (major_python_version == major_required and minor_python_version >= minor_required): + debug.error("Python {0}.{1} or greater is required.".format(major_required,minor_required),-1) # FIXME: Check versions of other tools here?? # or, this could be done in each module (e.g. verify, characterizer, etc.) From df2dce2439a4da184b3caacd6836b255411a1374 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Fri, 29 Jun 2018 09:45:07 -0700 Subject: [PATCH 3/3] Fix module import names for python3. Rename parse function to something meaningful. --- compiler/characterizer/charutils.py | 3 ++- compiler/characterizer/delay.py | 28 ++++++++++----------- compiler/characterizer/setup_hold.py | 8 +++--- compiler/tests/21_hspice_delay_test.py | 2 +- compiler/tests/21_hspice_setuphold_test.py | 2 +- compiler/tests/21_ngspice_delay_test.py | 2 +- compiler/tests/21_ngspice_setuphold_test.py | 2 +- 7 files changed, 24 insertions(+), 23 deletions(-) diff --git a/compiler/characterizer/charutils.py b/compiler/characterizer/charutils.py index 38ed8957..bc4beb88 100644 --- a/compiler/characterizer/charutils.py +++ b/compiler/characterizer/charutils.py @@ -8,7 +8,7 @@ def relative_compare(value1,value2,error_tolerance=0.001): return (abs(value1 - value2) / max(value1,value2) <= error_tolerance) -def parse_output(filename, key): +def parse_spice_list(filename, key): """Parses a hspice output.lis file for a key value""" if OPTS.spice_name == "xa" : # customsim has a different output file name @@ -22,6 +22,7 @@ def parse_output(filename, key): except IOError: debug.error("Unable to open spice output file: {0}".format(full_filename),1) contents = f.read() + f.close() # val = re.search(r"{0}\s*=\s*(-?\d+.?\d*\S*)\s+.*".format(key), contents) val = re.search(r"{0}\s*=\s*(-?\d+.?\d*[e]?[-+]?[0-9]*\S*)\s+.*".format(key), contents) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 6b58d5d3..a7b2df7c 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -339,16 +339,16 @@ class delay(): # Checking from not data_value to data_value self.write_delay_stimulus() self.stim.run_sim() - delay_hl = parse_output("timing", "delay_hl") - delay_lh = parse_output("timing", "delay_lh") - slew_hl = parse_output("timing", "slew_hl") - slew_lh = parse_output("timing", "slew_lh") + delay_hl = parse_spice_list("timing", "delay_hl") + delay_lh = parse_spice_list("timing", "delay_lh") + slew_hl = parse_spice_list("timing", "slew_hl") + slew_lh = parse_spice_list("timing", "slew_lh") delays = (delay_hl, delay_lh, slew_hl, slew_lh) - read0_power=parse_output("timing", "read0_power") - write0_power=parse_output("timing", "write0_power") - read1_power=parse_output("timing", "read1_power") - write1_power=parse_output("timing", "write1_power") + read0_power=parse_spice_list("timing", "read0_power") + write0_power=parse_spice_list("timing", "write0_power") + read1_power=parse_spice_list("timing", "read1_power") + write1_power=parse_spice_list("timing", "write1_power") if not self.check_valid_delays(delays): return (False,{}) @@ -378,13 +378,13 @@ class delay(): self.write_power_stimulus(trim=False) self.stim.run_sim() - leakage_power=parse_output("timing", "leakage_power") + leakage_power=parse_spice_list("timing", "leakage_power") debug.check(leakage_power!="Failed","Could not measure leakage power.") self.write_power_stimulus(trim=True) self.stim.run_sim() - trim_leakage_power=parse_output("timing", "leakage_power") + trim_leakage_power=parse_spice_list("timing", "leakage_power") debug.check(trim_leakage_power!="Failed","Could not measure leakage power.") # For debug, you sometimes want to inspect each simulation. @@ -473,10 +473,10 @@ class delay(): # Checking from not data_value to data_value self.write_delay_stimulus() self.stim.run_sim() - delay_hl = parse_output("timing", "delay_hl") - delay_lh = parse_output("timing", "delay_lh") - slew_hl = parse_output("timing", "slew_hl") - slew_lh = parse_output("timing", "slew_lh") + delay_hl = parse_spice_list("timing", "delay_hl") + delay_lh = parse_spice_list("timing", "delay_lh") + slew_hl = parse_spice_list("timing", "slew_hl") + slew_lh = parse_spice_list("timing", "slew_lh") # if it failed or the read was longer than a period if type(delay_hl)!=float or type(delay_lh)!=float or type(slew_lh)!=float or type(slew_hl)!=float: debug.info(2,"Invalid measures: Period {0}, delay_hl={1}ns, delay_lh={2}ns slew_hl={3}ns slew_lh={4}ns".format(self.period, diff --git a/compiler/characterizer/setup_hold.py b/compiler/characterizer/setup_hold.py index 4f261b5a..aaeff0cd 100644 --- a/compiler/characterizer/setup_hold.py +++ b/compiler/characterizer/setup_hold.py @@ -186,8 +186,8 @@ class setup_hold(): target_time=feasible_bound, correct_value=correct_value) self.stim.run_sim() - ideal_clk_to_q = convert_to_float(parse_output("timing", "clk2q_delay")) - setuphold_time = convert_to_float(parse_output("timing", "setup_hold_time")) + ideal_clk_to_q = convert_to_float(parse_spice_list("timing", "clk2q_delay")) + setuphold_time = convert_to_float(parse_spice_list("timing", "setup_hold_time")) debug.info(2,"*** {0} CHECK: {1} Ideal Clk-to-Q: {2} Setup/Hold: {3}".format(mode, correct_value,ideal_clk_to_q,setuphold_time)) if type(ideal_clk_to_q)!=float or type(setuphold_time)!=float: @@ -219,8 +219,8 @@ class setup_hold(): self.stim.run_sim() - clk_to_q = convert_to_float(parse_output("timing", "clk2q_delay")) - setuphold_time = convert_to_float(parse_output("timing", "setup_hold_time")) + clk_to_q = convert_to_float(parse_spice_list("timing", "clk2q_delay")) + setuphold_time = convert_to_float(parse_spice_list("timing", "setup_hold_time")) if type(clk_to_q)==float and (clk_to_q<1.1*ideal_clk_to_q) and type(setuphold_time)==float: if mode == "SETUP": # SETUP is clk-din, not din-clk setuphold_time *= -1e9 diff --git a/compiler/tests/21_hspice_delay_test.py b/compiler/tests/21_hspice_delay_test.py index 731c0d90..9ac3db2e 100644 --- a/compiler/tests/21_hspice_delay_test.py +++ b/compiler/tests/21_hspice_delay_test.py @@ -45,7 +45,7 @@ class timing_sram_test(openram_test): debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data)) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) - d = delay.delay(s,tempspice,corner) + d = delay(s,tempspice,corner) import tech loads = [tech.spice["msflop_in_cap"]*4] slews = [tech.spice["rise_time"]*2] diff --git a/compiler/tests/21_hspice_setuphold_test.py b/compiler/tests/21_hspice_setuphold_test.py index 4d469ac3..78403a56 100644 --- a/compiler/tests/21_hspice_setuphold_test.py +++ b/compiler/tests/21_hspice_setuphold_test.py @@ -33,7 +33,7 @@ class timing_setup_test(openram_test): slews = [tech.spice["rise_time"]*2] corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) - sh = setup_hold.setup_hold(corner) + sh = setup_hold(corner) data = sh.analyze(slews,slews) #print data if OPTS.tech_name == "freepdk45": diff --git a/compiler/tests/21_ngspice_delay_test.py b/compiler/tests/21_ngspice_delay_test.py index 6ebf4dd2..7f7bfd39 100644 --- a/compiler/tests/21_ngspice_delay_test.py +++ b/compiler/tests/21_ngspice_delay_test.py @@ -43,7 +43,7 @@ class timing_sram_test(openram_test): debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data)) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) - d = delay.delay(s,tempspice,corner) + d = delay(s,tempspice,corner) import tech loads = [tech.spice["msflop_in_cap"]*4] slews = [tech.spice["rise_time"]*2] diff --git a/compiler/tests/21_ngspice_setuphold_test.py b/compiler/tests/21_ngspice_setuphold_test.py index 9bf0fd4c..9a8ff67c 100644 --- a/compiler/tests/21_ngspice_setuphold_test.py +++ b/compiler/tests/21_ngspice_setuphold_test.py @@ -32,7 +32,7 @@ class timing_setup_test(openram_test): slews = [tech.spice["rise_time"]*2] corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) - sh = setup_hold.setup_hold(corner) + sh = setup_hold(corner) data = sh.analyze(slews,slews) #print data if OPTS.tech_name == "freepdk45":