Software APIs
rand_testutils.h
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_RAND_TESTUTILS_H_
6#define OPENTITAN_SW_DEVICE_LIB_TESTING_RAND_TESTUTILS_H_
7
8#include <stdint.h>
9
10#include "sw/device/lib/testing/rv_core_ibex_testutils.h"
11
12/**
13 * A random number generator testutil type.
14 *
15 * Provides ability to control and maintain a random number generator. A random
16 * number is produced via a mix of hardware-based (using on-device entropy
17 * from rv_core_ibex random registers) and software-based (an LFSR-based PRNG)
18 * approaches. The initial seed value for the PRNG is fetched from the
19 * hardware. Following that, the PRNG kicks in and supplies random values
20 * sought by the test. After a number of PRNG cycles, the LFSR can be freshly
21 * reseeded from the hardware. If this frequency is set to 0, then the PRNG is
22 * rendered disabled and random data is always fetched from the hardware.
23 *
24 * The software PRNG is faster because it consumes very few cycles compared to
25 * the hardware - it helps improve the simulation time.
26 */
27typedef struct rand_testutils_rng {
28 /**
29 * An rv_core_ibex DIF handle.
30 */
32 /**
33 * The timeout in microseconds for fetching data from the hardware.
34 */
36 /**
37 * The PRNG LFSR.
38 */
39 uint32_t lfsr;
40 /**
41 * The PRNG polynomial co-efficients.
42 */
44 /**
45 * The PRNG LFSR reseed frequency.
46 */
48 /**
49 * The LFSR operation counter. Resets on every reseed.
50 */
51 uint32_t op_counter;
52} rand_testutils_rng_t;
53
54/**
55 * A global random number generator testutil handle.
56 */
57extern rand_testutils_rng_t rand_testutils_rng_ctx;
58
59/**
60 * Initializes and returns a random number generator testutil handle.
61 *
62 * @param rv_core_ibex An rv_core_ibex DIF handle.
63 * @return The initialized timeout value.
64 */
65rand_testutils_rng_t rand_testutils_init(dif_rv_core_ibex_t *rv_core_ibex);
66
67/**
68 * Reseeds the PRNG LFSR.
69 *
70 * The LFSR value is updated later, when the caller fetches the next random
71 * data.
72 *
73 * Uses the global random number generator testutil handle
74 * `rand_testutils_rng_ctx` which is initialized in ottf_main().
75 */
76inline void rand_testutils_reseed(void) {
77 rand_testutils_rng_ctx.op_counter = UINT32_MAX;
78}
79
80/**
81 * Returns a random unsigned integer.
82 *
83 * The random number is sourced either from the LFSR-based PRNG or from the
84 * hardware, depending on the lobal random number generator testutil context
85 * settings.
86 * @return A pseudo-random 32-bit value.
87 */
88uint32_t rand_testutils_gen32(void);
89
90/**
91 * Returns a random unsigned integer within a given range.
92 *
93 * This function invokes `rand_testutils_gen32()` and restricts the returned
94 * value to be within the supplied range, inclusive of the range limits. Note
95 * that a uniform distribution of values within the given range is not
96 * guaranteed.
97 * @param min The lower limit of the range.
98 * @param max The upper limit of the range.
99 * @return The computed random value within the supplied range.
100 */
101uint32_t rand_testutils_gen32_range(uint32_t min, uint32_t max);
102
103/** Shuffles an arbitrary array of elements.
104 *
105 * The shuffling occurs in-place. The reseeding of the LFSR is temporarily
106 * turned off to allow faster runtime performance.
107 * @param array Pointer to the array being shuffled.
108 * @param size The size of each element in the array.
109 * @param length The number of elements in the array.
110 */
111void rand_testutils_shuffle(void *array, size_t size, size_t length);
112
113#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_RAND_TESTUTILS_H_