transactron.utils package

Subpackages

Submodules

transactron.utils.assign module

class transactron.utils.assign.AssignType

Bases: Enum

ALL = 4
COMMON = 1
LHS = 2
RHS = 3
transactron.utils.assign.assign(lhs: Value | int | Enum | ValueCastable | Mapping[str, AssignArg] | Mapping[int, AssignArg] | Sequence[AssignArg], rhs: Value | int | Enum | ValueCastable | Mapping[str, AssignArg] | Mapping[int, AssignArg] | Sequence[AssignArg], *, fields: AssignType | Iterable[str | int] | Mapping[str | int, AssignFields] = AssignType.RHS, lhs_strict=False, rhs_strict=False) Iterable[Assign]

Safe structured assignment.

This function recursively generates assignment statements for field-containing structures. This includes: Amaranth Views using StructLayout, Python dicts. In case of mismatching fields or bit widths, error is raised.

When both lhs and rhs are field-containing, assign generates assignment statements according to the value of the field parameter. If either of lhs or rhs is not field-containing, assign checks for the same bit width and generates a single assignment statement.

The bit width check is performed if:

  • Any of lhs or rhs is a View.

  • Both lhs and rhs have an explicitly defined shape (e.g. are a Signal, a field of a View).

Parameters:
lhsView or Value-castable or dict

View, signal or dict being assigned.

rhsView or Value-castable or dict

View, signal or dict containing assigned values.

fieldsAssignType or Iterable or Mapping, optional

Determines which fields will be assigned. Possible values:

AssignType.COMMON

Only fields common to lhs and rhs are assigned.

AssignType.LHS

All fields in lhs are assigned. If one of them is not present in rhs, an exception is raised.

AssignType.RHS

All fields in rhs are assigned. If one of them is not present in lhs, an exception is raised.

AssignType.ALL

Assume that both structures have the same layouts. All fields present in lhs or rhs are assigned.

Mapping

Keys are field names, values follow the format for fields.

Iterable

Items are field names. For subfields, AssignType.ALL is assumed.

Returns:
Iterable[Assign]

Generated assignment statements.

Raises:
ValueError

If the assignment can’t be safely performed.

transactron.utils.data_repr module

transactron.utils.data_repr.align_down_to_power_of_two(num: int, power: int) int

Rounds down a number to the given power of two.

Parameters:
numint

The number to align.

powerint

The power of two to align to.

Returns:
int

The aligned number.

transactron.utils.data_repr.align_to_power_of_two(num: int, power: int) int

Rounds up a number to the given power of two.

Parameters:
numint

The number to align.

powerint

The power of two to align to.

Returns:
int

The aligned number.

transactron.utils.data_repr.average_dict_of_lists(d: Mapping[Any, Sized]) float
transactron.utils.data_repr.bits_from_int(num: int, lower: int, length: int)

Returns [lower:lower`+`length) bits from integer num.

transactron.utils.data_repr.data_layout(val: Shape | int | range | type[Enum] | ShapeCastable) MethodLayout
transactron.utils.data_repr.int_to_signed(x: int, xlen: int) int

Converts a Python integer into its U2 representation.

Parameters:
x: int

Signed Python integer.

xlenint

Bit width of x.

Returns:
returnint

Representation of x in the U2 system.

transactron.utils.data_repr.layout_subset(layout: StructLayout, *, fields: set[str]) StructLayout
transactron.utils.data_repr.make_hashable(val) Hashable
transactron.utils.data_repr.neg(x: int, xlen: int) int

Computes the negation of a number in the U2 system.

Parameters:
x: int

Number in U2 system.

xlenint

Bit width of x.

Returns:
returnint

Negation of x in the U2 system.

transactron.utils.data_repr.signed_to_int(x: int, xlen: int) int

Changes U2 representation into Python integer

Parameters:
x: int

Number in U2 system.

xlenint

Bit width of x.

