rename FPAddStage1Data to FPPostCalcData
[ieee754fpu.git] / src / ieee754 / fpmul / pipeline.py
1 """IEEE Floating Point Multiplier Pipeline
2
3 Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=77
4
5 Stack looks like this:
6
7 * scnorm - FPMulSpecialCasesDeNorm
8 * mulstages - FPMulstages
9 * normpack - FPNormToPack
10
11 scnorm - FPDIVSpecialCasesDeNorm ispec FPADDBaseData
12 ------ ospec FPSCData
13
14 StageChain: FPMULSpecialCasesMod,
15 FPAddDeNormMod
16 FPAlignModSingle
17
18 mulstages - FPMulStages ispec FPSCData
19 --------- ospec FPPostCalcData
20
21 StageChain: FPMulStage0Mod
22 FPMulStage1Mod
23
24 normpack - FPNormToPack ispec FPPostCalcData
25 -------- ospec FPPackData
26
27 StageChain: Norm1ModSingle,
28 RoundMod,
29 CorrectionsMod,
30 PackMod
31
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
37
38 """
39
40 from nmigen import Module
41 from nmigen.cli import main, verilog
42
43 from nmutil.singlepipe import ControlBase
44 from nmutil.concurrentunit import ReservationStations, num_bits
45
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
53
54
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)
61
62 self._eqs = self.connect([self.pipe1, self.pipe2, self.pipe3])
63
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
69 m.d.comb += self._eqs
70 return m
71
72
73 class FPMULMuxInOut(ReservationStations):
74 """ Reservation-Station version of FPMUL pipeline.
75
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)
79
80 Fan-in and Fan-out are combinatorial.
81 """
82
83 def __init__(self, width, num_rows, op_wid=0):
84 self.id_wid = num_bits(num_rows)
85 self.op_wid = op_wid
86 self.pspec = PipelineSpec(width, self.id_wid, self.op_wid)
87 self.alu = FPMULBasePipe(self.pspec)
88 ReservationStations.__init__(self, num_rows)
89
90 def i_specfn(self):
91 return FPADDBaseData(self.pspec)
92
93 def o_specfn(self):
94 return FPPackData(self.pspec)