X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fieee754%2Ffpdiv%2Fdiv0.py;h=80ffc68996ff3faa6a3fcdd38596b29f1ce61012;hb=81b131e743f9d3f1c6b883a9793715f26db1a33b;hp=c6e74ecf9476ec5b443c0ebdadd8d29541819885;hpb=70f31283f40f4b9b135abddb03342c1e917ecb85;p=ieee754fpu.git diff --git a/src/ieee754/fpdiv/div0.py b/src/ieee754/fpdiv/div0.py index c6e74ecf..80ffc689 100644 --- a/src/ieee754/fpdiv/div0.py +++ b/src/ieee754/fpdiv/div0.py @@ -1,9 +1,9 @@ -"""IEEE754 Floating Point Divider +"""IEEE754 Floating Point Divider Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99 """ -from nmigen import Module, Signal, Cat, Elaboratable +from nmigen import Module, Signal, Cat, Elaboratable, Const from nmigen.cli import main, verilog from ieee754.fpcommon.fpbase import (FPNumBaseRecord, Overflow) @@ -13,28 +13,6 @@ from ieee754.fpcommon.getop import FPPipeContext from ieee754.div_rem_sqrt_rsqrt.div_pipe import DivPipeInputData -# TODO: delete (replace by DivPipeCoreInputData) -class FPDivStage0Data: - - def __init__(self, pspec): - self.z = FPNumBaseRecord(pspec.width, False) - self.out_do_z = Signal(reset_less=True) - self.oz = Signal(pspec.width, reset_less=True) - - self.ctx = FPPipeContext(pspec.width, pspec) # context: muxid, operator etc. - self.muxid = self.ctx.muxid # annoying. complicated. - - # TODO: here is where Q and R would be put, and passed - # down to Stage1 processing. - - mw = (self.z.m_width)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1 - self.product = Signal(mw, reset_less=True) - - def eq(self, i): - return [self.z.eq(i.z), self.out_do_z.eq(i.out_do_z), self.oz.eq(i.oz), - self.product.eq(i.product), self.ctx.eq(i.ctx)] - - class FPDivStage0Mod(Elaboratable): def __init__(self, pspec): @@ -46,8 +24,7 @@ class FPDivStage0Mod(Elaboratable): return FPSCData(self.pspec, False) def ospec(self): - # XXX TODO: replace with DivPipeCoreInputData, here - return FPDivStage0Data(self.pspec) + return DivPipeInputData(self.pspec) def process(self, i): return self.o @@ -67,7 +44,7 @@ class FPDivStage0Mod(Elaboratable): # pipeline chain) - see ospec. # INPUT SPEC: FPSCData - # OUTPUT SPEC: DivPipeCoreInputData + # OUTPUT SPEC: DivPipeInputData # NOTE: this stage does *NOT* do *ACTUAL* DIV processing, # it is PURELY the *ENTRY* point into the chain, performing @@ -75,13 +52,36 @@ class FPDivStage0Mod(Elaboratable): with m.If(~self.i.out_do_z): # do conversion here, of both self.i.a and self.i.b, - # into DivPipeCoreInputData dividend and divisor. + # into DivPipeInputData dividend and divisor. + + if self.pspec.width == 16: + extra = 3 + elif self.pspec.width == 32: + extra = 4 + elif self.pspec.width == 64: + extra = 3 + # the mantissas, having been de-normalised (and containing + # a "1" in the MSB) represent numbers in the range 0.5 to + # 0.9999999-recurring. the min and max range of the + # result is therefore 0.4999999 (0.5/0.99999) and 1.9999998 + # (0.99999/0.5). + + # zero-extend the mantissas (room for sticky/guard) + # plus the extra MSB. See DivPipeBaseStage.get_core_config + am0 = Signal(len(self.i.a.m)+3, reset_less=True) + bm0 = Signal(len(self.i.b.m)+3, reset_less=True) + m.d.comb += [ + am0.eq(Cat(0,0,0,self.i.a.m, 0)), + bm0.eq(Cat(0,0,0,self.i.b.m, 0)), + #am0.eq(0x392), + #bm0.eq(0x1110), + ] m.d.comb += [self.o.z.e.eq(self.i.a.e - self.i.b.e + 1), - self.o.z.s.eq(self.i.a.s ^ self.i.b.s) - self.o.dividend.eq(self.i.a.m), # TODO: check - self.o.divisor_radicand.eq(self.i.b.m), # TODO: check - self.o.operation.eq(Const(0)) # TODO (set from ctx.op) + self.o.z.s.eq(self.i.a.s ^ self.i.b.s), + self.o.dividend[len(self.i.a.m)+extra:].eq(am0), # TODO: check + self.o.divisor_radicand.eq(bm0), # TODO: check + self.o.operation.eq(Const(0)) # TODO check: DIV ] # these are required and must not be touched @@ -93,7 +93,7 @@ class FPDivStage0Mod(Elaboratable): class FPDivStage0(FPState): - """ First stage of div. + """ First stage of div. """ def __init__(self, pspec):