From 814ffde6fbf38598c7db31dbea1414d6d5624ecb Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 13 Apr 2020 15:56:39 +0000 Subject: [PATCH] back.rtlil: fix expansion of Part() for partial dummy writes. Before this commit, selecting a part that was fully out of bounds of a value was correctly implemented as a write to a dummy wire, but selecting a part that was only partially out of bounds resulted in a crash. Fixes #351. --- nmigen/back/rtlil.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/nmigen/back/rtlil.py b/nmigen/back/rtlil.py index c074a97f5..8433fe263 100644 --- a/nmigen/back/rtlil.py +++ b/nmigen/back/rtlil.py @@ -632,12 +632,14 @@ def _prepare_value_for_Slice(self, value): def on_Part(self, value): offset = self.s.expand(value.offset) if isinstance(offset, ast.Const): - if offset.value == len(value.value): - dummy_wire = self.s.rtlil.wire(value.width) - return dummy_wire - return self(ast.Slice(value.value, - offset.value * value.stride, - offset.value * value.stride + value.width)) + start = offset.value * value.stride + stop = start + value.width + slice = self(ast.Slice(value.value, start, min(len(value.value), stop))) + if len(value.value) >= stop: + return slice + else: + dummy_wire = self.s.rtlil.wire(stop - len(value.value)) + return "{{ {} {} }}".format(dummy_wire, slice) else: # Only so many possible parts. The amount of branches is exponential; if value.offset # is large (e.g. 32-bit wide), trying to naively legalize it is likely to exhaust