From ad925fc12563d9097dd1b93df0e0f3dc033b00ad Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 21 Oct 2021 15:04:33 +0100 Subject: [PATCH] continue truly awful hack which, in SimdSignal.__Assign__, detects the back-link to the submodule (PartitionedCat) in its return result, and calls set_lhs_mode(True) or (False) on LHS and RHS as appropriate. the default value is *NOT* set in the PartitionedCat constructor very very deliberately so as to show up any bugs. it is particularly fortunate that this was chosen to be done because there was, in fact, a bug in the TestCatMod unit test, which assumed that it was ok to splat a Cat() result of a pair of SimdSignals directly onto a Signal(). it *is* in fact "technically allowed" by nmigen due to automatic casting of UserValue, but should not strictly have been done. --- src/ieee754/part/partsig.py | 10 ++++++++++ src/ieee754/part/test/test_partsig.py | 6 ++++-- src/ieee754/part_cat/cat.py | 9 ++++++++- src/ieee754/part_cat/pcat.py | 2 +- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/ieee754/part/partsig.py b/src/ieee754/part/partsig.py index 9306f64d..8818e185 100644 --- a/src/ieee754/part/partsig.py +++ b/src/ieee754/part/partsig.py @@ -176,6 +176,16 @@ class SimdSignal(UserValue): def __Assign__(self, val, *, src_loc_at=0): print ("partsig assign", self, val) + # this is a truly awful hack, outlined here: + # https://bugs.libre-soc.org/show_bug.cgi?id=731#c13 + # during the period between constructing Simd-aware sub-modules + # and the elaborate() being called on them there is a window of + # opportunity to indicate which of those submodules is LHS and + # which is RHS. manic laughter is permitted. *gibber*. + if hasattr(self, "_hack_submodule"): + self._hack_submodule.set_lhs_mode(True) + if hasattr(val, "_hack_submodule"): + val._hack_submodule.set_lhs_mode(False) return PAssign(self.m, self, val, self.ptype) # TODO, http://bugs.libre-riscv.org/show_bug.cgi?id=458 diff --git a/src/ieee754/part/test/test_partsig.py b/src/ieee754/part/test/test_partsig.py index 1e3c457b..38efaadc 100644 --- a/src/ieee754/part/test/test_partsig.py +++ b/src/ieee754/part/test/test_partsig.py @@ -139,15 +139,17 @@ class TestCatMod(Elaboratable): self.partpoints = partpoints self.a = SimdSignal(partpoints, width) self.b = SimdSignal(partpoints, width*2) - self.cat_out = Signal(width*3) + self.o = SimdSignal(partpoints, width*3) + self.cat_out = self.o.sig def elaborate(self, platform): m = Module() comb = m.d.comb self.a.set_module(m) self.b.set_module(m) + self.o.set_module(m) - comb += self.cat_out.eq(Cat(self.a, self.b)) + comb += self.o.eq(Cat(self.a, self.b)) return m diff --git a/src/ieee754/part_cat/cat.py b/src/ieee754/part_cat/cat.py index 4fb5484c..f663afdd 100644 --- a/src/ieee754/part_cat/cat.py +++ b/src/ieee754/part_cat/cat.py @@ -74,6 +74,13 @@ class PartitionedCat(Elaboratable): self.partition_points = self.output.partpoints self.mwidth = len(self.partition_points)+1 + def set_lhs_mode(self, is_lhs): + """set an indication that this is a LHS mode + deliberately do not set self.is_lhs in the constructor + to a default value in order to detect when it is missing + """ + self.is_lhs = is_lhs + def get_chunk(self, y, idx, numparts): x = self.catlist[idx] keys = [0] + list(x.partpoints.keys()) + [len(x.sig)] @@ -88,7 +95,7 @@ class PartitionedCat(Elaboratable): return x.sig[start:end] def elaborate(self, platform): - print ("PartitionedCat start") + print ("PartitionedCat start", self.is_lhs) m = Module() comb = m.d.comb diff --git a/src/ieee754/part_cat/pcat.py b/src/ieee754/part_cat/pcat.py index a3b9c8c3..e94544b0 100644 --- a/src/ieee754/part_cat/pcat.py +++ b/src/ieee754/part_cat/pcat.py @@ -12,5 +12,5 @@ def PCat(m, arglist, ctx): setattr(m.submodules, "pcat%d" % modcount, pc) # add terrible hack back-link to be able to access PartitionedCat # in PartitionedAssign https://bugs.libre-soc.org/show_bug.cgi?id=731#c13 - pc.output.__hack_submodule = pc # blegh! + pc.output._hack_submodule = pc # blegh! return pc.output -- 2.30.2