scc  2022.4.0
SystemC components library
mt19937_rng.cpp
1 /*******************************************************************************
2  * Copyright 2020-2022 MINRES Technologies GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************/
16 
17 #include "mt19937_rng.h"
18 #include <cstdlib>
19 #include <systemc>
20 #include <unordered_map>
21 
22 namespace {
23 struct {
24  std::mt19937_64 global;
25  std::unordered_map<void*, std::mt19937_64> inst;
26  uint64_t seed{std::mt19937_64::default_seed};
27  bool global_seed;
28 } rng;
29 
30 bool debug_randomization = getenv("SCC_DEBUG_RANDOMIZATION") != nullptr;
31 }; // namespace
32 
33 auto scc::MT19937::inst() -> std::mt19937_64& {
34 #ifndef NCSC
35  if(auto* obj = sc_core::sc_get_current_object()) {
36  auto sz = rng.inst.size();
37  auto& ret = rng.inst[obj];
38  if(rng.inst.size() > sz) {
39  uint64_t seed{0};
40  if(rng.global_seed) {
41  seed = reinterpret_cast<uintptr_t>(&rng.inst) ^ rng.seed;
42  if(debug_randomization)
43  std::cout << "seeding rng for " << obj->name() << " with global seed " << seed << "\n";
44  } else {
45  std::string name{obj->name()};
46  std::hash<std::string> h;
47  seed = (h(name) ^ rng.seed);
48  if(debug_randomization)
49  std::cout << "seeding rng for " << obj->name() << " with local seed " << seed << "\n";
50  }
51  ret.seed(seed);
52  }
53  if(debug_randomization) {
54  std::cout << "retrieving next rnd number for " << obj->name() << "\n";
55  }
56  return ret;
57  }
58 #endif
59  return rng.global;
60 }
61 
62 void scc::MT19937::seed(uint64_t new_seed) {
63  rng.seed = new_seed;
64  rng.global.seed(new_seed);
65  for(auto& e : rng.inst)
66  e.second.seed(new_seed);
67 }
68 
69 void scc::MT19937::enable_global_seed(bool enable) { rng.global_seed = enable; }
static void enable_global_seed(bool enable)
Definition: mt19937_rng.cpp:69
static void seed(uint64_t new_seed=std::mt19937_64::default_seed)
Definition: mt19937_rng.cpp:62