[libre-riscv-dev] buffered pipeline
Jacob Lifshay
programmerjake at gmail.com
Mon Mar 18 16:10:38 GMT 2019
On Mon, Mar 18, 2019, 05:19 Luke Kenneth Casson Leighton <lkcl at lkcl.net>
wrote:
> ok so i implemented the ideas i had for a pipeline stage API, to
> create an input "spec" function and an output "spec" function that
> return a Signal, a list/tuple of signals, or an object that has an
> "eq" function.
>
>
> https://git.libre-riscv.org/?p=ieee754fpu.git;a=blob;f=src/add/example_buf_pipe.py;hb=HEAD
>
> i also separated Stage from the actual Pipeline class, and it turns
> out that the stage can be a static class. an add pipeline can be as
> simple as this:
>
> class ExampleAddStage:
> def ispec(self): return (Signal(16), Signal(16))
> def ospec(self): return Signal(16)
> def process(self, i): return i[0] + i[1]
>
> or:
>
> class ExampleAddStage:
> def ispec(): return (Signal(16), Signal(16))
> def ospec(): return Signal(16)
> def process(i): return i[0] + i[1]
>
> and need not really know anything about how the actual pipeline itself
> works. doesn't need to set up any input variables, doesn't need to
> set up any output variables, nor any intermediary registers, nor this,
> nor that, nor blah blah.
>
> *all* it needs to do is specify the format of the input, specify the
> format of the output, and process incoming data in the specified
> "input format" and return data in the "output" format.
>
> so it's a little different from the pipeline example you created,
> jacob, in that there's no need for explicit mention of or involvement
> of combinatorial logic, no module needs to be set up and so on.
>
I think that's fine, but we still need a way to have intermediate Signals
in our pipeline stage, since that's the only way to convert the
intermediate value to signed. See the implementation of alu.py sra/srl and
slt/sltu for examples where that is necessary.
>
> it's taking advantage of the features of python, by passing around
> (and returning) nmigen HDL fragments, rather than actually having the
> python code *do* the nmigen m.d.comb += in an explicit fashion: that's
> handled by the *base* class, such that the writer of the Stage doesn't
> have to.
>
> so in test_pipeline.py:
>
> def elaborate(self, platform: Any) -> Module:
> m = super().elaborate(platform)
> m.d.comb += self.comb_output.eq(self.comb_input + 1)
> return m
>
> that could be removed and replaced with this in the base class:
>
> def elaborate_more(self, platform: Any) -> Module:
> m = self.elaborate(platform)
> m.d.comb +=
> self.comb_output.eq(self.process(self.comb_input)
> return m
>
actually, it needs to be named elaborate since that's the name of the
function called by nmigen when you pass this class as an object to nmigen.
eg:
m.submodules.add = AddStage() # nmigen calls elaborate for us
>
> or actually just combine the m.d.comb line directly into
> SimpleStage.elaborate() and then create a process function like this:
>
> def elaborate(self, i):
> return i+1
>
assuming you meant def process()
>
> it's aalllmost at the point where i could consider using it in
> nmigen_add_experiment.py
>
> 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