Xilinx
Block Preview

Introduction

The Programmable Random Generator draws random values from an arbitrary distribution using inverse transform sampling, exactly like the fixed dist_gen block: a uniform u is drawn and a binary search over the cumulative histogram returns the bin u falls into.

The difference is where the table lives. Here it is a RAM written through CDF_ADDR / CDF_DATA / CDF_WE, so software can load a new distribution whenever it likes – per measurement, per channel, or from a spectrum just acquired. There is no designer: the table is whatever you write.

Pin Description

CLK Input 1 bit BIT
System clock. Default: Acquisition clock.
Default: Default Board Clock
RESET Input 1 bit BIT
Synchronous reset, active high. Flushes the queue and restarts the random sequence from the seed. Does NOT clear the CDF RAM.
Default: Default Board Reset
EN Input 1 bit BIT
Enable. While low the generator stops refilling the queue. Tied to ‘1’ when left unconnected.
GET Input 1 bit BIT
One-clock pulse requesting the next sample. The sample appears on OUT, with DV high, on the FOLLOWING clock. Tied to ‘0’ when left unconnected.
CDF_ADDR Input log2(Bins) bit BIT VECTOR
Table write address, log2(Bins) bits.
CDF_DATA Input CdfWidth bit BIT VECTOR
Table write data: one cumulative entry, CdfWidth bits.
CDF_WE Input 1 bit BIT
Write enable: on a rising clock edge with CDF_WE high, CDF_DATA is stored at CDF_ADDR. Tied to ‘0’ when left unconnected.
TBL_RDY Input 1 bit BIT
Table valid. While low the engine produces nothing. Raise it once the whole table has been written. Tied to ‘0’ when left unconnected, so an unconfigured block stays idle.
OUT Output OutputWidth bit BIT VECTOR
The random sample, updated on the clock after each accepted GET and held until the next one.
DV Output 1 bit BIT
Data valid strobe: high for exactly one clock, on the clock after an accepted GET, to mark that OUT carries a new sample.
READY Output 1 bit BIT
High while at least one sample is queued, i.e. a GET on this clock will succeed. Use it to gate GET and avoid UNDERFLOW.
UNDERFLOW Output 1 bit BIT
Pulses for one clock when GET arrived on an empty queue. Registered, so it appears one clock after that GET.

Properties

Property window

Bins Bins

Number of CDF entries. Sets the CDF_ADDR width and the search length (log2(bins)+2 clocks per sample).

Number of entries in the cumulative table: 256, 512, 1024, 2048, 4096, 8192 or 16384, default 4096. Sets the CDF_ADDR width and the sampling rate (log2(Bins) + 2 clocks per sample).

Default: 4096

Options: 256 512 1024 2048 4096 8192 16384

Output Width OutputWidth

Width of the OUT port. Must be at least log2(Bins); the bits below the bin index carry the sub-bin dither.

Width of the OUT port, 8 to 32, default 16. Must be at least log2(Bins) or the bin index would not fit; this is checked when the property window is confirmed.

Default: 16

Options: 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

CDF Word Width CdfWidth

Width of one CDF entry and of the CDF_DATA bus. The table must end at 2^CdfWidth-1.

Width of one table entry and of the CDF_DATA bus: 16, 24 or 32, default 32. The table must end at 2^CdfWidth - 1. Wider means finer probability resolution and more BRAM.

Default: 32

Options: 16 24 32

FIFO Depth FifoDepth

Depth of the output first-word-fall-through queue. The generator stalls while it is full.

Depth of the output queue, 16 to 4096, default 64. The generator stalls while it is full.

Default: 64

Options: 16 32 64 128 256 512 1024 2048 4096

Output Mapping OutputMapping

BIN INDEX: OUT is the bin number itself, 0..Bins-1 (1024 bins on a 16-bit port give 0..1023). RESCALED: the index is stretched over the whole output width, 0..2^OutputWidth-1, with the spare low bits filled by the sub-bin dither.

How the bin index becomes the value on OUT:

  • BIN INDEX – OUT is the bin number itself, 0..Bins-1. The port can be wider than the numbers it carries (1024 bins on 16 bits give 0..1023).
  • RESCALED – the index is stretched over the whole output width, OUT = index x 2^(OutputWidth-log2(Bins)) + dither, so 1024 bins on 16 bits give 0..65535 in steps of 64.

Default: RESCALED

Options: BIN INDEX RESCALED

Output Format OutputFormat

UNSIGNED: 0..Bins-1 (bin index) or 0..2^OutputWidth-1 (rescaled). SIGNED: the same span shifted to sit on zero, two’s complement – -Bins/2..Bins/2-1 (bin index) or -2^(OutputWidth-1)..2^(OutputWidth-1)-1 (rescaled).

