------------------------------------------------------------------------ -- -- This source file may be used and distributed without restriction. -- No declarations or definitions shall be added to this package. -- This package cannot be sold or distributed for profit. -- -- **************************************************************** -- * * -- * W A R N I N G * -- * * -- * This DRAFT version IS NOT endorsed or approved by IEEE * -- * * -- **************************************************************** -- -- Title: PACKAGE MATH_REAL -- -- Library: This package shall be compiled into a library -- symbolically named IEEE. -- -- Purpose: VHDL declarations for mathematical package MATH_REAL -- which contains common real constants, common real -- functions, and real trascendental functions. -- -- Author: IEEE VHDL Math Package Study Group -- -- Notes: -- The package body shall be considered the formal definition of -- the semantics of this package. Tool developers may choose to implement -- the package body in the most efficient manner available to them. -- -- History: -- Version 0.1 (Strawman) Jose A. Torres 6/22/92 -- Version 0.2 Jose A. Torres 1/15/93 -- Version 0.3 Jose A. Torres 4/13/93 -- Version 0.4 Jose A. Torres 4/19/93 -- Version 0.5 Jose A. Torres 4/20/93 Added RANDOM() -- Version 0.6 Jose A. Torres 4/23/93 Renamed RANDOM as -- UNIFORM. Modified -- rights banner. -- Version 0.7 Jose A. Torres 5/28/93 Rev up for compatibility -- with package body. ------------------------------------------------------------- Library IEEE; Package MATH_REAL is -- -- commonly used constants -- constant MATH_E : real := 2.71828_18284_59045_23536; -- value of e constant MATH_1_E: real := 0.36787_94411_71442_32160; -- value of 1/e constant MATH_PI : real := 3.14159_26535_89793_23846; -- value of pi constant MATH_1_PI : real := 0.31830_98861_83790_67154; -- value of 1/pi constant MATH_LOG_OF_2: real := 0.69314_71805_59945_30942; -- natural log of 2 constant MATH_LOG_OF_10: real := 2.30258_50929_94045_68402; -- natural log of10 constant MATH_LOG2_OF_E: real := 1.44269_50408_88963_4074; -- log base 2 of e constant MATH_LOG10_OF_E: real := 0.43429_44819_03251_82765; -- log base 10 of e constant MATH_SQRT2: real := 1.41421_35623_73095_04880; -- sqrt of 2 constant MATH_SQRT1_2: real := 0.70710_67811_86547_52440; -- sqrt of 1/2 constant MATH_SQRT_PI: real := 1.77245_38509_05516_02730; -- sqrt of pi constant MATH_DEG_TO_RAD: real := 0.01745_32925_19943_29577; -- conversion factor from degree to radian constant MATH_RAD_TO_DEG: real := 57.29577_95130_82320_87685; -- conversion factor from radian to degree -- -- attribute for functions whose implementation is foreign (C native) -- attribute FOREIGN : string; -- predefined attribute in VHDL-1992 -- -- function declarations -- function SIGN (X: real ) return real; -- returns 1.0 if X > 0.0; 0.0 if X == 0.0; -1.0 if X < 0.0 function CEIL (X : real ) return real; -- returns smallest integer value (as real) not less than X function FLOOR (X : real ) return real; -- returns largest integer value (as real) not greater than X function ROUND (X : real ) return real; -- returns integer FLOOR(X + 0.5) if X > 0; -- return integer CEIL(X - 0.5) if X < 0 function FMAX (X, Y : real ) return real; -- returns the algebraically larger of X and Y function FMIN (X, Y : real ) return real; -- returns the algebraically smaller of X and Y procedure UNIFORM (variable Seed1,Seed2:inout integer; variable X:out real); -- returns a pseudo-random number with uniform distribution in the -- interval (0.0, 1.0). -- Before the first call to UNIFORM, the seed values (Seed1, Seed2) must -- be initialized to values in the range [1, 2147483562] and -- [1, 2147483398] respectively. The seed values are modified after -- each call to UNIFORM. -- This random number generator is portable for 32-bit computers, and -- it has period ~2.30584*(10**18) for each set of seed values. -- -- For VHDL-1992, the seeds will be global variables, functions to -- initialize their values (INIT_SEED) will be provided, and the UNIFORM -- procedure call will be modified accordingly. function SRAND (seed: in integer ) return integer; -- -- sets value of seed for sequence of -- pseudo-random numbers. -- It uses the foreign native C function srand(). attribute FOREIGN of SRAND : function is "C_NATIVE"; function RAND return integer; -- -- returns an integer pseudo-random number with uniform distribution. -- It uses the foreign native C function rand(). -- Seed for the sequence is initialized with the -- SRAND() function and value of the seed is changed every -- time SRAND() is called, but it is not visible. -- The range of generated values is platform dependent. attribute FOREIGN of RAND : function is "C_NATIVE"; function GET_RAND_MAX return integer; -- -- returns the upper bound of the range of the -- pseudo-random numbers generated by RAND(). -- The support for this function is platform dependent, and -- it uses foreign native C functions or constants. -- It may not be available in some platforms. -- Note: the value of (RAND() / GET_RAND_MAX()) is a -- pseudo-random number distributed between 0 & 1. attribute FOREIGN of GET_RAND_MAX : function is "C_NATIVE"; function SQRT (X : real ) return real; -- returns square root of X; X >= 0 function CBRT (X : real ) return real; -- returns cube root of X function "**" (X : integer; Y : real) return real; -- returns Y power of X ==> X**Y; -- error if X = 0 and Y <= 0.0 -- error if X < 0 and Y does not have an integer value function "**" (X : real; Y : real) return real; -- returns Y power of X ==> X**Y; -- error if X = 0.0 and Y <= 0.0 -- error if X < 0.0 and Y does not have an integer value function EXP (X : real ) return real; -- returns e**X; where e = MATH_E function LOG (X : real ) return real; -- returns natural logarithm of X; X > 0 function LOG (BASE: positive; X : real) return real; -- returns logarithm base BASE of X; X > 0 function SIN (X : real ) return real; -- returns sin X; X in radians function COS ( X : real ) return real; -- returns cos X; X in radians function TAN (X : real ) return real; -- returns tan X; X in radians -- X /= ((2k+1) * PI/2), where k is an integer function ASIN (X : real ) return real; -- returns -PI/2 < asin X < PI/2; | X | <= 1 function ACOS (X : real ) return real; -- returns 0 < acos X < PI; | X | <= 1 function ATAN (X : real) return real; -- returns -PI/2 < atan X < PI/2 function ATAN2 (X : real; Y : real) return real; -- returns atan (X/Y); -PI < atan2(X,Y) < PI; Y /= 0.0 function SINH (X : real) return real; -- hyperbolic sine; returns (e**X - e**(-X))/2 function COSH (X : real) return real; -- hyperbolic cosine; returns (e**X + e**(-X))/2 function TANH (X : real) return real; -- hyperbolic tangent; -- returns (e**X - e**(-X))/(e**X + e**(-X)) function ASINH (X : real) return real; -- returns ln( X + sqrt( X**2 + 1)) function ACOSH (X : real) return real; -- returns ln( X + sqrt( X**2 - 1)); X >= 1 function ATANH (X : real) return real; -- returns (ln( (1 + X)/(1 - X)))/2 ; | X | < 1 end MATH_REAL; --------------------------------------------------------------- -- -- This source file may be used and distributed without restriction. -- No declarations or definitions shall be included in this package. -- This package cannot be sold or distributed for profit. -- -- **************************************************************** -- * * -- * W A R N I N G * -- * * -- * This DRAFT version IS NOT endorsed or approved by IEEE * -- * * -- **************************************************************** -- -- Title: PACKAGE MATH_COMPLEX -- -- Purpose: VHDL declarations for mathematical package MATH_COMPLEX -- which contains common complex constants and basic complex -- functions and operations. -- -- Author: IEEE VHDL Math Package Study Group -- -- Notes: -- The package body uses package IEEE.MATH_REAL -- -- The package body shall be considered the formal definition of -- the semantics of this package. Tool developers may choose to implement -- the package body in the most efficient manner available to them. -- -- History: -- Version 0.1 (Strawman) Jose A. Torres 6/22/92 -- Version 0.2 Jose A. Torres 1/15/93 -- Version 0.3 Jose A. Torres 4/13/93 -- Version 0.4 Jose A. Torres 4/19/93 -- Version 0.5 Jose A. Torres 4/20/93 -- Version 0.6 Jose A. Torres 4/23/93 Added unary minus -- and CONJ for polar -- Version 0.7 Jose A. Torres 5/28/93 Rev up for compatibility -- with package body. ------------------------------------------------------------- Library IEEE; Package MATH_COMPLEX is type COMPLEX is record RE, IM: real; end record; type COMPLEX_VECTOR is array (integer range <>) of COMPLEX; type COMPLEX_POLAR is record MAG: real; ARG: real; end record; constant CBASE_1: complex := COMPLEX'(1.0, 0.0); constant CBASE_j: complex := COMPLEX'(0.0, 1.0); constant CZERO: complex := COMPLEX'(0.0, 0.0); function CABS(Z: in complex ) return real; -- returns absolute value (magnitude) of Z function CARG(Z: in complex ) return real; -- returns argument (angle) in radians of a complex number function CMPLX(X: in real; Y: in real:= 0.0 ) return complex; -- returns complex number X + iY function "-" (Z: in complex ) return complex; -- unary minus function "-" (Z: in complex_polar ) return complex_polar; -- unary minus function CONJ (Z: in complex) return complex; -- returns complex conjugate function CONJ (Z: in complex_polar) return complex_polar; -- returns complex conjugate function CSQRT(Z: in complex ) return complex_vector; -- returns square root of Z; 2 values function CEXP(Z: in complex ) return complex; -- returns e**Z function COMPLEX_TO_POLAR(Z: in complex ) return complex_polar; -- converts complex to complex_polar function POLAR_TO_COMPLEX(Z: in complex_polar ) return complex; -- converts complex_polar to complex -- arithmetic operators function "+" ( L: in complex; R: in complex ) return complex; function "+" ( L: in complex_polar; R: in complex_polar) return complex; function "+" ( L: in complex_polar; R: in complex ) return complex; function "+" ( L: in complex; R: in complex_polar) return complex; function "+" ( L: in real; R: in complex ) return complex; function "+" ( L: in complex; R: in real ) return complex; function "+" ( L: in real; R: in complex_polar) return complex; function "+" ( L: in complex_polar; R: in real) return complex; function "-" ( L: in complex; R: in complex ) return complex; function "-" ( L: in complex_polar; R: in complex_polar) return complex; function "-" ( L: in complex_polar; R: in complex ) return complex; function "-" ( L: in complex; R: in complex_polar) return complex; function "-" ( L: in real; R: in complex ) return complex; function "-" ( L: in complex; R: in real ) return complex; function "-" ( L: in real; R: in complex_polar) return complex; function "-" ( L: in complex_polar; R: in real) return complex; function "*" ( L: in complex; R: in complex ) return complex; function "*" ( L: in complex_polar; R: in complex_polar) return complex; function "*" ( L: in complex_polar; R: in complex ) return complex; function "*" ( L: in complex; R: in complex_polar) return complex; function "*" ( L: in real; R: in complex ) return complex; function "*" ( L: in complex; R: in real ) return complex; function "*" ( L: in real; R: in complex_polar) return complex; function "*" ( L: in complex_polar; R: in real) return complex; function "/" ( L: in complex; R: in complex ) return complex; function "/" ( L: in complex_polar; R: in complex_polar) return complex; function "/" ( L: in complex_polar; R: in complex ) return complex; function "/" ( L: in complex; R: in complex_polar) return complex; function "/" ( L: in real; R: in complex ) return complex; function "/" ( L: in complex; R: in real ) return complex; function "/" ( L: in real; R: in complex_polar) return complex; function "/" ( L: in complex_polar; R: in real) return complex; end MATH_COMPLEX; --------------------------------------------------------------- -- -- This source file may be used and distributed without restriction. -- No declarations or definitions shall be added to this package. -- This package cannot be sold or distributed for profit. -- -- **************************************************************** -- * * -- * W A R N I N G * -- * * -- * This DRAFT version IS NOT endorsed or approved by IEEE * -- * * -- **************************************************************** -- -- Title: PACKAGE BODY MATH_REAL -- -- Library: This package shall be compiled into a library -- symbolically named IEEE. -- -- Purpose: VHDL declarations for mathematical package MATH_REAL -- which contains common real constants, common real -- functions, and real trascendental functions. -- -- Author: IEEE VHDL Math Package Study Group -- -- Notes: -- The package body shall be considered the formal definition of -- the semantics of this package. Tool developers may choose to implement -- the package body in the most efficient manner available to them. -- -- Source code and algorithms for this package body comes from the -- following sources: -- IEEE VHDL Math Package Study Group participants, -- U. of Mississippi, Mentor Graphics, Synopsys, -- Viewlogic/Vantage, Communications of the ACM (June 1988, Vol -- 31, Number 6, pp. 747, Pierre L'Ecuyer, Efficient and Portable -- Random Number Generators), Handbook of Mathematical Functions -- by Milton Abramowitz and Irene A. Stegun (Dover). -- -- History: -- Version 0.1 Jose A. Torres 4/23/93 First draft -- Version 0.2 Jose A. Torres 5/28/93 Fixed potentially illegal code ------------------------------------------------------------- Library IEEE; Package body MATH_REAL is -- -- some constants for use in the package body only -- constant Q_PI : real := MATH_PI/4.0; constant HALF_PI : real := MATH_PI/2.0; constant TWO_PI : real := MATH_PI*2.0; constant MAX_ITER: integer := 27; -- max precision factor for cordic -- -- some type declarations for cordic operations -- constant KC : REAL := 6.0725293500888142e-01; -- constant for cordic type REAL_VECTOR is array (NATURAL range <>) of REAL; type NATURAL_VECTOR is array (NATURAL range <>) of NATURAL; subtype REAL_VECTOR_N is REAL_VECTOR (0 to max_iter); subtype REAL_ARR_2 is REAL_VECTOR (0 to 1); subtype REAL_ARR_3 is REAL_VECTOR (0 to 2); subtype QUADRANT is INTEGER range 0 to 3; type CORDIC_MODE_TYPE is (ROTATION, VECTORING); -- -- auxiliary functions for cordic algorithms -- function POWER_OF_2_SERIES (d : NATURAL_VECTOR; initial_value : REAL; number_of_values : NATURAL) return REAL_VECTOR is variable v : REAL_VECTOR (0 to number_of_values); variable temp : REAL := initial_value; variable flag : boolean := true; begin for i in 0 to number_of_values loop v(i) := temp; for p in d'range loop if i = d(p) then flag := false; end if; end loop; if flag then temp := temp/2.0; end if; flag := true; end loop; return v; end POWER_OF_2_SERIES; constant two_at_minus : REAL_VECTOR := POWER_OF_2_SERIES( NATURAL_VECTOR'(100, 90),1.0, MAX_ITER); constant epsilon : REAL_VECTOR_N := ( 7.8539816339744827e-01, 4.6364760900080606e-01, 2.4497866312686413e-01, 1.2435499454676144e-01, 6.2418809995957351e-02, 3.1239833430268277e-02, 1.5623728620476830e-02, 7.8123410601011116e-03, 3.9062301319669717e-03, 1.9531225164788189e-03, 9.7656218955931937e-04, 4.8828121119489829e-04, 2.4414062014936175e-04, 1.2207031189367021e-04, 6.1035156174208768e-05, 3.0517578115526093e-05, 1.5258789061315760e-05, 7.6293945311019699e-06, 3.8146972656064960e-06, 1.9073486328101870e-06, 9.5367431640596080e-07, 4.7683715820308876e-07, 2.3841857910155801e-07, 1.1920928955078067e-07, 5.9604644775390553e-08, 2.9802322387695303e-08, 1.4901161193847654e-08, 7.4505805969238281e-09 ); function CORDIC ( x0 : REAL; y0 : REAL; z0 : REAL; n : NATURAL; -- precision factor CORDIC_MODE : CORDIC_MODE_TYPE -- rotation (z -> 0) -- or vectoring (y -> 0) ) return REAL_ARR_3 is variable x : REAL := x0; variable y : REAL := y0; variable z : REAL := z0; variable x_temp : REAL; begin if CORDIC_MODE = ROTATION then for k in 0 to n loop x_temp := x; if ( z >= 0.0) then x := x - y * two_at_minus(k); y := y + x_temp * two_at_minus(k); z := z - epsilon(k); else x := x + y * two_at_minus(k); y := y - x_temp * two_at_minus(k); z := z + epsilon(k); end if; end loop; else for k in 0 to n loop x_temp := x; if ( y < 0.0) then x := x - y * two_at_minus(k); y := y + x_temp * two_at_minus(k); z := z - epsilon(k); else x := x + y * two_at_minus(k); y := y - x_temp * two_at_minus(k); z := z + epsilon(k); end if; end loop; end if; return REAL_ARR_3'(x, y, z); end CORDIC; -- -- non-trascendental functions -- function SIGN (X: real ) return real is -- returns 1.0 if X > 0.0; 0.0 if X == 0.0; -1.0 if X < 0.0 begin if ( X > 0.0 ) then return 1.0; elsif ( X < 0.0 ) then return -1.0; else return 0.0; end if; end SIGN; function CEIL (X : real ) return real is -- returns smallest integer value (as real) not less than X -- No conversion to an integer type is expected, so truncate cannot -- overflow for large arguments. variable large: real := 1073741824.0; type long is range -1073741824 to 1073741824; -- 2**30 is longer than any single-precision mantissa variable rd: real; begin if abs( X) >= large then return X; else rd := real ( long( X)); if X > 0.0 then if rd >= X then return rd; else return rd + 1.0; end if; elsif X = 0.0 then return 0.0; else if rd <= X then return rd; else return rd - 1.0; end if; end if; end if; end CEIL; function FLOOR (X : real ) return real is -- returns largest integer value (as real) not greater than X -- No conversion to an integer type is expected, so truncate -- cannot overflow for large arguments. -- variable large: real := 1073741824.0; type long is range -1073741824 to 1073741824; -- 2**30 is longer than any single-precision mantissa variable rd: real; begin if abs( X ) >= large then return X; else rd := real ( long( X)); if X > 0.0 then if rd <= X then return rd; else return rd - 1.0; end if; elsif X = 0.0 then return 0.0; else if rd >= X then return rd; else return rd + 1.0; end if; end if; end if; end FLOOR; function ROUND (X : real ) return real is -- returns integer FLOOR(X + 0.5) if X > 0; -- return integer CEIL(X - 0.5) if X < 0 begin if X > 0.0 then return FLOOR(X + 0.5); elsif X < 0.0 then return CEIL( X - 0.5); else return 0.0; end if; end ROUND; function FMAX (X, Y : real ) return real is -- returns the algebraically larger of X and Y begin if X > Y then return X; else return Y; end if; end FMAX; function FMIN (X, Y : real ) return real is -- returns the algebraically smaller of X and Y begin if X < Y then return X; else return Y; end if; end FMIN; -- -- Pseudo-random number generators -- procedure UNIFORM(variable Seed1,Seed2:inout integer;variable X:out real) is -- returns a pseudo-random number with uniform distribution in the -- interval (0.0, 1.0). -- Before the first call to UNIFORM, the seed values (Seed1, Seed2) must -- be initialized to values in the range [1, 2147483562] and -- [1, 2147483398] respectively. The seed values are modified after -- each call to UNIFORM. -- This random number generator is portable for 32-bit computers, and -- it has period ~2.30584*(10**18) for each set of seed values. -- -- For VHDL-1992, the seeds will be global variables, functions to -- initialize their values (INIT_SEED) will be provided, and the UNIFORM -- procedure call will be modified accordingly. variable z, k: integer; begin k := Seed1/53668; Seed1 := 40014 * (Seed1 - k * 53668) - k * 12211; if Seed1 < 0 then Seed1 := Seed1 + 2147483563; end if; k := Seed2/52774; Seed2 := 40692 * (Seed2 - k * 52774) - k * 3791; if Seed2 < 0 then Seed2 := Seed2 + 2147483399; end if; z := Seed1 - Seed2; if z < 1 then z := z + 2147483562; end if; X := REAL(Z)*4.656613e-10; end UNIFORM; function SRAND (seed: in integer ) return integer is -- -- sets value of seed for sequence of -- pseudo-random numbers. -- Returns the value of the seed. -- It uses the foreign native C function srand(). begin end SRAND; function RAND return integer is -- -- returns an integer pseudo-random number with uniform distribution. -- It uses the foreign native C function rand(). -- Seed for the sequence is initialized with the -- SRAND() function and value of the seed is changed every -- time SRAND() is called, but it is not visible. -- The range of generated values is platform dependent. begin end RAND; function GET_RAND_MAX return integer is -- -- returns the upper bound of the range of the -- pseudo-random numbers generated by RAND(). -- The support for this function is platform dependent, and -- it uses foreign native C functions or constants. -- It may not be available in some platforms. -- Note: the value of (RAND / GET_RAND_MAX) is a -- pseudo-random number distributed between 0 & 1. begin end GET_RAND_MAX; -- -- trascendental and trigonometric functions -- function SQRT (X : real ) return real is -- returns square root of X; X >= 0 -- -- Computes square root using the Newton-Raphson approximation: -- F(n+1) = 0.5*[F(n) + x/F(n)]; -- constant inival: real := 1.5; constant eps : real := 0.000001; constant relative_err : real := eps*X; variable oldval : real ; variable newval : real ; begin -- check validity of argument if ( X < 0.0 ) then assert false report "X < 0 in SQRT(X)" severity ERROR; return (0.0); end if; -- get the square root for special cases if X = 0.0 then return 0.0; else if ( X = 1.0 ) then return 1.0; -- return exact value end if; end if; -- get the square root for general cases oldval := inival; newval := (X/oldval + oldval)/2.0; while ( abs(newval -oldval) > relative_err ) loop oldval := newval; newval := (X/oldval + oldval)/2.0; end loop; return newval; end SQRT; function CBRT (X : real ) return real is -- returns cube root of X -- Computes square root using the Newton-Raphson approximation: -- F(n+1) = (1/3)*[2*F(n) + x/F(n)**2]; -- constant inival: real := 1.5; constant eps : real := 0.000001; constant relative_err : real := eps*abs(X); variable xlocal : real := X; variable negative : boolean := X < 0.0; variable oldval : real ; variable newval : real ; begin -- compute root for special cases if X = 0.0 then return 0.0; elsif ( X = 1.0 ) then return 1.0; else if X = -1.0 then return -1.0; end if; end if; -- compute root for general cases if negative then xlocal := -X; end if; oldval := inival; newval := (xlocal/(oldval*oldval) + 2.0*oldval)/3.0; while ( abs(newval -oldval) > relative_err ) loop oldval := newval; newval :=(xlocal/(oldval*oldval) + 2.0*oldval)/3.0; end loop; if negative then newval := -newval; end if; return newval; end CBRT; function "**" (X : integer; Y : real) return real is -- returns Y power of X ==> X**Y; -- error if X = 0 and Y <= 0.0 -- error if X < 0 and Y does not have an integer value begin -- check validity of argument if ( X = 0 ) and ( Y <= 0.0 ) then assert false report "X = 0 and Y <= 0.0 in X**Y" severity ERROR; return (0.0); end if; if ( X < 0 ) and ( Y /= REAL(INTEGER(Y)) ) then assert false report "X < 0 and Y \= integer in X**Y" severity ERROR; return (0.0); end if; -- compute the result return EXP (Y * LOG (REAL(X))); end "**"; function "**" (X : real; Y : real) return real is -- returns Y power of X ==> X**Y; -- error if X = 0.0 and Y <= 0.0 -- error if X < 0.0 and Y does not have an integer value begin -- check validity of argument if ( X = 0.0 ) and ( Y <= 0.0 ) then assert false report "X = 0.0 and Y <= 0.0 in X**Y" severity ERROR; return (0.0); end if; if ( X < 0.0 ) and ( Y /= REAL(INTEGER(Y)) ) then assert false report "X < 0.0 and Y \= integer in X**Y" severity ERROR; return (0.0); end if; -- compute the result return EXP (Y * LOG (X)); end "**"; function EXP (X : real ) return real is -- returns e**X; where e = MATH_E -- -- This function computes the exponential using the following series: -- exp(x) = 1 + x + x**2/2! + x**3/3! + ... ; x > 0 -- constant eps : real := 0.000001; -- precision criteria variable reciprocal: boolean := x < 0.0;-- check sign of argument variable xlocal : real := abs(x); -- use positive value variable oldval: real ; -- following variables are variable num: real ; -- used for series evaluation variable count: integer ; variable denom: real ; variable newval: real ; begin -- compute value for special cases if X = 0.0 then return 1.0; else if X = 1.0 then return MATH_E; end if; end if; -- compute value for general cases oldval := 1.0; num := xlocal; count := 1; denom := 1.0; newval:= oldval + num/denom; while ( abs(newval - oldval) > eps ) loop oldval := newval; num := num*xlocal; count := count +1; denom := denom*(real(count)); newval := oldval + num/denom; end loop; if reciprocal then newval := 1.0/newval; end if; return newval; end EXP; function LOG (X : real ) return real is -- returns natural logarithm of X; X > 0 -- -- This function computes the exponential using the following series: -- log(x) = 2[ (x-1)/(x+1) + (((x-1)/(x+1))**3)/3.0 + ...] ; x > 0 -- constant eps : real := 0.000001; -- precision criteria variable xlocal: real ; -- following variables are variable oldval: real ; -- used to evaluate the series variable xlocalsqr: real ; variable factor : real ; variable count: integer ; variable newval: real ; begin -- check validity of argument if ( x <= 0.0 ) then assert false report "X <= 0 in LOG(X)" severity ERROR; return(REAL'LOW); end if; -- compute value for special cases if ( X = 1.0 ) then return 0.0; else if ( X = MATH_E ) then return 1.0; end if; end if; -- compute value for general cases xlocal := (X - 1.0)/(X + 1.0); oldval := xlocal; xlocalsqr := xlocal*xlocal; factor := xlocal*xlocalsqr; count := 3; newval := oldval + (factor/real(count)); while ( abs(newval - oldval) > eps ) loop oldval := newval; count := count +2; factor := factor * xlocalsqr; newval := oldval + factor/real(count); end loop; newval := newval * 2.0; return newval; end LOG; function LOG (BASE: positive; X : real) return real is -- returns logarithm base BASE of X; X > 0 begin -- check validity of argument if ( BASE <= 0 ) or ( x <= 0.0 ) then assert false report "BASE <= 0 or X <= 0.0 in LOG(BASE, X)" severity ERROR; return(REAL'LOW); end if; -- compute the value return ( LOG(X)/LOG(REAL(BASE))); end LOG; function SIN (X : real ) return real is -- returns sin X; X in radians variable n : INTEGER; begin if (x < 1.6 ) and (x > -1.6) then return CORDIC( KC, 0.0, x, 27, ROTATION)(1); end if; n := INTEGER( x / HALF_PI ); case QUADRANT( n mod 4 ) is when 0 => return CORDIC( KC, 0.0, x - REAL(n) * HALF_PI, 27, ROTATION)(1); when 1 => return CORDIC( KC, 0.0, x - REAL(n) * HALF_PI, 27, ROTATION)(0); when 2 => return -CORDIC( KC, 0.0, x - REAL(n) * HALF_PI, 27, ROTATION)(1); when 3 => return -CORDIC( KC, 0.0, x - REAL(n) * HALF_PI, 27, ROTATION)(0); end case; end SIN; function COS (x : REAL) return REAL is -- returns cos X; X in radians variable n : INTEGER; begin if (x < 1.6 ) and (x > -1.6) then return CORDIC( KC, 0.0, x, 27, ROTATION)(0); end if; n := INTEGER( x / HALF_PI ); case QUADRANT( n mod 4 ) is when 0 => return CORDIC( KC, 0.0, x - REAL(n) * HALF_PI, 27, ROTATION)(0); when 1 => return -CORDIC( KC, 0.0, x - REAL(n) * HALF_PI, 27, ROTATION)(1); when 2 => return -CORDIC( KC, 0.0, x - REAL(n) * HALF_PI, 27, ROTATION)(0); when 3 => return CORDIC( KC, 0.0, x - REAL(n) * HALF_PI, 27, ROTATION)(1); end case; end COS; function TAN (x : REAL) return REAL is -- returns tan X; X in radians -- X /= ((2k+1) * PI/2), where k is an integer variable n : INTEGER := INTEGER( x / HALF_PI ); variable v : REAL_ARR_3 := CORDIC( KC, 0.0, x - REAL(n) * HALF_PI, 27, ROTATION); begin if n mod 2 = 0 then return v(1)/v(0); else return -v(0)/v(1); end if; end TAN; function ASIN (x : real ) return real is -- returns -PI/2 < asin X < PI/2; | X | <= 1 begin if abs x > 1.0 then assert false report "Out of range parameter passed to ASIN" severity ERROR; return x; elsif abs x < 0.9 then return atan(x/(sqrt(1.0 - x*x))); elsif x > 0.0 then return HALF_PI - atan(sqrt(1.0 - x*x)/x); else return - HALF_PI + atan((sqrt(1.0 - x*x))/x); end if; end ASIN; function ACOS (x : REAL) return REAL is -- returns 0 < acos X < PI; | X | <= 1 begin if abs x > 1.0 then assert false report "Out of range parameter passed to ACOS" severity ERROR; return x; elsif abs x > 0.9 then if x > 0.0 then return atan(sqrt(1.0 - x*x)/x); else return MATH_PI - atan(sqrt(1.0 - x*x)/x); end if; else return HALF_PI - atan(x/sqrt(1.0 - x*x)); end if; end ACOS; function ATAN (x : REAL) return REAL is -- returns -PI/2 < atan X < PI/2 begin return CORDIC( 1.0, x, 0.0, 27, VECTORING )(2); end ATAN; function ATAN2 (x : REAL; y : REAL) return REAL is -- returns atan (X/Y); -PI < atan2(X,Y) < PI; Y /= 0.0 begin if y = 0.0 then if x = 0.0 then assert false report "atan2(0.0, 0.0) is undetermined, returned 0,0" severity NOTE; return 0.0; elsif x > 0.0 then return 0.0; else return MATH_PI; end if; elsif x > 0.0 then return CORDIC( x, y, 0.0, 27, VECTORING )(2); else return MATH_PI + CORDIC( x, y, 0.0, 27, VECTORING )(2); end if; end ATAN2; function SINH (X : real) return real is -- hyperbolic sine; returns (e**X - e**(-X))/2 begin return ( (EXP(X) - EXP(-X))/2.0 ); end SINH; function COSH (X : real) return real is -- hyperbolic cosine; returns (e**X + e**(-X))/2 begin return ( (EXP(X) + EXP(-X))/2.0 ); end COSH; function TANH (X : real) return real is -- hyperbolic tangent; -- returns (e**X - e**(-X))/(e**X + e**(-X)) begin return ( (EXP(X) - EXP(-X))/(EXP(X) + EXP(-X)) ); end TANH; function ASINH (X : real) return real is -- returns ln( X + sqrt( X**2 + 1)) begin return ( LOG( X + SQRT( X**2 + 1.0)) ); end ASINH; function ACOSH (X : real) return real is -- returns ln( X + sqrt( X**2 - 1)); X >= 1 begin if abs x >= 1.0 then assert false report "Out of range parameter passed to ACOSH" severity ERROR; return x; end if; return ( LOG( X + SQRT( X**2 - 1.0)) ); end ACOSH; function ATANH (X : real) return real is -- returns (ln( (1 + X)/(1 - X)))/2 ; | X | < 1 begin if abs x < 1.0 then assert false report "Out of range parameter passed to ATANH" severity ERROR; return x; end if; return( LOG( (1.0+X)/(1.0-X) )/2.0 ); end ATANH; end MATH_REAL; --------------------------------------------------------------- -- -- This source file may be used and distributed without restriction. -- No declarations or definitions shall be included in this package. -- This package cannot be sold or distributed for profit. -- -- **************************************************************** -- * * -- * W A R N I N G * -- * * -- * This DRAFT version IS NOT endorsed or approved by IEEE * -- * * -- **************************************************************** -- -- Title: PACKAGE BODY MATH_COMPLEX -- -- Purpose: VHDL declarations for mathematical package MATH_COMPLEX -- which contains common complex constants and basic complex -- functions and operations. -- -- Author: IEEE VHDL Math Package Study Group -- -- Notes: -- The package body uses package IEEE.MATH_REAL -- -- The package body shall be considered the formal definition of -- the semantics of this package. Tool developers may choose to implement -- the package body in the most efficient manner available to them. -- -- Source code for this package body comes from the following -- following sources: -- IEEE VHDL Math Package Study Group participants, -- U. of Mississippi, Mentor Graphics, Synopsys, -- Viewlogic/Vantage, Communications of the ACM (June 1988, Vol -- 31, Number 6, pp. 747, Pierre L'Ecuyer, Efficient and Portable -- Random Number Generators, Handbook of Mathematical Functions -- by Milton Abramowitz and Irene A. Stegun (Dover). -- -- History: -- Version 0.1 Jose A. Torres 4/23/93 First draft -- Version 0.2 Jose A. Torres 5/28/93 Fixed potentially illegal code -- ------------------------------------------------------------- Library IEEE; Use IEEE.MATH_REAL.all; -- real trascendental operations Package body MATH_COMPLEX is function CABS(Z: in complex ) return real is -- returns absolute value (magnitude) of Z variable ztemp : complex_polar; begin ztemp := COMPLEX_TO_POLAR(Z); return ztemp.mag; end CABS; function CARG(Z: in complex ) return real is -- returns argument (angle) in radians of a complex number variable ztemp : complex_polar; begin ztemp := COMPLEX_TO_POLAR(Z); return ztemp.arg; end CARG; function CMPLX(X: in real; Y: in real := 0.0 ) return complex is -- returns complex number X + iY begin return COMPLEX'(X, Y); end CMPLX; function "-" (Z: in complex ) return complex is -- unary minus; returns -x -jy for z= x + jy begin return COMPLEX'(-z.Re, -z.Im); end "-"; function "-" (Z: in complex_polar ) return complex_polar is -- unary minus; returns (z.mag, z.arg + MATH_PI) begin return COMPLEX_POLAR'(z.mag, z.arg + MATH_PI); end "-"; function CONJ (Z: in complex) return complex is -- returns complex conjugate (x-jy for z = x+ jy) begin return COMPLEX'(z.Re, -z.Im); end CONJ; function CONJ (Z: in complex_polar) return complex_polar is -- returns complex conjugate (z.mag, -z.arg) begin return COMPLEX_POLAR'(z.mag, -z.arg); end CONJ; function CSQRT(Z: in complex ) return complex_vector is -- returns square root of Z; 2 values variable ztemp : complex_polar; variable zout : complex_vector (0 to 1); variable temp : real; begin ztemp := COMPLEX_TO_POLAR(Z); temp := SQRT(ztemp.mag); zout(0).re := temp*COS(ztemp.arg/2.0); zout(0).im := temp*SIN(ztemp.arg/2.0); zout(1).re := temp*COS(ztemp.arg/2.0 + MATH_PI); zout(1).im := temp*SIN(ztemp.arg/2.0 + MATH_PI); return zout; end CSQRT; function CEXP(Z: in complex ) return complex is -- returns e**Z begin return COMPLEX'(EXP(Z.re)*COS(Z.im), EXP(Z.re)*SIN(Z.im)); end CEXP; function COMPLEX_TO_POLAR(Z: in complex ) return complex_polar is -- converts complex to complex_polar begin return COMPLEX_POLAR'(sqrt(z.re**2 + z.im**2),atan2(z.re,z.im)); end COMPLEX_TO_POLAR; function POLAR_TO_COMPLEX(Z: in complex_polar ) return complex is -- converts complex_polar to complex begin return COMPLEX'( z.mag*cos(z.arg), z.mag*sin(z.arg) ); end POLAR_TO_COMPLEX; -- -- arithmetic operators -- function "+" ( L: in complex; R: in complex ) return complex is begin return COMPLEX'(L.Re + R.Re, L.Im + R.Im); end "+"; function "+" (L: in complex_polar; R: in complex_polar) return complex is variable zL, zR : complex; begin zL := POLAR_TO_COMPLEX( L ); zR := POLAR_TO_COMPLEX( R ); return COMPLEX'(zL.Re + zR.Re, zL.Im + zR.Im); end "+"; function "+" ( L: in complex_polar; R: in complex ) return complex is variable zL : complex; begin zL := POLAR_TO_COMPLEX( L ); return COMPLEX'(zL.Re + R.Re, zL.Im + R.Im); end "+"; function "+" ( L: in complex; R: in complex_polar) return complex is variable zR : complex; begin zR := POLAR_TO_COMPLEX( R ); return COMPLEX'(L.Re + zR.Re, L.Im + zR.Im); end "+"; function "+" ( L: in real; R: in complex ) return complex is begin return COMPLEX'(L + R.Re, R.Im); end "+"; function "+" ( L: in complex; R: in real ) return complex is begin return COMPLEX'(L.Re + R, L.Im); end "+"; function "+" ( L: in real; R: in complex_polar) return complex is variable zR : complex; begin zR := POLAR_TO_COMPLEX( R ); return COMPLEX'(L + zR.Re, zR.Im); end "+"; function "+" ( L: in complex_polar; R: in real) return complex is variable zL : complex; begin zL := POLAR_TO_COMPLEX( L ); return COMPLEX'(zL.Re + R, zL.Im); end "+"; function "-" ( L: in complex; R: in complex ) return complex is begin return COMPLEX'(L.Re - R.Re, L.Im - R.Im); end "-"; function "-" ( L: in complex_polar; R: in complex_polar) return complex is variable zL, zR : complex; begin zL := POLAR_TO_COMPLEX( L ); zR := POLAR_TO_COMPLEX( R ); return COMPLEX'(zL.Re - zR.Re, zL.Im - zR.Im); end "-"; function "-" ( L: in complex_polar; R: in complex ) return complex is variable zL : complex; begin zL := POLAR_TO_COMPLEX( L ); return COMPLEX'(zL.Re - R.Re, zL.Im - R.Im); end "-"; function "-" ( L: in complex; R: in complex_polar) return complex is variable zR : complex; begin zR := POLAR_TO_COMPLEX( R ); return COMPLEX'(L.Re - zR.Re, L.Im - zR.Im); end "-"; function "-" ( L: in real; R: in complex ) return complex is begin return COMPLEX'(L - R.Re, -1.0 * R.Im); end "-"; function "-" ( L: in complex; R: in real ) return complex is begin return COMPLEX'(L.Re - R, L.Im); end "-"; function "-" ( L: in real; R: in complex_polar) return complex is variable zR : complex; begin zR := POLAR_TO_COMPLEX( R ); return COMPLEX'(L - zR.Re, -1.0*zR.Im); end "-"; function "-" ( L: in complex_polar; R: in real) return complex is variable zL : complex; begin zL := POLAR_TO_COMPLEX( L ); return COMPLEX'(zL.Re - R, zL.Im); end "-"; function "*" ( L: in complex; R: in complex ) return complex is begin return COMPLEX'(L.Re * R.Re - L.Im * R.Im, L.Re * R.Im + L.Im * R.Re); end "*"; function "*" ( L: in complex_polar; R: in complex_polar) return complex is variable zout : complex_polar; begin zout.mag := L.mag * R.mag; zout.arg := L.arg + R.arg; return POLAR_TO_COMPLEX(zout); end "*"; function "*" ( L: in complex_polar; R: in complex ) return complex is variable zL : complex; begin zL := POLAR_TO_COMPLEX( L ); return COMPLEX'(zL.Re*R.Re - zL.Im * R.Im, zL.Re * R.Im + zL.Im*R.Re); end "*"; function "*" ( L: in complex; R: in complex_polar) return complex is variable zR : complex; begin zR := POLAR_TO_COMPLEX( R ); return COMPLEX'(L.Re*zR.Re - L.Im * zR.Im, L.Re * zR.Im + L.Im*zR.Re); end "*"; function "*" ( L: in real; R: in complex ) return complex is begin return COMPLEX'(L * R.Re, L * R.Im); end "*"; function "*" ( L: in complex; R: in real ) return complex is begin return COMPLEX'(L.Re * R, L.Im * R); end "*"; function "*" ( L: in real; R: in complex_polar) return complex is variable zR : complex; begin zR := POLAR_TO_COMPLEX( R ); return COMPLEX'(L * zR.Re, L * zR.Im); end "*"; function "*" ( L: in complex_polar; R: in real) return complex is variable zL : complex; begin zL := POLAR_TO_COMPLEX( L ); return COMPLEX'(zL.Re * R, zL.Im * R); end "*"; function "/" ( L: in complex; R: in complex ) return complex is variable magrsq : REAL := R.Re ** 2 + R.Im ** 2; begin if (magrsq = 0.0) then assert FALSE report "Attempt to divide by (0,0)" severity ERROR; return COMPLEX'(REAL'RIGHT, REAL'RIGHT); else return COMPLEX'( (L.Re * R.Re + L.Im * R.Im) / magrsq, (L.Im * R.Re - L.Re * R.Im) / magrsq); end if; end "/"; function "/" ( L: in complex_polar; R: in complex_polar) return complex is variable zout : complex_polar; begin if (R.mag = 0.0) then assert FALSE report "Attempt to divide by (0,0)" severity ERROR; return COMPLEX'(REAL'RIGHT, REAL'RIGHT); else zout.mag := L.mag/R.mag; zout.arg := L.arg - R.arg; return POLAR_TO_COMPLEX(zout); end if; end "/"; function "/" ( L: in complex_polar; R: in complex ) return complex is variable zL : complex; variable temp : REAL := R.Re ** 2 + R.Im ** 2; begin if (temp = 0.0) then assert FALSE report "Attempt to divide by (0.0,0.0)" severity ERROR; return COMPLEX'(REAL'RIGHT, REAL'RIGHT); else zL := POLAR_TO_COMPLEX( L ); return COMPLEX'( (zL.Re * R.Re + zL.Im * R.Im) / temp, (zL.Im * R.Re - zL.Re * R.Im) / temp); end if; end "/"; function "/" ( L: in complex; R: in complex_polar) return complex is variable zR : complex := POLAR_TO_COMPLEX( R ); variable temp : REAL := zR.Re ** 2 + zR.Im ** 2; begin if (R.mag = 0.0) or (temp = 0.0) then assert FALSE report "Attempt to divide by (0.0,0.0)" severity ERROR; return COMPLEX'(REAL'RIGHT, REAL'RIGHT); else return COMPLEX'( (L.Re * zR.Re + L.Im * zR.Im) / temp, (L.Im * zR.Re - L.Re * zR.Im) / temp); end if; end "/"; function "/" ( L: in real; R: in complex ) return complex is variable temp : REAL := R.Re ** 2 + R.Im ** 2; begin if (temp = 0.0) then assert FALSE report "Attempt to divide by (0.0,0.0)" severity ERROR; return COMPLEX'(REAL'RIGHT, REAL'RIGHT); else temp := L / temp; return COMPLEX'( temp * R.Re, -temp * R.Im ); end if; end "/"; function "/" ( L: in complex; R: in real ) return complex is begin if (R = 0.0) then assert FALSE report "Attempt to divide by (0.0,0.0)" severity ERROR; return COMPLEX'(REAL'RIGHT, REAL'RIGHT); else return COMPLEX'(L.Re / R, L.Im / R); end if; end "/"; function "/" ( L: in real; R: in complex_polar) return complex is variable zR : complex := POLAR_TO_COMPLEX( R ); variable temp : REAL := zR.Re ** 2 + zR.Im ** 2; begin if (R.mag = 0.0) or (temp = 0.0) then assert FALSE report "Attempt to divide by (0.0,0.0)" severity ERROR; return COMPLEX'(REAL'RIGHT, REAL'RIGHT); else temp := L / temp; return COMPLEX'( temp * zR.Re, -temp * zR.Im ); end if; end "/"; function "/" ( L: in complex_polar; R: in real) return complex is variable zL : complex := POLAR_TO_COMPLEX( L ); begin if (R = 0.0) then assert FALSE report "Attempt to divide by (0.0,0.0)" severity ERROR; return COMPLEX'(REAL'RIGHT, REAL'RIGHT); else return COMPLEX'(zL.Re / R, zL.Im / R); end if; end "/"; end MATH_COMPLEX; ============================================================VHDL MATH Package Study Subgroup This is the state of the proposal about the standard math package. I only send you the declaration parts of the two packages (I can send you the bodies if needed). Implementation of package bodies is optional, but package bodies define the semantics and minimum level of precision required from an implementation If you need additional functionalities, please let me know which ones before it will be too late. This proposal has been compiled to check for valid VHDL syntax, but it has not been validated in terms of valid functionality (results). Thanks, Jean-Michel ****************************************************************** ------------------------------------------------------------------------ -- -- This source file may be used and distributed without restriction. -- No declarations or definitions shall be added to this package. -- This package cannot be sold or distributed for profit. -- -- **************************************************************** -- * * -- * W A R N I N G * -- * * -- * This DRAFT version IS NOT endorsed or approved by IEEE * -- * * -- **************************************************************** -- -- Title: PACKAGE MATH_REAL -- -- Library: This package shall be compiled into a library -- symbolically named IEEE. -- -- Purpose: VHDL declarations for mathematical package MATH_REAL -- which contains common real constants, common real -- functions, and real trascendental functions. -- -- Author: IEEE VHDL Math Package Study Group -- -- Notes: -- The package body shall be considered the formal definition of -- the semantics of this package. Tool developers may choose to implement -- the package body in the most efficient manner available to them. -- -- History: -- Version 0.1 (Strawman) Jose A. Torres 6/22/92 -- Version 0.2 Jose A. Torres 1/15/93 -- Version 0.3 Jose A. Torres 4/13/93 -- Version 0.4 Jose A. Torres 4/19/93 -- Version 0.5 Jose A. Torres 4/20/93 Added RANDOM() -- Version 0.6 Jose A. Torres 4/23/93 Renamed RANDOM as -- UNIFORM. Modified -- rights banner. -- Version 0.7 Jose A. Torres 5/28/93 Rev up for compatibility -- with package body. ------------------------------------------------------------- Library IEEE; Package MATH_REAL is -- -- commonly used constants -- constant MATH_E : real := 2.71828_18284_59045_23536; -- value of e constant MATH_1_E: real := 0.36787_94411_71442_32160; -- value of 1/e constant MATH_PI : real := 3.14159_26535_89793_23846; -- value of pi constant MATH_1_PI : real := 0.31830_98861_83790_67154; -- value of 1/pi constant MATH_LOG_OF_2: real := 0.69314_71805_59945_30942; -- natural log of 2 constant MATH_LOG_OF_10: real := 2.30258_50929_94045_68402; -- natural log of10 constant MATH_LOG2_OF_E: real := 1.44269_50408_88963_4074; -- log base 2 of e constant MATH_LOG10_OF_E: real := 0.43429_44819_03251_82765; -- log base 10 of e constant MATH_SQRT2: real := 1.41421_35623_73095_04880; -- sqrt of 2 constant MATH_SQRT1_2: real := 0.70710_67811_86547_52440; -- sqrt of 1/2 constant MATH_SQRT_PI: real := 1.77245_38509_05516_02730; -- sqrt of pi constant MATH_DEG_TO_RAD: real := 0.01745_32925_19943_29577; -- conversion factor from degree to radian constant MATH_RAD_TO_DEG: real := 57.29577_95130_82320_87685; -- conversion factor from radian to degree -- -- attribute for functions whose implementation is foreign (C native) -- attribute FOREIGN : string; -- predefined attribute in VHDL-1992 -- -- function declarations -- function SIGN (X: real ) return real; -- returns 1.0 if X > 0.0; 0.0 if X == 0.0; -1.0 if X < 0.0 function CEIL (X : real ) return real; -- returns smallest integer value (as real) not less than X function FLOOR (X : real ) return real; -- returns largest integer value (as real) not greater than X function ROUND (X : real ) return real; -- returns integer FLOOR(X + 0.5) if X > 0; -- return integer CEIL(X - 0.5) if X < 0 function FMAX (X, Y : real ) return real; -- returns the algebraically larger of X and Y function FMIN (X, Y : real ) return real; -- returns the algebraically smaller of X and Y procedure UNIFORM (variable Seed1,Seed2:inout integer; variable X:out real); -- returns a pseudo-random number with uniform distribution in the -- interval (0.0, 1.0). -- Before the first call to UNIFORM, the seed values (Seed1, Seed2) must -- be initialized to values in the range [1, 2147483562] and -- [1, 2147483398] respectively. The seed values are modified after -- each call to UNIFORM. -- This random number generator is portable for 32-bit computers, and -- it has period ~2.30584*(10**18) for each set of seed values. -- -- For VHDL-1992, the seeds will be global variables, functions to -- initialize their values (INIT_SEED) will be provided, and the UNIFORM -- procedure call will be modified accordingly. function SRAND (seed: in integer ) return integer; -- -- sets value of seed for sequence of -- pseudo-random numbers. -- It uses the foreign native C function srand(). attribute FOREIGN of SRAND : function is "C_NATIVE"; function RAND return integer; -- -- returns an integer pseudo-random number with uniform distribution. -- It uses the foreign native C function rand(). -- Seed for the sequence is initialized with the -- SRAND() function and value of the seed is changed every -- time SRAND() is called, but it is not visible. -- The range of generated values is platform dependent. attribute FOREIGN of RAND : function is "C_NATIVE"; function GET_RAND_MAX return integer; -- -- returns the upper bound of the range of the -- pseudo-random numbers generated by RAND(). -- The support for this function is platform dependent, and -- it uses foreign native C functions or constants. -- It may not be available in some platforms. -- Note: the value of (RAND() / GET_RAND_MAX()) is a -- pseudo-random number distributed between 0 & 1. attribute FOREIGN of GET_RAND_MAX : function is "C_NATIVE"; function SQRT (X : real ) return real; -- returns square root of X; X >= 0 function CBRT (X : real ) return real; -- returns cube root of X function "**" (X : integer; Y : real) return real; -- returns Y power of X ==> X**Y; -- error if X = 0 and Y <= 0.0 -- error if X < 0 and Y does not have an integer value function "**" (X : real; Y : real) return real; -- returns Y power of X ==> X**Y; -- error if X = 0.0 and Y <= 0.0 -- error if X < 0.0 and Y does not have an integer value function EXP (X : real ) return real; -- returns e**X; where e = MATH_E function LOG (X : real ) return real; -- returns natural logarithm of X; X > 0 function LOG (BASE: positive; X : real) return real; -- returns logarithm base BASE of X; X > 0 function SIN (X : real ) return real; -- returns sin X; X in radians function COS ( X : real ) return real; -- returns cos X; X in radians function TAN (X : real ) return real; -- returns tan X; X in radians -- X /= ((2k+1) * PI/2), where k is an integer function ASIN (X : real ) return real; -- returns -PI/2 < asin X < PI/2; | X | <= 1 function ACOS (X : real ) return real; -- returns 0 < acos X < PI; | X | <= 1 function ATAN (X : real) return real; -- returns -PI/2 < atan X < PI/2 function ATAN2 (X : real; Y : real) return real; -- returns atan (X/Y); -PI < atan2(X,Y) < PI; Y /= 0.0 function SINH (X : real) return real; -- hyperbolic sine; returns (e**X - e**(-X))/2 function COSH (X : real) return real; -- hyperbolic cosine; returns (e**X + e**(-X))/2 function TANH (X : real) return real; -- hyperbolic tangent; -- returns (e**X - e**(-X))/(e**X + e**(-X)) function ASINH (X : real) return real; -- returns ln( X + sqrt( X**2 + 1)) function ACOSH (X : real) return real; -- returns ln( X + sqrt( X**2 - 1)); X >= 1 function ATANH (X : real) return real; -- returns (ln( (1 + X)/(1 - X)))/2 ; | X | < 1 end MATH_REAL; --------------------------------------------------------------- -- -- This source file may be used and distributed without restriction. -- No declarations or definitions shall be included in this package. -- This package cannot be sold or distributed for profit. -- -- **************************************************************** -- * * -- * W A R N I N G * -- * * -- * This DRAFT version IS NOT endorsed or approved by IEEE * -- * * -- **************************************************************** -- -- Title: PACKAGE MATH_COMPLEX -- -- Purpose: VHDL declarations for mathematical package MATH_COMPLEX -- which contains common complex constants and basic complex -- functions and operations. -- -- Author: IEEE VHDL Math Package Study Group -- -- Notes: -- The package body uses package IEEE.MATH_REAL -- -- The package body shall be considered the formal definition of -- the semantics of this package. Tool developers may choose to implement -- the package body in the most efficient manner available to them. -- -- History: -- Version 0.1 (Strawman) Jose A. Torres 6/22/92 -- Version 0.2 Jose A. Torres 1/15/93 -- Version 0.3 Jose A. Torres 4/13/93 -- Version 0.4 Jose A. Torres 4/19/93 -- Version 0.5 Jose A. Torres 4/20/93 -- Version 0.6 Jose A. Torres 4/23/93 Added unary minus -- and CONJ for polar -- Version 0.7 Jose A. Torres 5/28/93 Rev up for compatibility -- with package body. ------------------------------------------------------------- Library IEEE; Package MATH_COMPLEX is type COMPLEX is record RE, IM: real; end record; type COMPLEX_VECTOR is array (integer range <>) of COMPLEX; type COMPLEX_POLAR is record MAG: real; ARG: real; end record; constant CBASE_1: complex := COMPLEX'(1.0, 0.0); constant CBASE_j: complex := COMPLEX'(0.0, 1.0); constant CZERO: complex := COMPLEX'(0.0, 0.0); function CABS(Z: in complex ) return real; -- returns absolute value (magnitude) of Z function CARG(Z: in complex ) return real; -- returns argument (angle) in radians of a complex number function CMPLX(X: in real; Y: in real:= 0.0 ) return complex; -- returns complex number X + iY function "-" (Z: in complex ) return complex; -- unary minus function "-" (Z: in complex_polar ) return complex_polar; -- unary minus function CONJ (Z: in complex) return complex; -- returns complex conjugate function CONJ (Z: in complex_polar) return complex_polar; -- returns complex conjugate function CSQRT(Z: in complex ) return complex_vector; -- returns square root of Z; 2 values function CEXP(Z: in complex ) return complex; -- returns e**Z function COMPLEX_TO_POLAR(Z: in complex ) return complex_polar; -- converts complex to complex_polar function POLAR_TO_COMPLEX(Z: in complex_polar ) return complex; -- converts complex_polar to complex -- arithmetic operators function "+" ( L: in complex; R: in complex ) return complex; function "+" ( L: in complex_polar; R: in complex_polar) return complex; function "+" ( L: in complex_polar; R: in complex ) return complex; function "+" ( L: in complex; R: in complex_polar) return complex; function "+" ( L: in real; R: in complex ) return complex; function "+" ( L: in complex; R: in real ) return complex; function "+" ( L: in real; R: in complex_polar) return complex; function "+" ( L: in complex_polar; R: in real) return complex; function "-" ( L: in complex; R: in complex ) return complex; function "-" ( L: in complex_polar; R: in complex_polar) return complex; function "-" ( L: in complex_polar; R: in complex ) return complex; function "-" ( L: in complex; R: in complex_polar) return complex; function "-" ( L: in real; R: in complex ) return complex; function "-" ( L: in complex; R: in real ) return complex; function "-" ( L: in real; R: in complex_polar) return complex; function "-" ( L: in complex_polar; R: in real) return complex; function "*" ( L: in complex; R: in complex ) return complex; function "*" ( L: in complex_polar; R: in complex_polar) return complex; function "*" ( L: in complex_polar; R: in complex ) return complex; function "*" ( L: in complex; R: in complex_polar) return complex; function "*" ( L: in real; R: in complex ) return complex; function "*" ( L: in complex; R: in real ) return complex; function "*" ( L: in real; R: in complex_polar) return complex; function "*" ( L: in complex_polar; R: in real) return complex; function "/" ( L: in complex; R: in complex ) return complex; function "/" ( L: in complex_polar; R: in complex_polar) return complex; function "/" ( L: in complex_polar; R: in complex ) return complex; function "/" ( L: in complex; R: in complex_polar) return complex; function "/" ( L: in real; R: in complex ) return complex; function "/" ( L: in complex; R: in real ) return complex; function "/" ( L: in real; R: in complex_polar) return complex; function "/" ( L: in complex_polar; R: in real) return complex; end MATH_COMPLEX;