How to Create a Pseudo-Random Number Generator (PRNG)
Overview
A Pseudo-Random Number Generator (PRNG) produces sequences of numbers that mimic randomness, making it essential for encryption, gaming, simulations, and other embedded applications. PRNGs are efficient, repeatable, and ideal for hardware-constrained environments.
This example demonstrates a PRNG using the Configurable Logic Block (CLB) and Serial Peripheral Interface (SPI) peripheral, with the SPI acting as a shift register and the CLB generating the Linear Feedback Shift Register (LFSR) tap feedback and control signals. This hardware-based approach enables continuous, efficient pseudo-random number generation without burdening the CPU.
PRNG using LFSR and SPI:
The figure shows an 8-stage LFSR-4 with a cycle size of 255, using XOR gates for the feedback path. Because XOR-based LFSRs cannot transition out of the all-zero state, the sequence will lock up if it ever reaches this condition. To prevent this, a simple seeding mechanism is used to ensure the LFSR always starts in a valid non-zero state, enabling proper operation and a full sequence cycle.
8-stage LFSR with feedback taps at positions 8, 6, 5, and 4:
Requirements:
- CLB Peripheral
- SPI Peripheral
Procedure
Configure the CLB to generate the logic needed for the PRNG and the 8-bit LFSR submodule. Refer to the block diagram as a guide to ensure proper implementation.
Select a Clock Source for the CLB
The clock source used in this implementation is HFINTOSC. However, other sources, such as LFINTOSC, can also be used without causing issues
Configure SPI as a Host with the following configuration:
- Mode 1
Assign the clock signal inputs to a stable source, such as MFINTOSC32 kHz, and connect the output pins to the appropriate SPI pins (SS, SDI, and SCK).
Verify the Design
Confirm the PRNG functionality by observing the output through your chosen method to ensure it operates as expected.
Results
The PRNG successfully generates pseudo-random numbers, verified by the outputs on the SPI pins (SS, SDI, and SCK) and observed over Universal Asynchronous Receiver Transmitter (UART). The numbers are read using MCC-generated SPI driver APIs when triggered by the on-board switch press, demonstrating consistent and reliable pseudo-random behavior. For users employing custom Application Programming Interfaces (APIs) or direct register access, the process can be adapted accordingly.
The following code snippet demonstrates the process, showing how the SPI module is initialized and how data is read on a user-triggered event. This is further illustrated in the results image below, displaying the pseudo-random numbers captured during testing.
{
SYSTEM_Initialize();
SPI_Open(CLIENT_CONFIG);
__delay_ms(100);
while(1)
{
if (SWITCH_GetValue () == 0)
{
if (SPI1_IsRXReady() == true ) printf (“\n\rRead byte: %x",
SPI1_ByteRead());
}
}
}