Skip to content

Commit

Permalink
Merge pull request #2165 from VOGL-electronic/bring_back_lower_slice
Browse files Browse the repository at this point in the history
litex: gen: fhdl: verilog.py: resolve slice in lower_complex_slices()
  • Loading branch information
enjoy-digital authored Jan 27, 2025
2 parents ad5d7d3 + 0ba777f commit d07c068
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions litex/gen/fhdl/verilog.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -415,6 +416,62 @@ def _generate_specials(name, overrides, specials, namespace, add_data_file, attr
r += pr
return r

# ------------------------------------------------------------------------------------------------ #
# 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)
start = 0
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:
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 #
# ------------------------------------------------------------------------------------------------ #
Expand Down

0 comments on commit d07c068

Please sign in to comment.