scc 2025.09
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
22namespace {
23struct {
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
30bool debug_randomization = getenv("SCC_DEBUG_RANDOMIZATION") != nullptr;
31}; // namespace
32
33auto 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
62void 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
69void scc::MT19937::enable_global_seed(bool enable) { rng.global_seed = enable; }
static void enable_global_seed(bool enable)
static void seed(uint64_t new_seed=std::mt19937_64::default_seed)