Custom Packet
User-defined packet readout block with graphical packet structure editor. Implements a FIFO-based list mode transfer with customizable data format.
Introduction
The Custom Packet block enables list mode data transfer with a fully customizable packet format. Using a graphical Packet Creator tool, you define the exact structure of data packets that are pushed into an output FIFO and transferred to the host PC.
The packet data can be read via Resource Explorer (with file dump capability) or programmatically using the SciSDK library.
SciSDK Documentation: https://nuclearinstruments.github.io/SCISDK/
Pin Description
Packet trigger input. A rising edge latches all INx values and initiates packet transfer to the FIFO.
Ignored while BUSY is HIGH.
User-defined input signals. The number and size of inputs is determined by the Packet Layout configuration.
All inputs are latched simultaneously on the rising edge of START. Data must be valid one clock cycle after START.
Properties
Set the name of the endpoint
Default: CP_0
Set the number of samples stored for each acquisition
Default: 1024
Options: 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288
Packet Layout
What the block writes to disk WHEN THE PROJECT IS SIMULATED (no effect on the synthesized design). None: nothing is written, and no simulation code is generated at all. Single file: every packet built goes into one file, one after the other. Multi file per packet: one file per packet. The files are written in the sim_results folder of the project, named after
Default: None
Options: None Single file Multi file per packet
How the packet words are written. Binary - little endian (default): a raw byte stream, 4 bytes per 32-bit word, least significant byte first. No header, no timestamp: feed it straight to a decoder. Extension .bin Binary - big endian: the same, most significant byte first - this is the on-the-wire order most packet decoders expect. Hex text: one row per packet, ‘<time_ns>
Default: Binary - little endian
Options: Binary - little endian Binary - big endian Hex text
Stop capturing after this many packets. The builder free-runs in simulation, so this is what keeps a long run from filling the disk - or, in ‘Multi file per packet’ mode, from producing a huge number of files. 0 means no limit.
Default: 1024
Output FIFO size in 32-bit words. Available values: 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288.
Larger buffers reduce the risk of overflow but use more FPGA resources. Default: 1024
Opens the Packet Creator graphical editor. Define the packet structure by adding rows and elements.
Each row is 32 bits. Elements can be:
- Constant: Fixed header/sync value
- Timecode: Internal timestamp
- Packet Counter: Sequential number
- Input: Data from input pins
- Packet Size: Total packet length
Multiple elements can share a row if their combined size ≤ 32 bits. Use slicing for inputs larger than 32 bits.
What the block writes to disk when the project is simulated. It has no effect on the synthesized design — with None the simulation code is not even generated.
| Value | Effect |
|---|---|
| None | Nothing is written (default). |
| Single file | Every packet built goes into one file, one after the other. |
| Multi file per packet | One file per packet. |
Files go to the project’s sim_results folder, named after <page>_<endpoint> plus
_pk<n> in the per-packet mode. The exact paths are printed in the compiler log.
In a simulation nobody writes CONFIG to arm the builder and nobody drains the FIFO,
so the block starts itself and its FIFO is drained as fast as it fills — no
packet is lost to FIFO_FULL.
Default: None
How the packet words are written.
| Value | File | Content |
|---|---|---|
| Binary - little endian | .bin |
Raw byte stream, 4 bytes per 32-bit word, least significant byte first. |
| Binary - big endian | .bin |
The same, most significant byte first — the on-the-wire order most packet decoders expect. |
| Hex text | .txt |
One row per packet: <time_ns> <w0> <w1> …, each word as 8 hex digits. |
The binary formats are a bare stream — no header, no timestamp, no padding — so
the file can be fed straight to a decoder. The hex format is text, carries a header
and the ns timestamp of the first word of every packet, and marks a nibble holding
X/U as X rather than silently zeroing it.
Default: Binary - little endian
Usage
How It Works
The Custom Packet operates as follows:
- When START goes HIGH, all input signals are latched simultaneously
- The latched data is packaged according to your defined format
- The packet is pushed into the output FIFO
- The PC reads packets from the FIFO via USB/Ethernet
┌──────────────────────────────────────────────────────────────────┐
│ Custom Packet Data Flow │
│ │
│ IN0 ────────►┌──────────────┐ │
│ IN1 ────────►│ │ ┌─────────────┐ │
│ IN2 ────────►│ Packet │────►│ FIFO │────► PC │
│ ... │ Builder │ │ Buffer │ │
│ START ─────►│ │ └─────────────┘ │
│ └──────────────┘ │
│ ▲ │
│ │ │
│ Packet Layout Definition │
└──────────────────────────────────────────────────────────────────┘
Important: The module latches inputs on the START rising edge. Data must be valid one clock cycle after START is issued.
Packet Creator Tool
The Packet Creator is a graphical editor for defining the packet structure. Access it by clicking the Edit button next to the “Packet Layout” property.
Packet Structure
Each packet consists of one or more 32-bit rows. Each row can contain:
| Element Type | Description |
|---|---|
| Constant | Fixed 32-bit value (useful as header/sync word) |
| Timecode | Internal timestamp counter |
| Packet Counter | Sequential packet number |
| Packet Size | Total packet size in words |
| Input | Data from input pins |
Adding Rows and Inputs
- Add a new row: Click “Add Row” and select the row number (each row = 32 bits)
- Add an element: Click “Add Input/Constant/Timecode/etc.” and specify the size
- Multiple elements per row: If combined size ≤ 32 bits, multiple elements fit in one row
Data is enqueued in the output FIFO in row order:
Multiple Inputs Per Row
Multiple inputs can fit in a single row if their combined size ≤ 32 bits:
Combining Inputs with Constants
Inputs can be combined with constant values in the same row:
Example: Simple Packet
Row 0: [CONSTANT: 0xFFFFFFFF] ← Header (sync word)
Row 1: [TIMECODE: 32 bits] ← Timestamp
Row 2: [PACKET_COUNTER: 32 bits] ← Sequence number
Row 3: [IN0: 16 bits][IN1: 16 bits] ← Two 16-bit inputs
Row 4: [IN2: 32 bits] ← One 32-bit input
Handling Large Inputs (Slicing)
If an input is larger than 32 bits, or if alignment requires it, you can slice the input across multiple rows:
Input: ENERGY (48 bits)
Row 3: [ENERGY[31:0]] ← Lower 32 bits
Row 4: [ENERGY[47:32]] ← Upper 16 bits + padding
Right-click on a bar in the Packet Creator to access the context menu:
From the context menu you can:
- Edit the slice range (e.g., [31:0], [47:32])
- Move the element to a different row
- Adjust size and alignment
Multi-Board Synchronization
The Custom Packet includes synchronization inputs for multi-board setups:
| Input | Function |
|---|---|
| SYNC_TRIG_IN | External trigger that increments the trigger counter |
| SYNC_RESET_IN | Resets trigger counter and external timestamp |
| SYNC_CLK_IN | External timestamp clock |
These allow multiple boards to share a common timebase and trigger numbering.
Status Outputs
| Output | Description |
|---|---|
| BUSY | HIGH while packet transfer is in progress. Inputs and START are ignored. |
| FIFO_FULL | HIGH if buffer overrun occurred (data loss). |
| RUN | HIGH when acquisition is enabled by software. |
Software Integration with SciSDK
The Custom Packet is fully supported by SciSDK. For complete documentation see: SciSDK Custom Packet Guide
Resource Explorer can also read and dump Custom Packet data to file.
Available Parameters
| Parameter | Access | Description |
|---|---|---|
acq_len |
R/W | Maximum samples per FIFO read (default: 1024) |
acq_mode |
R/W | blocking or non-blocking |
timeout |
R/W | Timeout in milliseconds (blocking mode) |
data_processing |
R/W | raw or decode mode |
Available Commands
| Command | Description |
|---|---|
start |
Begin acquisition |
stop |
Stop acquisition |
reset |
Reset counters and FIFO |
flush |
Clear FIFO content |
C/C++ Example
c
#include "SciSDK_DLL.h"
// Allocate decoded buffer (1024 packets)
SCISDK_CP_DECODED_BUFFER *buffer;
SCISDK_AllocateBufferSize("board0:/MMCComponents/CP_0",
T_BUFFER_TYPE_DECODED,
(void**)&buffer, _sdk, 1024);
// Configure decode mode
SCISDK_SetParameterString("board0:/MMCComponents/CP_0.data_processing",
"decode", _sdk);
// Start acquisition
SCISDK_ExecuteCommand("board0:/MMCComponents/CP_0.start", "", _sdk);
// Read data
while (running) {
int ret = SCISDK_ReadData("board0:/MMCComponents/CP_0",
(void*)buffer, _sdk);
if (ret == NI_OK) {
// Process buffer->data...
for (int i = 0; i < buffer->info.valid_data; i++) {
// Access packet fields
}
}
}
// Stop and free
SCISDK_ExecuteCommand("board0:/MMCComponents/CP_0.stop", "", _sdk);
SCISDK_FreeBuffer("board0:/MMCComponents/CP_0",
T_BUFFER_TYPE_DECODED, (void**)&buffer, _sdk);
Python Example
python
from scisdk.scisdk import SciSDK
sdk = SciSDK()
sdk.AddNewDevice("usb:10500", "dt5560", "board0", "RegisterFile.json")
# Allocate buffer
res, buf = sdk.AllocateBufferSize("board0:/MMCComponents/CP_0",
sdk.T_BUFFER_TYPE_DECODED, 1024)
# Configure
sdk.SetParameter("board0:/MMCComponents/CP_0.data_processing", "decode")
# Start and read
sdk.ExecuteCommand("board0:/MMCComponents/CP_0.start", "")
while True:
res, buf = sdk.ReadData("board0:/MMCComponents/CP_0", buf)
if res == 0:
for packet in buf.data:
# Process packet...
print(packet)
Best Practices
- Use a header constant: Start packets with a fixed value (e.g., 0xFFFFFFFF) for synchronization
- Include timecode: Essential for event timing and correlation
- Include packet counter: Helps detect data loss
- Monitor FIFO_FULL: Check for buffer overruns
- Size appropriately: Set FIFO size based on expected event rate
Simulation Output
In the synthesized design software arms the packet builder by writing CONFIG, and
drains the output FIFO over the register bus. During a project simulation neither
happens, so the builder would never start and nothing would be visible. With
SIM. Output set, the generated core arms itself, keeps its FIFO drained, and writes
every packet it assembles into the project’s sim_results folder.
The capture taps the FIFO write side, i.e. exactly the words the packet builder produces, and groups them by the packet length taken from the Packet Layout. What lands in the file is therefore the packet as designed — header constants, timestamps, counters and input fields already assembled — not a reconstruction.
This block has no separate simulation model: the same generated core is used for synthesis and simulation. The dump code is textio based and not synthesisable, so it is emitted only when SIM. Output is set; with None the generated VHDL is byte-for-byte the file this block has always produced.
Files are closed after every packet, so the data on disk is complete even if the simulation is stopped in the middle of the run, and an unwritable path degrades to one warning instead of killing the simulation.
Only Xilinx targets carry the dump code; on Intel targets the compiler warns that SIM. Output is not supported.
Resources & Timing
-
Latency: 1 clock cycle from START to data latch
-
Throughput: Limited by FIFO read speed and packet size
- Uses BRAM for FIFO storage
- Supports DMA on X5560 family (16 MWORD DDR3 FIFO)
- Data readable via Resource Explorer or SciSDK
- Resource Explorer can dump packets to file