argh! work-in-progress breaking / fixing how to do div unit tests
[soc.git] / src / soc / fu / div / sim_only_core.py
1 from nmigen import Signal, Elaboratable, Module
2 from ieee754.div_rem_sqrt_rsqrt.core import DivPipeCoreOperation
3
4
5 class SimOnlyCoreConfig:
6 n_stages = 1
7 bit_width = 64
8 fract_width = 64
9
10
11 class SimOnlyCoreInputData:
12 def __init__(self, core_config, reset_less=True):
13 self.core_config = core_config
14 self.dividend = Signal(128, reset_less=reset_less)
15 self.divisor_radicand = Signal(64, reset_less=reset_less)
16 self.operation = DivPipeCoreOperation.create_signal(
17 reset_less=reset_less)
18
19 def __iter__(self):
20 """ Get member signals. """
21 yield self.dividend
22 yield self.divisor_radicand
23 yield self.operation
24
25 def eq(self, rhs):
26 """ Assign member signals. """
27 return [self.dividend.eq(rhs.dividend),
28 self.divisor_radicand.eq(rhs.divisor_radicand),
29 self.operation.eq(rhs.operation),
30 ]
31
32
33 class SimOnlyCoreInterstageData:
34 def __init__(self, core_config, reset_less=True):
35 self.core_config = core_config
36 self.dividend = Signal(128, reset_less=reset_less)
37 self.divisor = Signal(64, reset_less=reset_less)
38
39 def __iter__(self):
40 """ Get member signals. """
41 yield self.dividend
42 yield self.divisor
43
44 def eq(self, rhs):
45 """ Assign member signals. """
46 return [self.dividend.eq(rhs.dividend),
47 self.divisor.eq(rhs.divisor)]
48
49
50 class SimOnlyCoreOutputData:
51 def __init__(self, core_config, reset_less=True):
52 self.core_config = core_config
53 self.quotient_root = Signal(64, reset_less=reset_less)
54 self.remainder = Signal(3 * 64, reset_less=reset_less)
55
56 def __iter__(self):
57 """ Get member signals. """
58 yield self.quotient_root
59 yield self.remainder
60 return
61
62 def eq(self, rhs):
63 """ Assign member signals. """
64 return [self.quotient_root.eq(rhs.quotient_root),
65 self.remainder.eq(rhs.remainder)]
66
67
68 class SimOnlyCoreSetupStage(Elaboratable):
69 def __init__(self, core_config):
70 self.core_config = core_config
71 self.i = self.ispec()
72 self.o = self.ospec()
73
74 def ispec(self):
75 """ Get the input spec for this pipeline stage."""
76 return SimOnlyCoreInputData(self.core_config)
77
78 def ospec(self):
79 """ Get the output spec for this pipeline stage."""
80 return SimOnlyCoreInterstageData(self.core_config)
81
82 def setup(self, m, i):
83 """ Pipeline stage setup. """
84 m.submodules.sim_only_core_setup = self
85 m.d.comb += self.i.eq(i)
86
87 def process(self, i):
88 """ Pipeline stage process. """
89 return self.o # return processed data (ignore i)
90
91 def elaborate(self, platform):
92 """ Elaborate into ``Module``. """
93 m = Module()
94 comb = m.d.comb
95
96 comb += self.o.divisor.eq(self.i.divisor_radicand)
97 comb += self.o.dividend.eq(self.i.dividend)
98
99 return m
100
101
102 class SimOnlyCoreCalculateStage(Elaboratable):
103 def __init__(self, core_config, stage_index):
104 assert stage_index == 0
105 self.core_config = core_config
106 self.stage_index = stage_index
107 self.i = self.ispec()
108 self.o = self.ospec()
109
110 def ispec(self):
111 """ Get the input spec for this pipeline stage. """
112 return SimOnlyCoreInterstageData(self.core_config)
113
114 def ospec(self):
115 """ Get the output spec for this pipeline stage. """
116 return SimOnlyCoreInterstageData(self.core_config)
117
118 def setup(self, m, i):
119 """ Pipeline stage setup. """
120 setattr(m.submodules,
121 f"sim_only_core_calculate_{self.stage_index}",
122 self)
123 m.d.comb += self.i.eq(i)
124
125 def process(self, i):
126 """ Pipeline stage process. """
127 return self.o
128
129 def elaborate(self, platform):
130 """ Elaborate into ``Module``. """
131 m = Module()
132 m.d.comb += self.o.eq(self.i)
133 return m
134
135
136 class SimOnlyCoreFinalStage(Elaboratable):
137 """ Final Stage of the core of the div/rem/sqrt/rsqrt pipeline. """
138
139 def __init__(self, core_config):
140 """ Create a ``SimOnlyCoreFinalStage`` instance."""
141 self.core_config = core_config
142 self.i = self.ispec()
143 self.o = self.ospec()
144
145 def ispec(self):
146 """ Get the input spec for this pipeline stage."""
147 return SimOnlyCoreInterstageData(self.core_config)
148
149 def ospec(self):
150 """ Get the output spec for this pipeline stage."""
151 return SimOnlyCoreOutputData(self.core_config)
152
153 def setup(self, m, i):
154 """ Pipeline stage setup. """
155 m.submodules.sim_only_core_final = self
156 m.d.comb += self.i.eq(i)
157
158 def process(self, i):
159 """ Pipeline stage process. """
160 return self.o # return processed data (ignore i)
161
162 def elaborate(self, platform):
163 """ Elaborate into ``Module``. """
164 m = Module()
165 remainder_shift = self.core_config.fract_width
166 with m.If(self.i.divisor != 0):
167 quotient = self.i.dividend // self.i.divisor
168 remainder = self.i.dividend % self.i.divisor
169 m.d.comb += self.o.quotient_root.eq(quotient)
170 m.d.comb += self.o.remainder.eq(remainder << remainder_shift)
171 with m.Else():
172 m.d.comb += self.o.quotient_root.eq(-1)
173 m.d.comb += self.o.remainder.eq(self.i.dividend << remainder_shift)
174
175 return m