[Libre-soc-bugs] [Bug 713] PartitionedSignal enhancement to add partition-context-aware lengths
bugzilla-daemon at libre-soc.org
bugzilla-daemon at libre-soc.org
Tue Oct 12 19:51:20 BST 2021
https://bugs.libre-soc.org/show_bug.cgi?id=713
--- Comment #82 from Jacob Lifshay <programmerjake at gmail.com> ---
(In reply to Luke Kenneth Casson Leighton from comment #73)
> i think we're slowly getting to the bottom of where the assumptions
> are that caused you to believe that it is impossible to use nmigen
> with such tiny modifications (and to believe that it is undesirable
> to do so).
>
> it revolves around elwidths and the definition of Shape.width.
>
> the past 18 months work have been fundamentally based on the assumption
> that it is, by design, possible to fit. much of that time was spent
> verifying that that was possible.
>
> the assumption / definition and all code is based on:
>
> Shape.width == SimdShape.width == len(SimdSignal._its_internalsignal)
well, the problem is that, to correctly maintain the appearance of operating on
*scalar* values needed for all our existing OpenPower ALUs (waay more code than
PartitionedSignal), we need it to look like a single element, *not* a list.
This means SimdSignal.width *has to be* the width of a *single* element.
>
> we need - and other users will expect - that Casting will "just work".
> SimdSignal should be castable to Signal and all bits *directly*
> copied (including unused padding partitions) seamlessly at the bitlevel.
we need Signal/SimdSignal interconversion, but it should be done via having
non-SIMD code access SimdSignal.sig, or by a .bitcast member function, not by
just doing Signal.eq. In particular, what your advocating for (for SimdSignal
to transparently inter-convert with Signal), just 1:1 copying bits, will *not
work* nicely -- it's in conflict with what happens when a scalar is converted
to a vector, which is that that scalar is *splatted* into all lanes of the
vector, not that the scalar is split into pieces and each piece becomes a lane.
Example (addi):
class MyAddI(...):
def __init__(self):
with simd_scope(self, create_elwid=True):
self.RT = SimdSignal(XLEN) # output: vector
self.RA = SimdSignal(XLEN) # input: vector
self.Imm = Signal(signed(16)) # input: *scalar*, since it's not a
register
def elaborate(self, platform):
m = Module()
with simd_scope(self, m=m):
sliced_imm = SimdSignal(XLEN)
m.d.comb += sliced_imm.eq(self.Imm) # slice off bits that don't fit
in XLEN
m.d.comb += self.RT.eq(self.RA + sliced_imm)
return m
In order for the semantics to be correct, the conversion from self.Imm to a
SimdSignal has to put *all* of Imm's value into each lane -- *instead of what
you are advocating for* -- what you are advocating for would split Imm into
2-bit/4-bit/8-bit/16-bit pieces and put each of those pieces into each
corresponding lane, which is exactly what a 1:1 bit copy does, which is
*totally wrong* here.
Example (with elwid == 16-bits):
RA = 0x0123_4567_89AB_CDEF
instruction:
addi rt, ra, 0x7531
Right way (splatting):
RA (lanes): [0xCDEF, 0x89AB, 0x4567, 0x0123]
Imm: 0x7531
sliced_imm (lanes): [0x7531, 0x7531, 0x7531, 0x7531]
RT (lanes): [0xCDEF + 0x7531, 0x89AB + 0x7531, 0x4567 + 0x7531, 0x0123 +
0x7531] ==
[0x4320, 0xFEDC, 0xBA98, 0x7654]
RT = 0x7654_BA98_FEDC_4320
Wrong way (1:1 bit conversion -- convert imm to 16-bit wide simd then sign
extend):
RA (lanes): [0xCDEF, 0x89AB, 0x4567, 0x0123]
Imm: 0x7531
sliced_imm (1:1 converted into lanes): [0x1, 0x3, 0x5, 0x7]
RT (lanes): [0xCDEF + 0x1, 0x89AB + 0x3, 0x4567 + 0x5, 0x0123 + 0x7] ==
[0xCDF0, 0x89AE, 0x456C, 0x012A]
RT = 0x012A_456C_89AE_CDF0
Another wrong way (1:1 bit conversion -- sign extend imm to simd width then
convert):
RA (lanes): [0xCDEF, 0x89AB, 0x4567, 0x0123]
Imm: 0x7531
sliced_imm (1:1 converted into lanes, only lower 16-bits of full 64-bits had
anything):
[0x1357, 0x0, 0x0, 0x0]
RT (lanes): [0xCDEF + 0x1357, 0x89AB + 0x0, 0x4567 + 0x0, 0x0123 + 0x0] ==
[0x7654, 0x89AB, 0x4567, 0x0123]
RT = 0x0123_4567_89AB_7654
> this *is* how nmigen works. all Value-derivatives *are* copyable
> from one to the other by making the fundamental assumption that
> when converted to bitlevel they are all effectively "the same".
Well, SimdSignal is *fundamentally* incompatible with nmigen Value/Signal,
since nmigen expects Values to act like a single scalar value, whereas
SimdSignal acts like a *list* of scalar values -- aka. a Vector.
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the libre-soc-bugs
mailing list