3c7be2b10aefda5fe16a362ba7469f24ca692c4e
[nmigen.git] / nmigen / back / verilog.py
1 import os
2 import re
3 import subprocess
4 import itertools
5
6 from .._yosys import *
7 from . import rtlil
8
9
10 __all__ = ["YosysError", "convert", "convert_fragment"]
11
12
13 def _convert_rtlil_text(rtlil_text, *, strip_internal_attrs=False, write_verilog_opts=()):
14 # this version requirement needs to be synchronized with the one in setup.py!
15 yosys = find_yosys(lambda ver: ver >= (0, 9))
16 yosys_version = yosys.version()
17
18 attr_map = []
19 if strip_internal_attrs:
20 attr_map.append("-remove generator")
21 attr_map.append("-remove top")
22 attr_map.append("-remove src")
23 attr_map.append("-remove nmigen.hierarchy")
24 attr_map.append("-remove nmigen.decoding")
25
26 return yosys.run(["-q", "-"], """
27 # Convert nMigen's RTLIL to readable Verilog.
28 read_ilang <<rtlil
29 {}
30 rtlil
31 {prune}delete w:$verilog_initial_trigger
32 {prune}proc_prune
33 proc_init
34 proc_arst
35 proc_dff
36 proc_clean
37 memory_collect
38 attrmap {attr_map}
39 attrmap -modattr {attr_map}
40 write_verilog -norename {write_verilog_opts}
41 """.format(rtlil_text,
42 # Yosys 0.9 release has buggy proc_prune.
43 prune="# " if yosys_version < (0, 9, 231) else "",
44 attr_map=" ".join(attr_map),
45 write_verilog_opts=" ".join(write_verilog_opts),
46 ))
47
48
49 def convert_fragment(*args, strip_internal_attrs=False, **kwargs):
50 rtlil_text, name_map = rtlil.convert_fragment(*args, **kwargs)
51 return _convert_rtlil_text(rtlil_text, strip_internal_attrs=strip_internal_attrs), name_map
52
53
54 def convert(*args, strip_internal_attrs=False, **kwargs):
55 rtlil_text = rtlil.convert(*args, **kwargs)
56 return _convert_rtlil_text(rtlil_text, strip_internal_attrs=strip_internal_attrs)