From 439dbe67bdc6582bfd3f62fedcf93d3d545b38d4 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sat, 4 Nov 2023 19:35:00 +0100 Subject: [PATCH 1/9] Add use_condition in method filter. --- test/transactions/test_transaction_lib.py | 10 ++++--- transactron/lib/transformers.py | 34 ++++++++++++++++------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/test/transactions/test_transaction_lib.py b/test/transactions/test_transaction_lib.py index a23ee077e..ca98b83d8 100644 --- a/test/transactions/test_transaction_lib.py +++ b/test/transactions/test_transaction_lib.py @@ -470,23 +470,25 @@ def target_mock(self, data): def cmeth_mock(self, data): return {"data": data % 2} - def test_method_filter_with_methods(self): + @parameterized.expand([(True,), (False,)]) + def test_method_filter_with_methods(self, use_condition): self.initialize() self.cmeth = TestbenchIO(Adapter(i=self.layout, o=data_layout(1))) - self.tc = SimpleTestCircuit(MethodFilter(self.target.adapter.iface, self.cmeth.adapter.iface)) + self.tc = SimpleTestCircuit(MethodFilter(self.target.adapter.iface, self.cmeth.adapter.iface, use_condition = use_condition)) m = ModuleConnector(test_circuit=self.tc, target=self.target, cmeth=self.cmeth) with self.run_simulation(m) as sim: sim.add_sync_process(self.source) sim.add_sync_process(self.target_mock) sim.add_sync_process(self.cmeth_mock) - def test_method_filter(self): + @parameterized.expand([(True,), (False,)]) + def test_method_filter(self, use_condition): self.initialize() def condition(_, v): return v[0] - self.tc = SimpleTestCircuit(MethodFilter(self.target.adapter.iface, condition)) + self.tc = SimpleTestCircuit(MethodFilter(self.target.adapter.iface, condition, use_condition=use_condition)) m = ModuleConnector(test_circuit=self.tc, target=self.target) with self.run_simulation(m) as sim: sim.add_sync_process(self.source) diff --git a/transactron/lib/transformers.py b/transactron/lib/transformers.py index e4b7aa0c0..85e1ede83 100644 --- a/transactron/lib/transformers.py +++ b/transactron/lib/transformers.py @@ -5,6 +5,7 @@ from collections.abc import Callable from coreblocks.utils import ValueLike, assign, AssignType from .connectors import Forwarder, ManyToOneConnectTrans, ConnectTrans +from .simultaneous import condition __all__ = [ "MethodTransformer", @@ -75,16 +76,13 @@ def _(arg): class MethodFilter(Elaboratable): """Method filter. - Takes a target method and creates a method which calls the target method only when some condition is true. The condition function takes two parameters, a module and the input `Record` of the method. Non-zero return value is interpreted as true. Alternatively to using a function, a `Method` can be passed as a condition. - - Caveat: because of the limitations of transaction scheduling, the target - method is locked for usage even if it is not called. - + By default the target method is locked for usage even if it is not called. + If this is not desired effect, set `use_condition` to True. Attributes ---------- method: Method @@ -92,7 +90,11 @@ class MethodFilter(Elaboratable): """ def __init__( - self, target: Method, condition: Callable[[TModule, Record], ValueLike], default: Optional[RecordDict] = None + self, + target: Method, + condition: Callable[[TModule, Record], ValueLike], + default: Optional[RecordDict] = None, + use_condition: bool = False, ): """ Parameters @@ -105,12 +107,16 @@ def __init__( default: Value or dict, optional The default value returned from the filtered method when the condition is false. If omitted, zero is returned. + use_condition : bool + Instead of `m.If` use simultaneus `condition` which allow to execute + this filter if the condition is False and target is not ready. """ if default is None: default = Record.like(target.data_out) self.target = target - self.method = Method.like(target) + self.use_condition = use_condition + self.method = Method(i=target.data_in.layout, o=target.data_out.layout, single_caller=self.use_condition) self.condition = condition self.default = default @@ -122,13 +128,21 @@ def elaborate(self, platform): @def_method(m, self.method) def _(arg): - with m.If(self.condition(m, arg)): - m.d.comb += ret.eq(self.target(m, arg)) + if self.use_condition: + cond = Signal() + m.d.top_comb += cond.eq(self.condition(m, arg)) + with condition(m, nonblocking=False) as branch: + with branch(cond): + m.d.comb += ret.eq(self.target(m, arg)) + with branch(~cond): + pass + else: + with m.If(self.condition(m, arg)): + m.d.comb += ret.eq(self.target(m, arg)) return ret return m - class MethodProduct(Elaboratable): def __init__( self, From 56264ea6e87a37e9c6c37951b3c4c304f2b7853e Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sat, 4 Nov 2023 19:35:58 +0100 Subject: [PATCH 2/9] Lint --- test/transactions/test_transaction_lib.py | 4 +++- transactron/lib/transformers.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/test/transactions/test_transaction_lib.py b/test/transactions/test_transaction_lib.py index ca98b83d8..88cfe4356 100644 --- a/test/transactions/test_transaction_lib.py +++ b/test/transactions/test_transaction_lib.py @@ -474,7 +474,9 @@ def cmeth_mock(self, data): def test_method_filter_with_methods(self, use_condition): self.initialize() self.cmeth = TestbenchIO(Adapter(i=self.layout, o=data_layout(1))) - self.tc = SimpleTestCircuit(MethodFilter(self.target.adapter.iface, self.cmeth.adapter.iface, use_condition = use_condition)) + self.tc = SimpleTestCircuit( + MethodFilter(self.target.adapter.iface, self.cmeth.adapter.iface, use_condition=use_condition) + ) m = ModuleConnector(test_circuit=self.tc, target=self.target, cmeth=self.cmeth) with self.run_simulation(m) as sim: sim.add_sync_process(self.source) diff --git a/transactron/lib/transformers.py b/transactron/lib/transformers.py index 85e1ede83..6f12b2967 100644 --- a/transactron/lib/transformers.py +++ b/transactron/lib/transformers.py @@ -143,6 +143,7 @@ def _(arg): return m + class MethodProduct(Elaboratable): def __init__( self, From c6448229288ef047867d25b0f2ba2297171447fe Mon Sep 17 00:00:00 2001 From: lekcyjna123 <34948061+lekcyjna123@users.noreply.github.com> Date: Sat, 4 Nov 2023 20:23:01 +0100 Subject: [PATCH 3/9] Update transformers.py --- transactron/lib/transformers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/transactron/lib/transformers.py b/transactron/lib/transformers.py index 6f12b2967..f8aeb8170 100644 --- a/transactron/lib/transformers.py +++ b/transactron/lib/transformers.py @@ -76,6 +76,7 @@ def _(arg): class MethodFilter(Elaboratable): """Method filter. + Takes a target method and creates a method which calls the target method only when some condition is true. The condition function takes two parameters, a module and the input `Record` of the method. Non-zero @@ -83,6 +84,7 @@ class MethodFilter(Elaboratable): a `Method` can be passed as a condition. By default the target method is locked for usage even if it is not called. If this is not desired effect, set `use_condition` to True. + Attributes ---------- method: Method From 6c1cba360e277a25cb1108cbd49c45482b68efce Mon Sep 17 00:00:00 2001 From: lekcyjna123 <34948061+lekcyjna123@users.noreply.github.com> Date: Sat, 4 Nov 2023 20:23:19 +0100 Subject: [PATCH 4/9] Update transformers.py --- transactron/lib/transformers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactron/lib/transformers.py b/transactron/lib/transformers.py index f8aeb8170..8d584b8ec 100644 --- a/transactron/lib/transformers.py +++ b/transactron/lib/transformers.py @@ -76,7 +76,7 @@ def _(arg): class MethodFilter(Elaboratable): """Method filter. - + Takes a target method and creates a method which calls the target method only when some condition is true. The condition function takes two parameters, a module and the input `Record` of the method. Non-zero From 1f4ce0cd122a5130d57fe46041ac33c649721243 Mon Sep 17 00:00:00 2001 From: lekcyjna123 <34948061+lekcyjna123@users.noreply.github.com> Date: Sat, 4 Nov 2023 20:23:39 +0100 Subject: [PATCH 5/9] Update transformers.py --- transactron/lib/transformers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactron/lib/transformers.py b/transactron/lib/transformers.py index 8d584b8ec..78cf97d38 100644 --- a/transactron/lib/transformers.py +++ b/transactron/lib/transformers.py @@ -76,7 +76,7 @@ def _(arg): class MethodFilter(Elaboratable): """Method filter. - + Takes a target method and creates a method which calls the target method only when some condition is true. The condition function takes two parameters, a module and the input `Record` of the method. Non-zero From ac8cf01ae630567fc643828f3b95b07965718f36 Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sat, 11 Nov 2023 10:06:32 +0100 Subject: [PATCH 6/9] Lint --- transactron/lib/transformers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactron/lib/transformers.py b/transactron/lib/transformers.py index 78cf97d38..7ec409dbb 100644 --- a/transactron/lib/transformers.py +++ b/transactron/lib/transformers.py @@ -84,7 +84,7 @@ class MethodFilter(Elaboratable): a `Method` can be passed as a condition. By default the target method is locked for usage even if it is not called. If this is not desired effect, set `use_condition` to True. - + Attributes ---------- method: Method From a95a87748f361aff8e55136b1df92907361ce56b Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sat, 11 Nov 2023 12:20:39 +0100 Subject: [PATCH 7/9] Update doc strings --- transactron/lib/transformers.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/transactron/lib/transformers.py b/transactron/lib/transformers.py index 7ec409dbb..fd5221bb4 100644 --- a/transactron/lib/transformers.py +++ b/transactron/lib/transformers.py @@ -82,8 +82,10 @@ class MethodFilter(Elaboratable): parameters, a module and the input `Record` of the method. Non-zero return value is interpreted as true. Alternatively to using a function, a `Method` can be passed as a condition. - By default the target method is locked for usage even if it is not called. - If this is not desired effect, set `use_condition` to True. + By default, the target method is locked for usa even if it is not called. + If this is not the desired effect, set `use_condition` to True, but this will + cause that the provided method will be `single_caller` and all other `condition` + drawbacks will be in place (e.g. risk of exponential complexity). Attributes ---------- From 1ab0783493a5804540914376dc4301dc1d8af60a Mon Sep 17 00:00:00 2001 From: lekcyjna123 <34948061+lekcyjna123@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:47:08 +0100 Subject: [PATCH 8/9] Fix doc string --- transactron/lib/transformers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactron/lib/transformers.py b/transactron/lib/transformers.py index fd5221bb4..63922bc3c 100644 --- a/transactron/lib/transformers.py +++ b/transactron/lib/transformers.py @@ -82,7 +82,7 @@ class MethodFilter(Elaboratable): parameters, a module and the input `Record` of the method. Non-zero return value is interpreted as true. Alternatively to using a function, a `Method` can be passed as a condition. - By default, the target method is locked for usa even if it is not called. + By default, the target method is locked for use even if it is not called. If this is not the desired effect, set `use_condition` to True, but this will cause that the provided method will be `single_caller` and all other `condition` drawbacks will be in place (e.g. risk of exponential complexity). From a2c5ee6df1f57e560d0e82ef06f5a7beef70476c Mon Sep 17 00:00:00 2001 From: Lekcyjna <309016@uwr.edu.pl> Date: Sun, 3 Dec 2023 19:36:53 +0100 Subject: [PATCH 9/9] Add priority = False --- transactron/lib/transformers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transactron/lib/transformers.py b/transactron/lib/transformers.py index 3ed01ab75..5bcf0a4d3 100644 --- a/transactron/lib/transformers.py +++ b/transactron/lib/transformers.py @@ -163,7 +163,7 @@ def _(arg): if self.use_condition: cond = Signal() m.d.top_comb += cond.eq(self.condition(m, arg)) - with condition(m, nonblocking=False) as branch: + with condition(m, nonblocking=False, priority=False) as branch: with branch(cond): m.d.comb += ret.eq(self.target(m, arg)) with branch(~cond):