Returns:
returnint

Representation of x as signed Python integer.

transactron.utils.debug_signals module

transactron.utils.debug_signals.auto_debug_signals(thing) ValueBundle

Automatic debug signal generation.

Exposes class attributes with debug signals (Amaranth Signals, Arrays and Elaboratables, Methods, classes which define debug_signals). Used for generating gtkw files in tests, for use in gtkwave.

transactron.utils.depcache module

class transactron.utils.depcache.DependentCache

Bases: object

Cache for classes, that depend on the DependentCache class itself.

Cached classes may accept one positional argument in the constructor, where this DependentCache class will be passed. Classes may define any number keyword arguments in the constructor and separate cache entry will be created for each set of the arguments.

Methods

get: T, **kwargs -> T

Gets class cls from cache. Caches cls reference if this is the first call for it. Optionally accepts kwargs for additional arguments in cls constructor.

__init__()
get(cls: Callable[[...], T], **kwargs) T

transactron.utils.dependencies module

class transactron.utils.dependencies.DependencyContext

Bases: object

__init__(manager: DependencyManager)
classmethod get() DependencyManager
stack: list[DependencyManager] = []
class transactron.utils.dependencies.DependencyKey

Bases: ABC, Generic

Base class for dependency keys.

Dependency keys are used to access dependencies in the DependencyManager. Concrete instances of dependency keys should be frozen data classes.

Parameters:
lock_on_get: bool, default: True

Specifies if no new dependencies should be added to key if it was already read by get_dependency.

cache: bool, default: True

If true, result of the combine method is cached and subsequent calls to get_dependency will return the value in the cache. Adding a new dependency clears the cache.

empty_valid: bool, defaultFalse

Specifies if getting key dependency without any added dependencies is valid. If set to False, that action would cause raising KeyError.

cache: bool = True
abstractmethod combine(data: list[T]) U

Combine multiple dependencies with the same key.

This method is used to generate the value returned from get_dependency in the DependencyManager. It takes dependencies added to the key using add_dependency and combines them to a single result.

Different implementations of combine give different combining behavior for different kinds of keys.

empty_valid: bool = False
lock_on_get: bool = True
class transactron.utils.dependencies.DependencyManager

Bases: object

Dependency manager.

Tracks dependencies across the core.

__init__()
add_dependency(key: DependencyKey[T, Any], dependency: T) None

Adds a new dependency to a key.

Depending on the key type, a key can have a single dependency or multple dependencies added to it.

get_dependency(key: DependencyKey[Any, U]) U

Gets the dependency for a key.

The way dependencies are interpreted is dependent on the key type.

get_optional_dependency(key: DependencyKey[Any, U]) U | None

Gets the dependency for a key, if it exists.

If the dependency is gettable, the return value is the same as in get_dependency. Otherwise, None is returned.

class transactron.utils.dependencies.ListKey

Bases: DependencyKey[T, list[T]], Generic

Base class for list key.

List keys are used when there is an one-to-many relation between keys and dependecies. Provides list of dependencies.

combine(data: list[T]) list[T]

Combine multiple dependencies with the same key.

This method is used to generate the value returned from get_dependency in the DependencyManager. It takes dependencies added to the key using add_dependency and combines them to a single result.

Different implementations of combine give different combining behavior for different kinds of keys.

empty_valid: bool = True
class transactron.utils.dependencies.SimpleKey

Bases: DependencyKey, Generic

Base class for simple dependency keys.

Simple dependency keys are used when there is an one-to-one relation between keys and dependencies. If more than one dependency is added to a simple key, an error is raised.

Parameters:
default_value: T

Specifies the default value returned when no dependencies are added. To enable it empty_valid must be True.

combine(data: list[T]) T

Combine multiple dependencies with the same key.

This method is used to generate the value returned from get_dependency in the DependencyManager. It takes dependencies added to the key using add_dependency and combines them to a single result.

