transactron.utils.amaranth_ext package

Submodules

transactron.utils.amaranth_ext.coding module

class transactron.utils.amaranth_ext.coding.Decoder

Bases: Elaboratable

Decode binary to one-hot.

If n is low, only the i-th bit in o is asserted. If n is high, o is 0.

Parameters
widthint

Bit width of the output.

Attributes
iSignal(range(width)), in

Input binary.

oSignal(width), out

Decoded one-hot.

nSignal, in

Invalid, no output bits are to be asserted.

__init__(width: int)
class transactron.utils.amaranth_ext.coding.Encoder

Bases: Elaboratable

Encode one-hot to binary.

If one bit in i is asserted, n is low and o indicates the asserted bit. Otherwise, n is high and o is 0.

Parameters
widthint

Bit width of the input

Attributes
iSignal(width), in

One-hot input.

oSignal(range(width)), out

Encoded natural binary.

nSignal, out

Invalid: either none or multiple input bits are asserted.

__init__(width: int)
class transactron.utils.amaranth_ext.coding.GrayDecoder

Bases: Elaboratable

Decode Gray code to binary.

Parameters
widthint

Bit width.

Attributes
iSignal(width), in

Gray code input.

oSignal(width), out

Decoded natural binary.

__init__(width: int)
class transactron.utils.amaranth_ext.coding.GrayEncoder

Bases: Elaboratable

Encode binary to Gray code.

Parameters
widthint

Bit width.

Attributes
iSignal(width), in

Natural binary input.

oSignal(width), out

Encoded Gray code.

__init__(width: int)
class transactron.utils.amaranth_ext.coding.PriorityDecoder

Bases: Decoder

Decode binary to priority request.

Identical to Decoder.

class transactron.utils.amaranth_ext.coding.PriorityEncoder

Bases: Elaboratable

Priority encode requests to binary.

If any bit in i is asserted, n is low and o indicates the least significant asserted bit. Otherwise, n is high and o is 0.

Parameters
widthint

Bit width of the input.

Attributes
iSignal(width), in

Input requests.

oSignal(range(width)), out

Encoded natural binary.

nSignal, out

Invalid: no input bits are asserted.

__init__(width: int)

transactron.utils.amaranth_ext.elaboratables module

class transactron.utils.amaranth_ext.elaboratables.ModuleConnector

Bases: Elaboratable

An Elaboratable to create a new module, which will have all arguments added as its submodules.

__init__(*args: HasElaborate, **kwargs: HasElaborate)
Parameters
*args

Modules which should be added as anonymous submodules.

**kwargs

Modules which will be added as named submodules.

class transactron.utils.amaranth_ext.elaboratables.MultiPriorityEncoder

Bases: Elaboratable

Priority encoder with more outputs

This is an extension of the PriorityEncoder from amaranth that supports more than one output from an input signal. In other words it decodes multi-hot encoded signal into lists of signals in binary format, each with the index of a different high bit in the input.

Attributes
input_widthint

Width of the input signal

outputs_countint

Number of outputs to generate at once.

inputSignal, in

Signal with 1 on i-th bit if i can be selected by encoder

outputslist[Signal], out

Signals with selected indicies, sorted in ascending order, if the number of ready signals is less than outputs_count then valid signals are at the beginning of the list.

validslist[Signal], out

One bit for each output signal, indicating whether the output is valid or not.

__init__(input_width: int, outputs_count: int)
build_tree(m: Module, in_sig: Signal, start_idx: int)
static create(m: Module, input_width: int, input: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, outputs_count: int = 1, name: Optional[str] = None) list[tuple[amaranth.hdl._ast.Signal, amaranth.hdl._ast.Signal]]

Syntax sugar for creating MultiPriorityEncoder

This static method allows to use MultiPriorityEncoder in a more functional way. Instead of creating the instance manually, connecting all the signals and adding a submodule, you can call this function to do it automatically.

This function is equivalent to:

m.submodules += prio_encoder = PriorityEncoder(cnt)
m.d.top_comb += prio_encoder.input.eq(one_hot_singal)
idx = prio_encoder.outputs
valid = prio.encoder.valids
Parameters
m: Module

