📄 mathpack.vhd
字号:
-- 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 CUSTOM;
Use CUSTOM.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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -