From 8c4afb1cbadad8580893da3986333f91403445ac Mon Sep 17 00:00:00 2001 From: azaidy Date: Mon, 19 Aug 2024 23:28:18 -0400 Subject: [PATCH 1/5] Add method to terminate SbDut --- switchboard/sbdut.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/switchboard/sbdut.py b/switchboard/sbdut.py index 3ef04f5e..79e6ec8a 100644 --- a/switchboard/sbdut.py +++ b/switchboard/sbdut.py @@ -216,6 +216,7 @@ def __init__( # initialization self.intfs = {} + self.subprocess_list = [] # simulator-agnostic settings @@ -615,9 +616,40 @@ def simulate( ) # return a Popen object that one can wait() on + self.subprocess_list.append(p) return p + def terminate( + self, + stop_timeout=10, + use_sigint=False + ): + if not self.subprocess_list: + raise Exception('No ongoing simulation.' + 'Please call simulate before trying to terminate.') + + for p in self.subprocess_list: + poll = p.poll() + if poll is not None: + # process has stopped + return + + if use_sigint: + try: + p.send_signal(signal.SIGINT) + p.wait(stop_timeout) + return + except: # noqa: E722 + # if there is an exception for any reason, including + # Ctrl-C during the wait() call, want to make sure + # that the process is actually terminated + pass + + # if we get to this point, the process is still running + # and sigint didn't work (or we didn't try it) + p.terminate() + def input_analog( self, filename: str, From e987f67097627ea34984cf1e751325ea55d437f0 Mon Sep 17 00:00:00 2001 From: azaidy Date: Mon, 19 Aug 2024 23:36:28 -0400 Subject: [PATCH 2/5] Fix lint --- switchboard/sbdut.py | 1 + 1 file changed, 1 insertion(+) diff --git a/switchboard/sbdut.py b/switchboard/sbdut.py index 79e6ec8a..c72286b9 100644 --- a/switchboard/sbdut.py +++ b/switchboard/sbdut.py @@ -29,6 +29,7 @@ from .cmdline import get_cmdline_args import siliconcompiler +import signal SB_DIR = sb_path() From 1f37f990bc5afff42d3dc61ec882d5789082cbc2 Mon Sep 17 00:00:00 2001 From: azaidy Date: Mon, 19 Aug 2024 23:40:18 -0400 Subject: [PATCH 3/5] Fix comments --- switchboard/sbdut.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/switchboard/sbdut.py b/switchboard/sbdut.py index c72286b9..5406ecb5 100644 --- a/switchboard/sbdut.py +++ b/switchboard/sbdut.py @@ -616,9 +616,11 @@ def simulate( args=plusargs_to_args(plusargs) + args ) - # return a Popen object that one can wait() on + # Add newly created Popen object to subprocess list self.subprocess_list.append(p) + # return a Popen object that one can wait() on + return p def terminate( From 43d395c8f0a9a1fe718b2a6115758259310045ec Mon Sep 17 00:00:00 2001 From: azaidy Date: Tue, 20 Aug 2024 15:53:57 -0400 Subject: [PATCH 4/5] Use ProcessCollection object instead of list. Add terminate to ProcessCollection. --- switchboard/network.py | 22 ++++++++++++++-------- switchboard/sbdut.py | 33 ++++++--------------------------- switchboard/util.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/switchboard/network.py b/switchboard/network.py index dd0875f5..b8b497f3 100644 --- a/switchboard/network.py +++ b/switchboard/network.py @@ -191,6 +191,9 @@ def __init__(self, cmdline=False, tool: str = 'verilator', trace: bool = False, self.name = name + # keep track of processes started + self.process_collection = ProcessCollection() + if cleanup: import atexit @@ -520,10 +523,6 @@ def simulate(self, start_delay=None, run=None, intf_objs=True, plusargs=None): if plusargs is None: plusargs = [] - # keep track of processes started - - process_collection = ProcessCollection() - # create interface objects if self.single_netlist: @@ -538,7 +537,7 @@ def simulate(self, start_delay=None, run=None, intf_objs=True, plusargs=None): plusargs = plusargs_processed process = self.dut.simulate(start_delay=start_delay, run=run, intf_objs=intf_objs, plusargs=plusargs) - process_collection.add(process) + self.process_collection.add(process) if intf_objs: self.intfs = self.dut.intfs @@ -590,14 +589,21 @@ def simulate(self, start_delay=None, run=None, intf_objs=True, plusargs=None): process = block.simulate(start_delay=start_delay, run=inst.name, intf_objs=False, plusargs=inst_plusargs) - process_collection.add(process) + self.process_collection.add(process) # start TCP bridges as needed for tcp_kwargs in self.tcp_intfs.values(): process = start_tcp_bridge(**tcp_kwargs) - process_collection.add(process) + self.process_collection.add(process) + + return self.process_collection - return process_collection + def terminate( + self, + stop_timeout=10, + use_sigint=False + ): + self.process_collection.terminate(stop_timeout=stop_timeout, use_sigint=use_sigint) def generate_inst_name(self, prefix): if prefix not in self.inst_name_counters: diff --git a/switchboard/sbdut.py b/switchboard/sbdut.py index 5406ecb5..494ca42f 100644 --- a/switchboard/sbdut.py +++ b/switchboard/sbdut.py @@ -21,7 +21,7 @@ from .switchboard import path as sb_path from .verilator import verilator_run from .icarus import icarus_build_vpi, icarus_find_vpi, icarus_run -from .util import plusargs_to_args, binary_run +from .util import plusargs_to_args, binary_run, ProcessCollection from .xyce import xyce_flags from .ams import make_ams_spice_wrapper, make_ams_verilog_wrapper, parse_spice_subckts from .autowrap import (normalize_clocks, normalize_interfaces, normalize_resets, normalize_tieoffs, @@ -217,7 +217,9 @@ def __init__( # initialization self.intfs = {} - self.subprocess_list = [] + + # keep track of processes started + self.process_collection = ProcessCollection() # simulator-agnostic settings @@ -617,7 +619,7 @@ def simulate( ) # Add newly created Popen object to subprocess list - self.subprocess_list.append(p) + self.process_collection.add(p) # return a Popen object that one can wait() on @@ -628,30 +630,7 @@ def terminate( stop_timeout=10, use_sigint=False ): - if not self.subprocess_list: - raise Exception('No ongoing simulation.' - 'Please call simulate before trying to terminate.') - - for p in self.subprocess_list: - poll = p.poll() - if poll is not None: - # process has stopped - return - - if use_sigint: - try: - p.send_signal(signal.SIGINT) - p.wait(stop_timeout) - return - except: # noqa: E722 - # if there is an exception for any reason, including - # Ctrl-C during the wait() call, want to make sure - # that the process is actually terminated - pass - - # if we get to this point, the process is still running - # and sigint didn't work (or we didn't try it) - p.terminate() + self.process_collection.terminate(stop_timeout=stop_timeout, use_sigint=use_sigint) def input_analog( self, diff --git a/switchboard/util.py b/switchboard/util.py index 2332061b..704fee64 100644 --- a/switchboard/util.py +++ b/switchboard/util.py @@ -97,3 +97,35 @@ def wait(self): process.join() else: raise Exception(f'Unknown process type: {type(process)}') + + def terminate( + self, + stop_timeout=10, + use_sigint=False + ): + if not self.processes: + return + + for p in self.processes: + if isinstance(p, ProcessCollection): + p.terminate(stop_timeout=stop_timeout, use_sigint=use_sigint) + else: + poll = p.poll() + if poll is not None: + # process has stopped + return + + if use_sigint: + try: + p.send_signal(signal.SIGINT) + p.wait(stop_timeout) + return + except: # noqa: E722 + # if there is an exception for any reason, including + # Ctrl-C during the wait() call, want to make sure + # that the process is actually terminated + pass + + # if we get to this point, the process is still running + # and sigint didn't work (or we didn't try it) + p.terminate() From 0a5fe1200d859297cd21220456468c229d44c01e Mon Sep 17 00:00:00 2001 From: azaidy Date: Tue, 20 Aug 2024 15:55:10 -0400 Subject: [PATCH 5/5] Lint fix --- switchboard/sbdut.py | 1 - 1 file changed, 1 deletion(-) diff --git a/switchboard/sbdut.py b/switchboard/sbdut.py index 494ca42f..90562d6f 100644 --- a/switchboard/sbdut.py +++ b/switchboard/sbdut.py @@ -29,7 +29,6 @@ from .cmdline import get_cmdline_args import siliconcompiler -import signal SB_DIR = sb_path()