Gaussian Noise Generator (GNG)
Generates true Gaussian (normal) distributed noise using a hardware PRNG. Output can be mixed with an input signal to add controllable random noise.
Introduction
The Gaussian Noise Generator (GNG) block generates true Gaussian (normally distributed) noise starting from an internal Pseudo-Random Number Generator (PRNG). The output is in signed integer format and can be combined with an input signal to add controllable random noise.
This component is useful for testing signal processing chains, simulating noisy signals, or adding dithering to signals.
Pin Description
Noise amplitude control (unsigned 16-bit). Controls the standard deviation of the Gaussian distribution.
- 0x0000: No noise
- 0xFFFF: Maximum amplitude
DC offset or signal input (unsigned 16-bit). Added to the noise output: NOISE = OFFSET + GN. Use to:
- Add a constant offset to center the noise
- Mix an external signal with the generated noise Default: 0
Output data valid indicator, aligned with the sample it qualifies.
- HIGH (1): NOISE output contains valid data
- LOW (0): NOISE output is pipeline content - do not read it Goes HIGH 14 clock cycles after CE is raised or RESET released, and 144 clock cycles after power-up (the one-off start-up reset).
Properties
Seed automatically generated in order to randomized the GN Noise. A new random seed is automatically generated when the component is created
Initial seed for the PRNG: exactly 48 hex digits, loaded as the raw state of the three Tausworthe components (digits 1-16 -> INIT_Z1 >= 2, 17-32 -> INIT_Z2 >= 64, 33-48 -> INIT_Z3 >= 512). Any other 48-digit hex value is valid. A field below its minimum is an absorbing state - that component is stuck at zero for ever, and with all three below their minimum the block emits a constant instead of noise - so such a seed is refused when the property window is confirmed, and a seed already stored in an old project is replaced at compile time with a warning that names the field and prints the seed used. Use the EDIT button to generate a new valid seed.Default: A2D38976D075D4D101B52EE84DF5011DA7E13C5B609E6DF9
Usage
Algorithm Overview
The GNG uses a Combined Tausworthe Generator (CTG) to produce uniformly distributed random numbers, followed by a polynomial interpolation stage that transforms the uniform distribution into a Gaussian distribution.
The algorithm implements the inverse cumulative distribution function (CDF) of the Gaussian distribution using piecewise polynomial approximation.
Architecture
The implementation consists of three main stages:
-
Combined Tausworthe PRNG (CTG)
- Uses three 64-bit Linear Feedback Shift Registers (LFSRs)
- XOR combination produces 64-bit uniform random values
- Initialized with a proprietary seed for maximum sequence length
-
Leading Zero Detector (LZD)
- Counts leading zeros in the random value
- Maps uniform distribution to exponential-like distribution
-
Polynomial Interpolator
- 248-entry coefficient lookup table
- Second-order polynomial approximation
- Converts to Gaussian distribution with fixed-point arithmetic
Output Characteristics
The output noise follows a Gaussian distribution:
$$ f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}} $$
where:
- $\mu$ = 0 (zero mean, before offset)
- $\sigma$ is proportional to the GAIN input
The noise is generated in signed 16-bit format with approximately 11 fractional bits (s<16,11>).
Gain Control
The GAIN input controls the noise amplitude (standard deviation). It is an
unsigned fixed-point multiplier with 14 fractional bits, i.e. the noise
sample is multiplied by GAIN / 0x4000, so 0x4000 is unity gain:
| GAIN Value | Noise amplitude | 1.0 sigma reads |
|---|---|---|
| 0x0000 | no noise at all: NOISE is the OFFSET input | - |
| 0x1000 | quarter amplitude | 512 counts |
| 0x4000 | unity (the raw s<16,11> sample) | 2048 counts |
| 0x8000 | double amplitude | 4096 counts |
| 0xFFFF | about four times (maximum) | 8191 counts |
The relationship is linear, the product is truncated (not rounded) and the output sum is not saturated: with a large GAIN an extreme sample can wrap in 16 bits instead of clipping, so pick the gain from the amplitude the design needs rather than from the top of the range.
Signal Mixing
The block performs the following operation:
$$ \text{NOISE} = \text{OFFSET} + \text{GN} \times \text{GAIN} $$
where GN is the internal Gaussian noise sample. This allows:
- Adding a DC offset to the noise
- Mixing noise with an external signal (connect signal to OFFSET)
- Creating noisy versions of clean signals
Seed Configuration
The seed is exactly 48 hexadecimal digits and it is the raw initial state of the three Tausworthe components - there is no seeding logic in the hardware, the three fields are loaded as they are:
| field | hex digits | generic | must be >= |
|---|---|---|---|
| 1 | 1 - 16 | INIT_Z1 |
2 (0000000000000002) |
| 2 | 17 - 32 | INIT_Z2 |
64 (0000000000000040) |
| 3 | 33 - 48 | INIT_Z3 |
512 (0000000000000200) |
Any other 48-digit hexadecimal value is a valid seed; in particular repeated digits, three identical fields, and the three minimums themselves are all perfectly usable states.
Why each field has its own minimum. A component whose value is below its minimum has nothing above the bits its feedback discards, so its next state is zero and it is then stuck at zero for ever. The limit is per field: one field below its minimum silently reduces the generator from three components to two (period from about 2^176 down to 2^118) while the output still looks like noise, and with all three fields below their minimum the block emits a constant instead of noise.
What the tool does about it:
- the EDIT button generates a seed that always satisfies the three minimums, so an automatically generated seed is never degenerate;
- a hand-typed seed that is not 48 hexadecimal digits, or that has any field below its minimum, is refused when the property window is confirmed, with a message naming the field: a degenerate seed can no longer be saved;
- a project saved before this check existed still builds: at compile time the offending fields are replaced and the compiler prints a warning naming the field and the seed actually used. That replacement is derived from the stored seed text and from the block designator, so every build of the same project gets the same seed (the run stays reproducible, and the printed value can be pasted back into the property), while two blocks that stored the same degenerate seed get different replacements and stay independent.
Different seeds produce statistically independent sequences; the same seed always produces the same sequence, and RESET replays it from the beginning.
Timing
All the numbers below are measured on the block’s own regression run
(ci-test/ci-sim/gng_top), not estimated.
| Path | Latency |
|---|---|
| CE raised, or RESET released -> VALID and the first noise sample | 14 clock cycles |
| OFFSET -> NOISE | 1 clock cycle |
| GAIN -> NOISE | 4 clock cycles |
| Throughput | 1 sample per clock cycle (when CE = 1) |
The 14 clocks are 10 of noise engine, 3 of the GAIN multiplier and 1 of the output register; the OFFSET input only crosses that last register, which is why a signal connected to OFFSET is delayed by one clock and not by 14.
VALID is exactly aligned with the sample it qualifies: NOISE is meaningful while VALID is high and is pipeline content while VALID is low - after a RESET the arithmetic pipeline is not cleared, so the samples of the 14-clock refill are leftovers and VALID low is the only thing marking them.
Start-up reset (once per configuration)
The block resets its noise engine by itself after power-up or reconfiguration: an internal counter asserts the engine’s reset on clock 18 and releases it on clock 129, so the first valid noise sample of a configuration arrives on clock 144 (129 + the 14 clocks of the pipeline).
This warm-up happens once. The RESET pin does not repeat it: a RESET reloads the seed words and replays the sequence from its first sample after the usual 14 clocks, while the start-up counter keeps its value. In a real design the 144 clocks are over long before the first acquisition.
Resources & Timing
-
Latency: 14 clock cycles (noise path); OFFSET to NOISE 1 clock cycle
-
Throughput: 1 sample per clock cycle