X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fadd%2Fnmigen_div_experiment.py;h=a7e215cb888817b750426af676a7825552dee431;hb=6bff1a997f3846872cf489c24b5c01426c4dc97c;hp=918713a0bbd94d9d49a1bdd3db412df618b6ee12;hpb=258b33ecb3853122ea29ec4c66936f19f5943138;p=ieee754fpu.git diff --git a/src/add/nmigen_div_experiment.py b/src/add/nmigen_div_experiment.py index 918713a0..a7e215cb 100644 --- a/src/add/nmigen_div_experiment.py +++ b/src/add/nmigen_div_experiment.py @@ -5,7 +5,8 @@ from nmigen import Module, Signal, Const, Cat from nmigen.cli import main, verilog -from fpbase import FPNum, FPOp, Overflow, FPBase +from fpbase import FPNumIn, FPNumOut, FPOpIn, FPOpOut, Overflow, FPBase, FPState +from singlepipe import eq class Div: def __init__(self, width): @@ -14,7 +15,7 @@ class Div: self.dor = Signal(width) # divisor self.dend = Signal(width) # dividend self.rem = Signal(width) # remainder - self.count = Signal(6) # loop count + self.count = Signal(7) # loop count self.czero = Const(0, width) @@ -22,7 +23,7 @@ class Div: m.d.sync += [ self.quot.eq(self.czero), self.rem.eq(self.czero), - self.count.eq(Const(0, 6)) + self.count.eq(Const(0, 7)) ] @@ -32,23 +33,36 @@ class FPDIV(FPBase): FPBase.__init__(self) self.width = width - self.in_a = FPOp(width) - self.in_b = FPOp(width) - self.out_z = FPOp(width) + self.in_a = FPOpIn(width) + self.in_b = FPOpIn(width) + self.out_z = FPOpOut(width) - def get_fragment(self, platform=None): + self.states = [] + + def add_state(self, state): + self.states.append(state) + return state + + def elaborate(self, platform=None): """ creates the HDL code-fragment for FPDiv """ m = Module() # Latches - a = FPNum(self.width, False) - b = FPNum(self.width, False) - z = FPNum(self.width, False) + a = FPNumIn(None, self.width, False) + b = FPNumIn(None, self.width, False) + z = FPNumOut(self.width, False) - div = Div(51) + div = Div(a.m_width*2 + 3) # double the mantissa width plus g/r/sticky of = Overflow() + m.submodules.in_a = a + m.submodules.in_b = b + m.submodules.z = z + m.submodules.of = of + + m.d.comb += a.v.eq(self.in_a.v) + m.d.comb += b.v.eq(self.in_b.v) with m.FSM() as fsm: @@ -56,13 +70,15 @@ class FPDIV(FPBase): # gets operand a with m.State("get_a"): - self.get_op(m, self.in_a, a, "get_b") + res = self.get_op(m, self.in_a, a, "get_b") + m.d.sync += eq([a, self.in_a.ready_o], res) # ****** # gets operand b with m.State("get_b"): - self.get_op(m, self.in_b, b, "special_cases") + res = self.get_op(m, self.in_b, b, "special_cases") + m.d.sync += eq([b, self.in_b.ready_o], res) # ****** # special cases: NaNs, infs, zeros, denormalised @@ -72,42 +88,38 @@ class FPDIV(FPBase): with m.State("special_cases"): # if a is NaN or b is NaN return NaN - with m.If(a.is_nan() | b.is_nan()): + with m.If(a.is_nan | b.is_nan): m.next = "put_z" m.d.sync += z.nan(1) # if a is Inf and b is Inf return NaN - with m.Elif(a.is_inf() | b.is_inf()): + with m.Elif(a.is_inf & b.is_inf): m.next = "put_z" m.d.sync += z.nan(1) # if a is inf return inf (or NaN if b is zero) - with m.Elif(a.is_inf()): + with m.Elif(a.is_inf): m.next = "put_z" - # if b is zero return NaN - with m.If(b.is_zero()): - m.d.sync += z.nan(1) - with m.Else(): - m.d.sync += z.inf(a.s ^ b.s) + m.d.sync += z.inf(a.s ^ b.s) # if b is inf return zero - with m.Elif(b.is_inf()): + with m.Elif(b.is_inf): m.next = "put_z" m.d.sync += z.zero(a.s ^ b.s) - # if a is inf return zero (or NaN if b is zero) - with m.Elif(a.is_inf()): + # if a is zero return zero (or NaN if b is zero) + with m.Elif(a.is_zero): m.next = "put_z" # if b is zero return NaN - with m.If(b.is_zero()): + with m.If(b.is_zero): m.d.sync += z.nan(1) with m.Else(): - m.d.sync += z.inf(a.s ^ b.s) + m.d.sync += z.zero(a.s ^ b.s) # if b is zero return Inf - with m.Elif(b.is_zero()): + with m.Elif(b.is_zero): m.next = "put_z" - m.d.sync += z.zero(a.s ^ b.s) + m.d.sync += z.inf(a.s ^ b.s) # Denormalised Number checks with m.Else(): @@ -135,7 +147,7 @@ class FPDIV(FPBase): m.d.sync += [ z.s.eq(a.s ^ b.s), # sign z.e.eq(a.e - b.e), # exponent - div.dend.eq(a.m<<27), + div.dend.eq(a.m<<(a.m_width+3)), # 3 bits for g/r/sticky div.dor.eq(b.m), ] div.reset(m) @@ -147,7 +159,7 @@ class FPDIV(FPBase): m.next = "divide_2" m.d.sync += [ div.quot.eq(div.quot << 1), - div.rem.eq(Cat(div.dend[50], div.rem[0:])), + div.rem.eq(Cat(div.dend[-1], div.rem[0:])), div.dend.eq(div.dend << 1), ] @@ -176,7 +188,7 @@ class FPDIV(FPBase): with m.State("divide_3"): m.next = "normalise_1" m.d.sync += [ - z.m.eq(div.quot[3:27]), + z.m.eq(div.quot[3:]), of.guard.eq(div.quot[2]), of.round_bit.eq(div.quot[1]), of.sticky.eq(div.quot[0] | (div.rem != 0)) @@ -198,7 +210,8 @@ class FPDIV(FPBase): # rounding stage with m.State("round"): - self.roundz(m, z, of, "corrections") + self.roundz(m, z, of.roundz) + m.next = "corrections" # ****** # correction stage