OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [lib/] [source/] [neorv32_trng.c] - Diff between revs 12 and 23

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 12 Rev 23
Line 60... Line 60...
  }
  }
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Enable and configure true random number generator. The TRNG control register bits are listed in #NEORV32_TRNG_CT_enum.
 * Enable true random number generator. The TRNG control register bits are listed in #NEORV32_TRNG_CT_enum.
 *
 
 * @param[in] tap_mask 16-bit tap mask for GARO array.
 
 * @return Returns 0 if the provided tap_mask works correctly (GARO-array is oscillating), returns 1 otherwise.
 
 **************************************************************************/
 **************************************************************************/
int neorv32_trng_setup(uint16_t tap_mask) {
void neorv32_trng_enable(void) {
 
 
 
  int i;
 
 
  TRNG_CT = 0; // reset
  TRNG_CT = 0; // reset
 
 
  // configure
  for (i=0; i<1000; i++) {
  uint32_t tap_config = (uint32_t)(tap_mask);
    asm volatile ("nop");
  tap_config = tap_config << TRNG_CT_TAP_LSB;
 
  TRNG_CT = (1 << TRNG_CT_EN) | tap_config;
 
 
 
  neorv32_cpu_delay_ms(1);
 
 
 
  // check if TRNG is oscillating
 
  uint16_t trng_data;
 
  if (neorv32_trng_get(&trng_data) == 0) {
 
    return 0;
 
  }
  }
  else {
 
    return 1;
  TRNG_CT = 1 << TRNG_CT_EN; // activate
 
 
 
  for (i=0; i<1000; i++) {
 
    asm volatile ("nop");
  }
  }
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
Line 99... Line 92...
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Get random data from TRNG.
 * Get random data from TRNG.
 *
 *
 * @param[in,out] data uint16_t pointer for storing random data word
 * @note The TRNG is automatically reset if a stuck-at-one/stuck-at-zero error is detected.
 * @return Valid data when 0, invalid data when 1
 
 **************************************************************************/
 
int neorv32_trng_get(uint16_t *data) {
 
 
 
  int i;
 
  const int max_try = 16;
 
  uint32_t trng_data;
 
  uint32_t rnd_data;
 
 
 
  for(i=0; i<max_try; i++) {
 
 
 
    trng_data = TRNG_DATA;
 
    rnd_data  = trng_data >> TRNG_DATA_LSB;
 
    *data = (uint16_t)rnd_data;
 
 
 
    if (trng_data & (1<<TRNG_DATA_VALID)) { // output data valid?
 
      return 0; // valid
 
    }
 
 
 
  }
 
 
 
  return 1; // invalid
 
}
 
 
 
 
 
/**********************************************************************//**
 
 * Try to find a valid TRNG tap configuration mask.
 
 *
 *
 * @return Tap mask for configuring the TRNG. If return is zero, no valid tap mask was found.
 * @param[in,out] data uint8_t pointer for storing random data word
 
 * @return Data is valid when 0, stuck-at-zero error when 1, stuck-at-one error when 2, data not (yet) valid when 3
 **************************************************************************/
 **************************************************************************/
uint16_t neorv32_trng_find_tap_mask(void) {
int neorv32_trng_get(uint8_t *data) {
 
 
  int j;
 
  uint16_t tap_config16 = 0xfff0; // keep the lowest inverters without feedback
 
  uint16_t trng_data;
 
  int success = 0;
 
 
 
  // tap mask is zero, try to find a nice one
  uint32_t trng_ct_reg = TRNG_CT;
  while (1) {
 
 
 
    // good mask found?
  if (trng_ct_reg & (1<<TRNG_CT_ERROR_0)) { // stuck at zero error
    if ((success) || (tap_config16 <= 0x0008)) {
    neorv32_trng_enable(); // reset TRNG
      break;
    return 1;
    }
    }
 
 
    // generate a new tap
  if (trng_ct_reg & (1<<TRNG_CT_ERROR_1)) { // stuck at one error
    tap_config16 -= 0x0008;
    neorv32_trng_enable(); // reset TRNG
 
    return 2;
    // install it
 
    if (neorv32_trng_setup(tap_config16)) {
 
      continue;
 
    }
    }
 
 
    // does it work?
  if ((trng_ct_reg & (1<<TRNG_CT_VALID)) == 0) { // output data valid (yet)?
    success = 1;
    return 3;
    for (j=0; j < 100; j++) {
 
      neorv32_cpu_delay_ms(1);
 
      if (neorv32_trng_get(&trng_data)) { // stop testing on fail
 
        success = 0;
 
        break;
 
      }
 
    }
 
  }
  }
 
 
  return (uint16_t)tap_config16;
  *data = (uint8_t)(trng_ct_reg >> TRNG_CT_DATA_LSB);
 
  return 0; // valid data
}
}
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.