@@ -405,12 +405,10 @@ def flatten(self):
405405
406406
407407class Register (wiring .Component ):
408- """CSR register .
408+ """Base class for CSR registers .
409409
410410 Parameters
411411 ----------
412- access : :class:`Element.Access`
413- Register access mode.
414412 fields : :class:`dict` or :class:`list`
415413 Collection of register fields. If ``None`` (default), a :class:`dict` is populated from
416414 Python :term:`variable annotations <python:variable annotations>`. If ``fields`` is a
@@ -424,31 +422,39 @@ class Register(wiring.Component):
424422
425423 Attributes
426424 ----------
427- access : :class:`Element.Access`
428- Register access mode.
429425 fields : :class:`FieldMap` or :class:`FieldArray`
430426 Collection of register fields.
431427 f : :class:`FieldMap` or :class:`FieldArray`
432428 Shorthand for :attr:`Register.fields`.
433429
434430 Raises
435431 ------
436- :exc:`TypeError`
437- If ``access`` is not a member of :class:`Element.Access`.
438432 :exc:`TypeError`
439433 If ``fields`` is not ``None`` or a :class:`dict` or a :class:`list`.
440434 :exc:`ValueError`
441435 If ``fields`` is not ``None`` and at least one variable annotation is a :class:`Field`.
442436 :exc:`ValueError`
443- If ``access`` is not readable and at least one field is readable.
437+ If ``element. access`` is not readable and at least one field is readable.
444438 :exc:`ValueError`
445- If ``access`` is not writable and at least one field is writable.
439+ If ``element. access`` is not writable and at least one field is writable.
446440 """
447- def __init__ (self , access = "rw" , fields = None ):
448- if not isinstance (access , Element .Access ) and access not in ("r" , "w" , "rw" ):
449- raise TypeError (f"Access mode must be one of \" r\" , \" w\" , or \" rw\" , not { access !r} " )
450- self ._access = Element .Access (access )
451441
442+ def __new__ (cls , * args , ** kwargs ):
443+ if cls is Register :
444+ raise TypeError ("csr.Register is a base class and cannot be directly instantiated" )
445+ return super ().__new__ (cls , * args , ** kwargs )
446+
447+ def __init_subclass__ (cls , * , access , ** kwargs ):
448+ # TODO(py3.9): Remove this. Python 3.8 and below use cls.__name__ in the error message
449+ # instead of cls.__qualname__.
450+ # cls.__access = Element.Access(access)
451+ try :
452+ cls .__access = Element .Access (access )
453+ except ValueError as e :
454+ raise ValueError (f"{ access !r} is not a valid Element.Access" ) from e
455+ super ().__init_subclass__ (** kwargs )
456+
457+ def __init__ (self , fields = None ):
452458 if hasattr (self , "__annotations__" ):
453459 def filter_dict (d ):
454460 fields = {}
@@ -494,18 +500,14 @@ def filter_list(l):
494500 width = 0
495501 for field_path , field in self ._fields .flatten ():
496502 width += Shape .cast (field .port .shape ).width
497- if field .port .access .readable () and not self ._access .readable ():
503+ if field .port .access .readable () and not self .__access .readable ():
498504 raise ValueError (f"Field { '__' .join (field_path )} is readable, but register access "
499- f"mode is { self ._access !r} " )
500- if field .port .access .writable () and not self ._access .writable ():
505+ f"mode is { self .__access !r} " )
506+ if field .port .access .writable () and not self .__access .writable ():
501507 raise ValueError (f"Field { '__' .join (field_path )} is writable, but register access "
502- f"mode is { self ._access !r} " )
508+ f"mode is { self .__access !r} " )
503509
504- super ().__init__ ({"element" : Out (Element .Signature (width , self ._access ))})
505-
506- @property
507- def access (self ):
508- return self ._access
510+ super ().__init__ ({"element" : Out (Element .Signature (width , self .__access ))})
509511
510512 @property
511513 def fields (self ):
0 commit comments