Skip to content

Commit f469e5a

Browse files
authored
Merge pull request #142 from krcb197/104-hidden-and-reserved-items
104 hidden items
2 parents d204673 + 183d73e commit f469e5a

15 files changed

Lines changed: 584 additions & 142 deletions

.github/workflows/action.yaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ on:
88
push:
99
branches: [ main ]
1010
pull_request:
11-
branches: [ main ]
11+
branches:
12+
- main
13+
- 0.9.0
1214
schedule:
1315
- cron: '00 6 1 * *'
1416
release:
@@ -152,10 +154,15 @@ jobs:
152154
run: |
153155
154156
peakrdl python tests/testcases/basic.rdl -o peakrdl_out/raw/
157+
peakrdl python tests/testcases/hidden_property.rdl -o peakrdl_out/raw/
158+
peakrdl python tests/testcases/hidden_property.rdl -o peakrdl_out/raw/show_hidden/ --show_hidden
155159
peakrdl python tests/testcases/simple.xml tests/testcases/multifile.rdl -o peakrdl_out/raw
156160
peakrdl python tests/testcases/extended_memories.rdl -o peakrdl_out/raw/
157161
python -m unittest discover -s peakrdl_out/raw
162+
158163
peakrdl python tests/testcases/basic.rdl -o peakrdl_out/raw_async/ --async
164+
peakrdl python tests/testcases/hidden_property.rdl -o peakrdl_out/raw_async/ --async
165+
peakrdl python tests/testcases/hidden_property.rdl -o peakrdl_out/raw_async/show_hidden/ --show_hidden --async
159166
python -m unittest discover -s peakrdl_out/raw_async
160167
peakrdl python tests/testcases/basic.rdl -o peakrdl_out/raw_legacy/ --legacy_block_access
161168
python -m unittest discover -s peakrdl_out/raw_legacy

docs/generated_package.rst

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ Legacy Block Callback and Block Access
109109

110110
.. versionchanged:: 0.9.0
111111

112-
Previous versions of peakrdl python used the python ``array.array`` for efficiently moving blocks
112+
Previous versions of PeakRDL Python used the python ``array.array`` for efficiently moving blocks
113113
of data. This was changed in version 0.9.0 in order to accommodate memories which were larger
114114
than 64 bit wide which could not be supported as the array type only support entries of up to
115115
64 bit.
@@ -120,19 +120,20 @@ Legacy Block Callback and Block Access
120120

121121
It could have left this as a future compatibility mode before making a breaking change but
122122
that would just delay the pain it was felt to be better to get as many users onto the new
123-
API as soon as possible whilst peakrdl-python is in beta.
123+
API as soon as possible whilst PeakRDL Python is in beta.
124124

125125
If you really want to just keep on with the array based interface and make only minimal changes
126126
to existing code, there are two simple steps:
127+
127128
1. The northbound interfaces that are provided by the generated package expect lists of integers
128129
rather than array. The old interfaces can be retained by using the ``legacy_block_access``
129130
build option.
130131
2. The southbound interfaces into the callbacks again need to use lists for the
131132
``read_block_callback`` and ``write_block_callback`` methods. If you want to continue to use
132133
the old scheme use the following callback classes which are part of the callbacks:
133134
* ``NormalCallbackSetLegacy`` for standard python function callbacks
134-
* ``AsyncCallbackSetLegacy`` for async python function callbacks, these are called from the
135-
library using ``await``
135+
* ``AsyncCallbackSetLegacy`` for async python function callbacks, these are called from the library using ``await``
136+
136137

137138
Using the Register Access Layer
138139
===============================
@@ -200,7 +201,9 @@ The following example shows the usage of the enumeration
200201
Array Access
201202
------------
202203

203-
SystemRDL supports multi-dimensional arrays, the following example shows an definition with an 1D and 3D array with various methods to access individual elements of the array and use of the iterators to walk through elements in loops
204+
SystemRDL supports multi-dimensional arrays, the following example shows an definition with an 1D
205+
and 3D array with various methods to access individual elements of the array and use of the
206+
iterators to walk through elements in loops
204207

205208
.. literalinclude :: ../example/array_access/array_access.rdl
206209
:language: systemrdl
@@ -386,7 +389,9 @@ Python Safe Names
386389
The systemRDL structure is converted to a python class structure, there are two concerns:
387390

388391
* if any systemRDL node name is a python keyname
389-
* if any systemRDL node name clashes with part of the peakrdl_standard types, for example all register nodes have an ``address`` property that would clash with a field of that register called ``address``
392+
* if any systemRDL node name clashes with part of the peakrdl_standard types, for example all
393+
register nodes have an ``address`` property that would clash with a field of that register
394+
called ``address``
390395

391396
consider the following example:
392397

