Skip to content

Commit 441af5b

Browse files
committed
csr.reg: rename to .field to .action and import it automatically.
1 parent aa79198 commit 441af5b

File tree

5 files changed

+198
-191
lines changed

5 files changed

+198
-191
lines changed

amaranth_soc/csr/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
from .bus import *
22
from .event import *
33
from .reg import *
4+
from . import action

amaranth_soc/csr/field.py renamed to amaranth_soc/csr/action.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010

1111
class R(wiring.Component):
12-
"""A read-only field.
12+
"""A read-only field action.
1313
1414
Parameters
1515
----------
@@ -36,7 +36,7 @@ def elaborate(self, platform):
3636

3737

3838
class W(wiring.Component):
39-
"""A write-only field.
39+
"""A write-only field action.
4040
4141
Parameters
4242
----------
@@ -63,7 +63,7 @@ def elaborate(self, platform):
6363

6464

6565
class RW(wiring.Component):
66-
"""A read/write field with built-in storage.
66+
"""A read/write field action, with built-in storage.
6767
6868
Storage is updated with the value of ``port.w_data`` one clock cycle after ``port.w_stb`` is
6969
asserted.
@@ -109,7 +109,7 @@ def elaborate(self, platform):
109109

110110

111111
class RW1C(wiring.Component):
112-
"""A read/write-one-to-clear field with built-in storage.
112+
"""A read/write-one-to-clear field action, with built-in storage.
113113
114114
Storage bits are:
115115
* cleared by high bits in ``port.w_data``, one clock cycle after ``port.w_stb`` is asserted;
@@ -164,7 +164,7 @@ def elaborate(self, platform):
164164

165165

166166
class RW1S(wiring.Component):
167-
"""A read/write-one-to-set field with built-in storage.
167+
"""A read/write-one-to-set field action, with built-in storage.
168168
169169
Storage bits are:
170170
* set by high bits in ``port.w_data``, one clock cycle after ``port.w_stb`` is asserted;

amaranth_soc/csr/reg.py

Lines changed: 73 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -160,51 +160,55 @@ def __repr__(self):
160160
class Field:
161161
"""Register field factory.
162162
163+
Actions
164+
-------
165+
166+
A field action is an Amaranth :class:`~wiring.Component` mediating access to a range of bits
167+
within a :class:`Register`. Its signature must contain a :class:`FieldPort.Signature` member
168+
named "port", with an :attr:`~wiring.In` direction.
169+
163170
Parameters
164171
----------
165-
field_cls : :class:`type`
166-
The field type instantiated by :meth:`Field.create`. It must be a :class:`wiring.Component`
167-
subclass. ``field_cls`` instances must have a signature containing a member named "port",
168-
which must be an input :class:`FieldPort.Signature`.
172+
action_cls : :class:`type`
173+
The type of field action to be instantiated by :meth:`Field.create`.
169174
*args : :class:`tuple`
170-
Positional arguments passed to ``field_cls.__init__``.
175+
Positional arguments passed to ``action_cls.__init__``.
171176
**kwargs : :class:`dict`
172-
Keyword arguments passed to ``field_cls.__init__``.
177+
Keyword arguments passed to ``action_cls.__init__``.
173178
174179
Raises
175180
------
176181
:exc:`TypeError`
177-
If ``field_cls`` is not a subclass of :class:`wiring.Component`.
182+
If ``action_cls`` is not a subclass of :class:`wiring.Component`.
178183
"""
179-
def __init__(self, field_cls, *args, **kwargs):
180-
if not issubclass(field_cls, wiring.Component):
181-
raise TypeError(f"{field_cls.__qualname__} must be a subclass of wiring.Component")
182-
183-
self._field_cls = field_cls
184-
self._args = args
185-
self._kwargs = kwargs
184+
def __init__(self, action_cls, *args, **kwargs):
185+
if not issubclass(action_cls, wiring.Component):
186+
raise TypeError(f"{action_cls.__qualname__} must be a subclass of wiring.Component")
187+
self._action_cls = action_cls
188+
self._args = args
189+
self._kwargs = kwargs
186190