Module to add the MultiPriorityEncoder to.

input_widthint

Width of the one hot signal.

inputValueLike

The one hot signal to decode.

outputs_countint

Number of different decoder outputs to generate at once. Default: 1.

nameOptional[str]

Name to use when adding MultiPriorityEncoder to submodules. If None, it will be added as an anonymous submodule. The given name can not be used in a submodule that has already been added. Default: None.

Returns
returnlist[tuple[Signal, Signal]]

Returns a list with len equal to outputs_count. Each tuple contains a pair of decoded index on the first position and a valid signal on the second position.

static create_simple(m: Module, input_width: int, input: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, name: Optional[str] = None) tuple[amaranth.hdl._ast.Signal, amaranth.hdl._ast.Signal]

Syntax sugar for creating MultiPriorityEncoder

This is the same as create function, but with outputs_count hardcoded to 1.

transactron.utils.amaranth_ext.elaboratables.OneHotSwitch(m: ModuleLike, test: Value)

One-hot switch.

This function allows one-hot matching in the style similar to the standard Amaranth Switch. This allows to get the performance benefit of using the one-hot representation.

Example:

with OneHotSwitch(m, sig) as OneHotCase:
    with OneHotCase(0b01):
        ...
    with OneHotCase(0b10):
        ...
    # optional default case
    with OneHotCase():
        ...
Parameters
mModule

The module for which the matching is defined.

testSignal

The signal being tested.

transactron.utils.amaranth_ext.elaboratables.OneHotSwitchDynamic(m: ModuleLike, test: Value, *, default: Literal[True]) Iterable[Optional[int]]
transactron.utils.amaranth_ext.elaboratables.OneHotSwitchDynamic(m: ModuleLike, test: Value, *, default: Literal[False] = False) Iterable[int]

Dynamic one-hot switch.

This function allows simple one-hot matching on signals which can have variable bit widths.

Example:

for i in OneHotSwitchDynamic(m, sig):
    # code dependent on the bit index i
    ...
Parameters
mModule

The module for which the matching is defined.

testSignal

The signal being tested.

defaultbool, optional

Whether the matching includes a default case (signified by a None).

class transactron.utils.amaranth_ext.elaboratables.RingMultiPriorityEncoder

Bases: Elaboratable

Priority encoder with one or more outputs and flexible start

This is an extension of the MultiPriorityEncoder that supports flexible start and end indexes. In the standard MultiPriorityEncoder the first bit is always at position 0 and the last is the last bit of the input signal. In this extended implementation, both can be selected at runtime.

This implementation is intended for selection from the circular buffers, so if last < first the encoder will first select bits from [first, input_width) and then from [0, last).

Attributes
input_widthint

Width of the input signal

outputs_countint

Number of outputs to generate at once.

inputSignal, in

Signal with 1 on i-th bit if i can be selected by encoder

firstSignal, in

Index of the first bit in the input. Inclusive.

lastSignal, out

Index of the last bit in the input. Exclusive.

outputslist[Signal], out

Signals with selected indicies, sorted in ascending order, if the number of ready signals is less than outputs_count then valid signals are at the beginning of the list.

validslist[Signal], out

One bit for each output signal, indicating whether the output is valid or not.

__init__(input_width: int, outputs_count: int)
static create(m: Module, input_width: int, input: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, first: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, last: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, outputs_count: int = 1, name: Optional[str] = None) list[tuple[amaranth.hdl._ast.Signal, amaranth.hdl._ast.Signal]]

Syntax sugar for creating RingMultiPriorityEncoder

This static method allows to use RingMultiPriorityEncoder in a more functional way. Instead of creating the instance manually, connecting all the signals and adding a submodule, you can call this function to do it automatically.

This function is equivalent to:

m.submodules += prio_encoder = RingMultiPriorityEncoder(input_width, outputs_count)
m.d.comb += prio_encoder.input.eq(one_hot_singal)
m.d.comb += prio_encoder.first.eq(first)
m.d.comb += prio_encoder.last.eq(last)
idx = prio_encoder.outputs
valid = prio.encoder.valids
Parameters
m: Module

Module to add the RingMultiPriorityEncoder to.

input_widthint

Width of the one hot signal.

inputValueLike

The one hot signal to decode.

firstValueLike

Index of the first bit in the input. Inclusive.

lastValueLike

Index of the last bit in the input. Exclusive.

outputs_countint

Number of different decoder outputs to generate at once. Default: 1.

nameOptional[str]

Name to use when adding RingMultiPriorityEncoder to submodules. If None, it will be added as an anonymous submodule. The given name can not be used in a submodule that has already been added. Default: None.

Returns
returnlist[tuple[Signal, Signal]]

Returns a list with len equal to outputs_count. Each tuple contains a pair of decoded index on the first position and a valid signal on the second position.

static create_simple(m: Module, input_width: int, input: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, first: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, last: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, name: Optional[str] = None) tuple[amaranth.hdl._ast.Signal, amaranth.hdl._ast.Signal]

Syntax sugar for creating RingMultiPriorityEncoder

This is the same as create function, but with outputs_count hardcoded to 1.

class transactron.utils.amaranth_ext.elaboratables.RoundRobin

Bases: Elaboratable

Round-robin scheduler. For a given set of requests, the round-robin scheduler will grant one request. Once it grants a request, if any other requests are active, it grants the next active request with a greater number, restarting from zero once it reaches the highest one. Use EnableInserter to control when the scheduler is updated.

Implementation ported from amaranth lib.

Parameters
countint

Number of requests.

Attributes
———-
requestsSignal(count), in

Set of requests.

grantSignal(range(count)), out

Number of the granted request. Does not change if there are no active requests.

validSignal(), out

Asserted if grant corresponds to an active request. Deasserted otherwise, i.e. if no requests are active.

__init__(*, count)
class transactron.utils.amaranth_ext.elaboratables.Scheduler

Bases: Elaboratable

Scheduler

An implementation of a round-robin scheduler, which is used in the transaction subsystem. It is based on Amaranth’s round-robin scheduler but instead of using binary numbers, it uses one-hot encoding for the grant output signal.

Attributes
requests: Signal(count), in

Signals that something (e.g. a transaction) wants to run. When i-th bit is high, then the i-th agent requests the grant signal.

grant: Signal(count), out

Signals that something (e.g. transaction) is granted to run. It uses one-hot encoding.

validSignal(1), out

Signal that grant signals are valid.

__init__(count: int)
Parameters
countint

Number of agents between which the scheduler should arbitrate.

transactron.utils.amaranth_ext.functions module

transactron.utils.amaranth_ext.functions.const_of(value: int, shape: amaranth.hdl._ast.Shape | amaranth.hdl._ast.ShapeCastable | int | range | type[enum.Enum]) Any
transactron.utils.amaranth_ext.functions.count_leading_zeros(s: Value) Value
transactron.utils.amaranth_ext.functions.count_trailing_zeros(s: Value) Value
transactron.utils.amaranth_ext.functions.flatten_signals(signals: amaranth.hdl._ast.Signal | amaranth.hdl._rec.Record | amaranth.lib.data.View | collections.abc.Iterable[amaranth.hdl._ast.Signal | amaranth.hdl._rec.Record | amaranth.lib.data.View | collections.abc.Iterable[SignalBundle] | collections.abc.Mapping[str, SignalBundle]] | collections.abc.Mapping[str, amaranth.hdl._ast.Signal | amaranth.hdl._rec.Record | amaranth.lib.data.View | collections.abc.Iterable[SignalBundle] | collections.abc.Mapping[str, SignalBundle]]) Iterable[Signal]

Flattens input data, which can be either a signal, a record, a list (or a dict) of SignalBundle items.

transactron.utils.amaranth_ext.functions.mod_incr(sig: Value, mod: int) Value

Perform (sig+1) % mod operation.

transactron.utils.amaranth_ext.functions.popcount(s: Value)
transactron.utils.amaranth_ext.functions.shape_of(value: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) amaranth.hdl._ast.Shape | amaranth.hdl._ast.ShapeCastable

transactron.utils.amaranth_ext.shifter module

transactron.utils.amaranth_ext.shifter.generic_shift_left(value1: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, value2: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Value

Generic left shift function.

Shift value1 left by offset bits, fill the empty space with bits from value2. The bit vectors value1 and value2 need to be of the same width. This function is used to implement shift_left and rotate_left.

Parameters
value1ValueLike

The bit vector to be shifted.

value2ValueLike

The bit vector used to fill space after shifting.

offsetValueLike

The number of bits to shift.

Returns
Value

The shifted value, the same width as value1.

transactron.utils.amaranth_ext.shifter.generic_shift_right(value1: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, value2: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Value

Generic right shift function.

Shift value1 right by offset bits, fill the empty space with bits from value2. The bit vectors value1 and value2 need to be of the same width. This function is used to implement shift_right and rotate_right.

Parameters
value1ValueLike

The bit vector to be shifted.

value2ValueLike

The bit vector used to fill space after shifting.

offsetValueLike

The number of bits to shift.

Returns
Value

The shifted value, the same width as value1.

transactron.utils.amaranth_ext.shifter.generic_shift_vec_left(data1: Sequence[_T_ValueCastable], data2: Sequence[_T_ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Sequence[_T_ValueCastable]
transactron.utils.amaranth_ext.shifter.generic_shift_vec_left(data1: Sequence[amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable], data2: Sequence[amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Sequence[Value]

Generic left shift function for bit vectors and complex data.

Given data1 and data2 which are sequences of ValueLike or ValueCastable, shift data1 left by offset bits, fill the empty space with entries from data2. The sequences data1 and value2 need to be of the same length, and their entries must be of the same width. This function is used to implement shift_vec_left and rotate_vec_left.

Parameters
data1Sequence[ValueLike | ValueCastable]

The sequence of data to be shifted.

data2Sequence[ValueLike | ValueCastable]

The sequence of data used to fill space after shifting.

offsetValueLike

The number of entries to shift.

Returns
Sequence[Value | ValueCastable]

The shifted sequence, the same length as data1.

transactron.utils.amaranth_ext.shifter.generic_shift_vec_right(data1: Sequence[_T_ValueCastable], data2: Sequence[_T_ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Sequence[_T_ValueCastable]
transactron.utils.amaranth_ext.shifter.generic_shift_vec_right(data1: Sequence[amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable], data2: Sequence[amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Sequence[Value]

Generic right shift function for bit vectors and complex data.

Given data1 and data2 which are sequences of ValueLike or ValueCastable, shift data1 right by offset bits, fill the empty space with entries from data2. The sequences data1 and value2 need to be of the same length, and their entries must be of the same width. This function is used to implement shift_vec_right and rotate_vec_right.

Parameters
data1Sequence[ValueLike | ValueCastable]

The sequence of data to be shifted.

data2Sequence[ValueLike | ValueCastable]

The sequence of data used to fill space after shifting.

offsetValueLike

The number of entries to shift.

Returns
Sequence[Value | ValueCastable]

The shifted sequence, the same length as data1.

transactron.utils.amaranth_ext.shifter.rotate_left(value: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Value

Left rotate function.

Rotate value left by offset bits.

Differs from value.rotate_left(offset) in that the shift amount is variable.

Parameters
valueValueLike

The bit vector to be rotated.

offsetValueLike

The number of bits to rotate.

Returns
Value

The rotated value, the same width as value.

transactron.utils.amaranth_ext.shifter.rotate_right(value: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Value

Right rotate function.

Rotate value right by offset bits.

Differs from value.rotate_right(offset) in that the shift amount is variable.

Parameters
valueValueLike

The bit vector to be rotated.

offsetValueLike

The number of bits to rotate.

Returns
Value

The rotated value, the same width as value.

transactron.utils.amaranth_ext.shifter.rotate_vec_left(data: Sequence[_T_ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Sequence[_T_ValueCastable]
transactron.utils.amaranth_ext.shifter.rotate_vec_left(data: Sequence[amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Sequence[Value]

Left rotate function for bit vectors and complex data.

Given data which is a sequence of ValueLike or ValueCastable, rotate data left by offset bits. The entries of data must be of the same width.

Parameters
dataSequence[ValueLike | ValueCastable]

The sequence of data to be rotated.

offsetValueLike

The number of entries to rotate.

Returns
Sequence[Value | ValueCastable]

The rotated sequence, the same length as data.

transactron.utils.amaranth_ext.shifter.rotate_vec_right(data: Sequence[_T_ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Sequence[_T_ValueCastable]
transactron.utils.amaranth_ext.shifter.rotate_vec_right(data: Sequence[amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable) Sequence[Value]

Right rotate function for bit vectors and complex data.

Given data which is a sequence of ValueLike or ValueCastable, rotate data right by offset bits. The entries of data must be of the same width.

Parameters
dataSequence[ValueLike | ValueCastable]

The sequence of data to be rotated.

offsetValueLike

The number of entries to rotate.

Returns
Sequence[Value | ValueCastable]

The rotated sequence, the same length as data.

transactron.utils.amaranth_ext.shifter.shift_left(value: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, placeholder: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable = 0) Value

Left shift function.

Shift value left by offset bits, fill the empty space with the placeholder bit (0 by default).

Differs from value.shift_left(offset) in that the shift amount is variable. Differs from value << offset in that the placeholder bit can be customized. Differs from both in that the result is of the same width as value.

Parameters
valueValueLike

The bit vector to be shifted.

offsetValueLike

The number of bits to shift.

placeholderValueLike, optional

The bit used to fill space after shifting.

Returns
Value

The shifted value, the same width as value.

transactron.utils.amaranth_ext.shifter.shift_right(value: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, placeholder: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable = 0) Value

Right shift function.

Shift value right by offset bits, fill the empty space with the placeholder bit (0 by default).

Differs from value.shift_right(offset) in that the shift amount is variable. Differs from value >> offset in that the placeholder bit can be customized.

Parameters
valueValueLike

The bit vector to be shifted.

offsetValueLike

The number of bits to shift.

placeholderValueLike, optional

The bit used to fill space after shifting.

Returns
Value

The shifted value, the same width as value.

transactron.utils.amaranth_ext.shifter.shift_vec_left(data: Sequence[_T_ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, placeholder: Optional[_T_ValueCastable]) Sequence[_T_ValueCastable]
transactron.utils.amaranth_ext.shifter.shift_vec_left(data: Sequence[amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, placeholder: Optional[Union[Value, int, Enum, ValueCastable]]) Sequence[Value]

Left shift function for bit vectors and complex data.

Given data which is a sequence of ValueLike or ValueCastable, shift data left by offset bits, fill the empty space with placeholder. The entries of data must be of the same width.

Parameters
dataSequence[ValueLike | ValueCastable]

The sequence of data to be shifted.

offsetValueLike

The number of entries to shift.

placeholderValueLike | ValueCastable, optional

The data used to fill space after shifting.

Returns
Sequence[Value | ValueCastable]

The shifted sequence, the same length as data.

transactron.utils.amaranth_ext.shifter.shift_vec_right(data: Sequence[_T_ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, placeholder: Optional[_T_ValueCastable]) Sequence[_T_ValueCastable]
transactron.utils.amaranth_ext.shifter.shift_vec_right(data: Sequence[amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable], offset: amaranth.hdl._ast.Value | int | enum.Enum | amaranth.hdl._ast.ValueCastable, placeholder: Optional[Union[Value, int, Enum, ValueCastable]]) Sequence[Value]

Right shift function for bit vectors and complex data.

Given data which is a sequence of ValueLike or ValueCastable, shift data right by offset bits, fill the empty space with placeholder. The entries of data must be of the same width.

Parameters
dataSequence[ValueLike | ValueCastable]

The sequence of data to be shifted.

offsetValueLike

The number of entries to shift.

placeholderValueLike | ValueCastable, optional

The data used to fill space after shifting.

Returns
Sequence[Value | ValueCastable]

The shifted sequence, the same length as data.

Module contents