// 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/rand_testutils.h"

#include <stdbool.h>
#include <stdint.h>

#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/dif/dif_rv_core_ibex.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/rv_core_ibex_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"

#include "hw/top_earlgrey/sw/autogen/top_earlgrey.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`.
 */
static const uint32_t kLfsrPolynomialCoefficients = 0x80000057;

/**
 * The default timeout in usecs for fetching data from the entropy source.
 */
static const uint32_t kEntropyFetchTimeoutMicros = 1000;

rand_testutils_rng_t rand_testutils_init(dif_rv_core_ibex_t *rv_core_ibex) {
  CHECK(rv_core_ibex != NULL);
  // For the simulation platforms (DV and Verilator), the LFSR reseed frequency
  // is arbitrarily set to 255. The test may choose to update this value if
  // needed.
  rand_testutils_rng_t ctx = (rand_testutils_rng_t){
      .rv_core_ibex = rv_core_ibex,
      .entropy_fetch_timeout_usec = kEntropyFetchTimeoutMicros,
      .lfsr = 0xdeadbeef,  // Arbitrary.
      .polynomial_coefficients = kLfsrPolynomialCoefficients,
      .reseed_frequency = 256,
      .op_counter = UINT32_MAX};
  // For non-runtime-sensitive simulations (for example, using FPGA or the
  // debug board), always fetch random data from the hardware.
  if (kDeviceType != kDeviceSimDV && kDeviceType != kDeviceSimVerilator) {
    ctx.reseed_frequency = 0;
  }
  return ctx;
}

static inline void reseed_lfsr(void) {
  rand_testutils_rng_ctx.lfsr = rv_core_ibex_testutils_get_rnd_data(
      rand_testutils_rng_ctx.rv_core_ibex,
      rand_testutils_rng_ctx.entropy_fetch_timeout_usec);
  rand_testutils_rng_ctx.op_counter = 0;
}

static inline void advance_lfsr(void) {
  bool lsb = rand_testutils_rng_ctx.lfsr & 0x1u;
  rand_testutils_rng_ctx.lfsr >>= 1;
  if (lsb) {
    rand_testutils_rng_ctx.lfsr ^=
        rand_testutils_rng_ctx.polynomial_coefficients;
  }
  rand_testutils_rng_ctx.op_counter++;
}

extern void rand_testutils_reseed(void);

uint32_t rand_testutils_gen32(void) {
  if (rand_testutils_rng_ctx.op_counter >=
      rand_testutils_rng_ctx.reseed_frequency) {
    reseed_lfsr();
  } else {
    advance_lfsr();
  }
  return rand_testutils_rng_ctx.lfsr;
}

uint32_t rand_testutils_gen32_range(uint32_t min, uint32_t max) {
  CHECK(max >= min);
  uint32_t range = max - min;
  if (range == 0) {
    return min;
  }
  return min + (rand_testutils_gen32() % (range + 1));
}
