1 """IEEE Floating Point Multiplier Pipeline
3 Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=77
7 * scnorm - FPMulSpecialCasesDeNorm
8 * mulstages - FPMulstages
9 * normpack - FPNormToPack
11 scnorm - FPDIVSpecialCasesDeNorm ispec FPADDBaseData
14 StageChain: FPMULSpecialCasesMod,
18 mulstages - FPMulStages ispec FPSCData
19 --------- ospec FPPostCalcData
21 StageChain: FPMulStage0Mod
24 normpack - FPNormToPack ispec FPPostCalcData
25 -------- ospec FPPackData
27 StageChain: Norm1ModSingle,
32 This is the *current* stack. FPMulStage0Mod is where the actual
33 mantissa multiply takes place, which in the case of FP64 is a
34 single (massive) combinatorial block. This can be fixed by using
35 a multi-stage fixed-point multiplier pipeline, which was implemented
36 in #60: http://bugs.libre-riscv.org/show_bug.cgi?id=60
40 from nmigen
import Module
41 from nmigen
.cli
import main
, verilog
43 from nmutil
.singlepipe
import ControlBase
44 from nmutil
.concurrentunit
import ReservationStations
, num_bits
46 from ieee754
.fpcommon
.getop
import FPADDBaseData
47 from ieee754
.fpcommon
.denorm
import FPSCData
48 from ieee754
.fpcommon
.pack
import FPPackData
49 from ieee754
.fpcommon
.normtopack
import FPNormToPack
50 from .specialcases
import FPMulSpecialCasesDeNorm
51 from .mulstages
import FPMulStages
52 from ieee754
.pipeline
import PipelineSpec
55 class FPMULBasePipe(ControlBase
):
56 def __init__(self
, pspec
):
57 ControlBase
.__init
__(self
)
58 self
.pipe1
= FPMulSpecialCasesDeNorm(pspec
)
59 self
.pipe2
= FPMulStages(pspec
)
60 self
.pipe3
= FPNormToPack(pspec
)
62 self
._eqs
= self
.connect([self
.pipe1
, self
.pipe2
, self
.pipe3
])
64 def elaborate(self
, platform
):
65 m
= ControlBase
.elaborate(self
, platform
)
66 m
.submodules
.scnorm
= self
.pipe1
67 m
.submodules
.mulstages
= self
.pipe2
68 m
.submodules
.normpack
= self
.pipe3
73 class FPMULMuxInOut(ReservationStations
):
74 """ Reservation-Station version of FPMUL pipeline.
76 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
77 * 2-stage multiplier pipeline
78 * fan-out on outputs (an array of FPPackData: z,mid)
80 Fan-in and Fan-out are combinatorial.
83 def __init__(self
, width
, num_rows
, op_wid
=0):
84 self
.id_wid
= num_bits(num_rows
)
86 self
.pspec
= PipelineSpec(width
, self
.id_wid
, self
.op_wid
)
87 self
.alu
= FPMULBasePipe(self
.pspec
)
88 ReservationStations
.__init
__(self
, num_rows
)
91 return FPADDBaseData(self
.pspec
)
94 return FPPackData(self
.pspec
)