diff options
Diffstat (limited to 'fpga/usrp3/sim/packages/PkgMath.sv')
-rw-r--r-- | fpga/usrp3/sim/packages/PkgMath.sv | 157 |
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 |