1 from nmutil
.singlepipe
import ControlBase
2 from nmutil
.pipemodbase
import PipeModBaseChain
3 from soc
.fu
.mul
.output_stage
import DivMulOutputStage
4 from soc
.fu
.div
.input_stage
import DivMulInputStage
5 from soc
.fu
.div
.output_stage
import DivOutputStage
6 from soc
.fu
.div
.setup_stage
import DivSetupStage
7 from soc
.fu
.div
.core_stages
import (DivCoreSetupStage
, DivCoreCalculateStage
,
9 from soc
.fu
.div
.pipe_data
import DivPipeKindConfigCombPipe
12 class DivStagesStart(PipeModBaseChain
):
14 alu_input
= DivMulInputStage(self
.pspec
)
15 div_setup
= DivSetupStage(self
.pspec
)
16 if isinstance(self
.pspec
.div_pipe_kind
.config
,
17 DivPipeKindConfigCombPipe
):
18 core_setup
= [DivCoreSetupStage(self
.pspec
)]
21 return [alu_input
, div_setup
, *core_setup
]
24 class DivStagesMiddle(PipeModBaseChain
):
25 def __init__(self
, pspec
, stage_start_index
, stage_end_index
):
26 assert isinstance(pspec
.div_pipe_kind
.config
,
27 DivPipeKindConfigCombPipe
),\
28 "DivStagesMiddle must be used with a DivPipeKindConfigCombPipe"
29 self
.stage_start_index
= stage_start_index
30 self
.stage_end_index
= stage_end_index
31 super().__init
__(pspec
)
35 for index
in range(self
.stage_start_index
, self
.stage_end_index
):
36 stages
.append(DivCoreCalculateStage(self
.pspec
, index
))
40 class DivStagesEnd(PipeModBaseChain
):
42 if isinstance(self
.pspec
.div_pipe_kind
.config
,
43 DivPipeKindConfigCombPipe
):
44 core_final
= [DivCoreFinalStage(self
.pspec
)]
47 div_out
= DivOutputStage(self
.pspec
)
48 self
.div_out
= div_out
# debugging - bug #425
49 return [*core_final
, div_out
]
52 class DivStagesFinalise(PipeModBaseChain
):
54 alu_out
= DivMulOutputStage(self
.pspec
)
58 class DivBasePipe(ControlBase
):
59 def __init__(self
, pspec
, compute_steps_per_stage
=4):
60 ControlBase
.__init
__(self
)
62 self
.pipe_start
= DivStagesStart(pspec
)
63 self
.pipe_middles
= []
64 if isinstance(self
.pspec
.div_pipe_kind
.config
,
65 DivPipeKindConfigCombPipe
):
66 compute_steps
= pspec
.core_config
.n_stages
67 for start
in range(0, compute_steps
, compute_steps_per_stage
):
68 end
= min(start
+ compute_steps_per_stage
, compute_steps
)
69 self
.pipe_middles
.append(DivStagesMiddle(pspec
, start
, end
))
71 self
.pipe_middles
.append(
72 self
.pspec
.div_pipe_kind
.config
.core_stage_class(pspec
))
73 self
.pipe_end
= DivStagesEnd(pspec
)
74 self
.pipe_final
= DivStagesFinalise(pspec
)
75 self
._eqs
= self
.connect([self
.pipe_start
,
80 def elaborate(self
, platform
):
81 m
= ControlBase
.elaborate(self
, platform
)
82 m
.submodules
.pipe_start
= self
.pipe_start
83 for i
in range(len(self
.pipe_middles
)):
84 name
= f
"pipe_middle_{i}"
85 setattr(m
.submodules
, name
, self
.pipe_middles
[i
])
86 m
.submodules
.pipe_end
= self
.pipe_end