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 nmutil
.pipemodbase
import FPModBase
11 from ieee754
.fpcommon
.fpbase
import FPNumBaseRecord
12 from ieee754
.fpcommon
.denorm
import FPSCData
13 from ieee754
.fpcommon
.getop
import FPPipeContext
16 class FPMulStage0Data
:
18 def __init__(self
, pspec
):
20 self
.z
= FPNumBaseRecord(width
, False)
21 self
.out_do_z
= Signal(reset_less
=True)
22 self
.oz
= Signal(width
, reset_less
=True)
23 mw
= (self
.z
.m_width
)*2 - 1 + 3 # sticky/round/guard bits + (2*mant) - 1
24 self
.product
= Signal(mw
, reset_less
=True)
25 self
.ctx
= FPPipeContext(pspec
)
26 self
.muxid
= self
.ctx
.muxid
29 return [self
.z
.eq(i
.z
), self
.out_do_z
.eq(i
.out_do_z
), self
.oz
.eq(i
.oz
),
30 self
.product
.eq(i
.product
), self
.ctx
.eq(i
.ctx
)]
33 class FPMulStage0Mod(FPModBase
):
35 def __init__(self
, pspec
):
36 super().__init
__(pspec
, "mul0")
39 return FPSCData(self
.pspec
, False)
42 return FPMulStage0Data(self
.pspec
)
44 def elaborate(self
, platform
):
48 # store intermediate tests (and zero-extended mantissas)
49 am0
= Signal(len(self
.i
.a
.m
)+1, reset_less
=True)
50 bm0
= Signal(len(self
.i
.b
.m
)+1, reset_less
=True)
52 am0
.eq(Cat(self
.i
.a
.m
, 0)),
53 bm0
.eq(Cat(self
.i
.b
.m
, 0))
55 # same-sign (both negative or both positive) mul mantissas
56 with m
.If(~self
.i
.out_do_z
):
57 comb
+= [self
.o
.z
.e
.eq(self
.i
.a
.e
+ self
.i
.b
.e
+ 1),
58 self
.o
.product
.eq(am0
* bm0
* 4),
59 self
.o
.z
.s
.eq(self
.i
.a
.s ^ self
.i
.b
.s
)
62 comb
+= self
.o
.oz
.eq(self
.i
.oz
)
63 comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
64 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)