Internal Representation

Topwrap uses a custom object hierarchy, further called “internal representation” or “IR”, in order to store block design and related data in memory and operate on it.

Frontend & Backend

The Frontend based classes converts external formats, such as SystemVerilog, VHDL or KPM into the IR. Complementarily, the Backend based classes convert our IR into external formats.

The reason for separating the logic like this is to be able to easily add support for multiple fronteds and backends formats and make them interchangeable.

API interface

exception FrontendParseException

Bases: TranslationError

Exception occurred during parsing sources by the frontend

class Frontend(modules: Iterable[Module] = (), interfaces: Iterable[InterfaceDefinition] = ())

Bases: ABC

parse_str(sources: Iterable[str]) Iterator[Module]

Parse a collection of string sources into IR modules

Parameters:
sources: Iterable[str]

Collection of string sources

abstract parse_files(sources: Iterable[Path]) Iterator[Module]

Parse a collection of source files into IR modules

Parameters:
sources: Iterable[Path]

Collection of paths to sources

class BackendOutputInfo(filename: str, content: str)

Bases: object

Output of the backend’s serialization process

filename : str

The filename for this output as suggested by the specific backend E.g. dataflow.kpm.json or axibridge.sv

content : str

The content of the file generated by the backend

save(path: Path)

Save this output as a file on the filesystem under a given path

Parameters:
path: Path

The path where to save the file. If it points only to a directory, then the file is saved with the self.filename name.

class Backend

Bases: ABC, Generic[_T]

The base class for backend implementations used to convert our IR represented by the Module class into various external formats, represented by the generic parameter _T.

abstract represent(module: Module, /) _T

Convert the IR into an arbitrary custom external format.

abstract serialize(repr: _T, /) Iterator[BackendOutputInfo]

Serialize the custom format object into one or more text files, represented by their content, alongside with additional information about them, like the suggested filename.

Module

class Module(*, id: Identifier, refs: Iterable[FileReference] = (), ports: Iterable[Port] = (), parameters: Iterable[Parameter] = (), interfaces: Iterable[Interface] = (), design: Design | None = None)

Bases: ModelBase

The top-level class of the IR. It fully represents the public interface of a HDL module, holding definitions of all of its structured ports and interfaces, parameters, and optionally its inner block design if available.

id : Identifier
property design

Returns the optional inner block design of this module

property ports : QuerableView[Port]
property parameters : QuerableView[Parameter]
property interfaces : QuerableView[Interface]
property ios : QuerableView[Port | Interface]

Returns a combined view on both ports and interfaces

property refs : Sequence[FileReference]

Returns references to external files that define this module, if any. This information is generally added by the respective frontend used to parse this module.

add_port(port: Port)
add_parameter(parameter: Parameter)
add_interface(interface: Interface)
add_reference(ref: FileReference)
non_intf_ports() Iterator[Port]

Yield ports that don’t realise signals of any interface

Design

class ModuleInstance(*, name: VariableName, module: Module, parameters: Mapping[ObjectId[Parameter], ElaboratableValue] = {})

Bases: ModelBase

Represents an instantiated module with values supplied for its appropriate respective parameters. This class is necessary to differentiate multiple instances of the same module in a design.

parent : Design

Reference to the design that contains this component

name : VariableName

The name of this instance. It corresponds to “instance_name” in this exemplary Verilog construct: MODULE #(.WIDTH(32)) instance_name (.clk(clk));

module : Module

The module that this is an instance of. Corresponds to “MODULE” in the Verilog construct defined above.

parameters : dict[ObjectId[Parameter], ElaboratableValue]

Concrete parameter values for the module that this is an instance of. Corresponds to “#(.WIDTH(32))” in the above Verilog construct.

class Design(*, components: Iterable[ModuleInstance] = (), interconnects: Iterable[Interconnect] = (), connections: Iterable[ConstantConnection | PortConnection | InterfaceConnection] = ())

Bases: ModelBase

This class represents the inner block design of a specific Module. It consists of instances of other modules (components) and connections between them, each other, and external ports of the module that this design represents.

parent : Module
property components : QuerableView[ModuleInstance]
property interconnects : QuerableView[Interconnect]
property connections : QuerableView[ConstantConnection | PortConnection | InterfaceConnection]
add_component(component: ModuleInstance)
add_interconnect(interconnect: Interconnect)
add_connection(connection: ConstantConnection | PortConnection | InterfaceConnection)
connections_with(io: ReferencedPort | ReferencedInterface) Iterator[ElaboratableValue | ReferencedPort | ReferencedInterface]

