[libre-riscv-dev] [Bug 216] LOAD STORE buffer needed

bugzilla-daemon at libre-soc.org bugzilla-daemon at libre-soc.org
Wed May 27 12:10:54 BST 2020


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

--- Comment #46 from Luke Kenneth Casson Leighton <lkcl at lkcl.net> ---
tobias, the DataMerger class looks good as a first cut: it looks like it
does the job.

couple of things:

----

+            for j in range(self.addr):

this should be self.array_size



----

+                with m.If(self.addr_match_i[j]>0):

instead of > 0, bool() can (should) be used:

                with m.If(self.addr_match_i[j].bool()):


-----

+                with m.If(self.addr_match_i[idx][j] && valid):

ah.  in nmigen, you can't use boolean operators (&& or ||) because
there is no operator-overload for "bool".  a PEP was actually raised
about this and, rather short-sightedly, turned down.

you therefore have to use the bit-wise operators, and make sure
that the things that you are comparing are only 1 bit wide.

                with m.If(self.addr_match_i[idx][j] & valid):

------

+            self.data_o.eq(0)

this line is not needed.  combinatorial circuits default to zero unless
you set some of the Signal initialisation arguments.



-----

+                    self.data_o.eq(self.data_i[j]|self.data_o)

this isn't python programming, unfortunately: you can't treat Signals in
a loop as "sequentially-accumulating variables".

this is why i said to use treereduce.  or, actually, now you can import
ortreereduce, from soc.regfile.regfile.

so do this instead:

            l = []
            for j in range(self.array_size):
                select = self.addr_match_i[idx][j] & valid)
                l.append(Mux(select, self.data_i[j], 0)
            self.data_o.eq(ortreereduce(l)

see how that works? because hardware is effectively "statically-assigned
variables", you can't really do dynamic-accumulation.  or... you can, but
it will create a massive chain of gates and the completion time will be
awful.

:)

so, use a Mux-in-a-loop, and tree-reduce them.  strictly speaking we
could hypothetically use the 2nd parameter of nmutil.utils.treereduce
to actually do the Mux there, reduce things down to maybe one or two
lines of code, however that's getting obtuse and "too clever" :)
too clever means the code becomes unreadable.

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


More information about the libre-riscv-dev mailing list