self.m.eq(Cat(inp.m[0] | inp.m[1], inp.m[2:], 0))
]
- def shift_down_multi(self, diff):
+ def shift_down_multi(self, diff, inp=None):
""" shifts a mantissa down. exponent is increased to compensate
accuracy is lost as a result in the mantissa however there are 3
inverted and used as a mask to get the LSBs of the mantissa.
those are then |'d into the sticky bit.
"""
+ if inp is None:
+ inp = self
sm = MultiShift(self.width)
mw = Const(self.m_width-1, len(diff))
maxslen = Mux(diff > mw, mw, diff)
- rs = sm.rshift(self.m[1:], maxslen)
+ rs = sm.rshift(inp.m[1:], maxslen)
maxsleni = mw - maxslen
m_mask = sm.rshift(self.m1s[1:], maxsleni) # shift and invert
- stickybits = reduce(or_, self.m[1:] & m_mask) | self.m[0]
- return [self.e.eq(self.e + diff),
+ stickybits = reduce(or_, inp.m[1:] & m_mask) | inp.m[0]
+ return [self.e.eq(inp.e + diff),
self.m.eq(Cat(stickybits, rs))
]
m = Module()
- #m.submodules.align_in_a = self.in_a
- #m.submodules.align_in_b = self.in_b
+ m.submodules.align_in_a = self.in_a
+ m.submodules.align_in_b = self.in_b
m.submodules.align_out_a = self.out_a
m.submodules.align_out_b = self.out_b
ediff = Signal((len(self.in_a.e), True), reset_less=True)
ediffr = Signal((len(self.in_a.e), True), reset_less=True)
+
m.d.comb += ediff.eq(self.in_a.e - self.in_b.e)
m.d.comb += ediffr.eq(self.in_b.e - self.in_a.e)
m.d.comb += self.out_a.copy(self.in_a)
m.d.comb += self.out_b.copy(self.in_b)
with m.If(ediff > 0):
- m.d.comb += self.out_b.shift_down_multi(ediff)
+ m.d.comb += self.out_b.shift_down_multi(ediff, self.in_b)
# exponent of b greater than a: shift a down
with m.Elif(ediff < 0):
- m.d.comb += self.out_a.shift_down_multi(ediffr)
+ m.d.comb += self.out_a.shift_down_multi(ediffr, self.in_a)
return m
yield from run_edge_cases(dut, count, add)
if __name__ == '__main__':
- dut = FPADD(width=32, single_cycle=False)
+ dut = FPADD(width=32, single_cycle=True)
run_simulation(dut, testbench(dut), vcd_name="test_add.vcd")