diff --git a/compiler/base/custom_cell_properties.py b/compiler/base/custom_cell_properties.py index 76bb10ce..b2697472 100644 --- a/compiler/base/custom_cell_properties.py +++ b/compiler/base/custom_cell_properties.py @@ -93,9 +93,9 @@ class cell: # It is assumed it is [nwell, pwell] self._body_bias = body_bias self._port_map['vnb'] = body_bias[0] - self._port_types['vnb'] = "POWER" + self._port_types['vnb'] = "GROUND" self._port_map['vpb'] = body_bias[1] - self._port_types['vpb'] = "GROUND" + self._port_types['vpb'] = "POWER" @property def port_types(self): diff --git a/compiler/base/pin_layout.py b/compiler/base/pin_layout.py index ff137022..cc13e049 100644 --- a/compiler/base/pin_layout.py +++ b/compiler/base/pin_layout.py @@ -52,7 +52,7 @@ class pin_layout: from tech import layer_override_name if layer_override[name]: self.lpp = layer_override[name] - self.layer = "m1" + self.layer = "pwellp" self._recompute_hash() return except: @@ -406,6 +406,13 @@ class pin_layout: try: from tech import label_purpose + try: + from tech import layer_override_purpose + if pin_layer_num in layer_override_purpose: + layer_num = layer_override_purpose[pin_layer_num][0] + label_purpose = layer_override_purpose[pin_layer_num][1] + except: + pass except ImportError: label_purpose = purpose diff --git a/compiler/characterizer/functional.py b/compiler/characterizer/functional.py index 9fad2be5..e7d03f25 100644 --- a/compiler/characterizer/functional.py +++ b/compiler/characterizer/functional.py @@ -81,7 +81,11 @@ class functional(simulation): self.create_graph() self.set_internal_spice_names() self.q_name, self.qbar_name = self.get_bit_name() - debug.info(2, "q name={0}\nqbar name={1}".format(self.q_name, self.qbar_name)) + debug.info(2, "q:\t\t{0}".format(self.q_name)) + debug.info(2, "qbar:\t{0}".format(self.qbar_name)) + debug.info(2, "s_en:\t{0}".format(self.sen_name)) + debug.info(2, "bl:\t{0}".format(self.bl_name)) + debug.info(2, "br:\t{0}".format(self.br_name)) # Number of checks can be changed self.num_cycles = cycles @@ -141,23 +145,25 @@ class functional(simulation): comment = self.gen_cycle_comment("noop", "0" * self.word_size, "0" * self.addr_size, "0" * self.num_wmasks, 0, self.t_current) self.add_noop_all_ports(comment) - # 1. Write all the write ports first to seed a bunch of locations. - for port in self.write_ports: - addr = self.gen_addr() - (word, spare) = self.gen_data() - combined_word = self.combine_word(spare, word) - comment = self.gen_cycle_comment("write", combined_word, addr, "1" * self.num_wmasks, port, self.t_current) - self.add_write_one_port(comment, addr, spare + word, "1" * self.num_wmasks, port) - self.stored_words[addr] = word - self.stored_spares[addr[:self.addr_spare_index]] = spare - # All other read-only ports are noops. - for port in self.read_ports: - if port not in self.write_ports: - self.add_noop_one_port(port) - self.cycle_times.append(self.t_current) - self.t_current += self.period - self.check_lengths() + # 1. Write all the write ports 2x to seed a bunch of locations. + for i in range(3): + for port in self.write_ports: + addr = self.gen_addr() + (word, spare) = self.gen_data() + combined_word = self.combine_word(spare, word) + comment = self.gen_cycle_comment("write", combined_word, addr, "1" * self.num_wmasks, port, self.t_current) + self.add_write_one_port(comment, addr, spare + word, "1" * self.num_wmasks, port) + self.stored_words[addr] = word + self.stored_spares[addr[:self.addr_spare_index]] = spare + + # All other read-only ports are noops. + for port in self.read_ports: + if port not in self.write_ports: + self.add_noop_one_port(port) + self.cycle_times.append(self.t_current) + self.t_current += self.period + self.check_lengths() # 2. Read at least once. For multiport, it is important that one # read cycle uses all RW and R port to read from the same @@ -297,38 +303,6 @@ class functional(simulation): self.read_results.append([sp_read_value, dout_port, eo_period, cycle]) return (1, "SUCCESS") - def combine_word(self, spare, word): - if len(spare) > 0: - return spare + "+" + word - - return word - - def format_value(self, value): - """ Format in better readable manner """ - - def delineate(word): - # Create list of chars in reverse order - split_word = list(reversed([x for x in word])) - # Add underscore every 4th char - split_word2 = [x + '_' * (n != 0 and n % 4 == 0) for n, x in enumerate(split_word)] - # Join the word unreversed back together - new_word = ''.join(reversed(split_word2)) - return(new_word) - - # Split extra cols - if self.num_spare_cols > 0: - vals = value[self.num_spare_cols:] - spare_vals = value[:self.num_spare_cols] - else: - vals = value - spare_vals = "" - - # Insert underscores - vals = delineate(vals) - spare_vals = delineate(spare_vals) - - return self.combine_word(spare_vals, vals) - def check_stim_results(self): for i in range(len(self.read_check)): if self.read_check[i][0] != self.read_results[i][0]: @@ -372,7 +346,8 @@ class functional(simulation): def gen_data(self): """ Generates a random word to write. """ - random_value = random.randint(0, self.max_data) + # Don't use 0 or max value + random_value = random.randint(1, self.max_data - 1) data_bits = binary_repr(random_value, self.word_size) if self.num_spare_cols>0: random_value = random.randint(0, self.max_col_data) @@ -431,11 +406,11 @@ class functional(simulation): # Write important signals to stim file self.sf.write("\n\n* Important signals for debug\n") - self.sf.write("* bl: {0}\n".format(self.bl_name.format(port))) - self.sf.write("* br: {0}\n".format(self.br_name.format(port))) - self.sf.write("* s_en: {0}\n".format(self.sen_name)) - self.sf.write("* q: {0}\n".format(self.q_name)) - self.sf.write("* qbar: {0}\n".format(self.qbar_name)) + self.sf.write("* bl:\t{0}\n".format(self.bl_name.format(port))) + self.sf.write("* br:\t{0}\n".format(self.br_name.format(port))) + self.sf.write("* s_en:\t{0}\n".format(self.sen_name)) + self.sf.write("* q:\t{0}\n".format(self.q_name)) + self.sf.write("* qbar:\t{0}\n".format(self.qbar_name)) # Write debug comments to stim file self.sf.write("\n\n* Sequence of operations\n") @@ -498,7 +473,7 @@ class functional(simulation): for (word, dout_port, eo_period, cycle) in self.read_check: t_initial = eo_period - t_final = eo_period + t_final = eo_period + 0.01 * self.period num_bits = self.word_size + self.num_spare_cols for bit in range(num_bits): signal_name = "{0}_{1}".format(dout_port, bit) diff --git a/compiler/characterizer/simulation.py b/compiler/characterizer/simulation.py index 4df83d96..b0ee56f3 100644 --- a/compiler/characterizer/simulation.py +++ b/compiler/characterizer/simulation.py @@ -372,6 +372,38 @@ class simulation(): time_spacing, comment)) + def combine_word(self, spare, word): + if len(spare) > 0: + return spare + "+" + word + + return word + + def format_value(self, value): + """ Format in better readable manner """ + + def delineate(word): + # Create list of chars in reverse order + split_word = list(reversed([x for x in word])) + # Add underscore every 4th char + split_word2 = [x + '_' * (n != 0 and n % 4 == 0) for n, x in enumerate(split_word)] + # Join the word unreversed back together + new_word = ''.join(reversed(split_word2)) + return(new_word) + + # Split extra cols + if self.num_spare_cols > 0: + vals = value[self.num_spare_cols:] + spare_vals = value[:self.num_spare_cols] + else: + vals = value + spare_vals = "" + + # Insert underscores + vals = delineate(vals) + spare_vals = delineate(spare_vals) + + return self.combine_word(spare_vals, vals) + def gen_cycle_comment(self, op, word, addr, wmask, port, t_current): if op == "noop": str = "\tIdle during cycle {0} ({1}ns - {2}ns)" @@ -483,8 +515,6 @@ class simulation(): self.sen_name = sen_with_port debug.warning("Error occurred while determining SEN name. Can cause faults in simulation.") - debug.info(2, "s_en name = {}".format(self.sen_name)) - column_addr = self.get_column_addr() bl_name_port, br_name_port = self.get_bl_name(self.graph.all_paths, port) port_pos = -1 - len(str(column_addr)) - len(str(port)) @@ -505,11 +535,12 @@ class simulation(): '{}{}_{}'.format(self.dout_name, port, self.probe_data)) self.sen_name = self.get_sen_name(self.graph.all_paths) - debug.info(2, "s_en name = {}".format(self.sen_name)) + #debug.info(2, "s_en {}".format(self.sen_name)) self.bl_name = "bl{0}_{1}".format(port, OPTS.word_size - 1) self.br_name = "br{0}_{1}".format(port, OPTS.word_size - 1) - debug.info(2, "bl name={}, br name={}".format(self.bl_name, self.br_name)) + # debug.info(2, "bl name={0}".format(self.bl_name)) + # debug.info(2, "br name={0}".format(self.br_name)) def get_sen_name(self, paths, assumed_port=None): """ diff --git a/compiler/characterizer/stimuli.py b/compiler/characterizer/stimuli.py index f546cb96..b9e4b3c7 100644 --- a/compiler/characterizer/stimuli.py +++ b/compiler/characterizer/stimuli.py @@ -222,7 +222,7 @@ class stimuli(): def gen_meas_value(self, meas_name, dout, t_initial, t_final): measure_string=".meas tran {0} FIND v({1}) AT={2}n\n\n".format(meas_name.lower(), dout, (t_initial + t_final) / 2) - # measure_string=".meas tran {0} AVG v({1}) FROM={2}n TO={3}n\n\n".format(meas_name.lower(), dout, t_initial, t_final) + #measure_string=".meas tran {0} AVG v({1}) FROM={2}n TO={3}n\n\n".format(meas_name.lower(), dout, t_initial, t_final) self.sf.write(measure_string) def write_control(self, end_time, runlvl=4): @@ -237,12 +237,13 @@ class stimuli(): reltol = 0.005 # 0.5% else: reltol = 0.001 # 0.1% - timestep = 10 # ps, was 5ps but ngspice was complaining the timestep was too small in certain tests. + timestep = 10 # ps if OPTS.spice_name == "ngspice": self.sf.write(".TEMP {}\n".format(self.temperature)) # UIC is needed for ngspice to converge - self.sf.write(".TRAN {0}p {1}n UIC\n".format(timestep, end_time)) + # Format: .tran tstep tstop < tstart < tmax >> + self.sf.write(".TRAN {0}p {1}n 0n {0}p UIC\n".format(timestep, end_time)) # ngspice sometimes has convergence problems if not using gear method # which is more accurate, but slower than the default trapezoid method # Do not remove this or it may not converge due to some "pa_00" nodes @@ -268,7 +269,8 @@ class stimuli(): self.sf.write("simulator lang=spice\n") elif OPTS.spice_name in ["hspice", "xa"]: self.sf.write(".TEMP {}\n".format(self.temperature)) - self.sf.write(".TRAN {0}p {1}n UIC\n".format(timestep, end_time)) + # Format: .tran tstep tstop < tstart < tmax >> + self.sf.write(".TRAN {0}p {1}n 0n {0}p UIC\n".format(timestep, end_time)) self.sf.write(".OPTIONS POST=1 RUNLVL={0} PROBE\n".format(runlvl)) self.sf.write(".OPTIONS PSF=1 \n") self.sf.write(".OPTIONS HIER_DELIM=1 \n") @@ -276,7 +278,9 @@ class stimuli(): self.sf.write(".OPTIONS DEVICE TEMP={}\n".format(self.temperature)) self.sf.write(".OPTIONS MEASURE MEASFAIL=1\n") self.sf.write(".OPTIONS LINSOL type=klu\n") - self.sf.write(".TRAN {0}p {1}n\n".format(timestep, end_time)) + self.sf.write(".OPTIONS TIMEINT RELTOL=1e-6 ABSTOL=1e-10 method=gear minorder=2\n") + # Format: .TRAN + self.sf.write(".TRAN {0}p {1}n 0n {0}p\n".format(timestep, end_time)) elif OPTS.spice_name: debug.error("Unkown spice simulator {}".format(OPTS.spice_name), -1) diff --git a/compiler/example_configs/sky130_sram_common.py b/compiler/example_configs/sky130_sram_common.py index a827b5a9..445c88cc 100644 --- a/compiler/example_configs/sky130_sram_common.py +++ b/compiler/example_configs/sky130_sram_common.py @@ -12,6 +12,7 @@ nominal_corner_only = True route_supplies = "ring" #route_supplies = "left" check_lvsdrc = True +uniquify = True #perimeter_pins = False #netlist_only = True #analytical_delay = False diff --git a/compiler/gdsMill/gdsMill/vlsiLayout.py b/compiler/gdsMill/gdsMill/vlsiLayout.py index c3469203..466f4be6 100644 --- a/compiler/gdsMill/gdsMill/vlsiLayout.py +++ b/compiler/gdsMill/gdsMill/vlsiLayout.py @@ -81,7 +81,7 @@ class VlsiLayout: coordinatesRotate.extend((newX,newY)) return coordinatesRotate - def uniquify(self): + def uniquify(self, prefix_name=None): new_structures = {} if self.rootStructureName[-1] == "\x00": prefix = self.rootStructureName[0:-1] + "_" @@ -92,7 +92,10 @@ class VlsiLayout: base_name = name[0:-1] else: base_name = name - if name != self.rootStructureName: + # Don't do library cells + if prefix_name and base_name.startswith(prefix_name): + new_name = name + elif name != self.rootStructureName: new_name = self.padText(prefix + base_name) else: new_name = name @@ -105,7 +108,11 @@ class VlsiLayout: base_sref_name = sref.sName[0:-1] else: base_sref_name = sref.sName - new_sref_name = self.padText(prefix + base_sref_name) + # Don't do library cells + if prefix_name and base_sref_name.startswith(prefix_name): + new_sref_name = sref.sName + else: + new_sref_name = self.padText(prefix + base_sref_name) sref.sName = new_sref_name #print("SREF: {0} -> {1}".format(base_sref_name, new_sref_name)) self.structures = new_structures @@ -770,7 +777,13 @@ class VlsiLayout: from tech import layer_override if layer_override[label_text]: shapes = self.getAllShapes((layer_override[label_text][0], None)) - lpp = layer_override[label_text] + if not shapes: + shapes = self.getAllShapes(lpp) + else: + lpp = layer_override[label_text] + + + except: pass for boundary in shapes: diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index 8fc176c7..666458ed 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -620,7 +620,7 @@ class bank(design.design): self.copy_power_pins(inst, "gnd", add_vias=False) if 'vpb' in self.bitcell_array_inst.mod.pins and 'vnb' in self.bitcell_array_inst.mod.pins: - for pin_name, supply_name in zip(['vpb','vnb'],['gnd','vdd']): + for pin_name, supply_name in zip(['vnb','vpb'],['gnd','vdd']): self.copy_power_pins(self.bitcell_array_inst, pin_name, new_name=supply_name) # If we use the pinvbuf as the decoder, we need to add power pins. diff --git a/compiler/modules/bitcell_base_array.py b/compiler/modules/bitcell_base_array.py index f26560f0..f9eeaeb7 100644 --- a/compiler/modules/bitcell_base_array.py +++ b/compiler/modules/bitcell_base_array.py @@ -162,9 +162,6 @@ class bitcell_base_array(design.design): inst = self.cell_inst[row, col] for pin_name in ["vdd", "gnd"]: self.copy_layout_pin(inst, pin_name) - if row == 2: #add only 1 label per col - for pin_name in ["vdd", "gnd"]: - self.copy_layout_pin(inst, pin_name) def add_layout_pins(self): """ Add the layout pins """ diff --git a/compiler/prefixGDS.py b/compiler/prefixGDS.py deleted file mode 100644 index 942bb7a0..00000000 --- a/compiler/prefixGDS.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python3 - -import sys -from gdsMill import gdsMill - -if len(sys.argv) < 3: - print("Script to prefix every instance and structure with the root cell name to provide unique namespace.") - print("Usage: {0} in.gds out.gds".format(sys.argv[0])) - sys.exit(1) - -gds_file = sys.argv[1] -gds = gdsMill.VlsiLayout() -reader = gdsMill.Gds2reader(gds) -reader.loadFromFile(gds_file) - -gds.uniquify() - -writer = gdsMill.Gds2writer(gds) -writer.writeToFile(sys.argv[2]) diff --git a/compiler/sram/sram.py b/compiler/sram/sram.py index a7d825a8..90855d8e 100644 --- a/compiler/sram/sram.py +++ b/compiler/sram/sram.py @@ -69,7 +69,12 @@ class sram(): reader = gdsMill.Gds2reader(gds) reader.loadFromFile(name) - gds.uniquify() + # Uniquify but skip the library cells since they are hard coded + try: + from tech import library_prefix_name + except ImportError: + library_prefix_name = None + gds.uniquify(library_prefix_name) writer = gdsMill.Gds2writer(gds) unique_name = name.replace(".gds", "_unique.gds") diff --git a/compiler/sram/sram_config.py b/compiler/sram/sram_config.py index 2c81ba0f..d28f28a8 100644 --- a/compiler/sram/sram_config.py +++ b/compiler/sram/sram_config.py @@ -17,7 +17,11 @@ class sram_config: def __init__(self, word_size, num_words, write_size=None, num_banks=1, words_per_row=None, num_spare_rows=0, num_spare_cols=0): self.word_size = word_size self.num_words = num_words - self.write_size = write_size + # Don't add a write mask if it is the same size as the data word + if write_size and write_size==word_size: + self.write_size = None + else: + self.write_size = write_size self.num_banks = num_banks self.num_spare_rows = num_spare_rows self.num_spare_cols = num_spare_cols diff --git a/compiler/tests/05_bitcell_array_test.py b/compiler/tests/05_bitcell_array_test.py index e641bbdb..916a4356 100755 --- a/compiler/tests/05_bitcell_array_test.py +++ b/compiler/tests/05_bitcell_array_test.py @@ -23,7 +23,15 @@ class array_test(openram_test): globals.init_openram(config_file) debug.info(2, "Testing 8x8 array for 6t_cell") - a = factory.create(module_type="bitcell_array", cols=8, rows=8) + + if OPTS.tech_name == "sky130": + num_spare_rows = 1 + num_spare_cols = 1 + else: + num_spare_rows = 0 + num_spare_cols = 0 + + a = factory.create(module_type="bitcell_array", cols=8 + num_spare_cols, rows=8 + num_spare_rows) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/14_replica_column_test.py b/compiler/tests/14_replica_column_test.py index 1bd91673..c8d50a53 100755 --- a/compiler/tests/14_replica_column_test.py +++ b/compiler/tests/14_replica_column_test.py @@ -19,9 +19,19 @@ class replica_column_test(openram_test): def runTest(self): config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) globals.init_openram(config_file) + if OPTS.tech_name == "sky130": + num_spare_rows = 1 + num_spare_cols = 1 + else: + num_spare_rows = 0 + num_spare_cols = 0 debug.info(2, "Testing replica column for single port") - a = factory.create(module_type="replica_column", rows=4, rbl=[1, 0], replica_bit=1) + a = factory.create(module_type="replica_column", + rows=4 + num_spare_rows, + rbl=[1, 0], + replica_bit=1, + column_offset=num_spare_cols) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/50_riscv_1k_1rw1r_func_test.py b/compiler/tests/50_riscv_1k_1rw1r_func_test.py new file mode 100755 index 00000000..6cd494aa --- /dev/null +++ b/compiler/tests/50_riscv_1k_1rw1r_func_test.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + #OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 1 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=256, + num_banks=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner, cycles=100) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_1k_1rw_func_test.py b/compiler/tests/50_riscv_1k_1rw_func_test.py new file mode 100755 index 00000000..a99fba03 --- /dev/null +++ b/compiler/tests/50_riscv_1k_1rw_func_test.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + #OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 0 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=256, + num_banks=1, + num_spare_rows=1, + num_spare_cols=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner, cycles=3) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_1rw1r_func_test.py b/compiler/tests/50_riscv_1rw1r_func_test.py index c643621e..19609159 100755 --- a/compiler/tests/50_riscv_1rw1r_func_test.py +++ b/compiler/tests/50_riscv_1rw1r_func_test.py @@ -16,7 +16,7 @@ from sram_factory import factory import debug -# @unittest.skip("SKIPPING 50_riscv_func_test") +@unittest.skip("SKIPPING 50_riscv_func_test") class riscv_func_test(openram_test): def runTest(self): @@ -24,6 +24,8 @@ class riscv_func_test(openram_test): globals.init_openram(config_file) OPTS.analytical_delay = False OPTS.netlist_only = True + OPTS.trim_netlist = False + OPTS.num_rw_ports = 1 OPTS.num_w_ports = 0 OPTS.num_r_ports = 1 @@ -48,7 +50,7 @@ class riscv_func_test(openram_test): c.num_banks)) s = factory.create(module_type="sram", sram_config=c) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) - f = functional(s.s, corner=corner, cycles=50) + f = functional(s.s, corner=corner, cycles=25) (fail, error) = f.run() self.assertTrue(fail, error) diff --git a/compiler/tests/50_riscv_1rw1r_phys_test.py b/compiler/tests/50_riscv_1rw1r_phys_test.py index af2e2312..40ae942f 100755 --- a/compiler/tests/50_riscv_1rw1r_phys_test.py +++ b/compiler/tests/50_riscv_1rw1r_phys_test.py @@ -16,7 +16,7 @@ from sram_factory import factory import debug -@unittest.skip("SKIPPING 50_riscv_phys_test") +# @unittest.skip("SKIPPING 50_riscv_phys_test") class riscv_phys_test(openram_test): def runTest(self): diff --git a/compiler/tests/50_riscv_1rw_func_test.py b/compiler/tests/50_riscv_1rw_func_test.py index 00921ec4..c77f21d1 100755 --- a/compiler/tests/50_riscv_1rw_func_test.py +++ b/compiler/tests/50_riscv_1rw_func_test.py @@ -16,7 +16,7 @@ from sram_factory import factory import debug -# @unittest.skip("SKIPPING 50_riscv_func_test") +@unittest.skip("SKIPPING 50_riscv_func_test") class riscv_func_test(openram_test): def runTest(self): @@ -24,6 +24,15 @@ class riscv_func_test(openram_test): globals.init_openram(config_file) OPTS.analytical_delay = False OPTS.netlist_only = True + OPTS.trim_netlist = False + + if OPTS.tech_name == "sky130": + num_spare_rows = 1 + num_spare_cols = 1 + else: + num_spare_rows = 0 + num_spare_cols = 0 + OPTS.num_rw_ports = 1 OPTS.num_w_ports = 0 OPTS.num_r_ports = 0 @@ -37,8 +46,10 @@ class riscv_func_test(openram_test): from sram_config import sram_config c = sram_config(word_size=32, write_size=8, - num_words=32, - num_banks=1) + num_words=64, + num_banks=1, + num_spare_cols=num_spare_cols, + num_spare_rows=num_spare_rows) c.words_per_row=1 c.recompute_sizes() debug.info(1, "Functional test RISC-V memory" @@ -48,7 +59,7 @@ class riscv_func_test(openram_test): c.num_banks)) s = factory.create(module_type="sram", sram_config=c) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) - f = functional(s.s, corner=corner, cycles=50) + f = functional(s.s, corner=corner, cycles=25) (fail, error) = f.run() self.assertTrue(fail, error) diff --git a/compiler/tests/50_riscv_1rw_phys_test.py b/compiler/tests/50_riscv_1rw_phys_test.py new file mode 100755 index 00000000..a2822b09 --- /dev/null +++ b/compiler/tests/50_riscv_1rw_phys_test.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +# @unittest.skip("SKIPPING 50_riscv_phys_test") +class riscv_phys_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + from sram_config import sram_config + + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 1 + OPTS.num_w_ports = 0 + OPTS.local_array_size = 16 + globals.setup_bitcell() + OPTS.route_supplies = False + OPTS.perimeter_pins = False + + c = sram_config(word_size=32, + write_size=8, + num_words=32, + num_banks=1, + num_spare_rows=1, + num_spare_cols=1) + c.words_per_row=2 + c.recompute_sizes() + debug.info(1, "Layout test for {}rw,{}r,{}w sram " + "with {} bit words, {} words, {} words per " + "row, {} banks".format(OPTS.num_rw_ports, + OPTS.num_r_ports, + OPTS.num_w_ports, + c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + a = factory.create(module_type="sram", sram_config=c) + self.local_check(a, final_verification=True) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_2k_1rw1r_func_test.py b/compiler/tests/50_riscv_2k_1rw1r_func_test.py new file mode 100755 index 00000000..2fa1ec47 --- /dev/null +++ b/compiler/tests/50_riscv_2k_1rw1r_func_test.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + #OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 1 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=512, + num_banks=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner, cycles=100) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_2k_1rw_func_test.py b/compiler/tests/50_riscv_2k_1rw_func_test.py new file mode 100755 index 00000000..24ec2e3a --- /dev/null +++ b/compiler/tests/50_riscv_2k_1rw_func_test.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + #OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 0 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=512, + num_banks=1, + num_spare_rows=1, + num_spare_cols=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner, cycles=100) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_4k_1rw1r_func_test.py b/compiler/tests/50_riscv_4k_1rw1r_func_test.py new file mode 100755 index 00000000..6b4f336e --- /dev/null +++ b/compiler/tests/50_riscv_4k_1rw1r_func_test.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + #OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 1 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=1024, + num_banks=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_4k_1rw_func_test.py b/compiler/tests/50_riscv_4k_1rw_func_test.py new file mode 100755 index 00000000..9f2dc2f6 --- /dev/null +++ b/compiler/tests/50_riscv_4k_1rw_func_test.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + #OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 0 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=1024, + num_banks=1, + num_spare_rows=1, + num_spare_cols=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_512b_1rw1r_func_test.py b/compiler/tests/50_riscv_512b_1rw1r_func_test.py new file mode 100755 index 00000000..17b3f518 --- /dev/null +++ b/compiler/tests/50_riscv_512b_1rw1r_func_test.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + #OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 1 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=128, + num_banks=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner, cycles=100) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_512b_1rw_func_test.py b/compiler/tests/50_riscv_512b_1rw_func_test.py new file mode 100755 index 00000000..4cceefd8 --- /dev/null +++ b/compiler/tests/50_riscv_512b_1rw_func_test.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + #OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 0 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=128, + num_banks=1, + num_spare_rows=1, + num_spare_cols=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner, cycles=25) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_8k_1rw1r_func_test.py b/compiler/tests/50_riscv_8k_1rw1r_func_test.py new file mode 100755 index 00000000..0783823c --- /dev/null +++ b/compiler/tests/50_riscv_8k_1rw1r_func_test.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 1 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=2048, + num_banks=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner, cycles=100) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/tests/50_riscv_8k_1rw_func_test.py b/compiler/tests/50_riscv_8k_1rw_func_test.py new file mode 100755 index 00000000..7b948aad --- /dev/null +++ b/compiler/tests/50_riscv_8k_1rw_func_test.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 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. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from globals import OPTS +from sram_factory import factory +import debug + + +@unittest.skip("SKIPPING 50_riscv_func_test") +class riscv_func_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.trim_netlist = False + + OPTS.local_array_size = 16 + OPTS.num_rw_ports = 1 + OPTS.num_r_ports = 0 + OPTS.num_w_ports = 0 + globals.setup_bitcell() + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram_config import sram_config + c = sram_config(word_size=32, + write_size=8, + num_words=2048, + num_banks=1, + num_spare_rows=1, + num_spare_cols=1) + + debug.info(1, "Functional test RISC-V memory" + "{} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = factory.create(module_type="sram", sram_config=c) + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, corner=corner, cycles=100) + (fail, error) = f.run() + self.assertTrue(fail, error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner()) diff --git a/compiler/uniquifyGDS.py b/compiler/uniquifyGDS.py index 942bb7a0..8eddce3d 100755 --- a/compiler/uniquifyGDS.py +++ b/compiler/uniquifyGDS.py @@ -3,17 +3,17 @@ import sys from gdsMill import gdsMill -if len(sys.argv) < 3: - print("Script to prefix every instance and structure with the root cell name to provide unique namespace.") - print("Usage: {0} in.gds out.gds".format(sys.argv[0])) +if len(sys.argv) < 4: + print("Script to prefix every instance and structure with the root cell name to provide unique namespace, but skip cells that begin with the library prefix.") + print("Usage: {0} in.gds out.gds".format(sys.argv[0])) sys.exit(1) -gds_file = sys.argv[1] +gds_file = sys.argv[2] gds = gdsMill.VlsiLayout() reader = gdsMill.Gds2reader(gds) reader.loadFromFile(gds_file) -gds.uniquify() +gds.uniquify(prefix_name=sys.argv[1]) writer = gdsMill.Gds2writer(gds) -writer.writeToFile(sys.argv[2]) +writer.writeToFile(sys.argv[3])