diff options
author | Martin Braun <martin.braun@ettus.com> | 2014-10-07 11:25:20 +0200 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2014-10-07 11:25:20 +0200 |
commit | fd3e84941de463fa1a7ebab0a69515b4bf2614cd (patch) | |
tree | 3fa721a13d41d2c0451d663a59a220a38fd5e614 /fpga/usrp3/sim/math.v | |
parent | 3b66804e41891e358c790b453a7a59ec7462dba4 (diff) | |
download | uhd-fd3e84941de463fa1a7ebab0a69515b4bf2614cd.tar.gz uhd-fd3e84941de463fa1a7ebab0a69515b4bf2614cd.tar.bz2 uhd-fd3e84941de463fa1a7ebab0a69515b4bf2614cd.zip |
Removed copy of FPGA source files.
Diffstat (limited to 'fpga/usrp3/sim/math.v')
-rw-r--r-- | fpga/usrp3/sim/math.v | 276 |
1 files changed, 0 insertions, 276 deletions
diff --git a/fpga/usrp3/sim/math.v b/fpga/usrp3/sim/math.v deleted file mode 100644 index cca10f60a..000000000 --- a/fpga/usrp3/sim/math.v +++ /dev/null @@ -1,276 +0,0 @@ -// All code take from the HDLCon paper: -// "Verilog Transcendental Functions for Numerical Testbenches" -// -// Authored by: -// Mark G. Arnold marnold@co.umist.ac.uk, -// Colin Walter c.walter@co.umist.ac.uk -// Freddy Engineer freddy.engineer@xilinx.com -// - - - -// The sine function is approximated with a polynomial which works -// for -π/2 < x < π/2. (This polynomial, by itself, was used as a -// Verilog example in [2]; unfortunately there was a typo with the -// coefficients. The correct coefficients together with an error -// analysis are given in [3].) For arguments outside of -π/2 < x < π/2, -// the identities sin(x) = -sin(-x) and sin(x) = -sin(x-π) allow the -// argument to be shifted to be within this range. The latter identity -// can be applied repeatedly. Doing so could cause inaccuracies for -// very large arguments, but in practice the errors are acceptable -// if the Verilog simulator uses double-precision floating point. - -function real sin; - input x; - real x; - real x1,y,y2,y3,y5,y7,sum,sign; - begin - sign = 1.0; - x1 = x; - if (x1<0) - begin - x1 = -x1; - sign = -1.0; - end - while (x1 > 3.14159265/2.0) - begin - x1 = x1 - 3.14159265; - sign = -1.0*sign; - end - y = x1*2/3.14159265; - y2 = y*y; - y3 = y*y2; - y5 = y3*y2; - y7 = y5*y2; - sum = 1.570794*y - 0.645962*y3 + - 0.079692*y5 - 0.004681712*y7; - sin = sign*sum; - end -endfunction - -// The cosine and tangent are computed from the sine: -function real cos; - input x; - real x; - begin - cos = sin(x + 3.14159265/2.0); - end -endfunction - - -function real tan; - input x; - real x; - begin - tan = sin(x)/cos(x); - end -endfunction - -// The base-two exponential (antilogarithm) function, 2x, is computed by -// examining the bits of the argument, and for those bits of the argument -// that are 1, multiplying the result by the corresponding power of a base -// very close to one. For example, if there were only two bits after -// the radix point, the base would be the fourth root of two, 1.1892. -// This number is squared on each iteration: 1.4142, 2.0, 4.0, 16.0. -// So, if x is 101.112, the function computes 25.75 as 1.1892*1.4142*2.0*16.0 = 53.81. -// In general, for k bits of precision, the base would be the 2k root of two. -// Since we need about 23 bits of accuracy for our function, the base we use -// is the 223 root of two, 1.000000082629586. This constant poses a problem -// to some Verilog parsers, so we construct it in two parts. The following -// function computes the appropriate root of two by repeatedly squaring this constant: - -function real rootof2; - input n; - integer n; - real power; - integer i; - - begin - power = 0.82629586; - power = power / 10000000.0; - power = power + 1.0; - i = -23; - - if (n >= 1) - begin - power = 2.0; - i = 0; - end - - for (i=i; i< n; i=i+1) - begin - power = power * power; - end - rootof2 = power; - end -endfunction // if - -// This function is used for computing both antilogarithms and logarithms. -// This routine is never called with n less than -23, thus no validity check -// need be performed. When n>0, the exponentiation begins with 2.0 in order to -// improve accuracy. -// For computing the antilogarithm, we make use of the identity ex = 2x/ln(2), -// and then proceed as in the example above. The constant 1/ln(2) = 1.44269504. -// Here is the natural exponential function: - -function real exp; - input x; - real x; - real x1,power,prod; - integer i; - begin - x1 = fabs(x)*1.44269504; - if (x1 > 255.0) - begin - exp = 0.0; - if (x>0.0) - begin - $display("exp illegal argument:",x); - $stop; - end - end - else - begin - prod = 1.0; - power = 128.0; - for (i=7; i>=-23; i=i-1) - begin - if (x1 > power) - begin - prod = prod * rootof2(i); - x1 = x1 - power; - end - power = power / 2.0; - end - if (x < 0) - exp = 1.0/prod; - else - exp = prod; - end - end -endfunction // fabs - -// The function prints an error message if the argument is too large -// (greater than about 180). All error messages in this package are -// followed by $stop to allow the designer to use the debugging -// features of Verilog to determine the cause of the error, and -// possibly to resume the simulation. An argument of less than -// about –180 simply returns zero with no error. The main loop -// assumes a positive argument. A negative argument is computed as 1/e-x. -// The logarithm function prints an error message for arguments less -// than or equal to zero because the real-valued logarithm is not -// defined for such arguments. The loop here requires an argument -// greater than or equal to one. For arguments between zero and one, -// this code uses the identity ln(1/x) = -ln(x). - -function real log; - input x; - real x; - real re,log2; - integer i; - begin - if (x <= 0.0) - begin - $display("log illegal argument:",x); - $stop; - log = 0; - end - else - begin - if (x<1.0) - re = 1.0/x; - else - re = x; - log2 = 0.0; - for (i=7; i>=-23; i=i-1) - begin - if (re > rootof2(i)) - begin - re = re/rootof2(i); - log2 = 2.0*log2 + 1.0; - end - else - log2 = log2*2; - end - if (x < 1.0) - log = -log2/12102203.16; - else - log = log2/12102203.16; - end - end -endfunction - -// The code only divides re by rootof2(i) when the re is larger -// (so that the quotient will be greater than 1.0). Each time -// such a division occurs, a bit that is 1 is recorded in the -// whole number result (multiply by 2 and add 1). Otherwise, -// a zero is recorded (multiply by 2). At the end of the loop, -// log2 will contain 223 log2|x|. We divide by 223 and use the -// identity ln(x) = log2(x)/log2(e). The constant 12102203.16 is 223 log2(e). -// The log(x) and exp(x)functions are used to implement the pow(x,y) and sqrt(x) functions: - -function real pow; - input x,y; - real x,y; - begin - if (x<0.0) - begin - $display("pow illegal argument:",x); - $stop; - end - pow = exp(y*log(x)); - end -endfunction - -function real sqrt; - input x; - real x; - begin - if (x<0.0) - begin - $display("sqrt illegal argument:",x); - $stop; - end - sqrt = exp(0.5*log(x)); - end -endfunction - -// The arctangent [3,7] is computed as a continued fraction, -// using the identities tan-1(x) = -tan-1(-x) and tan-1(x) = π/2 - tan-1(1/x) -// to reduce the range to 0 < x < 1: - -function real atan; - input x; - real x; - real x1,x2,sign,bias; - real d3,s3; - begin - sign = 1.0; - bias = 0.0; - x1 = x; - if (x1 < 0.0) - begin - x1 = -x1; - sign = -1.0; - end - if (x1 > 1.0) - begin - x1 = 1.0/x1; - bias = sign*3.14159265/2.0; - sign = -1.0*sign; - end - x2 = x1*x1; - d3 = x2 + 1.44863154; - d3 = 0.26476862 / d3; - s3 = x2 + 3.3163354; - d3 = s3 - d3; - d3 = 7.10676 / d3; - s3 = 6.762139 + x2; - d3 = s3 - d3; - d3 = 3.7092563 / d3; - d3 = d3 + 0.17465544; - atan = sign*x1*d3+bias; - end -endfunction - -// The other functions (asin(x) and acos(x)) are computed from the arctangent. |