@@ -243,6 +243,10 @@ def __init_subclass__(cls, **kwargs):
243
243
if cls .__call__ is ShapeCastable .__call__ :
244
244
raise TypeError (f"Class '{ cls .__name__ } ' deriving from 'ShapeCastable' must override "
245
245
f"the '__call__' method" )
246
+ if cls .from_bits is ShapeCastable .from_bits :
247
+ warnings .warn (f"Class '{ cls .__name__ } ' deriving from 'ShapeCastable' does not override "
248
+ f"the 'from_bits' method, which will be required in Amaranth 0.6" ,
249
+ DeprecationWarning , stacklevel = 2 )
246
250
247
251
# The signatures and definitions of these methods are weird because they are present here for
248
252
# documentation (and error checking above) purpose only and should not affect control flow.
@@ -308,6 +312,40 @@ def const(self, *args, **kwargs):
308
312
"""
309
313
return super ().const (* args , ** kwargs ) # :nocov:
310
314
315
+ def from_bits (self , raw ):
316
+ """Lift a bit pattern to a higher-level representation.
317
+
318
+ This method is called by the Amaranth language to lift :py:`raw`, which is an :class:`int`,
319
+ to a higher-level representation, which may be any object accepted by :meth:`const`.
320
+ Most importantly, the simulator calls this method when the value of a shape-castable
321
+ object is retrieved.
322
+
323
+ For any valid bit pattern :py:`raw`, the following condition must hold:
324
+
325
+ .. code::
326
+
327
+ Const.cast(self.const(self.from_bits(raw))).value == raw
328
+
329
+ While :meth:`const` will usually return an Amaranth value or a custom value-castable
330
+ object that is convenient to use while constructing the design, this method will usually
331
+ return a Python object that is convenient to use while simulating the design. While not
332
+ constrained here, these objects should have the same type whenever feasible.
333
+
334
+ This method may also be called by code that is not a part of the Amaranth language.
335
+
336
+ Returns
337
+ -------
338
+ unspecified type
339
+
340
+ Raises
341
+ ------
342
+ Exception
343
+ When the bit pattern isn't valid. This exception must be propagated by callers,
344
+ either directly or as a cause of another exception. While not constrained here,
345
+ usually the exception class will be :exc:`ValueError`.
346
+ """
347
+ return raw
348
+
311
349
def __call__ (self , * args , ** kwargs ):
312
350
"""__call__(obj)
313
351
0 commit comments