Merge pull request #34 from antmicro/clock_detection
Enchance clock detection
diff --git a/v2x/__main__.py b/v2x/__main__.py
index 8ab0174..38ba16d 100644
--- a/v2x/__main__.py
+++ b/v2x/__main__.py
@@ -5,8 +5,16 @@
import argparse
import sys
+from .yosys.run import get_yosys
+
def main(args):
+
+ # Check if Yosys can be found. Print an error message if not.
+ if get_yosys() is None:
+ print("ERROR: Cannot find the Yosys binary or its not executable.")
+ return -1
+
if args.mode == "pb_type":
with open(args.outfile, "w") as fp:
fp.write(vlog_to_pbtype.vlog_to_pbtype(
diff --git a/v2x/yosys/run.py b/v2x/yosys/run.py
index 5bf3f6a..ef2627e 100755
--- a/v2x/yosys/run.py
+++ b/v2x/yosys/run.py
@@ -19,9 +19,37 @@
def get_yosys():
- """Return how to execute Yosys: the value of $YOSYS if set, otherwise just
- `yosys`."""
- return os.getenv("YOSYS", "yosys")
+ """
+ Searches for the Yosys binary. If the env. var. "YOSYS" is set, then it
+ checks if it points to a valid executable binary. Otherwise it searches
+ in PATH for binaries named "yosys" and returns the first one found.
+ """
+
+ def is_exe(fpath):
+ """
+ Returns True if a file exists and is executable.
+ """
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+ # The environmental variable "YOSYS" is set. It should point to the Yosys
+ # executable.
+ if "YOSYS" in os.environ:
+ fpath = os.environ["YOSYS"]
+ if not is_exe(fpath):
+ return None
+
+ return fpath
+
+ # Look for the 'yosys' binary in the current PATH but only if the PATH
+ # variable is available.
+ elif "PATH" in os.environ:
+ for path in os.environ["PATH"].split(os.pathsep):
+ fpath = os.path.join(path, "yosys")
+ if is_exe(fpath):
+ return fpath
+
+ # Couldn't find Yosys.
+ return None
def get_yosys_common_args():
@@ -30,13 +58,16 @@
def get_output(params):
"""Run Yosys with given command line parameters, and return
- stdout as a string"""
+ stdout as a string. Raises CalledProcessError on a non-zero exit code."""
verbose = get_verbose()
cmd = [get_yosys()] + get_yosys_common_args() + params
if verbose:
- print(cmd)
+ msg = ""
+ msg += "command".ljust(9).ljust(80, "=") + "\n"
+ msg += str(cmd)
+ print(msg)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -47,23 +78,32 @@
retcode = p.wait()
- msg = ""
- msg += "stdout" + "=" * 75 + "\n"
- msg += stdout + "\n"
- msg += "stderr" + "-" * 75 + "\n"
- msg += stderr + "\n"
- msg += "=" * 75 + "\n"
- msg += "Return Code: {}".format(retcode)
-
if verbose:
+ msg = ""
+
+ if len(stdout):
+ msg += "stdout".ljust(9).ljust(80, "=") + "\n"
+ msg += stdout
+
+ if len(stderr):
+ msg += "stderr".ljust(9).ljust(80, "=") + "\n"
+ msg += stderr
+
+ msg += "exitcode".ljust(9).ljust(80, "=") + "\n"
+ msg += "{}\n".format(retcode)
+
+ msg += "=" * 80 + "\n"
print(msg)
if retcode != 0:
emsg = ""
- emsg += "Failed to run {}".join(" ".join(cmd)) + "\n"
- emsg += msg
+ emsg += "Yosys failed with exit code {}\n".format(retcode)
+ emsg += "Command: '{}'\n".format(" ".join(cmd))
+ emsg += "Message:\n"
+ emsg += "\n".join([" " + l for l in stderr.splitlines()])
raise subprocess.CalledProcessError(retcode, cmd, emsg)
+
return stdout
@@ -105,7 +145,7 @@
commands = "read_verilog {} {} {}; ".format(
get_defines(), get_includes(), " ".join(infiles)
) + commands
- params = ["-q", "-p", commands]
+ params = ["-p", commands]
return get_output(params)
@@ -117,7 +157,7 @@
script : path to Yosys script to run
infiles : list of input files
"""
- params = ["-q", "-s", script] + infiles
+ params = ["-s", script] + infiles
return get_output(params)
@@ -143,9 +183,13 @@
else:
mode_str = ""
cmds = "{}prep {}; write_json {}".format(mode_str, prep_opts, json_opts)
- j = utils.strip_yosys_json(commands(cmds, infiles))
- """with open('dump.json', 'w') as dbg:
- print(j,file=dbg)"""
+
+ try:
+ j = utils.strip_yosys_json(commands(cmds, infiles))
+ except subprocess.CalledProcessError as ex:
+ print(ex.output)
+ exit(-1)
+
return json.loads(j)
@@ -198,7 +242,13 @@
outfile = tempfile.mktemp()
sel_cmd = "{} cd {}; select -write {} {}".format(p, module, outfile, expr)
- commands(sel_cmd, infiles)
+
+ try:
+ commands(sel_cmd, infiles)
+ except subprocess.CalledProcessError as ex:
+ print(ex.output)
+ exit(-1)
+
pins = []
with open(outfile, 'r') as f:
for net in f:
@@ -207,6 +257,7 @@
pin = extract_pin(module, snet)
if pin is not None:
pins.append(pin)
+
os.remove(outfile)
return pins