Skip to content

Commit 3bb7499

Browse files
committed
Add back Parameter value caching. Add hack to avoid changing the function signature of Parameter.get_value(). SystemRDL/PeakRDL-regblock#162
1 parent 2b8ddcd commit 3bb7499

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

src/systemrdl/core/parameter.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,32 @@ def __init__(self, param_type: 'rdltypes.PreElabRDLType', name: str, default_exp
1414

1515
self.expr = default_expr
1616

17+
self._cached_value: Any = None
1718

18-
def get_value(self, assignee_node: 'Node') -> Any:
19+
20+
def get_value(self, assignee_node: Optional['Node'] = None) -> Any:
1921
"""
2022
Evaluate self.expr to get the parameter's value
23+
24+
HACK:
25+
assignee_node is normally ALWAYS required. However by the time a design
26+
is elaborated, the parameter will have been evaluated and the cached
27+
value available. This lets end-users avoid providing an assignee node if
28+
querying the value via Node.inst.parameters[...].get_value()
29+
Making the argument optional is a workaround for https://github.com/SystemRDL/PeakRDL-regblock/issues/162
30+
Once <Parameter> truly gets hidden from the public API (No more user
31+
access to Node.inst...), clean this up and make assignee_node not optional
2132
"""
33+
if self._cached_value is not None:
34+
return self._cached_value
35+
2236
if self.expr is None:
2337
# No expression was assigned
2438
return None
2539

26-
return self.expr.get_value(assignee_node=assignee_node)
40+
assert assignee_node is not None
41+
self._cached_value = self.expr.get_value(assignee_node=assignee_node)
42+
return self._cached_value
2743

2844

2945
def get_normalized_parameter(self, assignee_node: 'Node') -> str:
@@ -35,3 +51,14 @@ def get_normalized_parameter(self, assignee_node: 'Node') -> str:
3551
<parameter name> + "_" + <normalized value>
3652
"""
3753
return self.name + "_" + normalize(self.get_value(assignee_node))
54+
55+
def __copy__(self) -> 'Parameter':
56+
cls = self.__class__
57+
result = cls.__new__(cls)
58+
59+
result.name = self.name
60+
result.param_type = self.param_type
61+
result.expr = self.expr
62+
result._cached_value = None
63+
64+
return result

src/systemrdl/node.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ def __init__(self, inst: comp.Component, env: 'RDLEnvironment', parent: Optional
3131
self.env = env
3232

3333
#: Reference to :class:`~systemrdl.component.Component` that instantiates this node
34+
#:
35+
#: .. deprecated:: 1.30.0
36+
#: Querying the internal ``Component`` objects is no longer recommended.
37+
#:
38+
#: Equivalents for most concepts have been made available as direct
39+
#: methods or properties of the :class:`Node` objects. It is strongly
40+
#: recommended to use these instead to prevent compatibility issues.
3441
self.inst = inst
3542

3643
#: Reference to parent :class:`~Node`

test/rdl_src/elab_params.rdl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ addrmap elab_params #(
44
longint unsigned INT = 1,
55
longint unsigned INTARR[]= '{2, 3},
66
onwritetype ONWR = woset,
7-
boolean BOOL = true
7+
boolean BOOL = true,
8+
string UNUSED_STR = "asdf"
89
) {
910
reg reg_t #(
1011
longint unsigned WIDTH = 4

test/test_multiple_elab.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33

44
from systemrdl import RDLCompiler
5+
from systemrdl import rdltypes
56

67
from unittest_utils import TestPrinter
78

@@ -47,14 +48,43 @@ def test_multi_elab_params(self):
4748
rdlc = RDLCompiler(message_printer=TestPrinter())
4849
rdlc.compile_file(os.path.join(this_dir, "rdl_src/elab_params.rdl"))
4950

51+
print("1")
5052
default_root = rdlc.elaborate("elab_params")
53+
print("2")
5154
W10_root = rdlc.elaborate("elab_params", parameters={
55+
"STR": "ovr1",
5256
"INT": 10,
57+
"INTARR": [20, 30],
58+
"UNUSED_STR": "ovr2",
5359
})
5460

5561
self.assertEqual(default_root.top.find_by_path("r1.f").width, 1)
5662
self.assertEqual(W10_root.top.find_by_path("r1.f").width, 10)
5763

64+
# Test old parameter API - Was not explicitly made a private API!
65+
expected = {
66+
"STR": "default",
67+
"INT": 1,
68+
"INTARR": [2, 3],
69+
"ONWR": rdltypes.OnWriteType.woset,
70+
"BOOL": True,
71+
"UNUSED_STR": "asdf",
72+
}
73+
for param in default_root.top.inst.parameters:
74+
self.assertEqual(expected[param.name], param.get_value())
75+
76+
expected = {
77+
"STR": "ovr1",
78+
"INT": 10,
79+
"INTARR": [20, 30],
80+
"ONWR": rdltypes.OnWriteType.woset,
81+
"BOOL": True,
82+
"UNUSED_STR": "ovr2",
83+
}
84+
for param in W10_root.top.inst.parameters:
85+
self.assertEqual(expected[param.name], param.get_value())
86+
87+
5888
def test_multi_elab_common_dpa(self):
5989
rdlc = RDLCompiler(message_printer=TestPrinter())
6090
rdlc.compile_file(os.path.join(this_dir, "rdl_src/shared_dpa.rdl"))

0 commit comments

Comments
 (0)