support re-slicing and non-unit step size
authorRobert Jördens <jordens@gmail.com>
Thu, 27 Jun 2013 19:31:00 +0000 (13:31 -0600)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 30 Jun 2013 12:03:34 +0000 (14:03 +0200)
* support slicing of Slice/Cat/Replicate through lowering
* support non-unit step size slices through unpacking and Cat()

examples/basic/reslice.py [new file with mode: 0644]
migen/fhdl/structure.py
migen/fhdl/tools.py

diff --git a/examples/basic/reslice.py b/examples/basic/reslice.py
new file mode 100644 (file)
index 0000000..eee3951
--- /dev/null
@@ -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()))
index 5aee1b3a1a56e596def8cc9e820df3bee80a0a5b..a6e049726c959a50f6769c1301289a7db80555bb 100644 (file)
@@ -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
index fd55034d87c2d104f31c4f2effca5fda748539ff..ac538d039e31e94e7c98618d1a99133041b9a508 100644 (file)
@@ -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)