Improve dependencies.py and add a --synth option
authorAnton Blanchard <anton@linux.ibm.com>
Mon, 20 Jan 2020 23:38:48 +0000 (10:38 +1100)
committerAnton Blanchard <anton@ozlabs.org>
Mon, 20 Jan 2020 23:38:48 +0000 (10:38 +1100)
dependencies.py was pretty terrible at actually determining
dependencies. This improves it and also adds a --synth option.

Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
scripts/dependencies.py

index a06696f66e870699c693e07b45c4632485f5cbba..55c918137a806ae16d7a5a8b4eb9dc1aab6bc29d 100755 (executable)
 
 import sys
 import re
+import os
+from collections import defaultdict
 
+if len(sys.argv) == 1 and sys.argv[1] == '--help':
+    print("Usage: dependencies.py [--synth]")
+    sys.exit(1)
+
+synth = False
+args = sys.argv[1:]
+if sys.argv[1] == '--synth':
+    synth = True
+    args = sys.argv[2:]
+
+# Look at what a file provides
+entity = re.compile('entity (.*) is')
+package = re.compile('package (.*) is')
+
+# Look at what a file depends on
 work = re.compile('use work\.([^.]+)\.')
-entity = re.compile('entity work\.(.*)')
+entity_work = re.compile('entity work\.([^;]+)')
 
-for filename in sys.argv[1:]:
-    with open(filename, 'r') as f:
-        (basename, suffix) = filename.split('.')
-        print('%s.o:' % basename, end='')
+# Synthesis targets
+synth_provides = {
+    "dmi_dtm" : "dmi_dtm_dummy.vhdl",
+    "clock_generator" : "fpga/clk_gen_bypass.vhd",
+    "main_bram" : "fpga/main_bram.vhdl",
+    "pp_soc_uart" : "fpga/pp_soc_uart.vhd"
+}
 
+# Simulation targets
+sim_provides = {
+    "dmi_dtm" : "dmi_dtm_xilinx.vhdl",
+    "clock_generator" : "fpga/clk_gen_bypass.vhd",
+    "main_bram" : "sim_bram.vhdl",
+    "pp_soc_uart" : "sim_uart.vhdl"
+}
+
+if synth:
+    provides = synth_provides
+else:
+    provides = sim_provides
+
+dependencies = defaultdict(set)
+
+for filename in args:
+    with open(filename, 'r') as f:
         for line in f:
-            m = work.search(line)
+            l = line.rstrip(os.linesep)
+            m = entity.search(l)
             if m:
-                print(' %s.o' % m.group(1), end='')
+                p = m.group(1)
+                if p not in provides:
+                    provides[p] = filename
 
-            m = entity.search(line)
+            m = package.search(l)
             if m:
-                print(' %s.o' % m.group(1), end='')
-    print()
+                p = m.group(1)
+                if p not in provides:
+                    provides[p] = filename
+
+            m = work.search(l)
+            if m:
+                dependency = m.group(1)
+                dependencies[filename].add(dependency)
+
+            m = entity_work.search(l)
+            if m:
+                dependency = m.group(1)
+                dependencies[filename].add(dependency)
+
+
+emitted = set()
+def chase_dependencies(filename):
+    if filename not in dependencies:
+        if filename not in emitted:
+            print("%s " % (filename), end="")
+            emitted.add(filename)
+    else:
+        for dep in dependencies[filename]:
+            f = provides[dep]
+            chase_dependencies(f)
+            if f not in emitted:
+                print("%s " % (f), end="")
+                emitted.add(f)
+
+
+if synth:
+    chase_dependencies("fpga/toplevel.vhdl")
+    print("fpga/toplevel.vhdl")
+else:
+    for filename in dependencies:
+        (basename, suffix) = filename.split('.')
+        print("%s.o:" % (basename), end="")
+        for dependency in dependencies[filename]:
+            p = provides[dependency]
+            (basename2, suffix2) = p.split('.')
+            print(" %s.o" % (basename2), end="")
+        print("")