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)
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))
]
b = FPNum(self.width, False)
z = FPNum(self.width, False)
- div = Div(51)
+ div = Div(a.m_width*2 + 3) # double the mantissa width plus g/r/sticky
of = Overflow()
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)
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),
]
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))
--- /dev/null
+from nmigen import Module, Signal
+from nmigen.compat.sim import run_simulation
+
+from nmigen_div_experiment import FPDIV
+
+class ORGate:
+ def __init__(self):
+ self.a = Signal()
+ self.b = Signal()
+ self.x = Signal()
+
+ def get_fragment(self, platform=None):
+
+ m = Module()
+ m.d.comb += self.x.eq(self.a | self.b)
+
+ return m
+
+def check_case(dut, a, b, z):
+ yield dut.in_a.v.eq(a)
+ yield dut.in_a.stb.eq(1)
+ yield
+ yield
+ a_ack = (yield dut.in_a.ack)
+ assert a_ack == 0
+ yield dut.in_b.v.eq(b)
+ yield dut.in_b.stb.eq(1)
+ b_ack = (yield dut.in_b.ack)
+ assert b_ack == 0
+
+ while True:
+ yield
+ out_z_stb = (yield dut.out_z.stb)
+ if not out_z_stb:
+ continue
+ yield dut.in_a.stb.eq(0)
+ yield dut.in_b.stb.eq(0)
+ yield dut.out_z.ack.eq(1)
+ yield
+ yield dut.out_z.ack.eq(0)
+ yield
+ yield
+ break
+
+ out_z = yield dut.out_z.v
+ assert out_z == z, "Output z 0x%x not equal to expected 0x%x" % (out_z, z)
+
+def testbench(dut):
+ yield from check_case(dut, 0x4008000000000000, 0x3FF0000000000000,
+ 0x4008000000000000)
+ yield from check_case(dut, 0x3FF0000000000000, 0x4008000000000000,
+ 0x3FD5555555555555)
+
+ if False:
+ yield from check_case(dut, 0x3F800000, 0x40000000, 0x3F000000)
+ yield from check_case(dut, 0x3F800000, 0x40400000, 0x3EAAAAAB)
+ yield from check_case(dut, 0x40400000, 0x41F80000, 0x3DC6318C)
+ yield from check_case(dut, 0x41F9EB4D, 0x429A4C70, 0x3ECF52B2)
+ yield from check_case(dut, 0x7F7FFFFE, 0x70033181, 0x4EF9C4C8)
+ yield from check_case(dut, 0x7F7FFFFE, 0x70000001, 0x4EFFFFFC)
+ yield from check_case(dut, 0x7F7FFCFF, 0x70200201, 0x4ECCC7D5)
+ yield from check_case(dut, 0x70200201, 0x7F7FFCFF, 0x302003E2)
+
+if __name__ == '__main__':
+ dut = FPDIV(width=64)
+ run_simulation(dut, testbench(dut), vcd_name="test_div64.vcd")
+