[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