Host Wire Format

Host Wire Format: Frames and Slots

The host sends rows to the card in frames of 256 words, and each row goes inside a frame as a slot tagged raw or LIL. A sparse row may be sent compressed as LIL. A row too dense for LIL is always sent raw, so no row is ever refused or cut short. Every row the card sends back is raw, because the card never compresses.

You do not build frames yourself. The host library does it when your program calls the functions in sparsr.h. This page is for readers who want to know what crosses the PCIe link, and why.

What runs today. The Sparsr VM speaks this format from the nightly SDK build of 16 September 2026 onward, as version 3 of its wire protocol. The host library's compressed write, sparsr_write_data_wmem(), still refuses a row with more than 48 non-zero lanes; sparsr_write_data_wmem_raw() stores a row of any density. The receiver for this format on the FPGA hardware is still being built.


1. Words this page uses

  • A word is 32 bits.
  • A row is one wide register: 8,192 bits, or 1,024 bytes, in 256 lanes of 32 bits.
  • A frame is the unit the host and the card exchange over PCIe.
  • A slot is one row, or one piece of a row, inside a frame.
  • LIL (list of lanes) is the compressed form of a row. It lists only the lanes that hold at least one 1-bit, each with its lane number.
  • The raw escape is the rule that a row too dense for LIL is sent raw.

2. The frame

Part Words Holds
Header 3 CMD, LEN, ADDR
Payload 253 the slots, back to back
Total 256

A frame is 256 words in both directions. CMD says what the frame does. For a frame of rows, LEN is how many payload words the slots use and ADDR is how many slots the frame holds, from 1 to 4.

A frame contains up to four slots. A sparse row compressed as LIL uses a small part of the payload, so packing several rows in one frame keeps the link from carrying mostly padding.


3. The slot

A slot starts with two words:

Word Holds
0 the tag
1 the row number
2 onwards the payload, a whole number of words

The tag is one 32-bit word:

Bits Field Values
31 to 30 kind 00 end of the slots, 01 raw, 10 LIL, 11 reserved
29 to 28 lane width 2 means 32-bit lanes, the only width used
27 to 16 count LIL: entries, 0 to 102. Raw: words in this slot
15 to 0 offset Raw: the slot's first word within the row. LIL: 0
  • The tag contains the length, so a receiver always knows where a slot ends.
  • Kind 00 ends the list, so the zero padding at the end of a frame is never read as a slot.
  • Kind 11 and any other lane width are refused.

A raw slot

A raw slot's payload is count words of the row, starting at word offset.

A LIL slot

A LIL slot's payload is count entries, then zero bytes up to a whole word. Each entry is:

Bytes Holds
1 the lane number, from 0
4 the lane's 32 bits
  • Lane numbers strictly increase. A receiver refuses a lane number that repeats, goes backwards, or is past the end of the row.
  • A LIL slot with a count of 0 is an all-zero row. It clears a row in two words.

4. Raw or LIL

A row goes as LIL when it has at most 102 non-zero lanes and its LIL payload is shorter than the raw row. Every other row goes raw.

Raw row LIL slot at 102 entries
Bytes 1,024 510
Words 256 128

Why 102. A LIL slot at its limit is 2 tag words and at most 128 payload words, which always fits the 253 payload words of one frame. So a LIL slot is never split across frames.

The encoder counts the non-zero lanes before it writes anything. The limit decides only which form a row is sent in. It never stops a row from being sent.


5. Sending a 1,024-byte raw row

A raw row is 256 words, and a frame's payload is 253, so a raw row is split into pieces. Each piece is a raw slot, and its offset says where in the row it starts.

  • The pieces' offsets are contiguous: each starts where the previous one ended.
  • Nothing may come between two pieces of one row. A piece that leaves its row unfinished must be the last slot in its frame, and the next frame must open with the next piece.
  • The card stores the row only when its last piece arrives.
  • The last piece may share its frame with other slots.

The frame does not grow to fit a whole row, because the card's receive buffers are 256 words.


6. Storing a slot on the card

Destination What the card does
XMEM Stores the slot as it arrived, raw or LIL
WMEM Expands a LIL slot to a raw row, or stores a raw slot as it is

The card checks a whole frame before it stores any of it. A slot that does not parse, a LIL entry that breaks the rules above, a piece that does not continue the row in progress, or a header that disagrees with the slots refuses the whole frame. A row number past the end of the memory refuses only that slot.

Rows come back raw. When the host reads rows, each answer frame contains raw slots only, split into pieces in the same way.

The card has one LIL decoder, on the path into WMEM. The DMA uses the same decoder when it copies a LIL row from XMEM into WMEM, so no row is re-encoded on the card. See WMEM, XMEM and the DMA.


See also