From: Robert Jördens Date: Thu, 27 Jun 2013 19:31:00 +0000 (-0600) Subject: support re-slicing and non-unit step size X-Git-Tag: 24jan2021_ls180~2099^2~544 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a255296171e3a2736d1331d80eee7d9073b186c7;p=litex.git support re-slicing and non-unit step size * support slicing of Slice/Cat/Replicate through lowering * support non-unit step size slices through unpacking and Cat() --- diff --git a/examples/basic/reslice.py b/examples/basic/reslice.py new file mode 100644 index 00000000..eee3951f --- /dev/null +++ b/examples/basic/reslice.py @@ -0,0 +1,16 @@ +from migen.fhdl.std import * +from migen.fhdl import verilog + +class Example(Module): + def __init__(self): + a = Signal(3) + b = Signal(4) + c = Signal(5) + d = Signal(7) + s1 = c[:3][:2] + s2 = Cat(a, b)[:6] + s3 = Cat(s1, s2)[-5:] + self.comb += s3.eq(0) + self.comb += d.eq(Cat(d[::-1], Cat(s1[:1], s3[-4:])[:3])) + +print(verilog.convert(Example())) diff --git a/migen/fhdl/structure.py b/migen/fhdl/structure.py index 5aee1b3a..a6e04972 100644 --- a/migen/fhdl/structure.py +++ b/migen/fhdl/structure.py @@ -75,16 +75,9 @@ class Value(HUID): key += flen(self) return _Slice(self, key, key+1) elif isinstance(key, slice): - start = key.start or 0 - stop = key.stop or flen(self) - if start < 0: - start += flen(self) - if stop < 0: - stop += flen(self) - if stop > flen(self): - stop = flen(self) - if key.step != None: - raise KeyError + start, stop, step = key.indices(flen(self)) + if step != 1: + return Cat(*(self[i] for i in range(start, stop, step))) return _Slice(self, start, stop) else: raise KeyError diff --git a/migen/fhdl/tools.py b/migen/fhdl/tools.py index fd55034d..ac538d03 100644 --- a/migen/fhdl/tools.py +++ b/migen/fhdl/tools.py @@ -163,6 +163,17 @@ class _BasicLowerer(NodeTransformer): def visit_ResetSignal(self, node): return self.clock_domains[node.cd].rst + def visit_Slice(self, node): + if not isinstance(node.value, Signal): + slice_proxy = Signal(value_bits_sign(node.value)) + if self.target_context: + a = _Assign(node.value, slice_proxy) + else: + a = _Assign(slice_proxy, node.value) + self.comb.append(self.visit_Assign(a)) + node = _Slice(slice_proxy, node.start, node.stop) + return NodeTransformer.visit_Slice(self, node) + def lower_basics(f): bl = _BasicLowerer(f.clock_domains) f = bl.visit(f)