From 6e29fbcc61ed8e8ebdad8d64bda1ba52343fa296 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 28 Apr 2020 02:16:12 +0000 Subject: [PATCH] back.rtlil: fix incorrect escaping of signed parameters. Also, improve escaping code in general. --- nmigen/back/rtlil.py | 57 +++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/nmigen/back/rtlil.py b/nmigen/back/rtlil.py index 3f9936e..48fa125 100644 --- a/nmigen/back/rtlil.py +++ b/nmigen/back/rtlil.py @@ -14,6 +14,27 @@ class ImplementationLimit(Exception): pass +_escape_map = str.maketrans({ + "\"": "\\\"", + "\\": "\\\\", + "\t": "\\t", + "\r": "\\r", + "\n": "\\n", +}) + + +def const(value): + if isinstance(value, str): + return "\"{}\"".format(value.translate(_escape_map)) + elif isinstance(value, int): + return "{:d}".format(value) + elif isinstance(value, ast.Const): + value_twos_compl = value.value & ((1 << value.width) - 1) + return "{}'{:0{}b}".format(value.width, value_twos_compl, value.width) + else: + assert False, "Invalid constant {!r}".format(value) + + class _Namer: def __init__(self): super().__init__() @@ -58,21 +79,9 @@ class _ProxiedBuilder: class _AttrBuilder: - _escape_map = str.maketrans({ - "\"": "\\\"", - "\\": "\\\\", - "\t": "\\t", - "\r": "\\r", - "\n": "\\n", - }) - def _attribute(self, name, value, *, indent=0): - if isinstance(value, str): - self._append("{}attribute \\{} \"{}\"\n", - " " * indent, name, value.translate(self._escape_map)) - else: - self._append("{}attribute \\{} {}\n", - " " * indent, name, int(value)) + self._append("{}attribute \\{} {}\n", + " " * indent, name, const(value)) def _attributes(self, attrs, *, src=None, **kwargs): for name, value in attrs.items(): @@ -137,20 +146,12 @@ class _ModuleBuilder(_Namer, _BufferedBuilder, _AttrBuilder): name = self._make_name(name, local=False) self._append(" cell {} {}\n", kind, name) for param, value in params.items(): - if isinstance(value, str): - self._append(" parameter \\{} \"{}\"\n", - param, value.translate(self._escape_map)) - elif isinstance(value, int): - self._append(" parameter \\{} {}'{:b}\n", - param, bits_for(value), value) - elif isinstance(value, float): + if isinstance(value, float): self._append(" parameter real \\{} \"{!r}\"\n", param, value) - elif isinstance(value, ast.Const): - self._append(" parameter \\{} {}'{:b}\n", - param, len(value), value.value) else: - assert False, "Bad parameter {!r}".format(value) + self._append(" parameter \\{} {}\n", + param, const(value)) for port, wire in ports.items(): self._append(" connect {} {}\n", port, wire) self._append(" end\n") @@ -433,11 +434,7 @@ class _RHSValueCompiler(_ValueCompiler): return super().on_value(self.s.expand(value)) def on_Const(self, value): - if isinstance(value.value, str): - return "{}'{}".format(value.width, value.value) - else: - value_twos_compl = value.value & ((1 << value.width) - 1) - return "{}'{:0{}b}".format(value.width, value_twos_compl, value.width) + return const(value) def on_AnyConst(self, value): if value in self.s.anys: -- 2.30.2