Files
OpenRAM/compiler/verify/run_script.py
T
ThVerg 5696584608 Fix nix develop invocation for verification scripts
run_script() launches the DRC/LVS scripts with

    nix develop --command <script>

from a working directory of OPTS.openram_temp. nix develop resolves its
flake from the working directory, and the temp directory has no
flake.nix, so the command fails before the script ever runs:

    path '/tmp/openram_<user>_<pid>_temp' does not contain a 'flake.nix', searching up
    error: could not find a flake.nix file

Nothing is written to the report file, so verification then dies on the
missing output rather than on the nix error itself, which makes this
confusing to diagnose:

    ERROR: file magic.py: Unable to load LVS results from
    /tmp/openram_<user>_<pid>_temp/<name>.lvs.report
    FileNotFoundError: [Errno 2] No such file or directory

Name the flake explicitly so it is resolved from the repository while
the script still runs in the temp directory, which the scripts depend on
for their relative copies.

Verified on a sky130 build with use_nix = True: before the change no
report is produced and the run asserts, after it both DRC and LVS run
through the devShell and write their reports.
2026-08-11 15:03:55 +02:00

93 lines
3.0 KiB
Python

# See LICENSE for licensing information.
#
# Copyright (c) 2016-2024 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.
#
"""
Some baseline functions to run scripts.
"""
import os
import subprocess
import time
from openram import debug
from openram import OPTS
def run_script(cell_name, script="lvs"):
""" Run script and create output files. """
echo_cmd_output = OPTS.verbose_level > 1
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.{2}.err".format(OPTS.openram_temp, cell_name, script)
outfile = "{0}{1}.{2}.out".format(OPTS.openram_temp, cell_name, script)
resultsfile = "{0}{1}.{2}.report".format(OPTS.openram_temp, cell_name, script)
scriptpath = '{0}run_{1}.sh'.format(OPTS.openram_temp, script)
debug.info(2, "Starting {}".format(scriptpath))
start = time.time()
with open(outfile, 'wb') as fo, open(errfile, 'wb') as fe:
if OPTS.use_nix:
# The script runs in openram_temp, which has no flake.nix, so the
# flake has to be named explicitly or nix searches up from the temp
# directory, fails, and the script never runs at all.
repo_root = os.path.abspath(os.path.join(os.environ["OPENRAM_HOME"], ".."))
p_cmd = [
"nix",
"--extra-experimental-features", "nix-command flakes",
"develop",
"path:{}".format(repo_root),
"--command",
scriptpath,
]
else:
p_cmd = [scriptpath]
p = subprocess.Popen(
p_cmd, stdout=fo, stderr=fe, cwd=OPTS.openram_temp)
if echo_cmd_output:
tailo = subprocess.Popen([
'tail',
'-f', # Follow the output
'--pid', str(p.pid), # Close when this pid exits
outfile,
])
taile = subprocess.Popen([
'tail',
'-f', # Follow the output
'--pid', str(p.pid), # Close when this pid exits
errfile,
])
lastoutput = start
while p.poll() == None:
runningfor = time.time() - start
outputdelta = time.time() - lastoutput
if outputdelta > 30:
lastoutput = time.time()
debug.info(1, "Still running {} ({:.0f} seconds)".format(scriptpath, runningfor))
time.sleep(1)
assert p.poll() != None, (p.poll(), p)
p.wait()
# Kill the tail commands if they haven't finished.
if echo_cmd_output:
if tailo.poll() != None:
tailo.kill()
tailo.wait()
if taile.poll() != None:
taile.kill()
taile.wait()
debug.info(2, "Finished {} with {}".format(scriptpath, p.returncode))
os.chdir(cwd)
return (outfile, errfile, resultsfile)