_yosys: translate Yosys warnings to Python warnings.
This isn't used yet (the only Yosys warning we can get is useless), but will be handy for CXXRTL.
This commit is contained in:
		
							parent
							
								
									a7b8ced92c
								
							
						
					
					
						commit
						bddec3741e
					
				|  | @ -2,6 +2,7 @@ import os | |||
| import sys | ||||
| import re | ||||
| import subprocess | ||||
| import warnings | ||||
| try: | ||||
|     from importlib import metadata as importlib_metadata # py3.8+ stdlib | ||||
| except ImportError: | ||||
|  | @ -20,6 +21,10 @@ class YosysError(Exception): | |||
|     pass | ||||
| 
 | ||||
| 
 | ||||
| class YosysWarning(Warning): | ||||
|     pass | ||||
| 
 | ||||
| 
 | ||||
| class YosysBinary: | ||||
|     @classmethod | ||||
|     def available(cls): | ||||
|  | @ -72,6 +77,16 @@ class YosysBinary: | |||
|         """ | ||||
|         raise NotImplementedError | ||||
| 
 | ||||
|     @classmethod | ||||
|     def _process_result(cls, returncode, stdout, stderr, ignore_warnings, src_loc_at): | ||||
|         if returncode: | ||||
|             raise YosysError(stderr.strip()) | ||||
|         if not ignore_warnings: | ||||
|             for match in re.finditer(r"(?ms:^Warning: (.+)\n$)", stderr): | ||||
|                 message = match.group(1).replace("\n", " ") | ||||
|                 warnings.warn(message, YosysWarning, stacklevel=3 + src_loc_at) | ||||
|         return stdout | ||||
| 
 | ||||
| 
 | ||||
| class _BuiltinYosys(YosysBinary): | ||||
|     YOSYS_PACKAGE = "nmigen_yosys" | ||||
|  | @ -93,15 +108,12 @@ class _BuiltinYosys(YosysBinary): | |||
|         return (int(match[1]), int(match[2]), int(match[3] or 0)) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def run(cls, args, stdin=""): | ||||
|     def run(cls, args, stdin="", *, ignore_warnings=False, src_loc_at=0): | ||||
|         popen = subprocess.Popen([sys.executable, "-m", cls.YOSYS_PACKAGE, *args], | ||||
|             stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, | ||||
|             encoding="utf-8") | ||||
|         stdout, stderr = popen.communicate(stdin) | ||||
|         if popen.returncode: | ||||
|             raise YosysError(stderr.strip()) | ||||
|         else: | ||||
|             return stdout | ||||
|         return cls._process_result(popen.returncode, stdout, stderr, ignore_warnings, src_loc_at) | ||||
| 
 | ||||
| 
 | ||||
| class _SystemYosys(YosysBinary): | ||||
|  | @ -118,7 +130,7 @@ class _SystemYosys(YosysBinary): | |||
|         return (int(match[1]), int(match[2]), int(match[3] or 0)) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def run(cls, args, stdin=""): | ||||
|     def run(cls, args, stdin="", *, ignore_warnings=False, src_loc_at=0): | ||||
|         popen = subprocess.Popen([require_tool(cls.YOSYS_BINARY), *args], | ||||
|             stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, | ||||
|             encoding="utf-8") | ||||
|  | @ -129,10 +141,7 @@ class _SystemYosys(YosysBinary): | |||
|         # | ||||
|         # This is not ideal, but Verific license conditions rule out any other solution. | ||||
|         stdout = re.sub(r"\A(-- .+\n|\n)*", "", stdout) | ||||
|         if popen.returncode: | ||||
|             raise YosysError(stderr.strip()) | ||||
|         else: | ||||
|             return stdout | ||||
|         return cls._process_result(popen.returncode, stdout, stderr, ignore_warnings, src_loc_at) | ||||
| 
 | ||||
| 
 | ||||
| def find_yosys(requirement): | ||||
|  |  | |||
|  | @ -38,7 +38,11 @@ write_verilog -norename {write_verilog_opts} | |||
|         prune="# " if yosys_version < (0, 9, 231) else "", | ||||
|         attr_map=" ".join(attr_map), | ||||
|         write_verilog_opts=" ".join(write_verilog_opts), | ||||
|     )) | ||||
|     ), | ||||
|     # At the moment, Yosys always shows a warning indicating that not all processes can be | ||||
|     # translated to Verilog. We carefully emit only the processes that *can* be translated, and | ||||
|     # squash this warning. Once Yosys' write_verilog pass is fixed, we should remove this. | ||||
|     ignore_warnings=True) | ||||
| 
 | ||||
| 
 | ||||
| def convert_fragment(*args, strip_internal_attrs=False, **kwargs): | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 whitequark
						whitequark