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
00ends the list, so the zero padding at the end of a frame is never read as a slot. - Kind
11and 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
- Architecture - the host, the card, and where data lives.
- Memory Map - every memory, its address and its size.
- Glossary - the words this page uses.