24
#include "verilated_config.h"
25
#include "verilatedos.h"
32
static double _vl_dbase_uniform(IData& seedr, int32_t start, int32_t end) VL_MT_SAFE {
38
const double d = 0.00000011920928955078125;
39
if (VL_UNLIKELY(seedr == 0)) seedr = 259341593;
43
if (VL_UNCOVERABLE(start >= end)) {
47
a = static_cast<double>(start);
48
b = static_cast<double>(end);
50
seedr = 69069 * seedr + 1;
52
u.stemp = (u.stemp >> 9) | 0x3f800000;
54
double c = static_cast<double>(u.s);
56
c = ((b - a) * (c - 1.0)) + a;
60
static double _vl_dbase_normal(IData& seedr, int32_t mean, int32_t deviation) VL_MT_SAFE {
64
while ((s >= 1.0) || (s == 0.0)) {
65
v1 = _vl_dbase_uniform(seedr, -1, 1);
66
v2 = _vl_dbase_uniform(seedr, -1, 1);
67
s = v1 * v1 + v2 * v2;
69
s = v1 * std::sqrt(-2.0 * log(s) / s);
70
v1 = static_cast<double>(deviation);
71
v2 = static_cast<double>(mean);
75
static double _vl_dbase_exponential(IData& seedr, int32_t mean) VL_MT_SAFE {
76
double n = _vl_dbase_uniform(seedr, 0, 1);
77
if (n != 0) n = -log(n) * mean;
81
static double _vl_dbase_chi_square(IData& seedr, int32_t deg_of_free) VL_MT_SAFE {
83
if (deg_of_free % 2) {
84
x = _vl_dbase_normal(seedr, 0, 1);
89
for (int32_t k = 2; k <= deg_of_free; k += 2) x = x + 2 * _vl_dbase_exponential(seedr, 1);
93
IData VL_DIST_CHI_SQUARE(IData& seedr, IData udf) VL_MT_SAFE {
94
const int32_t df = static_cast<int32_t>(udf);
95
if (VL_UNLIKELY(df <= 0)) {
99
double r = _vl_dbase_chi_square(seedr, df);
102
i = static_cast<int32_t>(r + 0.5);
105
i = static_cast<int32_t>(r + 0.5);
108
return static_cast<IData>(i);
111
IData VL_DIST_ERLANG(IData& seedr, IData uk, IData umean) VL_MT_SAFE {
112
const int32_t k = static_cast<int32_t>(uk);
113
const int32_t mean = static_cast<int32_t>(umean);
114
if (VL_UNLIKELY(k <= 0)) {
119
for (int32_t i = 1; i <= k; i++) x = x * _vl_dbase_uniform(seedr, 0, 1);
120
const double a = static_cast<double>(mean);
121
const double b = static_cast<double>(k);
122
double r = -a * log(x) / b;
125
i = static_cast<int32_t>(r + 0.5);
128
i = static_cast<int32_t>(r + 0.5);
131
return static_cast<IData>(i);
134
IData VL_DIST_EXPONENTIAL(IData& seedr, IData umean) VL_MT_SAFE {
135
const int32_t mean = static_cast<int32_t>(umean);
136
if (VL_UNLIKELY(mean <= 0)) {
141
double r = _vl_dbase_exponential(seedr, mean);
143
i = static_cast<int32_t>(r + 0.5);
146
i = static_cast<int32_t>(r + 0.5);
149
return static_cast<IData>(i);
152
IData VL_DIST_NORMAL(IData& seedr, IData umean, IData usd) VL_MT_SAFE {
153
const int32_t mean = static_cast<int32_t>(umean);
154
const int32_t sd = static_cast<int32_t>(usd);
155
double r = _vl_dbase_normal(seedr, mean, sd);
158
i = static_cast<int32_t>(r + 0.5);
161
i = static_cast<int32_t>(r + 0.5);
164
return static_cast<IData>(i);
167
IData VL_DIST_POISSON(IData& seedr, IData umean) VL_MT_SAFE {
168
const int32_t mean = static_cast<int32_t>(umean);
169
if (VL_UNLIKELY(mean <= 0)) {
174
double q = -static_cast<double>(mean);
176
q = _vl_dbase_uniform(seedr, 0, 1);
179
q = _vl_dbase_uniform(seedr, 0, 1) * q;
181
return static_cast<IData>(i);
184
IData VL_DIST_T(IData& seedr, IData udf) VL_MT_SAFE {
185
const int32_t df = static_cast<int32_t>(udf);
186
if (VL_UNLIKELY(df <= 0)) {
190
const double chi2 = _vl_dbase_chi_square(seedr, df);
191
const double div = chi2 / static_cast<double>(df);
192
const double root = std::sqrt(div);
193
double r = _vl_dbase_normal(seedr, 0, 1) / root;
196
i = static_cast<int32_t>(r + 0.5);
199
i = static_cast<int32_t>(r + 0.5);
202
return static_cast<IData>(i);
205
IData VL_DIST_UNIFORM(IData& seedr, IData ustart, IData uend) VL_MT_SAFE {
206
int32_t start = static_cast<int32_t>(ustart);
207
int32_t end = static_cast<int32_t>(uend);
208
if (VL_UNLIKELY(start >= end)) return start;
210
if (end != std::numeric_limits<int32_t>::max()) {
212
const double r = _vl_dbase_uniform(seedr, start, end);
214
i = static_cast<int32_t>(r);
216
i = static_cast<int32_t>(r - 1);
218
if (i < start) i = start;
219
if (i >= end) i = end - 1;
220
} else if (start != std::numeric_limits<int32_t>::min()) {
222
const double r = _vl_dbase_uniform(seedr, start, end) + 1.0;
224
i = static_cast<int32_t>(r);
226
i = static_cast<int32_t>(r - 1);
228
if (i <= start) i = start + 1;
229
if (i > end) i = end;
231
double r = (_vl_dbase_uniform(seedr, start, end) + 2147483648.0) / 4294967295.0;
232
r = r * 4294967296.0 - 2147483648.0;
234
i = static_cast<int32_t>(r);
236
i = static_cast<int32_t>(r - 1);
239
return static_cast<IData>(i);