From 188eb8d4531e18602fd2886dde6d534abdb8bbe8 Mon Sep 17 00:00:00 2001 From: Wanda Date: Fri, 16 Feb 2024 22:48:54 +0100 Subject: [PATCH] back.rtlil: emit wire signedness according to `Signal` signedness. --- amaranth/back/rtlil.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/amaranth/back/rtlil.py b/amaranth/back/rtlil.py index a442238..1f934da 100644 --- a/amaranth/back/rtlil.py +++ b/amaranth/back/rtlil.py @@ -128,7 +128,7 @@ class _ModuleBuilder(_AttrBuilder, _BufferedBuilder, _Namer): self._append("end\n") self.rtlil._buffer.write(str(self)) - def wire(self, width, port_id=None, port_kind=None, name=None, attrs={}, src=""): + def wire(self, width, port_id=None, port_kind=None, name=None, attrs={}, src="", signed=False): # Very large wires are unlikely to work. Verilog 1364-2005 requires the limit on vectors # to be at least 2**16 bits, and Yosys 0.9 cannot read RTLIL with wires larger than 2**32 # bits. In practice, wires larger than 2**16 bits, although accepted, cause performance @@ -140,14 +140,15 @@ class _ModuleBuilder(_AttrBuilder, _BufferedBuilder, _Namer): self._attributes(attrs, src=src, indent=1) name = self._make_name(name, local=False) + signed = " signed" if signed else "" if port_id is None: - self._append(" wire width {} {}\n", width, name) + self._append(" wire width {}{} {}\n", width, signed, name) else: assert port_kind in ("input", "output", "inout") # By convention, Yosys ports named $\d+ are positional, so there is no way to use # a port with such a name. See amaranth-lang/amaranth#733. assert port_id is not None - self._append(" wire width {} {} {} {}\n", width, port_kind, port_id, name) + self._append(" wire width {} {} {}{} {}\n", width, port_kind, port_id, signed, name) return name def connect(self, lhs, rhs): @@ -383,14 +384,20 @@ class ModuleEmitter: assert value == port_value self.name_map[signal] = (*self.module.name, f"\\{name}") else: - wire = self.builder.wire(width=signal.width, name=name, attrs=attrs, + wire = self.builder.wire(width=signal.width, signed=signal.signed, + name=name, attrs=attrs, src=_src(signal.src_loc)) self.sigport_wires[name] = (wire, value) self.name_map[signal] = (*self.module.name, wire) def emit_port_wires(self): + named_signals = {name: signal for signal, name in self.module.signal_names.items()} for port_id, (name, (value, flow)) in enumerate(self.module.ports.items()): - wire = self.builder.wire(width=len(value), port_id=port_id, port_kind=flow.value, + signed = False + if name in named_signals: + signed = named_signals[name].signed + wire = self.builder.wire(width=len(value), signed=signed, + port_id=port_id, port_kind=flow.value, name=name, attrs=self.value_attrs.get(value, {})) self.sigport_wires[name] = (wire, value) if flow == _nir.ModuleNetFlow.OUTPUT: