1 """IEEE754 Floating Point Multiplier Pipeline
3 Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
7 from nmigen
import Module
, Signal
, Cat
, Elaboratable
8 from nmigen
.cli
import main
, verilog
10 from ieee754
.fpcommon
.fpbase
import FPNumBaseRecord
11 from ieee754
.fpcommon
.denorm
import FPSCData
12 from ieee754
.fpcommon
.getop
import FPPipeContext
15 class FPMulStage0Data
:
17 def __init__(self
, pspec
):
19 self
.z
= FPNumBaseRecord(width
, False)
20 self
.out_do_z
= Signal(reset_less
=True)
21 self
.oz
= Signal(width
, reset_less
=True)
22 mw
= (self
.z
.m_width
)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1
23 self
.product
= Signal(mw
, reset_less
=True)
24 self
.ctx
= FPPipeContext(pspec
)
25 self
.muxid
= self
.ctx
.muxid
28 return [self
.z
.eq(i
.z
), self
.out_do_z
.eq(i
.out_do_z
), self
.oz
.eq(i
.oz
),
29 self
.product
.eq(i
.product
), self
.ctx
.eq(i
.ctx
)]
32 class FPMulStage0Mod(Elaboratable
):
34 def __init__(self
, pspec
):
40 return FPSCData(self
.pspec
, False)
43 return FPMulStage0Data(self
.pspec
)
48 def setup(self
, m
, i
):
49 """ links module to inputs and outputs
51 m
.submodules
.mul0
= self
52 m
.d
.comb
+= self
.i
.eq(i
)
54 def elaborate(self
, platform
):
57 # store intermediate tests (and zero-extended mantissas)
58 am0
= Signal(len(self
.i
.a
.m
)+1, reset_less
=True)
59 bm0
= Signal(len(self
.i
.b
.m
)+1, reset_less
=True)
61 am0
.eq(Cat(self
.i
.a
.m
, 0)),
62 bm0
.eq(Cat(self
.i
.b
.m
, 0))
64 # same-sign (both negative or both positive) mul mantissas
65 with m
.If(~self
.i
.out_do_z
):
66 m
.d
.comb
+= [self
.o
.z
.e
.eq(self
.i
.a
.e
+ self
.i
.b
.e
+ 1),
67 self
.o
.product
.eq(am0
* bm0
* 4),
68 self
.o
.z
.s
.eq(self
.i
.a
.s ^ self
.i
.b
.s
)
71 m
.d
.comb
+= self
.o
.oz
.eq(self
.i
.oz
)
72 m
.d
.comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
73 m
.d
.comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)