diff --git a/dv/uvm/core_ibex/scripts/run-instr-gen.py b/dv/uvm/core_ibex/scripts/run-instr-gen.py index 32090775..6a3416a2 100755 --- a/dv/uvm/core_ibex/scripts/run-instr-gen.py +++ b/dv/uvm/core_ibex/scripts/run-instr-gen.py @@ -54,8 +54,8 @@ def main() -> int: # Ensure that the output directory actually exists os.makedirs(args.output_dir, exist_ok=True) - riscv_dv_log = os.path.join(args.output_dir, - f'{testname}.{seed}.riscv-dv.log') + riscv_dv_log = os.path.join(args.output_dir, f'riscv-dv.log') + gen_log = os.path.join(args.output_dir, f'gen-cmds.log') with tempfile.TemporaryDirectory() as td: orig_list = os.path.join(td, 'cmds.list') @@ -90,13 +90,15 @@ def main() -> int: testname, orig_list) - # Run the commands in sequence to create "test_0.S" and "gen.log" in - # the temporary directory. - ret = 0 - for cmd in cmds: - ret = run_one(args.verbose, cmd, redirect_stdstreams='/dev/null') - if ret != 0: - break + # Open up a file to take output from running the commands + with open(gen_log, 'w') as log_fd: + # Run the commands in sequence to create outputs in the temporary + # directory. Redirect stdout and stderr to gen_log + ret = 0 + for cmd in cmds: + ret = run_one(args.verbose, cmd, redirect_stdstreams=log_fd) + if ret != 0: + break test_file_copies = { 'riscv_csr_test': [('riscv_csr_test_0.S', 'test.S', False)] diff --git a/dv/uvm/core_ibex/scripts/scripts_lib.py b/dv/uvm/core_ibex/scripts/scripts_lib.py index d24bd59d..f43c0052 100644 --- a/dv/uvm/core_ibex/scripts/scripts_lib.py +++ b/dv/uvm/core_ibex/scripts/scripts_lib.py @@ -9,7 +9,7 @@ import re import shlex import subprocess import sys -from typing import Dict, List, Optional, Tuple +from typing import Dict, IO, List, Optional, Tuple, Union THIS_DIR = os.path.dirname(__file__) IBEX_ROOT = os.path.normpath(os.path.join(THIS_DIR, 4 * '../')) @@ -28,30 +28,48 @@ TestAndSeed = Tuple[str, int] def run_one(verbose: bool, cmd: List[str], - redirect_stdstreams: Optional[str] = None, + redirect_stdstreams: Optional[Union[str, IO]] = None, env: Dict[str, str] = None) -> int: '''Run a command, returning its return code If verbose is true, print the command to stderr first (a bit like bash -x). If redirect_stdstreams is true, redirect the stdout and stderr of the - subprocess to the given path. + subprocess to the given file object or path. ''' - if verbose: - # The equivalent of bash -x - cmd_str = ' '.join(shlex.quote(w) for w in cmd) - if redirect_stdstreams is not None: - cmd_str += f' >{shlex.quote(redirect_stdstreams)} 2>&1' - - print('+ ' + cmd_str, file=sys.stderr) - stdstream_dest = None + needs_closing = False + if redirect_stdstreams is not None: if redirect_stdstreams == '/dev/null': stdstream_dest = subprocess.DEVNULL - else: + elif isinstance(redirect_stdstreams, str): stdstream_dest = open(redirect_stdstreams, 'wb') + needs_closing = True + else: + stdstream_dest = redirect_stdstreams + + if verbose: + # The equivalent of bash -x + cmd_str = ' '.join(shlex.quote(w) for w in cmd) + redir_cmd = cmd_str + if redirect_stdstreams is not None: + if isinstance(redirect_stdstreams, str): + redir = f'>{shlex.quote(redirect_stdstreams)}' + else: + redir = f'>>{shlex.quote(redirect_stdstreams.name)}' + redir_cmd = f'{cmd_str} {redir} 2>&1' + + print('+ ' + redir_cmd, file=sys.stderr) + + # Try to print the command to the file as well. This will fail if it's + # a binary file: ignore the failure. + if stdstream_dest: + try: + print('+ ' + cmd_str, file=stdstream_dest) + except (TypeError, AttributeError): + pass try: # Passing close_fds=False ensures that if cmd is a call to Make then @@ -63,7 +81,7 @@ def run_one(verbose: bool, close_fds=False, env=env).returncode finally: - if stdstream_dest not in [None, subprocess.DEVNULL]: + if needs_closing: stdstream_dest.close()