Browse Source

add thread aware random generator

master
Eyck Jentzsch 2 months ago
parent
commit
9485ba7e94
4 changed files with 107 additions and 2 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +2
    -2
      incl/scc/memory.h
  3. +73
    -0
      incl/scc/mt19937_rng.h
  4. +31
    -0
      src/mt19937_rng.cpp

+ 1
- 0
CMakeLists.txt View File

@@ -72,6 +72,7 @@ set(LIB_SOURCES
src/tlm_ahb_bfm_target.cpp
src/tracer_base.cpp
src/tracer.cpp
src/mt19937_rng.cpp
)

if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9)


+ 2
- 2
incl/scc/memory.h View File

@@ -24,7 +24,7 @@
#include "target_mixin.h"
#include "utilities.h"
#include <tlm.h>
#include <util/mt19937_rng.h>
#include <scc/mt19937_rng.h>
#include <util/sparse_array.h>

namespace scc {
@@ -115,7 +115,7 @@ int memory<SIZE, BUSWIDTH>::handle_operation(tlm::tlm_generic_payload& trans) {
} else {
// no allocated page so return randomized data
for(size_t i = 0; i < len; i++)
ptr[i] = util::MT19937::uniform() % 256;
ptr[i] = scc::MT19937::uniform() % 256;
}
} else if(cmd == tlm::TLM_WRITE_COMMAND) {
auto& p = mem(adr / mem.page_size);


+ 73
- 0
incl/scc/mt19937_rng.h View File

@@ -0,0 +1,73 @@
/*
* mt19937_rng.h
*
* Created on: Jan 9, 2020
* Author: eyck
*/

#ifndef _UTIL_MT19937_RNG_H_
#define _UTIL_MT19937_RNG_H_

#include <iostream>
#include <random>
#include <assert.h>

namespace scc {
class MT19937 {
public:
/**
* Seeds the mersenne twister PRNG with the given value
* @param new_seed
*/
static void seed(uint64_t new_seed = std::mt19937_64::default_seed);
/**
* generates the next random integer number with uniform distribution (similar to rand() )
* @return
*/
static uint64_t uniform() {
std::uniform_int_distribution<uint64_t> u;
return u(inst());
}
/**
* generates the next random integer number with uniform distribution in the range of the given type
* @return
*/
template <typename T> static T uniform() {
std::uniform_int_distribution<T> u;
return u(inst());
}
/**
* generates the next random integer number with uniform distribution between (and including) min and max
* @param min the lower limit of the interval
* @param max the upper limit of the interval
* @return
*/
static uint64_t uniform(uint64_t min, uint64_t max) {
assert(min < max);
std::uniform_int_distribution<uint64_t> u(min, max);
return u(inst());
}
/**
* generates the next random double precision float number with normal distribution (similar to rand() )
* @return
*/
static double normal() {
std::normal_distribution<> u;
return u(inst());
}
/**
* generates the next random integer number with log normal distribution (similar to rand() )
* @return
*/
static double lognormal() {
std::lognormal_distribution<> u;
return u(inst());
}

private:
static std::mt19937_64& inst() ;
};


} // namespace scc
#endif /* _UTIL_MT19937_RNG_H_ */

+ 31
- 0
src/mt19937_rng.cpp View File

@@ -0,0 +1,31 @@
#include <scc/mt19937_rng.h>
#include <systemc>
#include <unordered_map>
namespace {
struct {
std::mt19937_64 global;
std::unordered_map<void*, std::mt19937_64> inst;
uint64_t seed{std::mt19937_64::default_seed};
} rng;
};

std::mt19937_64& scc::MT19937::inst() {
if(auto* obj = sc_core::sc_get_current_object()) {
auto sz = rng.inst.size();
auto& ret = rng.inst[obj];
if(rng.inst.size() > sz) {
std::string name{obj->name()};
std::hash<std::string> h;
ret.seed(h(name) ^ rng.seed);
}
return ret;
} else {
return rng.global;
}
}

void scc::MT19937::seed(uint64_t new_seed){
rng.seed=new_seed;
rng.global.seed(new_seed);
for(auto& e: rng.inst) e.second.seed(new_seed);
}

Loading…
Cancel
Save