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  */
27 typedef struct rand_testutils_rng {
28  /**
29  * An rv_core_ibex DIF handle.
30  */
31  dif_rv_core_ibex_t *rv_core_ibex;
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  */
47  uint32_t reseed_frequency;
48  /**
49  * The LFSR operation counter. Resets on every reseed.
50  */
51  uint32_t op_counter;
53 
54 /**
55  * A global random number generator testutil handle.
56  */
57 extern 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  */
65 rand_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  */
76 inline 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  */
88 uint32_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  */
101 uint32_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  */
111 void rand_testutils_shuffle(void *array, size_t size, size_t length);
112 
113 #endif // OPENTITAN_SW_DEVICE_LIB_TESTING_RAND_TESTUTILS_H_