switch to exact version of cython
[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 Jacob Lifshay <programmerjake@gmail.com>
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 nmutil.singlepipe import ControlBase
44 from nmutil.concurrentunit import ReservationStations, num_bits
45
46 from ieee754.fpcommon.normtopack import FPNormToPack
47 from ieee754.fpmul.specialcases import FPMulSpecialCasesDeNorm
48 from ieee754.fpmul.mulstages import FPMulStages
49 from ieee754.pipeline import PipelineSpec
50
51
52 class FPMULBasePipe(ControlBase):
53 def __init__(self, pspec):
54 ControlBase.__init__(self)
55 self.pipe1 = FPMulSpecialCasesDeNorm(pspec)
56 self.pipe2 = FPMulStages(pspec)
57 self.pipe3 = FPNormToPack(pspec)
58
59 self._eqs = self.connect([self.pipe1, self.pipe2, self.pipe3])
60
61 def elaborate(self, platform):
62 m = ControlBase.elaborate(self, platform)
63 m.submodules.scnorm = self.pipe1
64 m.submodules.mulstages = self.pipe2
65 m.submodules.normpack = self.pipe3
66 m.d.comb += self._eqs
67 return m
68
69
70 class FPMULMuxInOut(ReservationStations):
71 """ Reservation-Station version of FPMUL pipeline.
72
73 * fan-in on inputs (an array of FPBaseData: a,b,mid)
74 * 2-stage multiplier pipeline
75 * fan-out on outputs (an array of FPPackData: z,mid)
76
77 Fan-in and Fan-out are combinatorial.
78 """
79
80 def __init__(self, width, num_rows, op_wid=0):
81 self.id_wid = num_bits(num_rows)
82 self.op_wid = op_wid
83 self.pspec = PipelineSpec(width, self.id_wid, self.op_wid, n_ops=3)
84 self.alu = FPMULBasePipe(self.pspec)
85 ReservationStations.__init__(self, num_rows)