1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Package: PkgMath
//
// Description:
//
// SystemVerilog supports many Math functions. This adds a few that it
// doesn't have built in, as well as useful mathematical constants.
//
// SystemVerilog has built-in support for the following:
//
// $clog2 $asin
// $ln $acos
// $log10 $atan
// $exp $atan2
// $sqrt $hypot
// $pow $sinh
// $floor $cosh
// $ceil $tanh
// $sin $asinh
// $cos $acosh
// $tan $atanh
//
package PkgMath;
//---------------------------------------------------------------------------
// Constants
//---------------------------------------------------------------------------
localparam real PI = 2*$acos(0.0);
localparam real TAU = 4*$acos(0.0);
localparam real PHI = (1 + $sqrt(5.0)) / 2.0;
localparam real E = $exp(1);
localparam byte BYTE_MAX = 8'sh7F;
localparam byte BYTE_MIN = 8'sh80;
localparam shortint SHORT_MAX = 16'sh7FFF;
localparam shortint SHORT_MIN = 16'sh8000;
localparam int INT_MAX = 32'sh7FFFFFFF;
localparam int INT_MIN = 32'sh80000000;
localparam longint LONG_MAX = 64'sh7FFFFFFFFFFFFFFF;
localparam longint LONG_MIN = 64'sh8000000000000000;
localparam byte unsigned UBYTE_MAX = 8'hFF;
localparam byte unsigned UBYTE_MIN = 8'h00;
localparam shortint unsigned USHORT_MAX = 16'hFFFF;
localparam shortint unsigned USHORT_MIN = 16'h0000;
localparam int unsigned UINT_MAX = 32'hFFFFFFFF;
localparam int unsigned UINT_MIN = 32'h00000000;
localparam longint unsigned ULONG_MAX = 64'hFFFFFFFFFFFFFFFF;
localparam longint unsigned ULONG_MIN = 64'h0000000000000000;
//---------------------------------------------------------------------------
// Functions (For real data types)
//---------------------------------------------------------------------------
// Return the absolute value
function automatic real abs(real num);
if (num < 0) return -1.0*num;
return num;
endfunction : abs
// Round a float to the nearest whole number, rounding away from zero for 0.5
// (same as C++ and default SystemVerilog behavior).
function automatic real round(real num);
if (num >= 0) begin
// Round toward +inf
if (num - $floor(num) < 0.5) return $floor(num);
return $ceil(num);
end else begin
// Round toward -inf
if (num - $floor(num) <= 0.5) return $floor(num);
return $ceil(num);
end
endfunction : round
// Round a float to the nearest value having bits to the right of the binary
// point. For example:
//
// 1.2265625 (0b1.0011101) --> 3 bits --> 1.25000 (0b1.0100000)
// 1.2265625 (0b1.0011101) --> 5 bits --> 1.21875 (0b1.0011100)
//
function automatic real round_bits(real num, int unsigned bits);
return round(num * 2.0**bits) / (2.0**bits);
endfunction : round_bits
// Return the sign of num as +1.0 or -1.0;
function automatic real sign(real num);
if (num < 0.0) return -1.0;
return 1.0;
endfunction : sign;
// Return the modulus (remainder) of a / b, with the sign of the numerator.
// This should match the C++ standard library std::fmod() behavior, as well
// as SystemVerilog % operator with integer values.
function automatic real fmod(real a, real b);
a = abs(a);
b = abs(b);
return sign(b) * (a - ($floor(a / b) * b));
endfunction : fmod
// Return the (remainder) of a / b, where the quotient is rounded to the
// nearest integer. This should approximate the C++ standard library
// std::remainder() behavior.
function automatic real remainder(real a, real b);
return a - round(a/b)*b;
endfunction : remainder
// Return the maximum of a and b.
function automatic real fmax(real a, real b);
if (a > b) return a;
return b;
endfunction : fmax
// Return the minimum of a and b.
function automatic real fmin(real a, real b);
if (a < b) return a;
return b;
endfunction : fmin
//---------------------------------------------------------------------------
// Template Functions (For any data type)
//---------------------------------------------------------------------------
class Math #(type T);
static function T abs(T num);
if (num < 0) return -num;
return num;
endfunction : abs
static function T sign(T num);
if (num < 0) return -1;
return 1;
endfunction : sign
static function T max(T a, T b);
if (a > b) return a;
else return b;
endfunction : max
static function T min(T a, T b);
if (a < b) return a;
else return b;
endfunction : min
endclass : Math
endpackage : PkgMath
|