[libre-riscv-dev] buffered pipeline

Jacob Lifshay programmerjake at gmail.com
Tue Mar 19 05:32:21 GMT 2019


On Mon, Mar 18, 2019, 22:20 Luke Kenneth Casson Leighton <lkcl at lkcl.net>
wrote:

> On Tue, Mar 19, 2019 at 1:31 AM Jacob Lifshay <programmerjake at gmail.com>
> wrote:
> >
> > what do you think of the naming and structure used in
> >
> https://salsa.debian.org/Kazan-team/simple-barrel-processor/blob/c2b3d40611225ca8a274a4bff36ac31ef7f4b64b/src/pipeline.py
>
>  SignalGroup is a duplication of the nmigen Record class.  i just
> managed to understand what Record is for, last night, after
> encountering this, in hdl/ast.py Array's docstring:
>
>     Array of records::
>
>         layout = [
>             ("re",     1),
>             ("dat_r", 16),
>         ]
>         buses  = Array(Record(layout) for busno in range(4))
>         master = Record(layout)
>         m.d.comb += [
>             buses[sel].re.eq(master.re),
>             master.dat_r.eq(buses[sel].dat_r),
>         ]
>
> layout is basically signal_shapes.items()
>
> StageIOBase, by being generic, doesn't have the i_ and o_ prefixes
> (that make it a challenge to create generic, shared code) which also
> has the side-effect of making it impossible to track and differentiate
> prev/next inputs/outputs.
>
> also, it's still complicated by the use of SignalGroup (aka Record).
>
> with the "eq()" function convention, only 3 lines are needed, and both
> PrevControl and NextControl are dead-simple (yes, i know it's possible
> to use list *IN*comprehension to "simplify" eq below.  i call it list
> *in*comprehension for a reason...)
>
> def eq(o, i):
>     if not isinstance(o, Sequence):
>         o, i = [o], [i]
>     res = []
>     for (ao, ai) in zip(o, i):
>         res.append(ao.eq(ai))
>     return res
>
> class PrevControl:
>     def __init__(self):
>         self.i_valid = Signal(name="p_i_valid") # >>in
>         self.o_ready = Signal(name="p_o_ready") # <<out
>     def connect_in(self, prev):
>         return [self.i_valid.eq(prev.i_valid),
>                 prev.o_ready.eq(self.o_ready),
>                 eq(self.i_data, prev.i_data),
>                ]
>
> bottom line: StageIOBase is overengineered, and so is
> connected_between_stages, which by using the "eq()" function
> convention reduces down to 3 lines (above: see connect_in).
>
> eq is used elsewhere, and could be adapted to take in a dictionary of
> signals as well as a list/tuple.
>
>
> also: compare the use of SignalGroup's capabilities to the use of eq.
>
> * SignalGroup forces the user of the Pipeline module to use
> StageToPred and StageToSucc (with a Record spec).  therefore, if using
> a module or a class, it will be necessary to add additional code that
> syncs the signals in and out.  in addition, if the user wants some
> signals named "valid" or "ready", they're hosed.
>
> * eq (as a convention) can be used on a single signal, a list of
> signals, a class instance which happens to have an eq function (where
> *its* responsibility is - by convention - to take care of copying all
> Signals, which IN TURN may ALSO be class members).
>
>  *AND*... i just took a look at dsl/rec.py - Record has an eq
> function, because it derives from Value!  so, it will be possible to
> use a Record instance as an input (or output) stage, and pass *that*
> into eq as *well*.
>
Record.eq is not supported by Simulator.

>
> to illustrate: i already have exactly such a Signal-copying function
> in many of the IEEE754 FPU classes, it just happens to have been
> called copy, and needs a global/search/replace "s/copy/eq" to conform
> to the convention.
>
> i'll try creating a Record example to make sure it works.
>
> l.
>
> _______________________________________________
> libre-riscv-dev mailing list
> libre-riscv-dev at lists.libre-riscv.org
> http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev
>


More information about the libre-riscv-dev mailing list