1 # IEEE Floating Point Multiplier
3 from nmigen
import Module
, Signal
, Cat
, Mux
, Elaboratable
4 from nmigen
.cli
import main
, verilog
7 from nmutil
.singlepipe
import StageChain
9 from ieee754
.fpcommon
.fpbase
import (Overflow
, OverflowMod
,
10 FPNumBase
, FPNumBaseRecord
)
11 from ieee754
.fpcommon
.getop
import FPPipeContext
12 from ieee754
.fpcommon
.msbhigh
import FPMSBHigh
13 from ieee754
.fpcommon
.denorm
import FPSCData
14 from ieee754
.fpcommon
.postcalc
import FPAddStage1Data
17 class FPAlignModSingle(Elaboratable
):
19 def __init__(self
, pspec
, e_extra
=False):
21 self
.e_extra
= e_extra
26 return FPSCData(self
.pspec
, False)
29 return FPSCData(self
.pspec
, False)
31 def setup(self
, m
, i
):
32 """ links module to inputs and outputs
34 m
.submodules
.align
= self
35 m
.d
.comb
+= self
.i
.eq(i
)
40 def elaborate(self
, platform
):
43 self
.o
.a
.m
.name
= "o_a_m"
44 self
.o
.b
.m
.name
= "o_b_m"
46 m
.submodules
.norm1_insel_a
= insel_a
= FPNumBase(self
.i
.a
)
47 m
.submodules
.norm1_insel_b
= insel_b
= FPNumBase(self
.i
.b
)
48 insel_a
.m
.name
= "i_a_m"
49 insel_b
.m
.name
= "i_b_m"
51 mwid
= self
.o
.z
.m_width
52 msb_a
= FPMSBHigh(mwid
, len(insel_a
.e
))
53 msb_b
= FPMSBHigh(mwid
, len(insel_b
.e
))
54 m
.submodules
.norm_pe_a
= msb_a
55 m
.submodules
.norm_pe_b
= msb_b
57 # connect to msb_a/b module
58 m
.d
.comb
+= msb_a
.m_in
.eq(insel_a
.m
)
59 m
.d
.comb
+= msb_a
.e_in
.eq(insel_a
.e
)
60 m
.d
.comb
+= msb_b
.m_in
.eq(insel_b
.m
)
61 m
.d
.comb
+= msb_b
.e_in
.eq(insel_b
.e
)
63 # copy input to output (overridden below)
64 m
.d
.comb
+= self
.o
.a
.eq(insel_a
)
65 m
.d
.comb
+= self
.o
.b
.eq(insel_b
)
67 # normalisation increase/decrease conditions
68 decrease_a
= Signal(reset_less
=True)
69 decrease_b
= Signal(reset_less
=True)
70 m
.d
.comb
+= decrease_a
.eq(insel_a
.m_msbzero
)
71 m
.d
.comb
+= decrease_b
.eq(insel_b
.m_msbzero
)
73 # ok this is near-identical to FPNorm. TODO: modularise
74 with m
.If(~self
.i
.out_do_z
):
75 with m
.If(decrease_a
):
77 self
.o
.a
.e
.eq(msb_a
.e_out
),
78 self
.o
.a
.m
.eq(msb_a
.m_out
),
80 with m
.If(decrease_b
):
82 self
.o
.b
.e
.eq(msb_b
.e_out
),
83 self
.o
.b
.m
.eq(msb_b
.m_out
),
86 m
.d
.comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)
87 m
.d
.comb
+= self
.o
.out_do_z
.eq(self
.i
.out_do_z
)
88 m
.d
.comb
+= self
.o
.oz
.eq(self
.i
.oz
)