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
)
18 class DivStagesSetup(PipeModBaseChain
):
20 div_setup
= DivSetupStage(self
.pspec
)
21 if isinstance(self
.pspec
.div_pipe_kind
.config
,
22 DivPipeKindConfigCombPipe
):
23 core_setup
= [DivCoreSetupStage(self
.pspec
)]
26 return [div_setup
, *core_setup
]
29 class DivStagesMiddle(PipeModBaseChain
):
30 def __init__(self
, pspec
, stage_start_index
, stage_end_index
):
31 assert isinstance(pspec
.div_pipe_kind
.config
,
32 DivPipeKindConfigCombPipe
),\
33 "DivStagesMiddle must be used with a DivPipeKindConfigCombPipe"
34 self
.stage_start_index
= stage_start_index
35 self
.stage_end_index
= stage_end_index
36 super().__init
__(pspec
)
40 for index
in range(self
.stage_start_index
, self
.stage_end_index
):
41 stages
.append(DivCoreCalculateStage(self
.pspec
, index
))
45 class DivStagesEnd(PipeModBaseChain
):
47 if isinstance(self
.pspec
.div_pipe_kind
.config
,
48 DivPipeKindConfigCombPipe
):
49 core_final
= [DivCoreFinalStage(self
.pspec
)]
52 div_out
= DivOutputStage(self
.pspec
)
53 self
.div_out
= div_out
# debugging - bug #425
54 return [*core_final
, div_out
]
57 class DivStagesFinalise(PipeModBaseChain
):
59 alu_out
= DivMulOutputStage(self
.pspec
)
63 class DivBasePipe(ControlBase
):
64 def __init__(self
, pspec
, compute_steps_per_stage
=4):
65 ControlBase
.__init
__(self
)
67 self
.pipe_start
= DivStagesStart(pspec
)
68 self
.pipe_setup
= DivStagesSetup(pspec
)
69 self
.pipe_middles
= []
70 if isinstance(self
.pspec
.div_pipe_kind
.config
,
71 DivPipeKindConfigCombPipe
):
72 compute_steps
= pspec
.core_config
.n_stages
73 for start
in range(0, compute_steps
, compute_steps_per_stage
):
74 end
= min(start
+ compute_steps_per_stage
, compute_steps
)
75 self
.pipe_middles
.append(DivStagesMiddle(pspec
, start
, end
))
77 self
.pipe_middles
.append(
78 self
.pspec
.div_pipe_kind
.config
.core_stage_class(pspec
))
79 self
.pipe_end
= DivStagesEnd(pspec
)
80 self
.pipe_final
= DivStagesFinalise(pspec
)
81 self
._eqs
= self
.connect([self
.pipe_start
,
87 def elaborate(self
, platform
):
88 m
= ControlBase
.elaborate(self
, platform
)
89 m
.submodules
.pipe_start
= self
.pipe_start
90 m
.submodules
.pipe_setup
= self
.pipe_setup
91 for i
in range(len(self
.pipe_middles
)):
92 name
= f
"pipe_middle_{i}"
93 setattr(m
.submodules
, name
, self
.pipe_middles
[i
])
94 m
.submodules
.pipe_end
= self
.pipe_end
95 m
.submodules
.pipe_final
= self
.pipe_final