1 """IEEE Floating Point Divider Pipeline
3 Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99
7 scnorm - FPDIVSpecialCasesDeNorm ispec FPADDBaseData ospec FPSCData
8 StageChain: FPDIVSpecialCasesMod,
11 pipediv0 - FPDivStages(start=true) ispec FPSCData ospec FPDivStage0Data
12 StageChain: FPDivStage0Mod,
17 pipediv1 - FPDivStages() ispec FPDivStage0Data ospec FPDivStage0Data
18 StageChain: FPDivStage1Mod,
24 pipediv5 - FPDivStages(end=true ispec FPDivStage0Data ospec FPAddStage1Data
25 StageChain: FPDivStage1Mod,
30 normpack - FPNormToPack ispec FPAddStage1Data ospec FPPackData
31 StageChain: Norm1ModSingle,
36 the number of combinatorial StageChains (n_combinatorial_stages) in
37 FPDivStages is an argument arranged to get the length of the whole
38 pipeline down to sane numbers.
41 from nmigen
import Module
42 from nmigen
.cli
import main
, verilog
44 from nmutil
.singlepipe
import ControlBase
45 from nmutil
.concurrentunit
import ReservationStations
, num_bits
47 from ieee754
.fpcommon
.getop
import FPADDBaseData
48 from ieee754
.fpcommon
.denorm
import FPSCData
49 from ieee754
.fpcommon
.pack
import FPPackData
50 from ieee754
.fpcommon
.normtopack
import FPNormToPack
51 from .specialcases
import FPDIVSpecialCasesDeNorm
52 from .divstages
import FPDivStages
56 class FPDIVBasePipe(ControlBase
):
57 def __init__(self
, width
, pspec
):
58 ControlBase
.__init
__(self
)
59 self
.pipestart
= FPDIVSpecialCasesDeNorm(width
, pspec
)
62 n_combinatorial_stages
= 2 # TODO
63 for i
in range(n_stages
):
64 begin
= i
== 0 # needs to convert input from pipestart ospec
65 end
= i
== n_stages
- 1 # needs to convert output to pipeend ispec
66 pipechain
.append(FPDivStages(width
, pspec
,
67 n_combinatorial_stages
,
69 self
.pipechain
= pipechain
70 self
.pipeend
= FPNormToPack(width
, pspec
)
72 self
._eqs
= self
.connect([self
.pipestart
] + pipechain
+ [self
.pipeend
])
74 def elaborate(self
, platform
):
75 m
= ControlBase
.elaborate(self
, platform
)
76 m
.submodules
.scnorm
= self
.pipestart
77 for i
, p
in enumerate(self
.pipechain
):
78 setattr(m
.submodules
, "pipediv%d" % i
, p
)
79 m
.submodules
.normpack
= self
.pipeend
84 class FPDIVMuxInOut(ReservationStations
):
85 """ Reservation-Station version of FPDIV pipeline.
87 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
88 * N-stage divider pipeline
89 * fan-out on outputs (an array of FPPackData: z,mid)
91 Fan-in and Fan-out are combinatorial.
93 def __init__(self
, width
, num_rows
, op_wid
=0):
95 self
.id_wid
= num_bits(width
)
96 self
.pspec
= {'id_wid': self
.id_wid
, 'op_wid': op_wid
}
97 self
.alu
= FPDIVBasePipe(width
, self
.pspec
)
98 ReservationStations
.__init
__(self
, num_rows
)
101 return FPADDBaseData(self
.width
, self
.pspec
)
104 return FPPackData(self
.width
, self
.pspec
)