[libre-riscv-dev] buffered pipeline
Luke Kenneth Casson Leighton
lkcl at lkcl.net
Tue Mar 19 05:19:09 GMT 2019
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*.
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.
More information about the libre-riscv-dev
mailing list