[libre-riscv-dev] div/mod algorithm written in python

Jacob Lifshay programmerjake at gmail.com
Fri Jul 5 12:44:34 BST 2019

On Fri, Jul 5, 2019 at 4:26 AM Luke Kenneth Casson Leighton
<lkcl at lkcl.net> wrote:
> ---
> crowd-funded eco-conscious hardware: https://www.crowdsupply.com/eoma68
> On Fri, Jul 5, 2019 at 12:12 PM Jacob Lifshay <programmerjake at gmail.com> wrote:
> >
> > On Fri, Jul 5, 2019 at 3:59 AM Luke Kenneth Casson Leighton
> > <lkcl at lkcl.net> wrote:
> > >
> > > i've added the z-bypass signals (out_do_z, oz) and also the context
> > > (FPPipeContext) - all commented-out - as they need to be initialised
> > > correctly.
> > >
> > > these have to go into absolutely every data spec because they're
> > > passed (untouched) right the way through the pipeline.  bit annoying,
> > > but hey.
> > I had wanted to create new data spec and stage classes that add the
> > out_do_z, oz, muxid and route it around the DivPipeCore classes,
> > thereby keeping the algorithms more understandable since they don't
> > have a bunch of extraneous variables.
>  the trade-off being: "yet more classes".  if that's a balance you can
> live with, so can i.  bear in mind that out_do_z absolutely has to be
> used by what you [plan] call DivPipeCore, because it disables
> processing.
Since every DivPipeCore stage is only combinatorial, "disabling"
processing does nothing. in DivPipe (non-core), since it actually
tracks which pipeline stages actually have valid data (and supports
cancelling, tracking muxid, etc.), that's where the disabling will
>  also, when cancellation is added, that will affect DivPipeCore as
> well.  so bear that in mind, that there may not actually be much point
> in having the (planned) separation.
> > That's why I named them
> > DivPipeCore instead of DivPipe. The DivPipeCore classes would be
> > submodules of the DivPipe classes.
>  remember that every submodule added slows down simulations.  i had to
> drastically alter the design of the scoreboard code because of this.
I can live with that. if it gets too slow, we can simulate in verilog
-- where the inter-module boundaries shouldn't add any slow down
(maybe even using Verilator, though I haven't gotten that to work
> > > * the muxid *must* be unmodified.  it's the Reservation Station identifier.
> > >
> > > * out_do_z and z are set in SpecialCases.  they must not be touched by
> > > any "processing", as they already contain a result
> > >
> > > * ctx.op is where you can completely change the functionality of the
> > > pipeline: it's the ALU "operator", from the instruction decode phase
> > > (or is funct7, or... whatever).
> > That will be translated into DivPipeCoreOperation values (using
> > create_signal to create the signal, since it adds in the decoder
> > param, giving nicer debug output values). I'm not using ctx.op
> > directly, since there are several div variants that all translate to
> > UDivRem.
>  it would be better if that was done locally, i.e. the public API is
> self.ctx.op and the private *in-module* usage of self.ctx.op is done
> even without having a public self.operator (at all), i.e. there's a
> *local* variable "operator" within each DIV module, used like this:
>     size = len(self.ctx.op) # actually, from pspec, self.pspec['op_wid']
>     operator = DivPipeCoreOperation.create_signal(size) # whatever
>     m.d.comb += operator.eq(self.ctx.op)
> as i wrote in a cross-over message, the spec for that operator *HAS*
> to propagate *RIGHT* the way up to the ReservationStations.
> this is because it's a *public* (general) API, where self.ctx.op will
> change the SIMD behaviour, be used for MUL, ADD, FCVT and much, much
> more.
I'm planning on SIMD-ifying DivPipe and adding support for 64-bit
operations later, right now, I'm just making generic code that can
handle only one operand width.

> now, we _can_ look at propagating a class, all the way from the setup
> of FPipeContext, right the way down to the individual pipeline stages
> (make it a member of self.ctx)...
> ... but not right now.
> > The DivPipe (non-core) classes will need to handle translating signed
> > integer division into unsigned division + negations +
> > overflow/div-by-zero handling.

DivPipeCoreOperation is an internal detail of DivPipe. externally,
ctx.op is used, which can represent all the different operations.
DivPipeCoreOperation can't represent the difference between
div/mod/divu/modu/fdiv, because it doesn't matter to the core
algorithm (it's unsigned division in all the above cases). DivPipe
translates to/from DivPipeCore. Notably, DivPipe independently
propagates ctx.op to keep track of the exact operation.
> ... ok so if DivPipeCoreOperation is more complex than just a single
> signal, you can use Cat() or something, on DivPipeCoreOperation (see
> nmutil.nmoperator "cat()" function), to squash it down and jam it into
> self.ctx.op.
> or, we can look (right now) at making the default "class" for
> FPipeContext be a "Signal", and the setup for the fpdiv (back in
> test_fpdiv_pipe.py) passes in a DivPipeCoreOperation class name into
> FPipeContext.
> .... you get where i'm going with that?  DivPipeCoreOperation is an
> API specific to DIV, and it needs to fit into the *general* API
> (ReservationStation).
> 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