82b881ca8bc03209674e537343ea23dc1fe50b98
[ieee754fpu.git] / src / ieee754 / fpmul / pipeline.py
1 """IEEE754 Floating Point Multiplier Pipeline
2
3 Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
4 Copyright (C) 2019 Jake Lifshay
5
6 Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=77
7
8 Stack looks like this:
9
10 * scnorm - FPMulSpecialCasesDeNorm
11 * mulstages - FPMulstages
12 * normpack - FPNormToPack
13
14 scnorm - FPDIVSpecialCasesDeNorm ispec FPBaseData
15 ------ ospec FPSCData
16
17 StageChain: FPMULSpecialCasesMod,
18 FPAddDeNormMod
19 FPAlignModSingle
20
21 mulstages - FPMulStages ispec FPSCData
22 --------- ospec FPPostCalcData
23
24 StageChain: FPMulStage0Mod
25 FPMulStage1Mod
26
27 normpack - FPNormToPack ispec FPPostCalcData
28 -------- ospec FPPackData
29
30 StageChain: Norm1ModSingle,
31 RoundMod,
32 CorrectionsMod,
33 PackMod
34
35 This is the *current* stack. FPMulStage0Mod is where the actual
36 mantissa multiply takes place, which in the case of FP64 is a
37 single (massive) combinatorial block. This can be fixed by using
38 a multi-stage fixed-point multiplier pipeline, which was implemented
39 in #60: http://bugs.libre-riscv.org/show_bug.cgi?id=60
40
41 """
42
43 from nmigen import Module
44 from nmigen.cli import main, verilog
45
46 from nmutil.singlepipe import ControlBase
47 from nmutil.concurrentunit import ReservationStations, num_bits
48
49 from ieee754.fpcommon.basedata import FPBaseData
50 from ieee754.fpcommon.denorm import FPSCData
51 from ieee754.fpcommon.pack import FPPackData
52 from ieee754.fpcommon.normtopack import FPNormToPack
53 from .specialcases import FPMulSpecialCasesDeNorm
54 from .mulstages import FPMulStages
55 from ieee754.pipeline import PipelineSpec
56
57
58 class FPMULBasePipe(ControlBase):
59 def __init__(self, pspec):
60 ControlBase.__init__(self)
61 self.pipe1 = FPMulSpecialCasesDeNorm(pspec)
62 self.pipe2 = FPMulStages(pspec)
63 self.pipe3 = FPNormToPack(pspec)
64
65 self._eqs = self.connect([self.pipe1, self.pipe2, self.pipe3])
66
67 def elaborate(self, platform):
68 m = ControlBase.elaborate(self, platform)
69 m.submodules.scnorm = self.pipe1
70 m.submodules.mulstages = self.pipe2
71 m.submodules.normpack = self.pipe3
72 m.d.comb += self._eqs
73 return m
74
75
76 class FPMULMuxInOut(ReservationStations):
77 """ Reservation-Station version of FPMUL pipeline.
78
79 * fan-in on inputs (an array of FPBaseData: a,b,mid)
80 * 2-stage multiplier pipeline
81 * fan-out on outputs (an array of FPPackData: z,mid)
82
83 Fan-in and Fan-out are combinatorial.
84 """
85
86 def __init__(self, width, num_rows, op_wid=0):
87 self.id_wid = num_bits(num_rows)
88 self.op_wid = op_wid
89 self.pspec = PipelineSpec(width, self.id_wid, self.op_wid)
90 self.alu = FPMULBasePipe(self.pspec)
91 ReservationStations.__init__(self, num_rows)