ao_rngp.h
Pseudo-random number generator

Notes

The pseudo-random number generator generates numbers by generating a sequence of PLEN bits.

The numbers are generated either continuously (RNGCON.CONT = 1) or after reading the RNGNUMGEN register (RNGCON.CONT = 0).

Each new bit is shifted into the RNGNUMGEN register from the left at position PLEN - 1.

New bit → RNGNUMGEN2RNGNUMGEN1 → Old bit.

Consequently, the generator polynomial coefficients appear in the RNGPOLY register in reverse order.

RNGPOLY1 bit 0 is the coefficient of the term \(x^(\texttt{PLEN})\).

RNGPOLY1 bit 1 is the coefficient of the term \(x^(\texttt{PLEN} - 1)\).

RNGPOLY1 bit 2 is the coefficient of the term \(x^(\texttt{PLEN} - 2)\).

RNGPOLY1 bit 31 is the coefficient of the term \(x^(\texttt{PLEN} - 31)\).

RNGPOLY2 bit 0 is the coefficient of the term \(x^(\texttt{PLEN} - 32)\).

RNGPOLY2 bit 1 is the coefficient of the term \(x^(\texttt{PLEN} - 33)\).

RNGPOLY2 bit 31 is the coefficient of the term \(x^(\texttt{PLEN} - 63)\).

Example

ao_leds_t ld;
ao_leds_t le;
uint64_t v;

True random number generator.

Wait until 42 bits have been generated.

ao_rngt_enable();

while (ao_rngt_bits() < 42);

Pseudo-random number generator.

Set the number of bits to 42. Set the polynomial to \(x^{42} + x^{41} + x^{20} + x^{19} + 1\).

ao_rngp_bits_set(42);

ao_rngp_poly_lo_set(0x00C00003);
ao_rngp_poly_hi_set(0x00000000);

Seed by loading the value from the true random number generator.

ao_rngp_seed_true();

ao_rngp_enable();

Loop.

while (1)
{
    // Read the random number.
    v = ao_rngp_value();

    // LEDs.
    le = AO_LEDS_NONE;
    ld = AO_LEDS_NONE;

    if (v & (1 << 0)) { le |= AO_LEDS_0; } else { ld |= AO_LEDS_0; }
    if (v & (1 << 1)) { le |= AO_LEDS_1; } else { ld |= AO_LEDS_1; }
    if (v & (1 << 2)) { le |= AO_LEDS_2; } else { ld |= AO_LEDS_2; }

    ao_leds_enable(le);
    ao_leds_disable(ld);

    // We need to wait at least 42 clock cycles 
    // before reading the next random number.
    ao_spin(AO_MILLISECONDS(100));
}

Include

stdint.h
xc.h

Functions

ao_rngp_bits

#define ao_rngp_bits() (RNGCONbits.PLEN)

Gets the maximum number of bits to generate.

ao_rngp_continuous_disable

ao_rngp_continuous_enable

#define ao_rngp_continuous_disable() { RNGCONbits.CONT = 0; }
#define ao_rngp_continuous_enable()  { RNGCONbits.CONT = 1; }

Disables or enables, respectively, the continuous generation of random numbers. If enabled, the generation of a new random number will be triggered automatically when the generation of the previous number has finished. If disabled, the generation of a new random number must be triggered by reading the previously generated number.

ao_rngp_disable

ao_rngp_endable

#define ao_rngp_disable() { RNGCONbits.PRNGEN = 0; }
#define ao_rngp_enable()  { RNGCONbits.PRNGEN = 1; }

Disables or enables, respectively, the pseudo-random number generator.

ao_rngp_poly

#define ao_rngp_poly()            \
(                                 \
    ((uint64_t) RNGPOLY2 << 32) | \
     (uint64_t) RNGPOLY1          \
)

Gets the generator polynomial.

ao_rngp_poly_hi

ao_rngp_poly_lo

#define ao_rngp_poly_hi() (RNGPOLY2)
#define ao_rngp_poly_lo() (RNGPOLY1)

Gets the 32 most or least significant bits, respectively, of the generator polynomial.

ao_rngp_seed

#define ao_rngp_seed(x) ao_rngp_set_value(x)

Sets the seed.

ao_rngp_seed_hi

ao_rngp_seed_lo

#define ao_rngp_seed_hi(x) ao_rngp_set_value_hi(x)
#define ao_rngp_seed_lo(x) ao_rngp_set_value_lo(x)

Sets the 32 most or least significant bits, respectively, of the seed.

ao_rngp_seed_true

#define ao_rngp_seed_true(x) \
{                            \
    RNGCONbits.LOAD = 1;     \
}

Sets up to load the value generated by true random number generator as a seed to the pseudo-random number generator.

ao_rngp_set_bits

#define ao_rngp_set_bits(x)           \
{                                     \
    RNGCONbits.PLEN = (uint32_t) (x); \
}

Sets the maximum number of bits to generate.

ao_rngp_set_poly

#define ao_rngp_set_poly(x)                                         \
{                                                                   \
    RNGPOLY2 = (uint32_t) (((uint64_t) (x) >> 32) & 0xFFFFFFFFULL); \
    RNGPOLY1 = (uint32_t) (((uint64_t) (x) >>  0) & 0xFFFFFFFFULL); \
}

Sets the generator polynomial.

ao_rngp_set_poly_hi

ao_rngp_set_poly_lo

#define ao_rngp_set_poly_hi(x) { RNGPOLY2 = (uint32_t) (x); }
#define ao_rngp_set_poly_lo(x) { RNGPOLY1 = (uint32_t) (x); }

Sets the 32 most or least significant bits, respectively, of the generator polynomial.

ao_rngp_set_value

#define ao_rngp_set_value(x)                                          \
{                                                                     \
    RNGNUMGEN2 = (uint32_t) (((uint64_t) (x) >> 32) & 0xFFFFFFFFULL); \
    RNGNUMGEN1 = (uint32_t) (((uint64_t) (x) >>  0) & 0xFFFFFFFFULL); \
}

Sets the generated value.

ao_rngp_set_value_hi

ao_rngp_set_value_lo

#define ao_rngp_set_value_hi(x) { RNGNUMGEN2 = (uint32_t) (x); }
#define ao_rngp_set_value_lo(x) { RNGNUMGEN1 = (uint32_t) (x); }

Sets the 32 most or least significant bits, respectively, of the generated value.

ao_rngp_value

#define ao_rngp_value()             \
(                                   \
    ((uint64_t) RNGNUMGEN2 << 32) | \
     (uint64_t) RNGNUMGEN1          \
)

Gets the generated value.

ao_rngp_value_hi

ao_rngp_value_lo

#define ao_rngp_value_hi() (RNGNUMGEN2)
#define ao_rngp_value_lo() (RNGNUMGEN1)

Gets the 32 most or least significant bits, respectively, of the generated value.