From 1ded978256491b45e350e51ae25f4f3533ea8b84 Mon Sep 17 00:00:00 2001 From: mrg Date: Tue, 1 Jun 2021 15:10:55 -0700 Subject: [PATCH 1/8] Change nwell from gnd to vdd. dnwell space added. --- compiler/base/hierarchy_layout.py | 10 +++++----- compiler/router/router.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index e033e387..f16658c2 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -1409,7 +1409,7 @@ class layout(): [ll, ur] = bbox # Possibly inflate the bbox - nwell_offset = vector(self.nwell_width, self.nwell_width) + nwell_offset = vector(2 * self.nwell_width, 2 * self.nwell_width) ll -= nwell_offset.scale(inflate, inflate) ur += nwell_offset.scale(inflate, inflate) @@ -1448,7 +1448,7 @@ class layout(): to_layer="m1", offset=loc) else: - self.add_power_pin(name="gnd", + self.add_power_pin(name="vdd", loc=loc, start_layer="li") count += 1 @@ -1468,7 +1468,7 @@ class layout(): to_layer="m1", offset=loc) else: - self.add_power_pin(name="gnd", + self.add_power_pin(name="vdd", loc=loc, start_layer="li") count += 1 @@ -1488,7 +1488,7 @@ class layout(): to_layer="m2", offset=loc) else: - self.add_power_pin(name="gnd", + self.add_power_pin(name="vdd", loc=loc, start_layer="li") count += 1 @@ -1508,7 +1508,7 @@ class layout(): to_layer="m2", offset=loc) else: - self.add_power_pin(name="gnd", + self.add_power_pin(name="vdd", loc=loc, start_layer="li") count += 1 diff --git a/compiler/router/router.py b/compiler/router/router.py index d9903e49..d5bd4738 100644 --- a/compiler/router/router.py +++ b/compiler/router/router.py @@ -881,7 +881,7 @@ class router(router_tech): """ pg = pin_group(name, [], self) # Offset two spaces inside and one between the rings - if name == "vdd": + if name == "gnd": offset = width + 2 * space else: offset = space @@ -911,7 +911,7 @@ class router(router_tech): pg = pin_group(name, [], self) # Offset two spaces inside and one between the rings # Units are in routing grids - if name == "vdd": + if name == "gnd": offset = width + 2 * space else: offset = space From 537fd6eff9dc0f1980dfebf442d59f1ab8664023 Mon Sep 17 00:00:00 2001 From: mrg Date: Tue, 1 Jun 2021 16:41:14 -0700 Subject: [PATCH 2/8] Use None instead of empty string for tool names. --- compiler/characterizer/__init__.py | 4 ++-- compiler/characterizer/stimuli.py | 4 ++-- compiler/options.py | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/characterizer/__init__.py b/compiler/characterizer/__init__.py index a092ac1e..1b6ef642 100644 --- a/compiler/characterizer/__init__.py +++ b/compiler/characterizer/__init__.py @@ -24,7 +24,7 @@ debug.info(1, "Initializing characterizer...") OPTS.spice_exe = "" if not OPTS.analytical_delay: - if OPTS.spice_name != "": + if OPTS.spice_name: # Capitalize Xyce if OPTS.spice_name == "xyce": OPTS.spice_name = "Xyce" @@ -45,7 +45,7 @@ if not OPTS.analytical_delay: if OPTS.spice_name == "ngspice": os.environ["NGSPICE_INPUT_DIR"] = "{0}".format(OPTS.openram_temp) - if OPTS.spice_exe == "": + if not OPTS.spice_exe: debug.error("No recognizable spice version found. Unable to perform characterization.", 1) else: debug.info(1, "Finding spice simulator: {} ({})".format(OPTS.spice_name, OPTS.spice_exe)) diff --git a/compiler/characterizer/stimuli.py b/compiler/characterizer/stimuli.py index f5b5967f..80ddf4fc 100644 --- a/compiler/characterizer/stimuli.py +++ b/compiler/characterizer/stimuli.py @@ -276,8 +276,8 @@ class stimuli(): 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)) - else: - debug.error("Unkown spice simulator {}".format(OPTS.spice_name)) + elif OPTS.spice_name: + debug.error("Unkown spice simulator {}".format(OPTS.spice_name), -1) # create plots for all signals if not OPTS.use_pex: # Don't save all for extracted simulations diff --git a/compiler/options.py b/compiler/options.py index 65620c8c..87a30531 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -120,13 +120,13 @@ class options(optparse.Values): # Tool options ################### # Variable to select the variant of spice - spice_name = "" + spice_name = None # The spice executable being used which is derived from the user PATH. - spice_exe = "" + spice_exe = None # Variable to select the variant of drc, lvs, pex - drc_name = "" - lvs_name = "" - pex_name = "" + drc_name = None + lvs_name = None + pex_name = None # The DRC/LVS/PEX executable being used # which is derived from the user PATH. drc_exe = None From 4107c983e2d421b84c0f4c25911f8890b9b01118 Mon Sep 17 00:00:00 2001 From: mrg Date: Fri, 4 Jun 2021 07:14:49 -0700 Subject: [PATCH 3/8] Make sure channel route is below s_en --- compiler/sram/sram_1bank.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/compiler/sram/sram_1bank.py b/compiler/sram/sram_1bank.py index 9c3802be..0323ffdf 100644 --- a/compiler/sram/sram_1bank.py +++ b/compiler/sram/sram_1bank.py @@ -385,6 +385,7 @@ class sram_1bank(sram_base): if len(route_map) > 0: + # This layer stack must be different than the data dff layer stack layer_stack = self.m1_stack if port == 0: @@ -394,11 +395,11 @@ class sram_1bank(sram_base): offset=offset, layer_stack=layer_stack, parent=self) - # This causes problem in magic since it sometimes cannot extract connectivity of isntances + # This causes problem in magic since it sometimes cannot extract connectivity of instances # with no active devices. self.add_inst(cr.name, cr) self.connect_inst([]) - #self.add_flat_inst(cr.name, cr) + # self.add_flat_inst(cr.name, cr) else: offset = vector(0, self.bank.height + self.m3_pitch) @@ -406,11 +407,11 @@ class sram_1bank(sram_base): offset=offset, layer_stack=layer_stack, parent=self) - # This causes problem in magic since it sometimes cannot extract connectivity of isntances + # This causes problem in magic since it sometimes cannot extract connectivity of instances # with no active devices. self.add_inst(cr.name, cr) self.connect_inst([]) - #self.add_flat_inst(cr.name, cr) + # self.add_flat_inst(cr.name, cr) def route_data_dffs(self, port, add_routes): route_map = [] @@ -441,40 +442,42 @@ class sram_1bank(sram_base): if len(route_map) > 0: - # The write masks will have blockages on M1 - # if self.num_wmasks > 0 and port in self.write_ports: - # layer_stack = self.m3_stack - # else: - # layer_stack = self.m1_stack + # This layer stack must be different than the column addr dff layer stack layer_stack = self.m3_stack if port == 0: + # This is relative to the bank at 0,0 or the s_en which is routed on M3 also + s_en_bot = self.control_logic_insts[port].get_pin("s_en").by() + y_offset = min(0, s_en_bot) - self.data_bus_size[port] + 2 * self.m3_pitch + offset = vector(self.control_logic_insts[port].rx() + self.dff.width, - - self.data_bus_size[port] + 2 * self.m3_pitch) + y_offset) cr = channel_route(netlist=route_map, offset=offset, layer_stack=layer_stack, parent=self) if add_routes: - # This causes problem in magic since it sometimes cannot extract connectivity of isntances + # This causes problem in magic since it sometimes cannot extract connectivity of instances # with no active devices. self.add_inst(cr.name, cr) self.connect_inst([]) - #self.add_flat_inst(cr.name, cr) + # self.add_flat_inst(cr.name, cr) else: self.data_bus_size[port] = max(cr.height, self.col_addr_bus_size[port]) + self.data_bus_gap else: + s_en_top = self.control_logic_insts[port].get_pin("s_en").uy() + y_offset = max(self.bank.height, s_en_top) + self.m3_pitch offset = vector(0, - self.bank.height + self.m3_pitch) + y_offset) cr = channel_route(netlist=route_map, offset=offset, layer_stack=layer_stack, parent=self) if add_routes: - # This causes problem in magic since it sometimes cannot extract connectivity of isntances + # This causes problem in magic since it sometimes cannot extract connectivity of instances # with no active devices. self.add_inst(cr.name, cr) self.connect_inst([]) - #self.add_flat_inst(cr.name, cr) + # self.add_flat_inst(cr.name, cr) else: self.data_bus_size[port] = max(cr.height, self.col_addr_bus_size[port]) + self.data_bus_gap From cc4c6e909b3f406114ada5098aad793b1673da9b Mon Sep 17 00:00:00 2001 From: mrg Date: Fri, 4 Jun 2021 07:48:26 -0700 Subject: [PATCH 4/8] Check if s_en exists before using it --- compiler/sram/sram_1bank.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/sram/sram_1bank.py b/compiler/sram/sram_1bank.py index 0323ffdf..828edfdd 100644 --- a/compiler/sram/sram_1bank.py +++ b/compiler/sram/sram_1bank.py @@ -446,8 +446,12 @@ class sram_1bank(sram_base): layer_stack = self.m3_stack if port == 0: # This is relative to the bank at 0,0 or the s_en which is routed on M3 also - s_en_bot = self.control_logic_insts[port].get_pin("s_en").by() - y_offset = min(0, s_en_bot) - self.data_bus_size[port] + 2 * self.m3_pitch + if "s_en" in self.control_logic_insts[port].mod.pin_map: + y_bottom = min(0, self.control_logic_insts[port].get_pin("s_en").by()) + else: + y_bottom = 0 + + y_offset = y_bottom - self.data_bus_size[port] + 2 * self.m3_pitch offset = vector(self.control_logic_insts[port].rx() + self.dff.width, y_offset) @@ -464,8 +468,11 @@ class sram_1bank(sram_base): else: self.data_bus_size[port] = max(cr.height, self.col_addr_bus_size[port]) + self.data_bus_gap else: - s_en_top = self.control_logic_insts[port].get_pin("s_en").uy() - y_offset = max(self.bank.height, s_en_top) + self.m3_pitch + if "s_en" in self.control_logic_insts[port].mod.pin_map: + y_top = max(self.bank.height, self.control_logic_insts[port].get_pin("s_en").uy()) + else: + y_top = self.bank.height + y_offset = y_top + self.m3_pitch offset = vector(0, y_offset) cr = channel_route(netlist=route_map, From 53791d79c837ae1364f5dbbd3cfea776d7f71275 Mon Sep 17 00:00:00 2001 From: mrg Date: Fri, 4 Jun 2021 08:56:06 -0700 Subject: [PATCH 5/8] spacing must be two extensions (one for each cell) --- compiler/modules/dff_buf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/modules/dff_buf.py b/compiler/modules/dff_buf.py index e8474fed..d979c0fe 100644 --- a/compiler/modules/dff_buf.py +++ b/compiler/modules/dff_buf.py @@ -109,7 +109,7 @@ class dff_buf(design.design): except AttributeError: pass - well_spacing += self.well_extend_active + well_spacing += 2 * self.well_extend_active self.inv1_inst.place(vector(self.dff_inst.rx() + well_spacing, 0)) From 66437593459abe2b042e7000f042ad3521c79fe8 Mon Sep 17 00:00:00 2001 From: mrg Date: Fri, 4 Jun 2021 11:06:39 -0700 Subject: [PATCH 6/8] Add back drc listall with correct output. --- compiler/verify/magic.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/verify/magic.py b/compiler/verify/magic.py index 32a9f7e6..03051db4 100644 --- a/compiler/verify/magic.py +++ b/compiler/verify/magic.py @@ -180,7 +180,10 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa f.write('puts "Finished drc check"\n') f.write("drc catchup\n") f.write('puts "Finished drc catchup"\n') - f.write("drc count total\n") + f.write("puts -nonewline \"Total DRC errors found: \"\n") + # This is needed instead of drc count total because it displays + # some errors that are not "DRC" errors. + f.write("puts stdout [drc listall count total]\n") f.write("quit -noprompt\n") f.write("EOF\n") f.write("magic_retcode=$?\n") From 27c6a13923bb5b484aa8aca2b907588c2e202ef0 Mon Sep 17 00:00:00 2001 From: mrg Date: Fri, 4 Jun 2021 15:51:50 -0700 Subject: [PATCH 7/8] Back out drc listall count for detecting errors --- compiler/verify/magic.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/verify/magic.py b/compiler/verify/magic.py index 3e8b2c68..454dc176 100644 --- a/compiler/verify/magic.py +++ b/compiler/verify/magic.py @@ -180,10 +180,11 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa f.write('puts "Finished drc check"\n') f.write("drc catchup\n") f.write('puts "Finished drc catchup"\n') - f.write("puts -nonewline \"Total DRC errors found: \"\n") # This is needed instead of drc count total because it displays # some errors that are not "DRC" errors. - f.write("puts stdout [drc listall count total]\n") + # f.write("puts -nonewline \"Total DRC errors found: \"\n") + # f.write("puts stdout [drc listall count total]\n") + f.write("drc count total\n") f.write("quit -noprompt\n") f.write("EOF\n") f.write("magic_retcode=$?\n") From a1cb20878d74a480fc2fc66bea2d1ac9f32f6dce Mon Sep 17 00:00:00 2001 From: mrg Date: Tue, 8 Jun 2021 11:14:27 -0700 Subject: [PATCH 8/8] Swap LH/HL hold times in sky130. --- compiler/tests/21_hspice_setuphold_test.py | 4 ++-- compiler/tests/21_ngspice_setuphold_test.py | 4 ++-- compiler/tests/21_xyce_setuphold_test.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/tests/21_hspice_setuphold_test.py b/compiler/tests/21_hspice_setuphold_test.py index 634b2982..9154502e 100755 --- a/compiler/tests/21_hspice_setuphold_test.py +++ b/compiler/tests/21_hspice_setuphold_test.py @@ -45,8 +45,8 @@ class timing_setup_test(openram_test): 'setup_times_HL': [0.16357419999999998], 'setup_times_LH': [0.1757812]} elif OPTS.tech_name == "sky130": - golden_data = {'hold_times_HL': [-0.05615234], - 'hold_times_LH': [-0.03173828], + golden_data = {'hold_times_HL': [-0.03173828], + 'hold_times_LH': [-0.05615234], 'setup_times_HL': [0.078125], 'setup_times_LH': [0.1025391]} else: diff --git a/compiler/tests/21_ngspice_setuphold_test.py b/compiler/tests/21_ngspice_setuphold_test.py index dab02e7d..9bda2c2c 100755 --- a/compiler/tests/21_ngspice_setuphold_test.py +++ b/compiler/tests/21_ngspice_setuphold_test.py @@ -45,8 +45,8 @@ class timing_setup_test(openram_test): 'setup_times_HL': [0.1757812], 'setup_times_LH': [0.1879883]} elif OPTS.tech_name == "sky130": - golden_data = {'hold_times_HL': [-0.05615234], - 'hold_times_LH': [-0.03173828], + golden_data = {'hold_times_HL': [-0.03173828], + 'hold_times_LH': [-0.05615234], 'setup_times_HL': [0.078125], 'setup_times_LH': [0.1025391]} else: diff --git a/compiler/tests/21_xyce_setuphold_test.py b/compiler/tests/21_xyce_setuphold_test.py index f53212f8..3aabce06 100755 --- a/compiler/tests/21_xyce_setuphold_test.py +++ b/compiler/tests/21_xyce_setuphold_test.py @@ -45,8 +45,8 @@ class timing_setup_test(openram_test): 'setup_times_HL': [0.16357419999999998], 'setup_times_LH': [0.1757812]} elif OPTS.tech_name == "sky130": - golden_data = {'hold_times_HL': [-0.05615234], - 'hold_times_LH': [-0.03173828], + golden_data = {'hold_times_HL': [-0.03173828], + 'hold_times_LH': [-0.05615234], 'setup_times_HL': [0.078125], 'setup_times_LH': [0.1025391]} else: