move add to ieee754 directory
[ieee754fpu.git] / src / ieee754 / add / pipeline_example.py
1 """ Example 5: Making use of PyRTL and Introspection. """
2
3 from nmigen import Module, Signal, Const
4 from nmigen.cli import main, verilog, rtlil
5
6
7 from pipeline import SimplePipeline, ObjectProxy, PipeManager
8
9
10 class SimplePipelineExample(SimplePipeline):
11 """ A very simple pipeline to show how registers are inferred. """
12
13 def __init__(self, pipe):
14 SimplePipeline.__init__(self, pipe)
15 self._loopback = Signal(4)
16 self._setup()
17
18 def stage0(self):
19 self.n = ~self._loopback
20
21 def stage1(self):
22 self.n = self.n + 2
23
24 def stage2(self):
25 localv = Signal(4)
26 self._pipe.comb += localv.eq(2)
27 self.n = self.n << localv
28
29 def stage3(self):
30 self.n = ~self.n
31
32 def stage4(self):
33 self._pipe.sync += self._loopback.eq(self.n + 3)
34
35
36 class ObjectBasedPipelineExample(SimplePipeline):
37 """ A very simple pipeline to show how registers are inferred. """
38
39 def __init__(self, m):
40 SimplePipeline.__init__(self, m)
41 self._loopback = Signal(4)
42 o = ObjectProxy(m)
43 o.a = Signal(4)
44 o.b = Signal(4)
45 self._obj = o
46 self._setup()
47
48 def stage0(self):
49 self.n = ~self._loopback
50 self.o = self._obj
51
52 def stage1(self):
53 self.n = self.n + self.o.a
54 o = ObjectProxy(self._m)
55 o.c = self.n
56 o.d = self.o.b + self.n + Const(5)
57 self.o = o
58
59 def stage2(self):
60 localv = Signal(4)
61 self._m.d.comb += localv.eq(2)
62 self.n = self.n << localv
63 o = ObjectProxy(self._m)
64 o.e = self.n + self.o.c + self.o.d
65 self.o = o
66
67 def stage3(self):
68 self.n = ~self.n
69 self.o = self.o
70 self.o.e = self.o.e + self.n
71
72 def stage4(self):
73 self._m.d.sync += self._loopback.eq(self.n + 3 + self.o.e)
74
75
76 class PipeModule:
77
78 def __init__(self):
79 self.m = Module()
80 self.p = ObjectBasedPipelineExample(self.m)
81
82 def elaborate(self, platform=None):
83 return self.m
84
85
86 class PipelineStageExample:
87
88 def __init__(self):
89 self._loopback = Signal(4, name="loopback")
90
91 def elaborate(self, platform=None):
92
93 m = Module()
94
95 with PipeManager(m, pipemode=True) as pipe:
96
97 ispec={'loopback': self._loopback}
98 with pipe.Stage("first", ispec=ispec) as (p, m):
99 p.n = ~p.loopback
100 with pipe.Stage("second", p) as (p, m):
101 #p.n = ~self._loopback + 2
102 p.n = p.n + Const(2)
103 with pipe.Stage("third", p) as (p, m):
104 #p.n = ~self._loopback + 5
105 localv = Signal(4)
106 m.d.comb += localv.eq(2)
107 p.n = p.n << localv + Const(1)
108 #p.m = p.n + 2
109
110 print (pipe.stages)
111
112 return m
113
114 class PipelineStageObjectExample:
115
116 def __init__(self):
117 self.loopback = Signal(4)
118
119 def elaborate(self, platform=None):
120
121 m = Module()
122
123 o = ObjectProxy(None, pipemode=False)
124 o.a = Signal(4)
125 o.b = Signal(4)
126 self.obj = o
127
128 localv2 = Signal(4)
129 m.d.sync += localv2.eq(localv2 + 3)
130
131 #m.d.comb += self.obj.a.eq(localv2 + 1)
132 #m.d.sync += self._loopback.eq(localv2)
133
134 ispec= {'loopback': self.loopback, 'obj': self.obj}
135 with PipeManager(m, pipemode=True) as pipe:
136
137 with pipe.Stage("first", ispec=ispec) as (p, m):
138 p.n = ~p.loopback
139 p.o = p.obj
140 with pipe.Stage("second", p) as (p, m):
141 #p.n = ~self.loopback + 2
142 localn = Signal(4)
143 m.d.comb += localn.eq(p.n)
144 o = ObjectProxy(None, pipemode=False)
145 o.c = localn
146 o.d = p.o.b + localn + Const(5)
147 p.n = localn
148 p.o = o
149 with pipe.Stage("third", p) as (p, m):
150 #p.n = ~self._loopback + 5
151 localv = Signal(4)
152 m.d.comb += localv.eq(2)
153 p.n = p.n << localv
154 o = ObjectProxy(None, pipemode=False)
155 o.e = p.n + p.o.c + p.o.d
156 p.o = o
157
158 print ("stages", pipe.stages)
159
160 return m
161
162
163 class PipelineStageObjectExample2:
164
165 def __init__(self):
166 self._loopback = Signal(4)
167
168 def elaborate(self, platform=None):
169
170 m = Module()
171
172 ispec= [self._loopback]
173 with PipeManager(m, pipemode=True) as pipe:
174
175 with pipe.Stage("first",
176 ispec=ispec) as (p, m):
177 p.n = ~self._loopback
178 o = ObjectProxy(None, pipemode=False)
179 o.b = ~self._loopback + Const(5)
180 p.o = o
181
182 print ("stages", pipe.stages)
183
184 return m
185
186
187
188 if __name__ == "__main__":
189 example = PipeModule()
190 with open("pipe_module.il", "w") as f:
191 f.write(rtlil.convert(example, ports=[
192 example.p._loopback,
193 ]))
194 example = PipelineStageExample()
195 with open("pipe_stage_module.il", "w") as f:
196 f.write(rtlil.convert(example, ports=[
197 example._loopback,
198 ]))
199 #exit(0)
200 example = PipelineStageObjectExample()
201 with open("pipe_stage_object_module.il", "w") as f:
202 f.write(rtlil.convert(example, ports=[
203 example.loopback,
204 ]))