[sw] Implement prng for random testing
This adds the ability to generate and test randomized payloads from SW,
rather than test fixed payloads. Stimulus and hence, verification
quality is better when HW is programmed and checked against with
constrained random data. This will be mainly used in DV code where both,
SW image and the HW can be probed to extract the data and perform
checks.
Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/sw/device/lib/testing/meson.build b/sw/device/lib/testing/meson.build
index 78e3c3b..e207301 100644
--- a/sw/device/lib/testing/meson.build
+++ b/sw/device/lib/testing/meson.build
@@ -15,6 +15,17 @@
)
)
+# Random number generator.
+sw_lib_testing_random = declare_dependency(
+ link_with: static_library(
+ 'random_ot',
+ sources: ['random.c'],
+ dependencies: [
+ sw_lib_testing_test_status,
+ ],
+ )
+)
+
# NOP coverage dependencies when coverage is not enabled.
sw_lib_testing_test_coverage = declare_dependency(
link_with: static_library(
diff --git a/sw/device/lib/testing/random.c b/sw/device/lib/testing/random.c
new file mode 100644
index 0000000..db970b2
--- /dev/null
+++ b/sw/device/lib/testing/random.c
@@ -0,0 +1,36 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "sw/device/lib/testing/random.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "sw/device/lib/testing/check.h"
+
+/**
+ * The polynomial co-efficients used in the 32-bit LFSR implementation.
+ *
+ * This implementation matches the RTL design at `hw/ip/prim/rtl/prim_lfsr.sv`.
+ */
+const uint32_t kLfsrCoefficients = 0x80000057;
+
+uint32_t random_gen32(void) {
+ static uint32_t lfsr = 1;
+ bool lsb = lfsr & 0x1u;
+ lfsr >>= 1;
+ if (lsb) {
+ lfsr ^= kLfsrCoefficients;
+ }
+ return lfsr;
+}
+
+uint32_t random_gen32_range(uint32_t min, uint32_t max) {
+ CHECK(max >= min);
+ uint32_t range = max - min;
+ if (range == 0) {
+ return min;
+ }
+ return min + (random_gen32() % (range + 1));
+}
diff --git a/sw/device/lib/testing/random.h b/sw/device/lib/testing/random.h
new file mode 100644
index 0000000..4a8e45a
--- /dev/null
+++ b/sw/device/lib/testing/random.h
@@ -0,0 +1,32 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_RANDOM_H_
+#define OPENTITAN_SW_DEVICE_LIB_TESTING_RANDOM_H_
+
+#include <stdint.h>
+
+/**
+ * Generate a pseudo-random unsigned integer.
+ *
+ * For testing purposes, a simple LFSR generates random numbers starting with
+ * a known seed.
+ * @return A pseudo-random 32-bit value.
+ */
+uint32_t random_gen32(void);
+
+/**
+ * Generate a random unsigned integer within a given range.
+ *
+ * This function invokes `random_gen32()` and restricts the returned value to
+ * be within the supplied range, inclusive of the range limits. Note that PRNG
+ * is not expected to produce a uniform distribution of values within the given
+ * range.
+ * @param min The lower limit of the range.
+ * @param max The upper limit of the range.
+ * @return The computed random value within the supplied range.
+ */
+uint32_t random_gen32_range(uint32_t min, uint32_t max);
+
+#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_RANDOM_H_