back.{rtlil,verilog}: split convert_fragment() off convert().

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.
This commit is contained in:
whitequark 2019-08-19 19:27:02 +00:00
parent 8e048c5a7c
commit a2241fcfdb
3 changed files with 24 additions and 10 deletions

View file

@ -7,7 +7,7 @@ from ..tools import bits_for, flatten
from ..hdl import ast, rec, ir, mem, xfrm from ..hdl import ast, rec, ir, mem, xfrm
__all__ = ["convert"] __all__ = ["convert", "convert_fragment"]
class _Namer: class _Namer:
@ -720,7 +720,7 @@ class _StatementCompiler(xfrm.StatementVisitor):
self.on_statement(stmt) self.on_statement(stmt)
def convert_fragment(builder, fragment, hierarchy): def _convert_fragment(builder, fragment, hierarchy):
if isinstance(fragment, ir.Instance): if isinstance(fragment, ir.Instance):
port_map = OrderedDict() port_map = OrderedDict()
for port_name, (value, dir) in fragment.named_ports.items(): 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_params[param_name] = param_value
sub_type, sub_port_map = \ sub_type, sub_port_map = \
convert_fragment(builder, subfragment, hierarchy=hierarchy + (sub_name,)) _convert_fragment(builder, subfragment, hierarchy=hierarchy + (sub_name,))
sub_ports = OrderedDict() sub_ports = OrderedDict()
for port, value in sub_port_map.items(): for port, value in sub_port_map.items():
@ -938,8 +938,13 @@ def convert_fragment(builder, fragment, hierarchy):
return module.name, port_map return module.name, port_map
def convert(fragment, name="top", platform=None, **kwargs): def convert_fragment(fragment, name="top"):
fragment = ir.Fragment.get(fragment, platform).prepare(**kwargs) assert isinstance(fragment, ir.Fragment)
builder = _Builder() builder = _Builder()
convert_fragment(builder, fragment, hierarchy=(name,)) _convert_fragment(builder, fragment, hierarchy=(name,))
return str(builder) return str(builder)
def convert(elaboratable, name="top", platform=None, **kwargs):
fragment = ir.Fragment.get(elaboratable, platform).prepare(**kwargs)
return convert_fragment(fragment, name)

View file

@ -4,14 +4,14 @@ import subprocess
from . import rtlil from . import rtlil
__all__ = ["convert"] __all__ = ["YosysError", "convert", "convert_fragment"]
class YosysError(Exception): class YosysError(Exception):
pass pass
def convert(*args, strip_src=False, **kwargs): def _convert_il_text(il_text, strip_src):
try: try:
popen = subprocess.Popen([os.getenv("YOSYS", "yosys"), "-q", "-"], popen = subprocess.Popen([os.getenv("YOSYS", "yosys"), "-q", "-"],
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
@ -30,7 +30,6 @@ def convert(*args, strip_src=False, **kwargs):
if strip_src: if strip_src:
attr_map.append("-remove src") attr_map.append("-remove src")
il_text = rtlil.convert(*args, **kwargs)
verilog_text, error = popen.communicate(""" verilog_text, error = popen.communicate("""
# Convert nMigen's RTLIL to readable Verilog. # Convert nMigen's RTLIL to readable Verilog.
read_ilang <<rtlil read_ilang <<rtlil
@ -49,3 +48,13 @@ write_verilog -norename
raise YosysError(error.strip()) raise YosysError(error.strip())
else: else:
return verilog_text 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)

View file

@ -21,7 +21,7 @@ def convert(fi, ios=None, name="top", special_overrides=dict(),
if create_clock_domains: if create_clock_domains:
return ClockDomain(name) return ClockDomain(name)
v_output = verilog.convert( v_output = verilog.convert(
fragment=Fragment.get(fi.get_fragment(), platform=None), elaboratable=fi.get_fragment(),
name=name, name=name,
ports=ios or (), ports=ios or (),
missing_domain=missing_domain missing_domain=missing_domain