Merge pull request #73 from antmicro/yosys-select-fix

Yosys selection fix
diff --git a/conf/environment.yml b/conf/environment.yml
index c7a801f..fcdf0c1 100644
--- a/conf/environment.yml
+++ b/conf/environment.yml
@@ -2,7 +2,7 @@
 channels:
   - symbiflow
 dependencies:
-  - yosys
+  - symbiflow-yosys
   - pip:
     - tox
     - flake8
diff --git a/v2x/vlog_to_model.py b/v2x/vlog_to_model.py
index f234925..e3a7199 100755
--- a/v2x/vlog_to_model.py
+++ b/v2x/vlog_to_model.py
@@ -90,6 +90,14 @@
 
 
 def vlog_to_model(infiles, includes, top, outfile=None):
+
+    # Check Yosys version
+    pfx = run.determine_select_prefix()
+    if pfx != "=":
+        print("ERROR The version of Yosys found is outdated and not supported"
+              " by V2X")
+        sys.exit(-1)
+
     iname = os.path.basename(infiles[0])
 
     if outfile is None:
diff --git a/v2x/vlog_to_pbtype.py b/v2x/vlog_to_pbtype.py
index e0a0e66..338a766 100755
--- a/v2x/vlog_to_pbtype.py
+++ b/v2x/vlog_to_pbtype.py
@@ -910,6 +910,14 @@
 
 
 def vlog_to_pbtype(infiles, outfile, top=None):
+
+    # Check Yosys version
+    pfx = run.determine_select_prefix()
+    if pfx != "=":
+        print("ERROR The version of Yosys found is outdated and not supported"
+              " by V2X")
+        sys.exit(-1)
+
     iname = os.path.basename(infiles[0])
 
     run.add_define("PB_TYPE")
diff --git a/v2x/yosys/run.py b/v2x/yosys/run.py
index 25b4e82..1a51dbd 100755
--- a/v2x/yosys/run.py
+++ b/v2x/yosys/run.py
@@ -62,17 +62,43 @@
     return None
 
 
+def determine_select_prefix():
+    """
+    Older and newer versions of Yosys exhibit different behavior of the
+    'select' command regarding black/white boxes. Newer version requires a
+    prefix before some queries. This function determines whether the prefix
+    is required or not.
+    """
+
+    # Query help string of the select command
+    cmd = ["-p", "help select"]
+    stdout = get_output(cmd, no_common_args=True)
+
+    # Look for the phrase. If found then the prefix is required
+    PHRASE = "prefix the pattern with '='"
+    if PHRASE in stdout:
+        return "="
+
+    # No prefix needed
+    return ""
+
+
 def get_yosys_common_args():
     return ["-e", "wire '[^']*' is assigned in a block", "-q"]
 
 
-def get_output(params):
+def get_output(params, no_common_args=False):
     """Run Yosys with given command line parameters, and return
     stdout as a string. Raises CalledProcessError on a non-zero exit code."""
 
     verbose = get_verbose()
 
-    cmd = [get_yosys()] + get_yosys_common_args() + params
+    cmd = [get_yosys()]
+    if not no_common_args:
+        cmd += get_yosys_common_args()
+
+    cmd += params
+
     if verbose:
         msg = ""
         msg += "command".ljust(9).ljust(80, "=") + "\n"
@@ -283,7 +309,7 @@
     innet: Name of input net to find sinks of
     """
     return do_select(
-        infiles, module, "{} %co* o:* %i {} %d".format(innet, innet)
+        infiles, module, "={} %co* =o:* %i ={} %d".format(innet, innet)
     )
 
 
@@ -297,7 +323,7 @@
     """
     return do_select(
         infiles, module,
-        "c:* %x:+[CLK]:+[clk]:+[clock]:+[CLOCK] c:* %d x:* %i"
+        "=c:* %x:+[CLK]:+[clk]:+[clock]:+[CLOCK] =c:* %d =x:* %i"
     )
 
 
@@ -312,7 +338,8 @@
     """
     return do_select(
         infiles, module,
-        "select -list {} %a %co* %x i:* o:* %u %i a:ASSOC_CLOCK={} %u {} %d".
+        "select -list ={} %a %co* %x =i:* =o:* %u %i =a:ASSOC_CLOCK={} %u ={} "
+        "%d".
         format(clk, clk, clk)
     )
 
@@ -337,7 +364,7 @@
     clk: Name of clock to find associated signals
     """
     return do_select(
-        infiles, module, "select -list w:*{} %a %co* o:* %i".format(signal)
+        infiles, module, "select -list =w:*{} %a %co* =o:* %i".format(signal)
     )
 
 
@@ -353,6 +380,6 @@
     return [
         x for x in do_select(
             infiles, module,
-            "select -list w:*{} %a %co* %x i:* %i".format(signal)
+            "select -list =w:*{} %a %co* %x =i:* %i".format(signal)
         ) if x != signal
     ]