187191
def create(self):
188192
"""Create a field instance.
189193
190194
Returns
191195
-------
192196
:class:`object`
193-
The instance returned by ``field_cls(*args, **kwargs)``.
197+
The instance returned by ``action_cls(*args, **kwargs)``.
194198
195199
Raises
196200
------
197201
:exc:`TypeError`
198-
If the instance returned by ``field_cls(*args, **kwargs)`` doesn't have a signature
199-
with a member named "port" that is a :class:`FieldPort.Signature` with a
200-
:attr:`wiring.In` direction.
202+
If the instance returned by ``action_cls(*args, **kwargs)`` doesn't have a signature
203+
containing a :class:`FieldPort.Signature` member named "port", with an
204+
:attr:`~wiring.In` direction.
201205
"""
202-
field = self._field_cls(*self._args, **self._kwargs)
206+
field = self._action_cls(*self._args, **self._kwargs)
203207
if not ("port" in field.signature.members
204208
and field.signature.members["port"].flow is In
205209
and field.signature.members["port"].is_signature
206210
and isinstance(field.signature.members["port"].signature, FieldPort.Signature)):
207-
raise TypeError(f"{self._field_cls.__qualname__} instance signature must have a "
211+
raise TypeError(f"{self._action_cls.__qualname__} instance signature must have a "
208212
f"csr.FieldPort.Signature member named 'port' and oriented as In")
209213
return field
210214

@@ -215,18 +219,18 @@ class FieldMap(Mapping):
215219
Parameters
216220
----------
217221
fields : :class:`dict` of :class:`str` to (:class:`Field` or :class:`dict` or :class:`list`)
218-
Field map members. A :class:`FieldMap` stores an instance of :class:`Field` members (see
219-
:meth:`Field.create`). :class:`dict` members are cast to :class:`FieldMap`. :class:`list`
220-
members are cast to :class:`FieldArray`.
222+
Fields to instantiate. A :class:`FieldMap` contains instances of :class:`Field` actions
223+
(returned by :meth:`Field.create`). Nested :class:`FieldMap`s are created from dicts, and
224+
:class:`FieldArray`s from lists.
221225
222226
Raises
223227
------
224228
:exc:`TypeError`
225-
If ``fields`` is not a non-empty dict.
229+
If ``fields`` is not a dict, or is empty.
226230
:exc:`TypeError`
227-
If ``fields`` has a key that is not a non-empty string.
231+
If ``fields`` has a key that is not a string, or is empty.
228232
:exc:`TypeError`
229-
If ``fields`` has a value that is neither a :class:`Field` object or a dict or list of
233+
If ``fields`` has a value that is neither a :class:`Field` object, a dict or a list of
230234
:class:`Field` objects.
231235
"""
232236
def __init__(self, fields):
@@ -235,34 +239,34 @@ def __init__(self, fields):
235239
if not isinstance(fields, dict) or len(fields) == 0:
236240
raise TypeError(f"Fields must be provided as a non-empty dict, not {fields!r}")
237241

238-
for key, field in fields.items():
242+
for key, value in fields.items():
239243
if not isinstance(key, str) or not key:
240244
raise TypeError(f"Field name must be a non-empty string, not {key!r}")
241245

242-
if isinstance(field, Field):
243-
field_inst = field.create()
244-
elif isinstance(field, dict):
245-
field_inst = FieldMap(field)
246-
elif isinstance(field, list):
247-
field_inst = FieldArray(field)
246+
if isinstance(value, Field):
247+
field = value.create()
248+
elif isinstance(value, dict):
249+
field = FieldMap(value)
250+
elif isinstance(value, list):
251+
field = FieldArray(value)
248252
else:
249-
raise TypeError(f"{field!r} must be a Field object or a collection of Field "
250-
f"objects")
253+
raise TypeError(f"{value!r} must either be a Field object, a dict or a list of "
254+
f"Field objects")
251255

252-
self._fields[key] = field_inst
256+
self._fields[key] = field
253257

254258
def __getitem__(self, key):
255259
"""Access a field by name or index.
256260
257261
Returns
258262
--------
259-
:class:`Field` or :class:`FieldMap` or :class:`FieldArray`
260-
The field associated with ``key``.
263+
:class:`wiring.Component` or :class:`FieldMap` or :class:`FieldArray`
264+
The field instance associated with ``key``.
261265
262266
Raises
263267
------
264268
:exc:`KeyError`
265-
If there is no field associated with ``key``.
269+
If there is no field instance associated with ``key``.
266270
"""
267271
return self._fields[key]
268272

@@ -271,13 +275,13 @@ def __getattr__(self, name):
271275
272276
Returns
273277
-------
274-
:class:`Field` or :class:`FieldMap` or :class:`FieldArray`
275-
The field associated with ``name``.
278+
:class:`wiring.Component` or :class:`FieldMap` or :class:`FieldArray`
279+
The field instance associated with ``name``.
276280
277281
Raises
278282
------
279283
:exc:`AttributeError`
280-
If the field map does not have a field associated with ``name``.
284+
If the field map does not have a field instance associated with ``name``.
281285
:exc:`AttributeError`
282286
If ``name`` is reserved (i.e. starts with an underscore).
283287
"""
@@ -302,7 +306,7 @@ def __iter__(self):
302306
yield from self._fields
303307

304308
def __len__(self):
305-
"""Field map length.
309+
"""Field map size.
306310
307311
Returns
308312
-------
@@ -317,9 +321,10 @@ def flatten(self):
317321
Yields
318322
------
319323
iter(:class:`str`)
320-
Path of the field. It is prefixed by the name of every nested field collection.
324+
Path of the field. It is prefixed by the name of every nested :class:`FieldMap` or
325+
:class:`FieldArray`.
321326
:class:`wiring.Component`
322-
Register field.
327+
Field instance. See :meth:`Field.create`.
323328
"""
324329
for key, field in self.items():
325330
if isinstance(field, (FieldMap, FieldArray)):
@@ -335,16 +340,16 @@ class FieldArray(Sequence):
335340
Parameters
336341
----------
337342
fields : :class:`list` of (:class:`Field` or :class:`dict` or :class:`list`)
338-
Field array members. A :class:`FieldArray` stores an instance of :class:`Field` members
339-
(see :meth:`Field.create`). :class:`dict` members are cast to :class:`FieldMap`.
340-
:class:`list` members are cast to :class:`FieldArray`.
343+
Fields to instantiate. A :class:`FieldArray` contains instances of :class:`Field` actions
344+
(returned by :meth:`Field.create`). Nested :class:`FieldArrays`s are created from lists,
345+
and :class:`FieldMaps`s from dicts.
341346
342347
Raises
343348
------
344349
:exc:`TypeError`
345-
If ``fields`` is not a non-empty list.
350+
If ``fields`` is not a list, or is empty.
346351
:exc:`TypeError`
347-
If ``fields`` has an item that is neither a :class:`Field` object or a dict or list of
352+
If ``fields`` has an item that is neither a :class:`Field` object, a dict or a list of
348353
:class:`Field` objects.
349354
"""
350355
def __init__(self, fields):
@@ -353,36 +358,36 @@ def __init__(self, fields):
353358
if not isinstance(fields, list) or len(fields) == 0:
354359
raise TypeError(f"Fields must be provided as a non-empty list, not {fields!r}")
355360

356-
for field in fields:
357-
if isinstance(field, Field):
358-
field_inst = field.create()
359-
elif isinstance(field, dict):
360-
field_inst = FieldMap(field)
361-
elif isinstance(field, list):
362-
field_inst = FieldArray(field)
361+
for item in fields:
362+
if isinstance(item, Field):
363+
field = item.create()
364+
elif isinstance(item, dict):
365+
field = FieldMap(item)
366+
elif isinstance(item, list):
367+
field = FieldArray(item)
363368
else:
364-
raise TypeError(f"{field!r} must be a Field object or a collection of Field "
369+
raise TypeError(f"{item!r} must be a Field object or a collection of Field "
365370
f"objects")
366371

367-
self._fields.append(field_inst)
372+
self._fields.append(field)
368373

369374
def __getitem__(self, key):
370375
"""Access a field by index.
371376
372377
Returns
373378
-------
374-
:class:`Field` or :class:`FieldMap` or :class:`FieldArray`
375-
The field associated with ``key``.
379+
:class:`wiring.Component` or :class:`FieldMap` or :class:`FieldArray`
380+
The field instance associated with ``key``.
376381
"""
377382
return self._fields[key]
378383

379384
def __len__(self):
380-
"""Field array length.
385+
"""Field array size.
381386
382387
Returns
383388
-------
384389
:class:`int`
385-
The number of fields in the array.
390+
The number of items in the array.
386391
"""
387392
return len(self._fields)
388393

@@ -392,9 +397,10 @@ def flatten(self):
392397
Yields
393398
------
394399
iter(:class:`str`)
395-
Path of the field. It is prefixed by the name of every nested field collection.
400+
Path of the field. It is prefixed by the name of every nested :class:`FieldMap` or
401+
:class:`FieldArray`.
396402
:class:`wiring.Component`
397-
Register field.
403+
Field instance. See :meth:`Field.create`.
398404
"""
399405
for key, field in enumerate(self._fields):
400406
if isinstance(field, (FieldMap, FieldArray)):
@@ -524,8 +530,8 @@ def __iter__(self):
524530
------
525531
iter(:class:`str`)
526532
Path of the field. It is prefixed by the name of every nested field collection.
527-
:class:`Field`
528-
Register field.
533+
:class:`wiring.Component`
534+
Register field instance.
529535
"""
530536
yield from self.fields.flatten()
531537

0 commit comments

Comments
 (0)