Different implementations of combine give different combining behavior for different kinds of keys.

default_value: T

transactron.utils.gen module

class transactron.utils.gen.GeneratedLog

Bases: LogRecordInfo

Information about a log record in the generated Verilog code.

Attributes:
trigger_locationSignalHandle

The location of the trigger signal.

fields_locationlist[SignalHandle]

Locations of the log fields.

__init__(logger_name: str, level: int, format_str: str, location: tuple[str, int], trigger_location: list[str], fields_location: list[list[str]]) None
fields_location: list[list[str]]
classmethod from_dict(kvs: dict | list | str | int | float | bool | None, *, infer_missing=False) A
classmethod from_json(s: str | bytes | bytearray, *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) A
classmethod schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) SchemaF[A]
to_dict(encode_json=False) Dict[str, dict | list | str | int | float | bool | None]
to_json(*, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: int | str | None = None, separators: Tuple[str, str] | None = None, default: Callable | None = None, sort_keys: bool = False, **kw) str
trigger_location: list[str]
class transactron.utils.gen.GenerationInfo

Bases: object

Various information about the generated circuit.

Attributes:
metrics_locationdict[str, MetricInfo]

Mapping from a metric name to an object storing Verilog locations of its registers.

logslist[GeneratedLog]

Locations and metadata for all log records.

__init__(metrics_location: dict[str, MetricLocation], transaction_signals_location: dict[int, TransactionSignalsLocation], method_signals_location: dict[int, MethodSignalsLocation], profile_data: ProfileData, logs: list[GeneratedLog]) None
static decode(file_name: str) GenerationInfo

Loads the generation information from a JSON file.

encode(file_name: str)

Encodes the generation information as JSON and saves it to a file.

classmethod from_dict(kvs: dict | list | str | int | float | bool | None, *, infer_missing=False) A
classmethod from_json(s: str | bytes | bytearray, *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) A
logs: list[GeneratedLog]
method_signals_location: dict[int, MethodSignalsLocation]
metrics_location: dict[str, MetricLocation]
profile_data: ProfileData
classmethod schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) SchemaF[A]
to_dict(encode_json=False) Dict[str, dict | list | str | int | float | bool | None]
to_json(*, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: int | str | None = None, separators: Tuple[str, str] | None = None, default: Callable | None = None, sort_keys: bool = False, **kw) str
transaction_signals_location: dict[int, TransactionSignalsLocation]
class transactron.utils.gen.MetricLocation

Bases: object

Information about the location of a metric in the generated Verilog code.

Attributes:
regsdict[str, SignalHandle]

The location of each register of that metric.

__init__(regs: dict[str, list[str]] = <factory>) None
classmethod from_dict(kvs: dict | list | str | int | float | bool | None, *, infer_missing=False) A
classmethod from_json(s: str | bytes | bytearray, *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) A
regs: dict[str, list[str]]
classmethod schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) SchemaF[A]
to_dict(encode_json=False) Dict[str, dict | list | str | int | float | bool | None]
to_json(*, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: int | str | None = None, separators: Tuple[str, str] | None = None, default: Callable | None = None, sort_keys: bool = False, **kw) str
transactron.utils.gen.generate_verilog(elaboratable: Elaboratable, ports: list[Value] | None = None, top_name: str = 'top', *, enable_hacks: Iterable[str] = {}) tuple[str, GenerationInfo]

transactron.utils.gen_hacks module

transactron.utils.gen_hacks.fixup_vivado_transparent_memories(design: Design)

transactron.utils.idgen module

class transactron.utils.idgen.IdGenerator

Bases: object

__init__()

transactron.utils.logging module

class transactron.utils.logging.HardwareLogger

Bases: object

A class for creating log messages in the hardware.

Intuitively, the hardware logger works similarly to a normal software logger. You can log a message anywhere in the circuit, but due to the parallel nature of the hardware you must specify a special trigger signal which will indicate if a message shall be reported in that cycle.

