aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/sim/packages/PkgMath.sv
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/sim/packages/PkgMath.sv')
-rw-r--r--fpga/usrp3/sim/packages/PkgMath.sv157
1 files changed, 157 insertions, 0 deletions
diff --git a/fpga/usrp3/sim/packages/PkgMath.sv b/fpga/usrp3/sim/packages/PkgMath.sv
new file mode 100644
index 000000000..db5c15840
--- /dev/null
+++ b/fpga/usrp3/sim/packages/PkgMath.sv
@@ -0,0 +1,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