From d02b0b9e8ea94c0d19356e91948d5faa019582d8 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 16 Jun 2019 13:52:05 +0100 Subject: [PATCH] got fpdiv FSM operational --- src/ieee754/fpcommon/fpbase.py | 45 +++++++++++++--------- src/ieee754/fpdiv/nmigen_div_experiment.py | 22 +++++++---- src/ieee754/fpdiv/test/test_div.py | 5 ++- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/ieee754/fpcommon/fpbase.py b/src/ieee754/fpcommon/fpbase.py index 6f14f5b1..307fa5e1 100644 --- a/src/ieee754/fpcommon/fpbase.py +++ b/src/ieee754/fpcommon/fpbase.py @@ -87,27 +87,36 @@ class FPNumBaseRecord: self.e = Signal((e_width, True), reset_less=True) # exp+2 bits, signed self.s = Signal(reset_less=True) # Sign bit - self.mzero = Const(0, (m_width, False)) - m_msb = 1<<(self.m_width-2) - self.msb1 = Const(m_msb, (m_width, False)) - self.m1s = Const(-1, (m_width, False)) - self.P128 = Const(e_max, (e_width, True)) - self.P127 = Const(e_max-1, (e_width, True)) - self.N127 = Const(-(e_max-1), (e_width, True)) - self.N126 = Const(-(e_max-2), (e_width, True)) + self.fp = self + self.drop_in(self) def drop_in(self, fp): fp.s = self.s fp.e = self.e fp.m = self.m fp.v = self.v + fp.rmw = self.rmw fp.width = self.width fp.e_width = self.e_width + fp.e_max = self.e_max fp.m_width = self.m_width fp.e_start = self.e_start fp.e_end = self.e_end fp.m_extra = self.m_extra + m_width = self.m_width + e_max = self.e_max + e_width = self.e_width + + self.mzero = Const(0, (m_width, False)) + m_msb = 1<<(self.m_width-2) + self.msb1 = Const(m_msb, (m_width, False)) + self.m1s = Const(-1, (m_width, False)) + self.P128 = Const(e_max, (e_width, True)) + self.P127 = Const(e_max-1, (e_width, True)) + self.N127 = Const(-(e_max-1), (e_width, True)) + self.N126 = Const(-(e_max-2), (e_width, True)) + def create(self, s, e, m): """ creates a value from sign / exponent / mantissa @@ -115,18 +124,18 @@ class FPNumBaseRecord: """ return [ self.v[-1].eq(s), # sign - self.v[self.e_start:self.e_end].eq(e + self.P127), # exp (add on bias) + self.v[self.e_start:self.e_end].eq(e + self.fp.P127), # (add on bias) self.v[0:self.e_start].eq(m) # mantissa ] def nan(self, s): - return self.create(s, self.P128, 1<<(self.e_start-1)) + return self.create(s, self.fp.P128, 1<<(self.e_start-1)) def inf(self, s): - return self.create(s, self.P128, 0) + return self.create(s, self.fp.P128, 0) def zero(self, s): - return self.create(s, self.N127, 0) + return self.create(s, self.fp.N127, 0) def create2(self, s, e, m): """ creates a value from sign / exponent / mantissa @@ -416,7 +425,7 @@ class FPNumIn(FPNumBase): #print ("decode", self.e_end) res = ObjectProxy(m, pipemode=False) res.m = Cat(*args) # mantissa - res.e = v[self.e_start:self.e_end] - self.P127 # exp + res.e = v[self.e_start:self.e_end] - self.fp.P127 # exp res.s = v[-1] # sign return res @@ -622,7 +631,7 @@ class FPBase: which has to be taken into account when extracting the result. """ with m.If(a.exp_n127): - m.d.sync += a.e.eq(a.N126) # limit a exponent + m.d.sync += a.e.eq(a.fp.N126) # limit a exponent with m.Else(): m.d.sync += a.m[-1].eq(1) # set top mantissa bit @@ -647,7 +656,7 @@ class FPBase: NOTE: the weirdness of reassigning guard and round is due to the extra mantissa bits coming from tot[0..2] """ - with m.If((z.m[-1] == 0) & (z.e > z.N126)): + with m.If((z.m[-1] == 0) & (z.e > z.fp.N126)): m.d.sync += [ z.e.eq(z.e - 1), # DECREASE exponent z.m.eq(z.m << 1), # shift mantissa UP @@ -667,7 +676,7 @@ class FPBase: NOTE: the weirdness of reassigning guard and round is due to the extra mantissa bits coming from tot[0..2] """ - with m.If(z.e < z.N126): + with m.If(z.e < z.fp.N126): m.d.sync +=[ z.e.eq(z.e + 1), # INCREASE exponent z.m.eq(z.m >> 1), # shift mantissa DOWN @@ -684,7 +693,7 @@ class FPBase: """ with m.If(roundz): m.d.sync += z.m.eq(z.m + 1) # mantissa rounds up - with m.If(z.m == z.m1s): # all 1s + with m.If(z.m == z.fp.m1s): # all 1s m.d.sync += z.e.eq(z.e + 1) # exponent rounds up def corrections(self, m, z, next_state): @@ -693,7 +702,7 @@ class FPBase: m.next = next_state # denormalised, correct exponent to zero with m.If(z.is_denormalised): - m.d.sync += z.e.eq(z.N127) + m.d.sync += z.e.eq(z.fp.N127) def pack(self, m, z, next_state): """ packs the result into the output (detects overflow->Inf) diff --git a/src/ieee754/fpdiv/nmigen_div_experiment.py b/src/ieee754/fpdiv/nmigen_div_experiment.py index a244777c..32431e26 100644 --- a/src/ieee754/fpdiv/nmigen_div_experiment.py +++ b/src/ieee754/fpdiv/nmigen_div_experiment.py @@ -2,11 +2,12 @@ # Copyright (C) Jonathan P Dawson 2013 # 2013-12-12 -from nmigen import Module, Signal, Const, Cat +from nmigen import Module, Signal, Const, Cat, Elaboratable from nmigen.cli import main, verilog from ieee754.fpcommon.fpbase import (FPNumIn, FPNumOut, FPOpIn, - FPOpOut, Overflow, FPBase, FPState) + FPOpOut, Overflow, FPBase, FPState, + FPNumBaseRecord) from nmutil.nmoperator import eq @@ -29,7 +30,7 @@ class Div: ] -class FPDIV(FPBase): +class FPDIV(FPBase, Elaboratable): def __init__(self, width): FPBase.__init__(self) @@ -38,6 +39,9 @@ class FPDIV(FPBase): self.in_a = FPOpIn(width) self.in_b = FPOpIn(width) self.out_z = FPOpOut(width) + self.in_a.data_i = Signal(width) + self.in_b.data_i = Signal(width) + self.out_z.data_o = Signal(width) self.states = [] @@ -51,9 +55,12 @@ class FPDIV(FPBase): m = Module() # Latches - a = FPNumIn(None, self.width, False) - b = FPNumIn(None, self.width, False) - z = FPNumOut(self.width, False) + a = FPNumBaseRecord(self.width, False) + b = FPNumBaseRecord(self.width, False) + z = FPNumBaseRecord(self.width, False) + a = FPNumIn(None, a) + b = FPNumIn(None, b) + z = FPNumOut(z) div = Div(a.m_width*2 + 3) # double the mantissa width plus g/r/sticky @@ -61,8 +68,9 @@ class FPDIV(FPBase): m.submodules.in_a = a m.submodules.in_b = b m.submodules.z = z - m.submodules.of = of + #m.submodules.of = of + print ("a.v", a.v, self.in_a.v) m.d.comb += a.v.eq(self.in_a.v) m.d.comb += b.v.eq(self.in_b.v) diff --git a/src/ieee754/fpdiv/test/test_div.py b/src/ieee754/fpdiv/test/test_div.py index 76790109..0670900b 100644 --- a/src/ieee754/fpdiv/test/test_div.py +++ b/src/ieee754/fpdiv/test/test_div.py @@ -6,9 +6,10 @@ from operator import truediv from nmigen import Module, Signal from nmigen.compat.sim import run_simulation -from nmigen_div_experiment import FPDIV +from ieee754.fpdiv.nmigen_div_experiment import FPDIV -from unit_test_single import (get_mantissa, get_exponent, get_sign, is_nan, +from ieee754.fpcommon.test.unit_test_single import (get_mantissa, + get_exponent, get_sign, is_nan, is_inf, is_pos_inf, is_neg_inf, match, get_case, check_case, run_fpunit, run_edge_cases, run_corner_cases) -- 2.30.2