Yields everything that is connected to a given IO.

Parameters:
io: ReferencedPort | ReferencedInterface

The IO of which connections to yield.

Interface

class InterfaceMode(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

MANAGER = 'manager'
SUBORDINATE = 'subordinate'
UNSPECIFIED = 'unspecified'
class InterfaceSignalConfiguration(direction: PortDirection, required: bool, default: ElaboratableValue | None = None)

Bases: object

Holds the mode-specific configuration of an interface signal

direction : PortDirection

The direction of this signal in a given InterfaceMode

required : bool

Whether this signal is required or optional

default : ElaboratableValue | None = None

The default value for this signal, if any

class InterfaceSignal(*, name: str, regexp: Pattern[str], type: Logic, modes: Mapping[InterfaceMode, InterfaceSignalConfiguration])

Bases: ModelBase

This class represents a signal in an interface definition. E.g.: The awaddr signal in the AXI interface etc.

parent : InterfaceDefinition

The definition that this signal belongs to

name : VariableName
regexp : re.Pattern[str]

While automatically deducing interfaces, if an arbitrary signal’s name matches this regular expression then that signal is considered as a candidate for realizing this signal definition

type : Logic

The logical type of this signal. Fulfills the same function as Port.type

modes : dict[InterfaceMode, InterfaceSignalConfiguration]

A dictionary of modes for this signal and their specific configurations E.g.: A signal that only has an InterfaceMode.MANAGER entry in this dictionary means that it’s valid only on the manager’s side.

class InterfaceDefinition(*, id: Identifier, signals: Iterable[InterfaceSignal] = ())

Bases: object

This represents a definition of an entire interface/bus. E.g. AXI, AHB, Wishbone, etc.

id : Identifier
property signals : QuerableView[InterfaceSignal]

A list of signal definitions that make up this interface E.g. awaddr, araddr, wdata, rdata, etc…. in AXI

add_signal(signal: InterfaceSignal)
class Interface(name: str, mode: ~topwrap.model.interface.InterfaceMode, definition: ~topwrap.model.interface.InterfaceDefinition, signals: dict[~topwrap.model.misc.ObjectId[~topwrap.model.interface.InterfaceSignal], ~topwrap.model.connections.ReferencedPort | None] = <factory>)

Bases: object

A realised instance of an interface that can be connected with other interface instances through InterfaceConnection.

The relationship between this class and InterfaceDefinition is similar to the relationship between ModuleInstance and Module classes.

name : VariableName

Name for this interface instance

mode : InterfaceMode

The mode of this instance (e.g. manager/subordinate)

definition : InterfaceDefinition

The definition of the interface that this is an instance of

parent : Module

The module definition that contains this interface instance

signals : dict[ObjectId[InterfaceSignal], ReferencedPort | None]

Realization of signals defined in this interface. A signal can be realized either by:

  • Slicing an already existing external port of the module that this instance belongs to (self.parent), in that case the value in this dictionary is the aforementioned port reference.

  • Independently, meaning that whenever necessary, e.g. during output generation by a Backend that does not support interfaces, an arbitrarily generated port based on the InterfaceSignal.type should be generated to represent it. In that case the value in this dictionary is None.

If an entry for a specific signal that exists in the definition is not present in this dictionary, then that signal will not be realized at all. E.g. when it was configured as optional or was given a default value in InterfaceSignalConfiguration.

Connections

class PortDirection(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

IN = 'in'
OUT = 'out'
INOUT = 'inout'
reverse() PortDirection
class Port(*, name: str, direction: PortDirection, type: Logic | None = None)

Bases: object

This represents an external port of a HDL module that can be connected to other ports or constant values in a design.

parent : Module

The module definition that exposes this port

name : VariableName
direction : PortDirection
type : Logic

The type of this port. (Bit, BitStruct, LogicArray etc.)

class ReferencedPort(*, instance: ModuleInstance | None = None, io: Port, select: LogicSelect | None = None)

Bases: _ReferencedIO[Port]

Represents a correctly typed reference to a port

select : LogicSelect
classmethod external(io: Port, select: LogicSelect | None = None)

A shortcut constructor for a reference to a top-level IO of the current module

class ReferencedInterface(*, instance: ModuleInstance | None = None, io: _REFIO)

Bases: _ReferencedIO[Interface]

Represents a correctly typed reference to an interface

class ConstantConnection(source: _SRC, target: _TRG)

Bases: _Connection[ElaboratableValue, ReferencedPort]

Represents a connection between a constant value and a port of a component

class PortConnection(source: _SRC, target: _TRG)

Bases: _Connection[ReferencedPort, ReferencedPort]

Represents a connection between two ports of some components

class InterfaceConnection(source: _SRC, target: _TRG)

Bases: _Connection[ReferencedInterface, ReferencedInterface]

Represents a connection between two interfaces of some components

HDL Types

class Dimensions(upper: ~topwrap.model.misc.ElaboratableValue = <factory>, lower: ~topwrap.model.misc.ElaboratableValue = <factory>)

Bases: object

A pair of values representing bounds for a single dimension of a Logic type. Verilog examples: - logic -> upper == lower == 0 - logic[31:0] -> upper == 31, lower == 0 - logic[0:64] -> upper == 0, lower == 64

upper : ElaboratableValue
lower : ElaboratableValue
class Logic(name: str | None = None)

Bases: ABC

An abstract class representing anything that can be used as a logical type for a port or a signal in a module.

parent : Logic | None

The parent of this type. Used to create a reference tree between complex type definitions, for example between LogicArray and the inner type it contains or between a BitStruct and its fields. Is None when this represents a top-level type

name : str | None
abstract property size : ElaboratableValue

All Logic subclasses should have an elaboratable size (the number of bits)

class Bit(name: str | None = None)

Bases: Logic

A single bit type. Equivalent to logic or logic[0:0] type in Verilog.

property size : ElaboratableValue

All Logic subclasses should have an elaboratable size (the number of bits)

class LogicArray(*, name: str | None = None, dimensions: list[Dimensions], item: _ArrayItemOrField)

Bases: Logic, Generic[_ArrayItemOrField]

A type representing a multidimensional array of logical elements.

property size

All Logic subclasses should have an elaboratable size (the number of bits)

dimensions : list[Dimensions]
item : _ArrayItemOrField
class Bits(*, name: str | None = None, dimensions: list[Dimensions])

Bases: LogicArray[Bit]

A multidimensional array of bits

class StructField(*, name: str, type: _ArrayItemOrField)

Bases: Logic, Generic[_ArrayItemOrField]

A field in a BitStruct

property size

All Logic subclasses should have an elaboratable size (the number of bits)

field_name : str
type : _ArrayItemOrField
class BitStruct(*, name: str | None = None, fields: list[StructField[Logic]])

Bases: Logic

A complex structural type equivalent to a struct {...} construct in SystemVerilog.

property size

All Logic subclasses should have an elaboratable size (the number of bits)

fields : list[StructField[Logic]]
class LogicSelect(logic: ~topwrap.model.hdl_types.Logic, ops: list[~topwrap.model.hdl_types.LogicFieldSelect | ~topwrap.model.hdl_types.LogicBitSelect] = <factory>)

Bases: object

Represents an arbitrary selection of a part of a logical type. For example if self.logic references a multidimensional LogicArray, then you could have multiple LogicBitSelect operations in self.ops to select an arbitrary bit from that slice. Similarly, if there’s a structure somewhere in the path you can add LogicFieldSelect to the operations to subscribe a specific logical field.

logic : Logic
ops : list[LogicFieldSelect | LogicBitSelect]
class LogicFieldSelect(field: StructField[Logic])

Bases: object

Represents access operation to a field of a structure

field : StructField[Logic]
class LogicBitSelect(slice: Dimensions)

Bases: object

Represents a logic array indexing operation

slice : Dimensions

Interconnects

class InterconnectParams

Bases: MarshmallowDataclassExtensions

Base class for parameters/settings specific to a concrete interconnect type

Schema

alias of InterconnectParams

class InterconnectManagerParams

Bases: MarshmallowDataclassExtensions

Base class for manager parameters specific to a concrete interconnect type

Schema

alias of InterconnectManagerParams

class InterconnectSubordinateParams(address: ~topwrap.model.misc.ElaboratableValue = <factory>, size: ~topwrap.model.misc.ElaboratableValue = <factory>)

Bases: MarshmallowDataclassExtensions

Base class for subordinate parameters specific to a concrete interconnect type.

Transactions to addresses in range [self.address; self.address + self.size) will be routed to this subordinate.

address : ElaboratableValue.Field

The start address of this subordinate in the memory map

size : ElaboratableValue.Field

The size in bytes of this subordinate’s address space

Schema

alias of InterconnectSubordinateParams

class Interconnect(*, name: str, clock: ReferencedPort, reset: ReferencedPort, params: _IPAR, managers: Mapping[ObjectId[ReferencedInterface], _MANPAR] = {}, subordinates: Mapping[ObjectId[ReferencedInterface], _SUBPAR] = {})

Bases: ABC, Generic[_IPAR, _MANPAR, _SUBPAR]

Base class for multiple interconnect generator implementations.

Interconnects connect multiple interface instances together in a many-to-many topology, combining multiple subordinates into a unified address space so that one or multiple managers can access them.

parent : Design

The design containing this interconnect

name : VariableName
clock : ReferencedPort

The clock signal for this interconnect

reset : ReferencedPort

The reset signal for this interconnect

params : _IPAR

Interconnect-wide type-specific parameters

managers : dict[ObjectId[ReferencedInterface], _MANPAR]

Manager interfaces controlling this interconnect described as a mapping between a referenced interface in a design and the type-specific manager configuration

subordinates : dict[ObjectId[ReferencedInterface], _SUBPAR]

Subordinate interfaces subject to this interconnect described in the same format as managers

Miscellaneous

exception TranslationError

Bases: Exception

Fatal error while translating between IR and other formats

exception RelationshipError

Bases: Exception

Logic error of an IR hierarchy, like trying to double-assign a parent to an object

set_parent(child: Any, parent: Any)
VariableName

A placeholder for a future, possibly bounded type for IR object names. For example we may want to reduce possible names to only alphanumerical strings in the future.

class QuerableView(*parts: Sequence[_E])

Bases: Sequence[_E]

A lightweight proxy for exploring sequences of elements or concatenations of multiple sequences of elements in our IR, e.g. Design.components, Module.ios, etc. that has convenient methods for finding specific entries, for example by their name, which can replace such cumbersome constructs:

comp = next((c for c in design.components if c.name == “name”), None)

with:

comp = design.components.find_by_name(“name”)

find_by(filter: Callable[[_E], Any]) _E | None
find_by_name(name: str) _E | None
class ModelBase

Bases: ABC

This is a base class for all IR objects implementing common behavior that should be shared by all of them. Currently it only assigns them unique ObjectId s.

class ObjectId(obj: _T)

Bases: Generic[_T]

Represents a runtime-unique id for an IR object that can always be resolved to that object and can be used as a dictionary key/set value.

resolve() _T

Resolve this id to a concrete object instance

class ElaboratableValue(expr: int | str)

Bases: object

A WIP class aiming to represent any generic value that can be resolved to a concrete constant during elaboration.

It should be able to e.g. reference multiple Parameter s by name and perform arbitrary arithmetic operations on them.

value : str
class DataclassRepr(*, load_default: ~typing.Any = <marshmallow.missing>, missing: ~typing.Any = <marshmallow.missing>, dump_default: ~typing.Any = <marshmallow.missing>, default: ~typing.Any = <marshmallow.missing>, data_key: str | None = None, attribute: str | None = None, validate: ~typing.Callable[[~typing.Any], ~typing.Any] | ~typing.Iterable[~typing.Callable[[~typing.Any], ~typing.Any]] | None = None, required: bool = False, allow_none: bool | None = None, load_only: bool = False, dump_only: bool = False, error_messages: dict[str, str] | None = None, metadata: ~typing.Mapping[str, ~typing.Any] | None = None, **additional_metadata)

Bases: Field

Field

alias of ElaboratableValue[ElaboratableValue]

class Identifier(name: str, vendor: str = 'vendor', library: str = 'libdefault')

Bases: ModelBase

An advanced identifier of some IR objects that can benefit from storing more information than just their name. Based on the VLNV convention.

name : str
vendor : str = 'vendor'
library : str = 'libdefault'
combined() str
class FileReference(file: Path, line: int, column: int)

Bases: object

A reference to a particular location in a text file on the filesystem

file : Path
line : int
column : int
class Parameter(*, name: str, default_value: ElaboratableValue | None = None)

Bases: ModelBase

Represents a parameter definition for a HDL module

parent : Module
name : VariableName
default_value : ElaboratableValue | None

If a value for this parameter was not provided during elaboration, this default will be used.


Last update: 2025-06-11