Hardware logs are evaluated and printed during simulation, so both the trigger and the format fields are Amaranth values, i.e. signals or arbitrary Amaranth expressions.

Instances of the HardwareLogger class represent a logger for a single submodule of the circuit. Exactly how a “submodule” is defined is up to the developer. Submodule are identified by a unique string and the names can be nested. Names are organized into a namespace hierarchy where levels are separated by periods, much like the Python package namespace. So in the instance, submodules names might be “frontend” for the upper level, and “frontend.icache” and “frontend.bpu” for the sub-levels. There is no arbitrary limit to the depth of nesting.

Attributes:
name: str

Name of this logger.

__init__(name: str)
Parameters:
name: str

Name of this logger. Hierarchy levels are separated by periods, e.g. “backend.fu.jumpbranch”.

assertion(m: ModuleLike, value: Value | int | Enum | ValueCastable, format: str = '', *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Define an assertion.

This function might help find some hardware bugs which might otherwise be hard to detect. If value is false, it will terminate the simulation or it can also be used to turn on a warning LED on a board.

Internally, this is a convenience wrapper over log.error.

See HardwareLogger.log function for more details.

debug(m: ModuleLike, trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Log a message with severity ‘DEBUG’.

See HardwareLogger.log function for more details.

error(m: ModuleLike, trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Log a message with severity ‘ERROR’.

This severity level has special semantics. If a log with this serverity level is triggered, the simulation will be terminated.

See HardwareLogger.log function for more details.

info(m: ModuleLike, trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Log a message with severity ‘INFO’.

See HardwareLogger.log function for more details.

log(m: ModuleLike, level: int, trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Registers a hardware log record with the given severity.

Parameters:
m: ModuleLike

The module for which the log record is added.

trigger: ValueLike

If the value of this Amaranth expression is true, the log will reported.

format: str

The format of the message as defined in PEP 3101.

*args: ValueLike

Amaranth values that will be read during simulation and used to format the message.

src_loc: int, optional

How many stack frames below to look for the source location, used to identify the failing assertion.

top_assertion(value: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Define an assertion.

Unlike HardwareLogger.assertion, this function can be used in contexts where a module is not available.

See HardwareLogger.assertion function for more details.

top_debug(trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Log a message with severity ‘DEBUG’.

See HardwareLogger.top_log function for more details.

top_error(trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Log a message with severity ‘ERROR’.

See HardwareLogger.top_log function for more details.

top_info(trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Log a message with severity ‘INFO’.

See HardwareLogger.top_log function for more details.

top_log(level: int, trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Registers a hardware log record with the given severity.

The top_* logging functions ignore m.If etc. for triggering. They can be used in contexts where a module is not available.

See HardwareLogger.log function for more details.

top_warning(trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Log a message with severity ‘WARNING’.

See HardwareLogger.top_log function for more details.

warning(m: ModuleLike, trigger: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, src_loc: int | tuple[str, int] = 0)

Log a message with severity ‘WARNING’.

See HardwareLogger.log function for more details.

class transactron.utils.logging.LogKey

Bases: ListKey[LogRecord]

__init__() None
transactron.utils.logging.LogLevel

alias of int

class transactron.utils.logging.LogRecord

Bases: LogRecordInfo

A LogRecord instance represents an event being logged.

__init__(logger_name: str, level: int, format_str: str, location: tuple[str, int], trigger: Value, fields: tuple[Value | ValueCastable, ...] = ()) None
fields: tuple[Value | ValueCastable, ...] = ()

Amaranth signals that will be used to format the message.

trigger: Value

Single bit Amaranth signal triggering the log.

class transactron.utils.logging.LogRecordInfo

Bases: object

Simulator-backend-agnostic information about a log record that can be serialized and used outside the Amaranth context.

__init__(logger_name: str, level: int, format_str: str, location: tuple[str, int]) None
format(*args) str

Format the log message with a set of concrete arguments.

format_str: str

The template of the message. Should follow PEP 3101 standard.

classmethod from_dict(kvs: dict | list | str | int | float | bool | None, *, infer_missing=False) A
classmethod from_json(s: str | bytes | bytearray, *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) A
level: int

The severity level of the log.

location: tuple[str, int]

Source location of the log.

logger_name: str

Name of the logger which produced the record.

classmethod schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) SchemaF[A]
to_dict(encode_json=False) Dict[str, dict | list | str | int | float | bool | None]
to_json(*, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: int | str | None = None, separators: Tuple[str, str] | None = None, default: Callable | None = None, sort_keys: bool = False, **kw) str
transactron.utils.logging.assertion(m: ModuleLike, value: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, name: str = 'global', src_loc: int | tuple[str, int] = 0)

Define an assertion.

This is a short form, for use in generic code. For general use, see HardwareLogger.assertion.

transactron.utils.logging.get_log_records(level: int, namespace_regexp: str = '.*') list[LogRecord]

Get log records in for the given severity level and in the specified namespace.

This function returns all log records with the severity bigger or equal to the specified level and belonging to the specified namespace.

Parameters:
level: LogLevel

The minimum severity level.

namespace: str, optional

The regexp of the namespace. If not specified, logs from all namespaces will be processed.

transactron.utils.logging.get_trigger_bit(level: int, namespace_regexp: str = '.*') Value

Get a trigger bit for logs of the given severity level and in the specified namespace.

The signal returned by this function is high whenever the trigger signal of any of the records with the severity bigger or equal to the specified level is high.

Parameters:
level: LogLevel

The minimum severity level.

namespace: str, optional

The regexp of the namespace. If not specified, logs from all namespaces will be processed.

transactron.utils.logging.top_assertion(value: Value | int | Enum | ValueCastable, format: str, *args: Value | int | Enum | ValueCastable, name: str = 'global', src_loc: int | tuple[str, int] = 0)

Define an assertion.

This is a short form, for use in generic code. For general use, see HardwareLogger.top_assertion.

transactron.utils.transactron_helpers module

transactron.utils.transactron_helpers.async_mock_def_helper(tb, func: Callable[[...], T], arg: data.Const[StructLayout]) T
transactron.utils.transactron_helpers.dataclass_asdict(obj: Any) dict[str, Any]
transactron.utils.transactron_helpers.def_helper(description, func: Callable[[...], T], tp: type[U], arg: U, /, **kwargs) T
transactron.utils.transactron_helpers.extend_layout(layout: StructLayout, *fields: LayoutListField) StructLayout
transactron.utils.transactron_helpers.from_method_layout(layout: MethodLayout) StructLayout
transactron.utils.transactron_helpers.get_caller_class_name(default: str | None = None) tuple[Elaboratable | None, str]
transactron.utils.transactron_helpers.get_src_loc(src_loc: int | tuple[str, int]) tuple[str, int]
transactron.utils.transactron_helpers.local_src_loc(src_loc: tuple[str, int]) tuple[str, int]
transactron.utils.transactron_helpers.longest_common_prefix(*seqs: Sequence) Sequence
transactron.utils.transactron_helpers.make_layout(*fields: LayoutListField) StructLayout
transactron.utils.transactron_helpers.method_def_helper(method, func: Callable[[...], T], arg: View[StructLayout]) T
transactron.utils.transactron_helpers.mock_def_helper(tb, func: Callable[[...], T], arg: Mapping[str, Any]) T
transactron.utils.transactron_helpers.silence_mustuse(elaboratable: Elaboratable)

transactron.utils.typing module

class transactron.utils.typing.HasDebugSignals

Bases: Protocol

__init__(*args, **kwargs)
debug_signals() ValueBundle

Module contents