From: Luke Kenneth Casson Leighton Date: Mon, 1 Apr 2019 00:23:39 +0000 (+0100) Subject: start on ObjectProxy example X-Git-Tag: ls180-24jan2020~1358 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=31d445001bd24aab38bda9f17a7e71ea9c373e7e;p=ieee754fpu.git start on ObjectProxy example --- diff --git a/src/add/pipeline.py b/src/add/pipeline.py index e4be4100..7df6a67d 100644 --- a/src/add/pipeline.py +++ b/src/add/pipeline.py @@ -21,7 +21,7 @@ from singlepipe import UnbufferedPipeline def like(value, rname, pipe): if isinstance(value, ObjectProxy): - return ObjectProxy.like(pipe, value, name=rname, reset_less=True) + return ObjectProxy.like(None, value, name=rname, reset_less=True) else: return Signal(value_bits_sign(value), name=rname, reset_less=True) @@ -29,19 +29,20 @@ def like(value, rname, pipe): class ObjectProxy: - def __init__(self, pipe, name=None): - self._pipe = pipe + def __init__(self, m, name=None, pipemode=False): + self._m = m if name is None: name = tracer.get_var_name(default=None) self.name = name + self._pipemode = pipemode @classmethod - def like(cls, pipe, value, name=None, src_loc_at=0, **kwargs): + def like(cls, m, value, name=None, src_loc_at=0, **kwargs): name = name or tracer.get_var_name(depth=2 + src_loc_at, default="$like") src_loc_at_1 = 1 + src_loc_at - r = ObjectProxy(pipe, value.name) + r = ObjectProxy(m, value.name) for a in value.ports(): aname = a.name setattr(r, aname, a) @@ -71,10 +72,10 @@ class ObjectProxy: return #rname = "%s_%s" % (self.name, name) rname = name - new_pipereg = like(value, rname, self._pipe) + new_pipereg = like(value, rname, self._m) object.__setattr__(self, name, new_pipereg) - if self._pipe: - self._pipe.sync += eq(new_pipereg, value) + if self._m: + self._m.d.sync += eq(new_pipereg, value) class PipelineStage: @@ -208,8 +209,8 @@ class SimplePipeline: """ Pipeline builder with auto generation of pipeline registers. """ - def __init__(self, pipe): - self._pipe = pipe + def __init__(self, m): + self._m = m self._pipeline_register_map = {} self._current_stage_num = 0 @@ -242,12 +243,12 @@ class SimplePipeline: #new_pipereg = Signal(value_bits_sign(value), name=rname, # reset_less=True) if isinstance(value, ObjectProxy): - new_pipereg = ObjectProxy.like(self._pipe, value, + new_pipereg = ObjectProxy.like(self._m, value, name=rname, reset_less = True) else: new_pipereg = Signal.like(value, name=rname, reset_less = True) if next_stage not in self._pipeline_register_map: self._pipeline_register_map[next_stage] = {} self._pipeline_register_map[next_stage][name] = new_pipereg - self._pipe.sync += eq(new_pipereg, value) + self._m.d.sync += eq(new_pipereg, value) diff --git a/src/add/pipeline_example.py b/src/add/pipeline_example.py index 0d060da3..86bc8549 100644 --- a/src/add/pipeline_example.py +++ b/src/add/pipeline_example.py @@ -36,10 +36,10 @@ class SimplePipelineExample(SimplePipeline): class ObjectBasedPipelineExample(SimplePipeline): """ A very simple pipeline to show how registers are inferred. """ - def __init__(self, pipe): - SimplePipeline.__init__(self, pipe) + def __init__(self, m): + SimplePipeline.__init__(self, m) self._loopback = Signal(4) - o = ObjectProxy(pipe) + o = ObjectProxy(m) o.a = Signal(4) o.b = Signal(4) self._obj = o @@ -51,16 +51,16 @@ class ObjectBasedPipelineExample(SimplePipeline): def stage1(self): self.n = self.n + self.o.a - o = ObjectProxy(self._pipe) + o = ObjectProxy(self._m) o.a = self.n o.b = self.o.b self.o = o def stage2(self): localv = Signal(4) - self._pipe.comb += localv.eq(2) + self._m.d.comb += localv.eq(2) self.n = self.n << localv - o = ObjectProxy(self._pipe) + o = ObjectProxy(self._m) o.b = self.n + self.o.a + self.o.b self.o = o @@ -70,14 +70,14 @@ class ObjectBasedPipelineExample(SimplePipeline): self.o.b = self.o.b + self.n def stage4(self): - self._pipe.sync += self._loopback.eq(self.n + 3 + self.o.b) + self._m.d.sync += self._loopback.eq(self.n + 3 + self.o.b) class PipeModule: def __init__(self): self.m = Module() - self.p = ObjectBasedPipelineExample(self.m.d) + self.p = ObjectBasedPipelineExample(self.m) def get_fragment(self, platform=None): return self.m @@ -109,6 +109,46 @@ class PipelineStageExample: return m +class PipelineStageObjectExample: + + def __init__(self): + self._loopback = Signal(4) + + def get_fragment(self, platform=None): + + m = Module() + + o = ObjectProxy(None) + o.a = Signal(4) + o.b = Signal(4) + self._obj = o + + with PipeManager(m, pipemode=True) as pipe: + + with pipe.Stage("first", + ispec=[self._loopback, self._obj]) as (p, m): + p.n = ~self._loopback + p.o = self._obj + with pipe.Stage("second", p) as (p, m): + #p.n = ~self._loopback + 2 + p.n = p.n + 2 + o = ObjectProxy(None) + o.a = p.n + o.b = p.o.b + p.o = o + with pipe.Stage("third", p) as (p, m): + #p.n = ~self._loopback + 5 + localv = Signal(4) + m.d.comb += localv.eq(2) + p.n = p.n << localv + o = ObjectProxy(None) + o.b = p.n + p.o.a + p.o.b + p.o = o + + print (pipe.stages) + + return m + if __name__ == "__main__": @@ -122,3 +162,8 @@ if __name__ == "__main__": f.write(rtlil.convert(example, ports=[ example._loopback, ])) + example = PipelineStageObjectExample() + with open("pipe_stage_object_module.il", "w") as f: + f.write(rtlil.convert(example, ports=[ + example._loopback, + ]))