@@ -430,6 +435,55 @@ field from the example above
430435
.. literalinclude :: ../example/overridden_names/demo_over_ridden_names.py
431436
:language: python
432437
438+
Hidden Elements
439+
===============
440+
441+
Commonly some parts of the register map want to be hidden from some users, for example register
442+
included to reserve space or test functions.
443+
444+
User Defined Property
445+
---------------------
446+
447+
PeakRDL Python supports a User Defined Propery (UDP): ``python_hide`` that can be used to hide
448+
items that should not appear in the generated python wrappers.
449+
450+
In the following example, python wrapper generated would have the registers:
451+
452+
* ``explictly_visible_reg``
453+
* ``implicitly_visible_reg``
454+
455+
However the ``hidden_reg`` would not be included in the python wrappers
456+
457+
.. code-block:: systemrdl
458+
459+
property python_hide { type = boolean; component = addrmap | regfile | reg | field | mem; };
460+
461+
addrmap my_addr_map {
462+
463+
reg {
464+
default sw = rw;
465+
default hw = r;
466+
python_hide = true;
467+
field { fieldwidth=1; } field_a;
468+
} hidden_reg;
469+
470+
reg {
471+
default sw = rw;
472+
default hw = r;
473+
python_hide = false;
474+
field { fieldwidth=1; } field_a;
475+
} explictly_visible_reg;
476+
477+
reg {
478+
default sw = rw;
479+
default hw = r;
480+
field { fieldwidth=1; } field_a;
481+
} implicitly_visible_reg;
482+
483+
};
484+
485+
The ``python_hide`` property can be overridden with the ``show_hidden`` argument to the peakrdl
486+
command line tool or the ``export`` method.
433487

434488
Autoformating
435489
=============
@@ -454,7 +508,7 @@ PeakRDL Python also generates an simulator, this can be used to test and develop
454508
generated package. The simulator is used in a the examples shown earlier in this section. The
455509
simulator has the option to attach a callback to the read and write operations of either a
456510
register or field. In addition there is a ``value`` property that allows access to the register
457-
or feild content, this allows the contents to be accessed or updated without activating the
511+
or field content, this allows the contents to be accessed or updated without activating the
458512
callbacks, this is intended to allow the simulator to be extended with behaviour that is not
459513
fully described by the systemRDL.
460514

docs/index.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ At some point another software component called a Hardware Abstraction Layer (HA
3838
get produced that abstracts the device function providing functions to do more useful things.
3939
The RAL could be used as part of a HAL.
4040

41-
.. note:: The Hardware Abstraction Layer (HAL) provides abstact functionality and allows
41+
.. note:: The Hardware Abstraction Layer (HAL) provides abstract functionality and allows
4242
people to use the device without needing a full knowledge of how it works.
4343

4444
What does it do
@@ -91,7 +91,7 @@ manipulations
9191
.. warning:: A Register Access Layer (RAL) is not for everyone. Some engineers like to see the
9292
address of each register and the content of a register as a hex word. You may be quite
9393
happy with this, if that is you please stop, the overhead of an extra
94-
layer, its opaque nature and inefficency will annoy you.
94+
layer, its opaque nature and inefficiency will annoy you.
9595

9696
In order to move on the systemRDL code for the registers needs to exist
9797

@@ -111,7 +111,7 @@ Once built, a set of test cases can be run on the code to confirm its integrity,
111111
112112
python -m unittest discover -s gpio\tests -t .
113113
114-
Using the RAL allows for much simipler to understand code that does the function that was intended
114+
Using the RAL allows for much simpler to understand code that does the function that was intended
115115

116116
.. literalinclude :: ../example/why_ral/with_ral.py
117117
:language: python

src/peakrdl_python/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
1818
Variables that describes the peakrdl-python Package
1919
"""
20-
__version__ = "0.9.0.rc2"
20+
__version__ = "0.9.0.rc3"

src/peakrdl_python/__peakrdl__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,19 @@ def add_exporter_arguments(self, arg_group: 'argparse._ActionsContainer') -> Non
6464
'files found in the directory where the package will be'
6565
' generated. This is normally useful if the user is '
6666
'generating over the top of an existing package and prevents '
67-
'problems when the strucutre of the register map changes. '
67+
'problems when the structure of the register map changes. '
6868
'However, if additional python files are added by the user '
6969
'(not recommended) this cleanup will need to be suppressed '
7070
'and managed by the user')
7171
arg_group.add_argument('--legacy_block_access', action='store_true',
7272
dest='legacy_block_access',
7373
help='peakrdl python has two methods to hold blocks of data, the '
7474
'legacy mode based on array.array or the new mode using lists')
75+
arg_group.add_argument('--show_hidden', action='store_true',
76+
dest='show_hidden',
77+
help='show addrmap, regfile, memory, register and fields that '
78+
'have been given the python_hide user defined property and '
79+
'would be removed from the build python by default')
7580

7681
def do_export(self, top_node: 'AddrmapNode', options: 'argparse.Namespace') -> None:
7782
"""
@@ -94,5 +99,6 @@ def do_export(self, top_node: 'AddrmapNode', options: 'argparse.Namespace') -> N
9499
options.is_async,
95100
skip_test_case_generation=options.skip_test_case_generation,
96101
delete_existing_package_content=not options.suppress_cleanup,
97-
legacy_block_access=options.legacy_block_access
102+
legacy_block_access=options.legacy_block_access,
103+
show_hidden=options.show_hidden
98104
)

