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

Luke Kenneth Casson Leighton lkcl at lkcl.net
Sun Jul 21 14:01:17 BST 2019


jacob, i'm thinking this through, and i can't see the need for making
the exponent even.

in the case of integers: yes, you have to treat the bits in groups of
2 (or, in groups of radix-size), and if you get that wrong you end up
multiplying accidentally by sqrt(2).

however in the FP case, you have to:

* copy the mantissa (which is always an odd number of bits)
* set (*add*) an extra bit at the top to "1".

this is what the "denormalisation" phase is for, and it's done in jon
dawson's div FSM, and in the multiplier as well:

        a_m <= a[22 : 0];
        ....
         //Denormalised Number
          if ($signed(a_e) == -127) begin
            a_e <= -126;
          end else begin
            a_m[23] <= 1; <<<<<------ set HI bit to 1, here
          end

if you have a look at the pre-prepared ieee754/fpdiv/pipeline.py code
i've already set up, you'll see that in specialcases.py there's
*already* a module in place that has "de-normed" both A and B,
already:

class FPDIVSpecialCasesDeNorm(FPState, SimpleHandshake):
        ....
        smod = FPDIVSpecialCasesMod(self.pspec)
        dmod = FPAddDeNormMod(self.pspec, False)

and in ieee754/fpcommon/denorm.py:

class FPAddDeNormMod(....):

    def elaborate():
            ....
            # XXX hmmm, don't like repeating identical code
            m.d.comb += self.o.a.eq(self.i.a)
            with m.If(in_a.exp_n127):
                m.d.comb += self.o.a.e.eq(self.i.a.N126) # limit a exponent
            with m.Else():
                m.d.comb += self.o.a.m[-1].eq(1) # set top mantissa bit

            m.d.comb += self.o.b.eq(self.i.b)
            with m.If(in_b.exp_n127):
                m.d.comb += self.o.b.e.eq(self.i.b.N126) # limit a exponent
            with m.Else():
                m.d.comb += self.o.b.m[-1].eq(1) # set top mantissa bit

so basically, this is, i believe, far, far simpler than you may be
imagining it to be [because the work's already been done].  all that's
needed is some code that converts from FPSCData into DivPipeInputData
(to get the output from that denorm module into the pipeline),
performing the divide on the (two ALREADY denormalised) mantissas,
then converting *back* out on the other side.

the exponents are subtracted and, along with the sign bit, need to be
passed through the pipeline, with no modifications.

l.



More information about the libre-riscv-dev mailing list