Added crude top-level module name detection to doc builder

Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
diff --git a/docs/Makefile b/docs/Makefile
index b175e17..4673ff7 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -13,6 +13,7 @@
 MAKEDIR := $(dir $(lastword $(MAKEFILE_LIST)))
 
 # You can set these variables from the command line.
+COLLECTEXAMPLES = [ -e env/bin/activate ] && source env/bin/activate; python -c "from collect_examples import collect_examples; collect_examples()"
 SPHINXOPTS      =
 SPHINXBUILD     = [ -e env/bin/activate ] && source env/bin/activate; sphinx-build
 SPHINXAUTOBUILD = [ -e env/bin/activate ] && source env/bin/activate; sphinx-autobuild --watch $(MAKEDIR)../tests
@@ -44,6 +45,7 @@
 
 livehtml:
 	rm -rf examples
+	@$(COLLECTEXAMPLES) # Do this here to prevent sphinx-autobuild from slowly detecting all the changes
 	@$(SPHINXAUTOBUILD) -b html --host ${LIVEHTML_HOST} --port ${LIVEHTML_PORT} --ignore \*.swp --ignore \*~ $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html"
 
 .PHONY: help livehtml Makefile
diff --git a/docs/make_xml_for_docs.py b/docs/make_xml_for_docs.py
index 1d4b1b1..92d0adc 100644
--- a/docs/make_xml_for_docs.py
+++ b/docs/make_xml_for_docs.py
@@ -12,6 +12,7 @@
 import argparse
 import os
 import shlex
+import re
 
 from v2x import vlog_to_model
 from v2x import vlog_to_pbtype
@@ -22,6 +23,9 @@
 # =============================================================================
 
 
+MODULE_RE = re.compile(r"^module\s+(?P<module>[\w$]+)")
+
+
 def make_xml_for_docs(vlog_src, output_dir):
     """
     Recursively runs V2X (model and pb_type) on the given Verilog file and
@@ -48,13 +52,16 @@
     vlog_dst = os.path.join(output_dir, vlog_title)
 
     # Scan it for dependencies (includes), rewrite them
+    # Try also to guess the top-level module name (assuming that there is only
+    # one module per file!).
     vlog_deps = []
+    vlog_top = None
 
     with open(vlog_src, "r") as fsrc, open(vlog_dst, "w") as fdst:
         for src_line in fsrc:
+            line = src_line.strip()
 
             # Modify included file path
-            line = src_line.strip()
             if line.startswith("`include"):
                 fields = shlex.split(line)
                 assert len(fields) == 2, fields
@@ -71,6 +78,13 @@
             else:
                 dst_line = src_line
 
+            # Detect top-level module
+            # FIXME: This is crude and assumes the syntax "module <name>...".
+            # Both the keyword and module name must be in the same line
+            match = MODULE_RE.match(line)
+            if vlog_top is None and match is not None:
+                vlog_top = match.group("module")
+
             # Write the line
             fdst.write(dst_line)
 
@@ -88,7 +102,7 @@
     pbtype_file = os.path.join(output_dir, vlog_mod + ".pb_type.xml")
 
     if not os.path.isfile(model_file):
-        xml = vlog_to_model.vlog_to_model([vlog_dst], None, None, model_file)
+        xml = vlog_to_model.vlog_to_model([vlog_dst], None, vlog_top, model_file)
         with open(model_file, "w") as fp:
             fp.write(xml)
 
@@ -97,7 +111,7 @@
             fp.write(xml)
 
     if not os.path.isfile(pbtype_file):
-        xml = vlog_to_pbtype.vlog_to_pbtype([vlog_dst], pbtype_file, None)
+        xml = vlog_to_pbtype.vlog_to_pbtype([vlog_dst], pbtype_file, vlog_top)
         with open(pbtype_file, "w") as fp:
             fp.write(xml)