src/peakrdl_python/_node_walkers.py

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,49 +28,79 @@ class AddressMaps(RDLListener):
2828
class intended to be used as part of the walker/listener protocol to find all the descendant
2929
address maps
3030
"""
31-
def __init__(self) -> None:
31+
def __init__(self, show_hidden: bool) -> None:
3232
super().__init__()
3333
self.__address_maps: List[AddrmapNode] = []
34+
self.__show_hidden = show_hidden
3435

3536
def enter_Addrmap(self, node: AddrmapNode) -> Optional[WalkerAction]:
37+
if node.get_property('python_hide', default=False) and not self.__show_hidden:
38+
return WalkerAction.SkipDescendants
39+
3640
self.__address_maps.append(node)
3741
return WalkerAction.Continue
3842

3943
def __iter__(self) -> Iterator[AddrmapNode]:
4044
return self.__address_maps.__iter__()
4145

4246

47+
# pylint: disable=too-many-instance-attributes
4348
class OwnedbyAddressMap(RDLListener):
4449
"""
4550
class intended to be used as part of the walker/listener protocol to find all the items owned
4651
by an address map but not the descendents of any address map
4752
"""
48-
def __init__(self) -> None:
53+
def __init__(self, show_hidden: bool) -> None:
4954
super().__init__()
5055

5156
self.registers: List[RegNode] = []
5257
self.fields: List[RegNode] = []
5358
self.memories: List[RegNode] = []
5459
self.addr_maps: List[AddrmapNode] = []
5560
self.reg_files: List[RegfileNode] = []
61+
self._hidden_registers: List[RegNode] = []
62+
self._hidden_fields: List[RegNode] = []
63+
self._hidden_memories: List[RegNode] = []
64+
self._hidden_addr_maps: List[AddrmapNode] = []
65+
self._hidden_reg_files: List[RegfileNode] = []
66+
self.__show_hidden = show_hidden
5667

5768
def enter_Reg(self, node: RegNode) -> Optional[WalkerAction]:
69+
if node.get_property('python_hide', default=False) and not self.__show_hidden:
70+
self._hidden_registers.append(node)
71+
return WalkerAction.SkipDescendants
72+
5873
self.registers.append(node)
5974
return WalkerAction.Continue
6075

6176
def enter_Mem(self, node: MemNode) -> Optional[WalkerAction]:
77+
if node.get_property('python_hide', default=False) and not self.__show_hidden:
78+
self._hidden_memories.append(node)
79+
return WalkerAction.SkipDescendants
80+
6281
self.memories.append(node)
6382
return WalkerAction.Continue
6483

6584
def enter_Field(self, node: FieldNode) -> Optional[WalkerAction]:
85+
if node.get_property('python_hide', default=False) and not self.__show_hidden:
86+
self._hidden_fields.append(node)
87+
return WalkerAction.SkipDescendants
88+
6689
self.fields.append(node)
6790
return WalkerAction.Continue
6891

6992
def enter_Addrmap(self, node: AddrmapNode) -> Optional[WalkerAction]:
70-
self.addr_maps.append(node)
93+
if not node.get_property('python_hide', default=False) or self.__show_hidden:
94+
self.addr_maps.append(node)
95+
else:
96+
self._hidden_addr_maps.append(node)
7197
return WalkerAction.SkipDescendants
7298

7399
def enter_Regfile(self, node: RegfileNode) -> Optional[WalkerAction]:
100+
if node.get_property('python_hide', default=False) and not self.__show_hidden:
101+
self._hidden_reg_files.append(node)
102+
return WalkerAction.SkipDescendants
103+
74104
self.reg_files.append(node)
75105
return WalkerAction.Continue
76106

@@ -89,6 +119,29 @@ def nodes(self) -> List[Union[RegNode, MemNode, FieldNode, AddrmapNode, RegfileN
89119
"""
90120
return self.addr_maps + self.reg_files + self.memories + self.registers + self.fields
91121

122+
@property
123+
def hidden_nodes(self) -> List[Union[RegNode, MemNode, FieldNode, AddrmapNode, RegfileNode]]:
124+
"""
125+
All the 1st tier nodes owned by the address map which are hidden, including:
126+
- address maps
127+
- register files
128+
- registers
129+
- memories
130+
- fields
131+
132+
Returns: list of nodes
133+
134+
"""
135+
return self._hidden_addr_maps + self._hidden_reg_files + self._hidden_memories + \
136+
self._hidden_registers + self._hidden_fields
137+
138+
@property
139+
def has_hidden_nodes(self) -> bool:
140+
"""
141+
If there are 1st tier hidden nodes in the address map
142+
"""
143+
return len(self.hidden_nodes) > 0
144+
92145
@property
93146
def addressable_nodes(self) -> List[Union[RegNode, MemNode, AddrmapNode, RegfileNode]]:
94147
"""
@@ -102,3 +155,4 @@ def addressable_nodes(self) -> List[Union[RegNode, MemNode, AddrmapNode, Regfile
102155
103156
"""
104157
return self.addr_maps + self.reg_files + self.memories + self.registers
158+
# pylint: enable=too-many-instance-attributes

0 commit comments

Comments
 (0)