From f9f55e1c0f3593bc23d91ba8bf7ef0489da2cfd6 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 25 Aug 2019 11:45:36 +0100 Subject: [PATCH] rework add1 to not use out_do_z and use Mux instead of m.If/Else --- src/ieee754/fpadd/add1.py | 51 ++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/ieee754/fpadd/add1.py b/src/ieee754/fpadd/add1.py index e8fd5e99..c57534c0 100644 --- a/src/ieee754/fpadd/add1.py +++ b/src/ieee754/fpadd/add1.py @@ -4,7 +4,7 @@ Copyright (C) 2019 Luke Kenneth Casson Leighton """ -from nmigen import Module, Signal +from nmigen import Module, Signal, Mux, Cat from nmigen.cli import main, verilog from math import log @@ -16,6 +16,12 @@ from ieee754.fpadd.add0 import FPAddStage0Data class FPAddStage1Mod(PipeModBase): """ Second stage of add: preparation for normalisation. detects when tot sum is too big (tot[27] is kinda a carry bit) + + if sum is too big (MSB is set), the mantissa needs shifting + down and the exponent increased by 1. + + we also need to extract the overflow info: sticky "accumulates" + the bottom 2 LSBs if the shift occurs. """ def __init__(self, pspec): @@ -30,28 +36,29 @@ class FPAddStage1Mod(PipeModBase): def elaborate(self, platform): m = Module() comb = m.d.comb + z = self.i.z + tot = self.i.tot + + # intermediaries + msb = Signal(reset_less=True) + to = Signal.like(self.i.tot, reset_less=True) + + comb += self.o.z.s.eq(z.s) # copy sign + comb += msb.eq(self.i.tot[-1]) # get mantissa MSB + + # mantissa shifted down, exponent increased - if MSB set + comb += self.o.z.e.eq(Mux(msb, z.e + 1, z.e)) + comb += to.eq(Mux(msb, Cat(tot, 0), Cat(0, tot))) - comb += self.o.z.eq(self.i.z) - # tot[-1] (MSB) gets set when the sum overflows. shift result down - with m.If(~self.i.out_do_z): - with m.If(self.i.tot[-1]): - comb += [ - self.o.z.m.eq(self.i.tot[4:]), - self.o.of.m0.eq(self.i.tot[4]), - self.o.of.guard.eq(self.i.tot[3]), - self.o.of.round_bit.eq(self.i.tot[2]), - self.o.of.sticky.eq(self.i.tot[1] | self.i.tot[0]), - self.o.z.e.eq(self.i.z.e + 1) - ] - # tot[-1] (MSB) zero case - with m.Else(): - comb += [ - self.o.z.m.eq(self.i.tot[3:]), - self.o.of.m0.eq(self.i.tot[3]), - self.o.of.guard.eq(self.i.tot[2]), - self.o.of.round_bit.eq(self.i.tot[1]), - self.o.of.sticky.eq(self.i.tot[0]) - ] + # this works by adding an extra zero LSB if the MSB is *not* set + comb += [ + self.o.z.m.eq(to[4:]), + self.o.of.m0.eq(to[4]), + self.o.of.guard.eq(to[3]), + self.o.of.round_bit.eq(to[2]), + # sticky sourced from LSB and shifted if MSB hi, else unshifted + self.o.of.sticky.eq(Mux(msb, to[1] | tot[0], to[1])) + ] comb += self.o.out_do_z.eq(self.i.out_do_z) comb += self.o.oz.eq(self.i.oz) -- 2.30.2