Xilinx
Block Preview

Introduction

The 2D Histogram block calculates a two-dimensional histogram (matrix) from a pair of 16-bit input values (X, Y). Each time a STROBE pulse arrives, the block increments the bin at position (X, Y) in the internal memory.

The histogram data can be read via Resource Explorer or programmatically using the SciSDK library.

SciSDK Documentation: https://nuclearinstruments.github.io/SCISDK/

Pin Description

X Input 16 bit BIT VECTOR

16-bit input value for the X-axis (columns). Determines the horizontal position in the histogram matrix.

Typically connected to energy output from a pulse processor.

Y Input 16 bit BIT VECTOR

16-bit input value for the Y-axis (rows). Determines the vertical position in the histogram matrix.

Typically connected to PSD, time-of-flight, or other correlated parameter.

STROBE Input 1 bit BIT

Data valid strobe signal. When HIGH, the X and Y values are sampled and the corresponding bin is incremented.

Connect to the data valid signal from your processing chain.

CLK Input 1 bit BIT
Clock input signal. All operations are synchronous to this clock.
Default: Default Board Clock
RUNNING Output 1 bit BIT
Acquisition status output. HIGH when the histogram has been started via software and is actively accumulating data.
ACCEPT Output 1 bit BIT
Pulse acceptance indicator. Goes HIGH for one clock cycle when a valid (X, Y) pair has been successfully accumulated.

Properties

Property window

Name EndpointName

Set the name of the endpoint

Default: Hist2D_0

BINs X BinsX

Number of bins on X axe

Default: 64

Options: 4 8 16 32 64 128 256 512 1024 2048

BINs Y BinsY

Number of bins on Y axe

Default: 64

Options: 4 8 16 32 64 128 256 512

Number of bits Bits

Number of bits for each bin

Default: 16

Range: 8 – 32

SIM. Output SimulationOutput

What the block does with its input WHEN THE PROJECT IS SIMULATED (it has no effect on the synthesized design). None: the block does nothing, as it has always done. Event list: every strobed pair is written to a text file, one ‘<time_ns> ’ line per event, with the RAW input values. Histogram: the events are binned exactly like the real block does and the whole array is written as ‘ ’, ONE ROW PER BIN, with X running fastest. The file is written in the sim_results folder of the project and is named _.txt (just .txt on the top page).

Default: None

Options: None Event list Histogram

SIM. Flush Every SimulationFlush

How many accepted events the simulation output waits before writing to disk. VHDL has no end-of-simulation hook, so the file cannot simply be written once at the end. In ‘Histogram’ mode a flush rewrites all BINs X * BINs Y rows, so flushing after every event is very slow - at 2048 x 512 that is a million lines per event. The default of 100 trades the last partial batch for speed; lower it to 1 to never lose anything. The file is flushed anyway as soon as the event stream goes quiet, so a run with fewer events than this still produces complete data.

Default: 100

Name Name
Endpoint name for the histogram. Used to identify the component in software (Resource Explorer, SciSDK). Default: Hist2D_0
BINs X BINs X
Number of bins on the X-axis (columns). Available values: 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048. Default: 64
BINs Y BINs Y
Number of bins on the Y-axis (rows). Available values: 4, 8, 16, 32, 64, 128, 256, 512. Default: 64
Number of bits Number of bits

Bit depth per bin (8-32 bits). Determines the maximum count per bin: max_count = 2^bits - 1.

Bits Max Count
8 255
16 65,535
24 16,777,215
32 4,294,967,295

Default: 16

SIM. Output SIM. Output

What the block writes to disk when the project is simulated. It has no effect on the synthesized design.

Value File content
None Nothing is written (default).
Event list One <time_ns> <x> <y> line per strobed pair, with the raw input values.
Histogram The whole array as <x> <y> <counts>, one row per bin, X running fastest.

The histogram rows come out in memory order — the same order the hardware address y*BinsX + x walks — so the file is the flat array laid out in sequence:

  # format   : <x> <y> <counts>
0 0 2
1 0 0
2 0 1
3 0 0
0 1 0
...
  

The file is written to the project’s sim_results folder as <page>_<endpoint>.txt (<endpoint>.txt on the top page). The path is printed in the compiler log.

Binning is the hardware’s: x = min(X, BINs X - 1) and y = min(Y, BINs Y - 1) — the index saturates on the last bin, it does not wrap the way the 1D Spectrum does. Bin counters wrap at 2^bits like the BRAM ones.

Default: None

SIM. Flush Every SIM. Flush Every

How many accepted events the simulation output waits before writing to disk. VHDL has no end-of-simulation hook, so the file cannot simply be written once at the end of the run.

In Histogram mode a flush rewrites all BINs X × BINs Y rows — at 2048 × 512 that is a million lines — so flushing after every event is very slow. The default of 100 trades the last partial batch for speed; set it to 1 to never lose anything.

The file is flushed anyway as soon as the event stream goes quiet, so a run with fewer events than this still produces complete data.

Default: 100

Usage

How It Works

The 2D Histogram accumulates events in a matrix structure:

  1. X value determines the column (horizontal position)
  2. Y value determines the row (vertical position)
  3. STROBE validates the data and increments the corresponding bin
  ┌──────────────────────────────────────────────────────────────────┐
│                     2D Histogram Operation                       │
│                                                                  │
│   X (16-bit) ───►┌──────────────┐                                │
│                  │              │     ┌─────────────────────┐    │
│   Y (16-bit) ───►│  2D Histogram│────►│   Internal Memory   │    │
│                  │              │     │   (BRAM Matrix)     │    │
│   STROBE ───────►│              │     └─────────────────────┘    │
│                  └──────────────┘              │                 │
│                                                ▼                 │
│                                    Resource Explorer / SciSDK    │
└──────────────────────────────────────────────────────────────────┘
  

