SRP Protocol Version 0

For legacy SRP register links that still use version 0 framing, Rogue provides rogue.protocols.srp.SrpV0. SrpV0 converts Rogue memory transactions into SRPv0 stream frames and decodes hardware responses back into memory transaction completion.

Rogue does not re-document the SRPv0 wire format here. Use the protocol specification for packet-level details:

When To Use SrpV0

  • Use when endpoint firmware is fixed to SRPv0 framing.

  • Prefer SRP Protocol Version 3 for newer systems unless compatibility requires v0.

  • Use SRP Protocol Command instead when the link carries opcodes rather than memory transactions.

Behavior

  • Rogue can issue multiple SRPv0 requests before responses return; these are tracked as in-flight transactions by transaction ID.

  • Responses are matched by ID, so response order does not need to match request order.

  • If a response is missing, the initiating memory master times out based on the configured software timeout (see Master.setTimeout(), microseconds).

  • Late responses that arrive after timeout are treated as expired and ignored.

  • SrpV0 enforces 4-byte alignment and defaults to a 2048-byte max transaction size (from constructor memory::Slave(4, 2048)).

The class sits directly between the memory and stream interfaces. Connect it to a lower stream transport, then use the SRP object itself as the memBase for PyRogue devices or other memory clients.

Threading And Locking

  • doTransaction() and acceptFrame() can be invoked from different runtime contexts.

  • In-flight transaction matching is protected by the base memory-slave mutex.

  • Per-transaction payload/state access is protected via TransactionLock.

Logging

SrpV0 uses Rogue C++ logging.

  • Logger name: pyrogue.SrpV0

  • Unified Logging API: pyrogue.setLogLevel('SrpV0', 'DEBUG')

  • Legacy Logging API: rogue.Logging.setFilter('pyrogue.SrpV0', rogue.Logging.Debug)

  • Typical messages: transmitted request headers, received response headers, undersized frames, bad headers, expired transactions, and error tails

You can set the filter before or after constructing the SrpV0 object. Enable it before construction only if you want constructor or very early protocol-startup messages.

Python Example

The common PyRogue pattern is to construct the transport and SrpV0 inside a Root subclass, then pass the SRP object as memBase when adding devices.

import pyrogue as pr
import rogue.hardware.axi
import rogue.protocols.srp

class MyRegs(pr.Device):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.add(pr.RemoteVariable(
            name='ScratchPad',
            description='Example RW register',
            offset=0x0000,
            bitSize=32,
            mode='RW',
            base=pr.UInt,
        ))

class MyRoot(pr.Root):
    def __init__(self, dev='/dev/datadev_0', **kwargs):
        super().__init__(timeout=2.0, **kwargs)

        # Stream transport carrying SRPv0 frames.
        self.regStream = rogue.hardware.axi.AxiStreamDma(dev, 0, True)

        # SRPv0 protocol bridge.
        self.srp = rogue.protocols.srp.SrpV0()

        # Bidirectional stream connection: transport <-> SRPv0.
        self.regStream == self.srp

        # Attach register map device to SRPv0 memory slave interface.
        self.add(MyRegs(
            name='Regs',
            offset=0x00000000,
            memBase=self.srp,
            expand=True,
        ))

API Reference