mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
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()
This commit is contained in:
parent
9d241f8cd3
commit
a255296171
3 changed files with 30 additions and 10 deletions
16
examples/basic/reslice.py
Normal file
16
examples/basic/reslice.py
Normal file
|
@ -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()))
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue