div pipe completed except for tests
[soc.git] / src / soc / fu / div / pipeline.py
1 from nmutil.singlepipe import ControlBase
2 from nmutil.pipemodbase import PipeModBaseChain
3 from soc.fu.alu.input_stage import ALUInputStage
4 from soc.fu.alu.output_stage import ALUOutputStage
5 from soc.fu.div.setup_stage import DivSetupStage
6 from soc.fu.div.core_stages import DivCoreSetupStage, DivCoreCalculateStage, DivCoreFinalStage
7 from soc.fu.div.output_stage import DivOutputStage
8
9
10 class DivStagesStart(PipeModBaseChain):
11 def get_chain(self):
12 alu_input = ALUInputStage(self.pspec)
13 div_setup = DivSetupStage(self.pspec)
14 core_setup = DivCoreSetupStage(self.pspec)
15 return [alu_input, div_setup, core_setup]
16
17
18 class DivStagesMiddle(PipeModBaseChain):
19 def __init__(self, pspec, stage_start_index, stage_end_index):
20 self.stage_start_index = stage_start_index
21 self.stage_end_index = stage_end_index
22 super().__init__(pspec)
23
24 def get_chain(self):
25 stages = []
26 for index in range(self.stage_start_index, self.stage_end_index):
27 stages.append(DivCoreCalculateStage(self.pspec, index))
28 return stages
29
30
31 class DivStagesEnd(PipeModBaseChain):
32 def get_chain(self):
33 core_final = DivCoreFinalStage(self.pspec)
34 div_out = DivOutputStage(self.pspec)
35 alu_out = ALUOutputStage(self.pspec)
36 return [core_final, div_out, alu_out]
37
38
39 class DivPipe(ControlBase):
40 def __init__(self, pspec, compute_steps_per_stage=2):
41 ControlBase.__init__(self)
42 self.pipe_start = DivStagesStart(pspec)
43 compute_steps = pspec.core_config.n_stages
44 self.pipe_middles = []
45 for start in range(0, compute_steps, compute_steps_per_stage):
46 end = min(start + compute_steps_per_stage, compute_steps)
47 self.pipe_middles.append(DivStagesMiddle(pspec, start, end))
48 self.pipe_end = DivStagesEnd(pspec)
49 self._eqs = self.connect([self.pipe_start,
50 *self.pipe_middles,
51 self.pipe_end])
52
53 def elaborate(self, platform):
54 m = ControlBase.elaborate(self, platform)
55 m.submodules.pipe_start = self.pipe_start
56 for i in self.pipe_middles:
57 name = f"pipe_{i.stage_start_index}_to_{i.stage_end_index}"
58 setattr(m.submodules, name, i)
59 m.submodules.pipe_end = self.pipe_end
60 m.d.comb += self._eqs
61 return m