add pipeline context / stage management
[ieee754fpu.git] / src / add / pipeline_example.py
1 """ Example 5: Making use of PyRTL and Introspection. """
2
3 from nmigen import Module, Signal
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, pipe):
40 SimplePipeline.__init__(self, pipe)
41 self._loopback = Signal(4)
42 o = ObjectProxy(pipe)
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._pipe)
55 o.a = self.n
56 o.b = self.o.b
57 self.o = o
58
59 def stage2(self):
60 localv = Signal(4)
61 self._pipe.comb += localv.eq(2)
62 self.n = self.n << localv
63 o = ObjectProxy(self._pipe)
64 o.b = self.n + self.o.a + self.o.b
65 self.o = o
66
67 def stage3(self):
68 self.n = ~self.n
69 self.o = self.o
70 self.o.b = self.o.b + self.n
71
72 def stage4(self):
73 self._pipe.sync += self._loopback.eq(self.n + 3 + self.o.b)
74
75
76 class PipeModule:
77
78 def __init__(self):
79 self.m = Module()
80 self.p = ObjectBasedPipelineExample(self.m.d)
81
82 def get_fragment(self, platform=None):
83 return self.m
84
85
86 class PipelineStageExample(PipeManager):
87
88 def __init__(self):
89 self.m = Module()
90 self._loopback = Signal(4)
91 PipeManager.__init__(self, self.m.d)
92
93 def stage0(self):
94 self.n = ~self._loopback
95
96 def stage1(self):
97 self.n = self.n + 2
98
99 def stage2(self):
100 localv = Signal(4)
101 self._pipe.comb += localv.eq(2)
102 self.n = self.n << localv
103
104 def stage3(self):
105 self.n = ~self.n
106
107 def stage4(self):
108 self._pipe.sync += self._loopback.eq(self.n + 3)
109
110 def get_fragment(self, platform=None):
111
112 with self.Stage() as p:
113 p.n = ~self._loopback
114 with self.Stage(p) as p:
115 p.n = p.n + 2
116
117 return self.m
118
119
120
121 if __name__ == "__main__":
122 example = PipeModule()
123 with open("pipe_module.il", "w") as f:
124 f.write(rtlil.convert(example, ports=[
125 example.p._loopback,
126 ]))
127 example = PipelineStageExample()
128 with open("pipe_stage_module.il", "w") as f:
129 f.write(rtlil.convert(example, ports=[
130 example._loopback,
131 ]))