gen/fhdl/verilog: list available clock domains on keyerror
[litex.git] / litex / gen / fhdl / verilog.py
index 4a647dd1bcd8abbf273602d68f4dcc6622573c8f..d5aef8d6d4f6ad0fbddf7cd20d9b95484ad272bc 100644 (file)
@@ -116,9 +116,7 @@ def _printexpr(ns, node):
 
 
 def _printnode(ns, at, level, node):
-    if node is None:
-        return ""
-    elif isinstance(node, Display):
+    if isinstance(node, Display):
         s = "\"" + node.s + "\\r\""
         for arg in node.args:
             s += ", "
@@ -176,8 +174,30 @@ def _list_comb_wires(f):
             r |= g[0]
     return r
 
+def _printattr(sig, attr_translate):
+    r = ""
+    firsta = True
+    for attr in sorted(sig.attr,
+                       key=lambda x: ("", x) if isinstance(x, str) else x):
+        if isinstance(attr, tuple):
+            # platform-dependent attribute
+            attr_name, attr_value = attr
+        else:
+            # translated attribute
+            at = attr_translate[attr]
+            if at is None:
+                continue
+            attr_name, attr_value = at
+        if not firsta:
+            r += ", "
+        firsta = False
+        r += attr_name + " = \"" + attr_value + "\""
+    if r:
+        r = "(* " + r + " *)"
+    return r
 
-def _printheader(f, ios, name, ns,
+
+def _printheader(f, ios, name, ns, attr_translate,
                  reg_initialization):
     sigs = list_signals(f) | list_special_ios(f, True, True, True)
     special_outs = list_special_ios(f, False, True, True)
@@ -190,6 +210,9 @@ def _printheader(f, ios, name, ns,
         if not firstp:
             r += ",\n"
         firstp = False
+        attr = _printattr(sig, attr_translate)
+        if attr:
+            r += "\t" + attr
         if sig in inouts:
             r += "\tinout " + _printsig(ns, sig)
         elif sig in targets:
@@ -201,6 +224,9 @@ def _printheader(f, ios, name, ns,
             r += "\tinput " + _printsig(ns, sig)
     r += "\n);\n\n"
     for sig in sorted(sigs - ios, key=lambda x: x.duid):
+        attr = _printattr(sig, attr_translate)
+        if attr:
+            r += attr + " "
         if sig in wires:
             r += "wire " + _printsig(ns, sig) + ";\n"
         else:
@@ -219,15 +245,19 @@ def _printcomb(f, ns,
     r = ""
     if f.comb:
         if dummy_signal:
-            # Generate a dummy event to get the simulator
-            # to run the combinatorial process once at the beginning.
+            explanation = """
+// Adding a dummy event (using a dummy signal 'dummy_s') to get the simulator
+// to run the combinatorial process once at the beginning.
+"""
             syn_off = "// synthesis translate_off\n"
             syn_on = "// synthesis translate_on\n"
             dummy_s = Signal(name_override="dummy_s")
+            r += explanation
             r += syn_off
             r += "reg " + _printsig(ns, dummy_s) + ";\n"
             r += "initial " + ns.get_name(dummy_s) + " <= 1'd0;\n"
             r += syn_on
+            r += "\n"
 
         groups = group_by_targets(f.comb)
 
@@ -280,8 +310,14 @@ def _printspecials(overrides, specials, ns, add_data_file):
     return r
 
 
+class DummyAttrTranslate:
+    def __getitem__(self, k):
+        return (k, "true")
+
+
 def convert(f, ios=None, name="top",
   special_overrides=dict(),
+  attr_translate=DummyAttrTranslate(),
   create_clock_domains=True,
   display_run=False,
   reg_initialization=True,
@@ -303,6 +339,9 @@ def convert(f, ios=None, name="top",
                 f.clock_domains.append(cd)
                 ios |= {cd.clk, cd.rst}
             else:
+                print("available clock domains:")
+                for f in f.clock_domains:
+                    print(f.name)
                 raise KeyError("Unresolved clock domain: '"+cd_name+"'")
 
     f = lower_complex_slices(f)
@@ -323,7 +362,7 @@ def convert(f, ios=None, name="top",
     r.ns = ns
 
     src = "/* Machine-generated using LiteX gen */\n"
-    src += _printheader(f, ios, name, ns,
+    src += _printheader(f, ios, name, ns, attr_translate,
                         reg_initialization=reg_initialization)
     src += _printcomb(f, ns,
                       display_run=display_run,