back.verilog: omit Verilog initial trigger only if Yosys adds it.
[nmigen.git] / nmigen / back / verilog.py
1 from .._toolchain.yosys import *
2 from . import rtlil
3
4
5 __all__ = ["YosysError", "convert", "convert_fragment"]
6
7
8 def _convert_rtlil_text(rtlil_text, *, strip_internal_attrs=False, write_verilog_opts=()):
9 # this version requirement needs to be synchronized with the one in setup.py!
10 yosys = find_yosys(lambda ver: ver >= (0, 9))
11 yosys_version = yosys.version()
12
13 script = []
14 script.append("read_ilang <<rtlil\n{}\nrtlil".format(rtlil_text))
15
16 if yosys_version >= (0, 9, 3468):
17 # Yosys >=0.9+3468 (since commit f3d7e9a1) emits Verilog without a possible sim/synth
18 # mismatch, making $verilog_initial_trigger unnecessary.
19 script.append("delete w:$verilog_initial_trigger")
20 script.append("proc_prune")
21 script.append("proc_init")
22 script.append("proc_arst")
23 script.append("proc_dff")
24 script.append("proc_clean")
25 script.append("memory_collect")
26
27 if strip_internal_attrs:
28 attr_map = []
29 attr_map.append("-remove generator")
30 attr_map.append("-remove top")
31 attr_map.append("-remove src")
32 attr_map.append("-remove nmigen.hierarchy")
33 attr_map.append("-remove nmigen.decoding")
34 script.append("attrmap {}".format(" ".join(attr_map)))
35 script.append("attrmap -modattr {}".format(" ".join(attr_map)))
36
37 script.append("write_verilog -norename {}".format(" ".join(write_verilog_opts)))
38
39 return yosys.run(["-q", "-"], "\n".join(script),
40 # At the moment, Yosys always shows a warning indicating that not all processes can be
41 # translated to Verilog. We carefully emit only the processes that *can* be translated, and
42 # squash this warning. Once Yosys' write_verilog pass is fixed, we should remove this.
43 ignore_warnings=True)
44
45
46 def convert_fragment(*args, strip_internal_attrs=False, **kwargs):
47 rtlil_text, name_map = rtlil.convert_fragment(*args, **kwargs)
48 return _convert_rtlil_text(rtlil_text, strip_internal_attrs=strip_internal_attrs), name_map
49
50
51 def convert(*args, strip_internal_attrs=False, **kwargs):
52 rtlil_text = rtlil.convert(*args, **kwargs)
53 return _convert_rtlil_text(rtlil_text, strip_internal_attrs=strip_internal_attrs)