Typical Applications

  • PSD Matrix: Energy on X-axis, Pulse Shape Discrimination (PSD) value on Y-axis
  • Time-of-Flight: Energy vs time correlation
  • Rise Time Analysis: Pulse characteristics correlation
  • Multi-parameter coincidence: Any two correlated parameters

Memory Organization

The 2D matrix is stored in linear memory in row-major order:

Memory Layout

Address calculation: address = Y * BinsX + X

For example, with BinsX = 8:

  • (0,0) → address 0
  • (7,0) → address 7
  • (0,1) → address 8
  • (7,1) → address 15

Memory Usage

The BRAM memory consumption is:

  Memory = BinsX × BinsY × (Bits / 16) BRAM blocks
  
Configuration Memory (16-bit) Memory (32-bit)
64 × 64 4K words 8K words
128 × 128 16K words 32K words
256 × 256 64K words 128K words
512 × 512 256K words 512K words

Software Integration with SciSDK

The 2D Histogram is fully supported by SciSDK. For complete documentation see: SciSDK 2D Histogram Guide

Available Parameters

Parameter Access Description
limitmode R/W Integration mode: freerun, time_ms, total_count, peak_count
limit R/W Target threshold value (32-bit)
binsX R Number of bins on X axis
binsY R Number of bins on Y axis

Available Commands

Command Description
start Begin histogram integration
stop Pause integration
reset Clear all bins to zero
reset_counters Reset limit and statistics counters

C/C++ Example

c
  #include "SciSDK_DLL.h"

// Allocate buffer
SCISDK_2DHISTOGRAM_DECODED_BUFFER *hist2d;
SCISDK_AllocateBuffer("board0:/MMCComponents/Hist2D_0",
                      T_BUFFER_TYPE_DECODED,
                      (void**)&hist2d, _sdk);

// Configure and start
SCISDK_SetParameterString("board0:/MMCComponents/Hist2D_0.limitmode",
                          "freerun", _sdk);
SCISDK_ExecuteCommand("board0:/MMCComponents/Hist2D_0.reset", "", _sdk);
SCISDK_ExecuteCommand("board0:/MMCComponents/Hist2D_0.start", "", _sdk);

// Read data
SCISDK_ReadData("board0:/MMCComponents/Hist2D_0", (void*)hist2d, _sdk);

// Access data: hist2d->data[y * binsX + x]
for (int y = 0; y < hist2d->info.binsY; y++) {
    for (int x = 0; x < hist2d->info.binsX; x++) {
        uint32_t count = hist2d->data[y * hist2d->info.binsX + x];
        // Process count...
    }
}

// Free buffer
SCISDK_FreeBuffer("board0:/MMCComponents/Hist2D_0",
                  T_BUFFER_TYPE_DECODED,
                  (void**)&hist2d, _sdk);
  

Python Example

python
  from scisdk.scisdk import SciSDK

sdk = SciSDK()
sdk.AddNewDevice("usb:10500", "dt5560", "board0", "RegisterFile.json")

# Allocate and configure
res, buf = sdk.AllocateBuffer("board0:/MMCComponents/Hist2D_0",
                               sdk.T_BUFFER_TYPE_DECODED)
sdk.SetParameter("board0:/MMCComponents/Hist2D_0.limitmode", "freerun")
sdk.ExecuteCommand("board0:/MMCComponents/Hist2D_0.reset", "")
sdk.ExecuteCommand("board0:/MMCComponents/Hist2D_0.start", "")

# Read and display
res, buf = sdk.ReadData("board0:/MMCComponents/Hist2D_0", buf)

import matplotlib.pyplot as plt
import numpy as np

data_2d = np.reshape(buf.data, (buf.info.binsY, buf.info.binsX))
plt.imshow(data_2d, aspect='auto', origin='lower')
plt.colorbar()
plt.show()
  

Simulation Output

In the synthesized design the array is read back over the register bus by software. During a project simulation nothing reads it, so a simulated 2D Histogram showed nothing at all. With SIM. Output set, the block dumps either the raw event stream or the binned array into the project’s sim_results folder, next to the waveform dump.

The histogram is written as a plain three-column table, one row per bin, which drops straight into gnuplot (splot), numpy loadtxt or a spreadsheet.

Two notes:

  • The bin index saturates on the last bin — min(X, BINs X - 1) — which is what the hardware does (qX is forced to all ones when any bit above the axis width is set). Note this differs from the 1D Spectrum, whose index wraps.
  • Like the Spectrum’s model, this one counts one event per strobed clock. The real block needs 3 clocks per event and drops strobes that arrive while it is busy, so back-to-back strobes give a higher count in simulation than on hardware.

When the data reaches disk

The file is flushed every SIM. Flush Every accepted events (100 by default), and also as soon as the event stream goes quiet (256 write clocks with no event). The quiet-stream flush is what makes a short run — fewer events than the flush period — still come out complete; you only lose events that are still arriving when the simulation stops.

Resources & Timing

  • Latency: 2-3 clock cycles for bin update

  • Throughput: One event per clock cycle

  • Uses BRAM for histogram storage
  • Memory usage: BinsX × BinsY × ceil(bits/16) BRAM words
  • Fully supported by Resource Explorer and SciSDK
  • Row-major memory layout for efficient sequential access