How the span is interpreted:

  • UNSIGNED – 0..Bins-1 or 0..2^OutputWidth-1.
  • SIGNED – the same span shifted onto zero, two’s complement: -Bins/2..Bins/2-1 or -2^(OutputWidth-1)..2^(OutputWidth-1)-1.

Default: UNSIGNED

Options: UNSIGNED SIGNED

Sub-bin Dithering SubBinDithering

Fill the OutputWidth-log2(Bins) bits below the bin index with random bits. A histogram means constant density inside a bin, so this is the correct reconstruction; without it the output is a comb of discrete codes.

Only meaningful with OutputMapping = RESCALED, which is the only case with bits below the index; ignored for BIN INDEX.

  • YES – fill the OutputWidth - log2(Bins) bits below the bin index with random bits. A histogram means constant density inside a bin, so this is the correct reconstruction.
  • NO – those bits are zero and the output is a comb of Bins discrete codes with gaps between them.

Default: YES

Options: YES NO

RNG Seed (hex) Seed

Initial state of the xorshift64 generator, 16 hex digits. Must not be zero (a zero state locks the generator up); zero is replaced automatically. Two blocks with the same seed produce the same stream.

Initial state of the 64-bit xorshift generator, 16 hex digits, default 123456789ABCDEF0. Must not be zero (a zero state locks a xorshift generator up); zero is replaced automatically. Two blocks with the same seed produce the same stream – give independent channels different seeds.

Default: 123456789ABCDEF0

Usage

What software must write

The already cumulated and normalised table, not the raw histogram. Nothing in the hardware cumulates, clears or normalises anything:

      cdf(i) = round( cumsum(hist)(i) / cumsum(hist)(NBINS-1)
                    * (2^CdfWidth - 1) )
  

so that cdf is non-decreasing and cdf(Bins-1) = 2^CdfWidth - 1. All Bins entries must be written; entries never written keep whatever the RAM powered up with.

Bin i is selected when cdf(i-1) <= u < cdf(i), with cdf(-1) taken as zero. Bins whose cdf equals the previous entry have zero probability and are never produced – that is how a histogram with empty channels is represented.

Loading sequence

      1. hold TBL_RDY low                 -> the engine stays idle, DV low
    2. write all Bins entries: drive CDF_ADDR / CDF_DATA, pulse CDF_WE
       (one word per clock, any order)
    3. raise TBL_RDY                    -> the engine starts filling the queue
  

Lowering TBL_RDY again stops the engine, so a table can be swapped live. Samples already queued are not flushed; pulse RESET as well if the old distribution must not appear at all.

TBL_RDY defaults to '0' when the pin is left unconnected, so an unconfigured block stays quiet instead of streaming values from an all-zero (invalid) table.

Output value, rate and queue

Identical to the fixed variant:

  • OUT follows OutputMapping and OutputFormat. BIN INDEX puts the bin number itself on the port (0..Bins-1, so 1024 bins on a 16-bit port give 0..1023); RESCALED stretches it over the whole width (0..2^OutputWidth-1) with the spare low bits filled by SubBinDithering. SIGNED shifts either span onto zero, so the four combinations give 0..1023, -512..511, 0..65535 or -32768..32767.
  • one sample every log2(Bins) + 2 clocks – the cost of the binary search.
  • request / strobe queue: GET at clock N delivers the sample on OUT at clock N+1 together with a one-clock DV strobe. READY says whether a GET will succeed, UNDERFLOW pulses one clock after a GET on an empty queue (and DV does not strobe), and the generator stalls while the queue is full.

Choosing the CDF width

CdfWidth is the resolution of the probabilities, not of the values. A bin whose probability is smaller than 1 / 2^CdfWidth rounds away to zero and is never produced. With 16384 bins and a spectrum spanning four decades, 16 bits is not enough – use 32.

Typical applications

  • Replaying a spectrum measured moments earlier, without recompiling.
  • Per-channel distributions in a multi-channel emulator.
  • Sweeping a parameter (peak position, resolution, background level) from software during a firmware test campaign.

Resources & Timing

  • Latency: log2(Bins) + 2 clock cycles per sample (14 with the default 4096 bins)

  • Throughput: one sample every log2(Bins) + 2 clocks; the FIFO decouples the reader

No DSP and no multiplier. The table costs ceil(CdfWidth/36) x ceil(Bins/1024) BRAM36 plus the output FIFO. Pure VHDL, no HLS. Shares the engine (dist_gen_core) with the fixed-distribution block; the random source is a 64-bit xorshift generator and the output queue is a Xilinx XPM FIFO in standard read mode (one clock of read latency), which is what gives the GET-then-strobe protocol.