[libre-riscv-dev] buffered pipeline
programmerjake at gmail.com
Wed Mar 20 08:52:30 GMT 2019
On Wed, Mar 20, 2019, 00:58 Luke Kenneth Casson Leighton <lkcl at lkcl.net>
> On Wed, Mar 20, 2019 at 7:34 AM Jacob Lifshay <programmerjake at gmail.com>
> > I'm in the midst of converting the pipeline stages I wrote to using
> jacob, please: i already said that dependence on a specific class or
> data structure is undesirable, and restricts options as well as
> increases code size. removal of SignalGroup and replacing it with
> Record will not solve that particular problem.
> i've also *already developed* an example that uses Record, and shown
> that the pipeline infrastructure and the API associated with it can
> support the use of Records.
I created some record utility functions:
visit_records function that calls a callback once for each signal in a
record that behaves like zip() does on iterators
connect_records: creates a list of assignments, can be told to assign in to
out or out to in.
functions that manipulate and check the direction of all signals in a
a function to create a reversed Layout
Yeah, I had seen that. I may have gotten a little carried away, because I
think the API of my redesigned stage classes is really nice:
code for simple pipeline:
m = Module()
input_stage = InputStage() # user defined
add_stage = CombStage([('src1', 64), ('src2', 64)],
lambda pred, succ, m: # can also be member fn that reads from self.prev
and writes to self.next
m.d.comb += succ.data.eq(pred.src1 + pred.src2))
reg_stage = RegStage(add_stage.succ.data.layout)
output_stage = OutputStage() # user defined
> remember that i have some code in the IEEE754 FPU which has already
> been subdivided into modules that correspond with pipeline stages, so
> am already taking that into account in the design of the Buffered
> Pipeline code.
> i now have *four* different examples all of which conform to the same
> API and, to my eye, i believe are already extremely clear and simple,
> and i've found that efforts to further simplify or clarify them have
> disadvantages, and actually restrict the flexibility of the API.
> please can you stop for a moment, and take a look at ExampleStage,
> ExampleAddStage, ExampleAddRecordStage and LTStage, and let me know if
> there's a way that the API which supports *all* of these examples may
> be improved?
I think having the input and output signals be named is a good idea.
Also, support creating a pipeline stage from a lambda.
I think we should also have a separation of concerns:
my combstage can be connected in a row and all of them have 0 clocks of
latency because succ and pred's ready and valid signals are wired directly
my regstage does nothing but be a 1 clock latency register.
my ReadyIsolateStage does nothing but isolate the ready line by inserting a
register when ready is low, it has 0 cycles of delay when ready is high.
each of them has a separate function:
you don't need to supply a comb operation when you just want a regstage.
you don't need a cycle of delay when you want a combinatorial function
> bear in mind that both CombPipe and BufferedPipe may be used as
> mix-ins with all of those four examples, to create *interoperable*
> pipelines with different characteristics, as both CombPipe and
> BufferedPipe conform to the *exact* same pipeline / control API.
your combpipe is equivalent to my regstage followed by my combstage.
your bufferedpipe is equivalent to my regstage followed by my
ReadyIsolateStage followed by my CombStage
using my stage designs, if you have a pipeline already split into stages
and you want to make it take less clock cycles, you just have to remove
some regstage instances. with your design, you have to do some major
refactoring, because the pipeline registers are built into your stage
Note: none of the code I referred to is up on salsa yet, I haven't finished
updating the tests yet.
More information about the libre-riscv-dev