diff options
author | gingold | 2005-09-24 05:10:24 +0000 |
---|---|---|
committer | gingold | 2005-09-24 05:10:24 +0000 |
commit | 977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849 (patch) | |
tree | 7bcf8e7aff40a8b54d4af83e90cccd73568e77bb /libraries/ieee/math_complex-body.vhdl | |
download | ghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.tar.gz ghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.tar.bz2 ghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.zip |
First import from sources
Diffstat (limited to 'libraries/ieee/math_complex-body.vhdl')
-rw-r--r-- | libraries/ieee/math_complex-body.vhdl | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/libraries/ieee/math_complex-body.vhdl b/libraries/ieee/math_complex-body.vhdl new file mode 100644 index 0000000..9b8b75a --- /dev/null +++ b/libraries/ieee/math_complex-body.vhdl @@ -0,0 +1,394 @@ +--------------------------------------------------------------- +-- +-- 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; |