back.{rtlil,verilog}: split convert_fragment() off convert().
authorwhitequark <cz@m-labs.hk>
Mon, 19 Aug 2019 19:27:02 +0000 (19:27 +0000)
committerwhitequark <cz@m-labs.hk>
Mon, 19 Aug 2019 19:49:51 +0000 (19:49 +0000)
Because Fragment.prepare is not (currently) idempotent, it is useful
to be able to avoid calling it when converting. Even if it is made
idempotent, it can be slow on large designs, so it is advantageous
regardless of that.

nmigen/back/rtlil.py
nmigen/back/verilog.py
nmigen/compat/fhdl/verilog.py

index 3c4da8b3ba9315f543b5a49adc6250c8a157ff38..875212d195182e7e6aebf14898ba8bff5dc97dd0 100644 (file)
@@ -7,7 +7,7 @@ from ..tools import bits_for, flatten
 from ..hdl import ast, rec, ir, mem, xfrm
 
 
-__all__ = ["convert"]
+__all__ = ["convert", "convert_fragment"]
 
 
 class _Namer:
@@ -720,7 +720,7 @@ class _StatementCompiler(xfrm.StatementVisitor):
             self.on_statement(stmt)
 
 
-def convert_fragment(builder, fragment, hierarchy):
+def _convert_fragment(builder, fragment, hierarchy):
     if isinstance(fragment, ir.Instance):
         port_map = OrderedDict()
         for port_name, (value, dir) in fragment.named_ports.items():
@@ -807,7 +807,7 @@ def convert_fragment(builder, fragment, hierarchy):
                     sub_params[param_name] = param_value
 
             sub_type, sub_port_map = \
-                convert_fragment(builder, subfragment, hierarchy=hierarchy + (sub_name,))
+                _convert_fragment(builder, subfragment, hierarchy=hierarchy + (sub_name,))
 
             sub_ports = OrderedDict()
             for port, value in sub_port_map.items():
@@ -938,8 +938,13 @@ def convert_fragment(builder, fragment, hierarchy):
     return module.name, port_map
 
 
-def convert(fragment, name="top", platform=None, **kwargs):
-    fragment = ir.Fragment.get(fragment, platform).prepare(**kwargs)
+def convert_fragment(fragment, name="top"):
+    assert isinstance(fragment, ir.Fragment)
     builder = _Builder()
-    convert_fragment(builder, fragment, hierarchy=(name,))
+    _convert_fragment(builder, fragment, hierarchy=(name,))
     return str(builder)
+
+
+def convert(elaboratable, name="top", platform=None, **kwargs):
+    fragment = ir.Fragment.get(elaboratable, platform).prepare(**kwargs)
+    return convert_fragment(fragment, name)
index 444e1247b4ce7fd63bbc317fddb13cc42c5fdd38..9761427582f04244cfdbcf3c8fec4803fff2f8bb 100644 (file)
@@ -4,14 +4,14 @@ import subprocess
 from . import rtlil
 
 
-__all__ = ["convert"]
+__all__ = ["YosysError", "convert", "convert_fragment"]
 
 
 class YosysError(Exception):
     pass
 
 
-def convert(*args, strip_src=False, **kwargs):
+def _convert_il_text(il_text, strip_src):
     try:
         popen = subprocess.Popen([os.getenv("YOSYS", "yosys"), "-q", "-"],
             stdin=subprocess.PIPE,
@@ -30,7 +30,6 @@ def convert(*args, strip_src=False, **kwargs):
     if strip_src:
         attr_map.append("-remove src")
 
-    il_text = rtlil.convert(*args, **kwargs)
     verilog_text, error = popen.communicate("""
 # Convert nMigen's RTLIL to readable Verilog.
 read_ilang <<rtlil
@@ -49,3 +48,13 @@ write_verilog -norename
         raise YosysError(error.strip())
     else:
         return verilog_text
+
+
+def convert_fragment(*args, strip_src=False, **kwargs):
+    il_text = rtlil.convert_fragment(*args, **kwargs)
+    return _convert_il_text(il_text, strip_src)
+
+
+def convert(*args, strip_src=False, **kwargs):
+    il_text = rtlil.convert(*args, **kwargs)
+    return _convert_il_text(il_text, strip_src)
index 29e5daa41da4c71b61a22973889b5a48937064a7..35a1ca59a11bb45969a6a4860ef74d1183cfb710 100644 (file)
@@ -21,7 +21,7 @@ def convert(fi, ios=None, name="top", special_overrides=dict(),
         if create_clock_domains:
             return ClockDomain(name)
     v_output = verilog.convert(
-        fragment=Fragment.get(fi.get_fragment(), platform=None),
+        elaboratable=fi.get_fragment(),
         name=name,
         ports=ios or (),
         missing_domain=missing_domain