[Libre-soc-bugs] [Bug 458] PartitionedSignal needs nmigen constructs "m.If", Switch etc

bugzilla-daemon at libre-soc.org bugzilla-daemon at libre-soc.org
Sun Sep 26 17:11:34 BST 2021


https://bugs.libre-soc.org/show_bug.cgi?id=458

Luke Kenneth Casson Leighton <lkcl at lkcl.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                URL|                            |https://libre-soc.org/3d_gp
                   |                            |u/architecture/dynamic_simd
                   |                            |/

--- Comment #9 from Luke Kenneth Casson Leighton <lkcl at lkcl.net> ---
working through this, this afternoon (see main bug URL),
although the parallel "columnisation" concept is
fine, i.e. treating a parallelised SIMD Switch
as a for-loop around "Lanes" of completely separate
and independent Switch/Cases, one per partition,
the *assignment* part of that - the action to
be taken *in* each column - is more involved than
i otiginslly envisaged, and that comes down
not to the assignments themselves but to the
fact that If and Switch statements *can be nested*.

the original assumption i made was that the use
of ast.Switch() by dsl.py would always create
assignments within each case. this code:

     with m.If(iftest):
          comb += o.eq(c)
     with m.Elif(elsetest)
          comb += o eq(d)

gets turned into:

     ast.Switch Cat(iftest, eliftest):
          case("1-"):
              comb += o.eq(c)
          case("-1"):
              comb += o.eq(d)

which can be parallelised with a simple for-loop
creating *multiple* Switch statements:

     for i in range(4partitions):
        ast.Switch Cat(iftest[i], eliftest[i]):
          case("1-"):
              comb += o[i].eq(c[i])
          case("-1"):
              comb += o[i].eq(d[i])

the problem comes if there is a Switch inside a Switch.
or, an m.If inside an m.If.

i have no problem at all with limiting the nested depth
to one and ONLY one in order to get this done as quickly as
possible.

this would involve analysing the first depth of all
case statements, prior to creating the (independent)
for-loops, checking that they are of type Assign,
and creating a temporary Signal set (one for each
assignment of each case) and, in each of the for-loop
replace with *partial* assignment.

    o.eq(d) # d being potentially a complex expression
    o.eq(c) # likewise

would be replaced with:

    tempin_d.eq(d)
    tempin_c.eq(c)
    o.eq(tempout)

and the switch statement for-loop then
morphed to:

     for i in range(4partitions):
        ast.Switch Cat(iftest[i], eliftest[i]):
          case("1-"):
              comb += tempout_o[i].eq(tempin_c[i])
          case("-1"):
              comb += tempout_o[i].eq(tempin_d[i])

in and of itself this is a lot more involved that i first envisaged.
hm.  it involves analysing all Case statements LHS and RHS to create
a global temporary substitution lookup table.

also, anything such as "Cat(a,b,c).eq(.....)" will not be supported
within an m.If or m.Switch, which is perfectly fine.

this needs to be done as fast as possible, we are under time pressure now.
complex analysis and complex "elegant, complete" solutions that take months to
complete unfortunately are off the table.

limited functionality is perfectly fine as a first pass, so we can get things
moving, given that this is now on the critical path.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the libre-soc-bugs mailing list