From e989564369e968ce30bd6eeda11a64e34985c73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 20 Jan 2025 11:01:30 +0100 Subject: [PATCH 1/2] litex: gen: fhdl: verilog.py: resolve slice in lower_complex_slices() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resove slices in lower_complex_slices() completly, to reduce complexity in the verilog files. Signed-off-by: Fin Maaß --- litex/gen/fhdl/verilog.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/litex/gen/fhdl/verilog.py b/litex/gen/fhdl/verilog.py index 91c9c929f4..50280fec9b 100644 --- a/litex/gen/fhdl/verilog.py +++ b/litex/gen/fhdl/verilog.py @@ -23,6 +23,7 @@ from migen.fhdl.structure import * from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment from migen.fhdl.tools import * +from migen.fhdl.tools import _apply_lowerer, _Lowerer from migen.fhdl.conv_output import ConvOutput from migen.fhdl.specials import Instance, Memory @@ -415,6 +416,32 @@ def _generate_specials(name, overrides, specials, namespace, add_data_file, attr r += pr return r +# ------------------------------------------------------------------------------------------------ # +# LOWERER # +# ------------------------------------------------------------------------------------------------ # + +class _ComplexSliceLowerer(_Lowerer): + def visit_Slice(self, node): + length = len(node) + start = 0 + while isinstance(node, _Slice): + start += node.start + node = node.value + if isinstance(node, Signal): + node = _Slice(node, start, start + length) + else: + slice_proxy = Signal(value_bits_sign(node)) + if self.target_context: + a = _Assign(node, slice_proxy) + else: + a = _Assign(slice_proxy, node) + self.comb.append(self.visit_Assign(a)) + node = _Slice(slice_proxy, start, start + length) + return NodeTransformer.visit_Slice(self, node) + +def lower_complex_slices(f): + return _apply_lowerer(_ComplexSliceLowerer(), f) + # ------------------------------------------------------------------------------------------------ # # FHDL --> VERILOG # # ------------------------------------------------------------------------------------------------ # From 0ba777f5ffb7153cb9753fec3cf3617cffab7e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 23 Jan 2025 13:22:09 +0100 Subject: [PATCH 2/2] litex: gen: fhdl: verilog.py: resolve slice of Cat and Replicate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the Slice is inside the boarders of one Objekt of Cat or Replicate resolve it too. Signed-off-by: Fin Maaß --- litex/gen/fhdl/verilog.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/litex/gen/fhdl/verilog.py b/litex/gen/fhdl/verilog.py index 50280fec9b..da41e80e7c 100644 --- a/litex/gen/fhdl/verilog.py +++ b/litex/gen/fhdl/verilog.py @@ -420,6 +420,28 @@ def _generate_specials(name, overrides, specials, namespace, add_data_file, attr # LOWERER # # ------------------------------------------------------------------------------------------------ # +def _lower_slice_cat(node, start, length): + while isinstance(node, Cat): + cat_start = 0 + for e in node.l: + if cat_start <= start < cat_start + len(e) >= start + length: + start -= cat_start + node = e + break + cat_start += len(e) + else: + break + return node, start + +def _lower_slice_replicate(node, start, length): + while isinstance(node, Replicate): + if start//len(node.v) == (start + length - 1)//len(node.v): + start = start % len(node.v) + node = node.v + else: + break + return node, start + class _ComplexSliceLowerer(_Lowerer): def visit_Slice(self, node): length = len(node) @@ -427,6 +449,14 @@ def visit_Slice(self, node): while isinstance(node, _Slice): start += node.start node = node.value + while True: + node, start = _lower_slice_cat(node, start, length) + former_node = node + node, start = _lower_slice_replicate(node, start, length) + if node is former_node: + break + if start == 0 and len(node) == length: + return NodeTransformer.visit(self, node) if isinstance(node, Signal): node = _Slice(node, start, start + length) else: