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.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)

Module contents