continue truly awful hack which, in SimdSignal.__Assign__, detects the
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 21 Oct 2021 14:04:33 +0000 (15:04 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 21 Oct 2021 14:04:33 +0000 (15:04 +0100)
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
src/ieee754/part/test/test_partsig.py
src/ieee754/part_cat/cat.py
src/ieee754/part_cat/pcat.py

index 9306f64d862ced34b5e96d8722c9bb4de8cbbe5a..8818e185156a25391b94a45198f4163e8e606b8d 100644 (file)
@@ -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
index 1e3c457bf9de026d40adf04c2d88045eb8ee1fb5..38efaadce66fb574c9021b6e084272b44c8c9696 100644 (file)
@@ -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
 
index 4fb5484cdee83c8cac857a8722caae8771598045..f663afdd3c93e890feb26fd12277fcb71bafbf8c 100644 (file)
@@ -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
 
index a3b9c8c3051bfafe5ad4766db559e7fba3cf3baf..e94544b0ed2a6f088262a71bfbc3579b4b18d093 100644 (file)
@@ -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