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

Luke Kenneth Casson Leighton lkcl at lkcl.net
Sun Jul 21 16:20:15 BST 2019


this is the *last* piece of the puzzle - where quotient_root gets
dropped into the mantissa of z (where, previously the z mantissa field
has *not* been touched, at all, in *any* of the previous pipeline
stages), and the "remainder" is simply used to calculate the sticky
bit.

now, this *might* require instead that the MSB of the remainder goes
into "guard", and MSB-1 goes into "round", and remainder[:-2].bool()
goes into the sticky, i honestly don't know, and i don't know if it
even matters.

what the code below does, is it assumes that there are 2 extra bits on
the mantissa, one is "guard" and the other is "round".  anything
"spare" at the beginning of the quotient_root (if it wasn't "designed"
to be *exactly* the right length) will be used for "sticky".

this isn't perfect, by any means: it's just to give you the general idea, ok?

however, the point is to illustrate that there *really is* no need to
do any "extra development", i *really have* laid the groundwork
already and it *really is* just a simple matter of connecting things
together.

no need to do exponent shifting, no need to do de-normalisation, no
need to do re-normalisation, alignment, conversion: nothing.  the
*only* thing(s) needed are to sort out the operator, the conversion of
pspec into config, and so on.

l.


index 8db281a..9e36cb2 100644
--- a/src/ieee754/fpdiv/div2.py
+++ b/src/ieee754/fpdiv/div2.py
@@ -21,8 +21,7 @@ class FPDivStage2Mod(FPState, Elaboratable):
         self.o = self.ospec()

     def ispec(self):
-        # TODO: DivPipeCoreInterstageData
-        return FPDivStage0Data(self.pspec) # Q/Rem in...
+        return DivPipeOutputData(self.pspec) # Q/Rem in...

     def ospec(self):
         # XXX REQUIRED.  MUST NOT BE CHANGED.  this is the format
@@ -58,11 +57,11 @@ class FPDivStage2Mod(FPState, Elaboratable):
         with m.If(~self.i.out_do_z):
             mw = self.o.z.m_width
             m.d.comb += [
-                self.o.z.m.eq(self.i.product[mw+2:]),
-                self.o.of.m0.eq(self.i.product[mw+2]),
-                self.o.of.guard.eq(self.i.product[mw+1]),
-                self.o.of.round_bit.eq(self.i.product[mw]),
-                self.o.of.sticky.eq(self.i.product[0:mw].bool())
+                self.o.z.m.eq(self.i.quotient_root[mw+2:]),
+                self.o.of.m0.eq(self.i.quotient_root[mw+2]), # copy of LSB
+                self.o.of.guard.eq(self.i.quotient_root[mw+1]),
+                self.o.of.round_bit.eq(self.i.quotient_root[mw]),
+                self.o.of.sticky.eq(Cat(self.i.remainder,
+                                        self.i.quotient_root[:mw]).bool())

             ]

         m.d.comb += self.o.out_do_z.eq(self.i.out_do_z)

On Sun, Jul 21, 2019 at 3:56 PM Luke Kenneth Casson Leighton
<lkcl at lkcl.net> wrote:
>
> forgot to add an FPNumBaseRecord (the result).  z will be used (back
> in FPDivStage0Mod) to carry the sign and exponent right the way
> through the DivPipe* pipeline.  not DivPipeCore* pipeline classes,
> because those handle the *mantissa*.  DivPipeBaseData, by having an
> FPNumBaseRecord, carries the sign and exponent (and the member
> variable "m" gets ignored).
>
> it's... okay.  z.m, by never being used, should get optimised out.
>
> @@ -28,6 +28,9 @@ class DivPipeConfig:
>  class DivPipeBaseData:
>      """ input data base type for ``DivPipe``.
>
> +    :attribute z: a convenient way to carry the sign and exponent through
> +                  the pipeline from when they were computed right at the
> +                  start.
>      :attribute out_do_z: FIXME: document
>      :attribute oz: FIXME: document
>      :attribute ctx: FIXME: document
> @@ -41,6 +44,7 @@ class DivPipeBaseData:
>          """ Create a ``DivPipeBaseData`` instance. """
>          self.config = config
>          width = config.pspec.width
> +        self.z = FPNumBaseRecord(width, False) # s and e carried: m ignored
>          self.out_do_z = Signal(reset_less=True)
>          self.oz = Signal(width, reset_less=True)



More information about the libre-riscv-dev mailing list