[libre-riscv-dev] buffered pipeline

Luke Kenneth Casson Leighton lkcl at lkcl.net
Wed Mar 27 10:29:16 GMT 2019


class BreakReadyChainStage:

        def visitor(name: str,
                    pred_tuple: Tuple[Signal, Direction],
                    succ_tuple: Tuple[Signal, Direction],
                    buffer_tuple: Tuple[Signal, Direction]) -> None:
            pred = pred_tuple[0]
            succ = succ_tuple[0]
            buffer = buffer_tuple[0]
            m.d.comb += succ.eq(Mux(self.buffer_full, buffer, pred))
            m.d.sync += buffer.eq(succ)

        visit_records(visitor,
                      [self.pred.data_in,
                       self.succ.data_out,
                       self.buffer])
        return m

can be replaced with:

m.d.sync += self.succ.data_out.eq(self.buffer)
with m.If(self.buffer_full):
    m.d.comb += eq(self.succ.data_out, buffer)
with m.Else():
    m.d.comb += eq(self.succ.data_out, self.succ.data_in)

and as a result i find it is far easier to understand, because the
logic about the decision of what to do (the If/Else) is an invariant
that's moved *outside* of the use of the higher-order-function,
"visitor()".

it also has the distinct advantage that it is *NOT* critically
hard-dependent on Records, any more. ["eq()" covers the *exact* same
job as visit_records].

plus, it's less lines of code.

this is what i meant about certain types of things that can be done in
python... which you're learning that they're possible... the trick
then is to *not* use them if it makes it impossible for other people
to understand what's going on.

l.



More information about the libre-riscv-dev mailing list