- improved UTILS_FREQ_M(), UTILS_FREQ_D().

Committed on the Free edition of March Hare Software CVSNT Server.
Upgrade to CVS Suite for more features and support:
http://march-hare.com/cvsnt/


git-svn-id: http://moon:8086/svn/vhdl/trunk@739 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2010-02-09 10:16:36 +00:00
parent 80dbbd7024
commit a3a85d2c98
+62 -21
View File
@@ -1,5 +1,5 @@
-----------------------------------------------------------------------
-- $Header: /tmp/cvsroot/VHDL/lib/misc/utils_pkg.vhd,v 1.4 2010-02-09 07:46:19 Jens Exp $
-- $Header: /tmp/cvsroot/VHDL/lib/misc/utils_pkg.vhd,v 1.5 2010-02-09 10:16:36 Jens Exp $
-----------------------------------------------------------------------
library IEEE;
@@ -21,6 +21,7 @@ package utils_pkg is
function UTILS_PERIOD_NS(f_in_MHz : real) return real;
function UTILS_FREQ_M(f_in_MHz, f_out_MHz : real) return natural;
function UTILS_FREQ_D(f_in_MHz, f_out_MHz : real) return natural;
function f_correct(f : real) return natural;
end utils_pkg;
@@ -82,37 +83,77 @@ package body utils_pkg is
end UTILS_PERIOD_NS;
function UTILS_FREQ_M(f_in_MHz, f_out_MHz : real) return natural is
variable f_in_hz : natural;
variable f_out_hz : natural;
variable m : natural;
variable f_in : natural;
variable f_out : natural;
variable C : natural;
variable M : natural;
variable D : natural;
begin
f_in_hz := natural(f_in_MHz*1.0E6);
f_out_hz := natural(f_out_MHz*1.0E6);
m := f_out_hz/GCD(f_in_hz, f_out_hz);
if m = 1 then
m := 2;
C := f_correct(f_out_MHz);
if C < 2 then
C := f_correct(f_in_MHz);
end if;
return m;
f_out := natural(ceil(real(C)*f_out_MHz));
f_in := natural(ceil(real(C)*f_in_MHz));
M := LCM(f_in, f_out)/f_in;
D := f_in/GCD(f_in, f_out);
assert (M*D) /= (f_in*f_out) report "Finding M and D failed!" severity failure;
if M = 1 then
M := 2;
end if;
return M;
end UTILS_FREQ_M;
function UTILS_FREQ_D(f_in_MHz, f_out_MHz : real) return natural is
variable f_in_hz : natural;
variable f_out_hz : natural;
variable m : natural;
variable d : natural;
variable f_in : natural;
variable f_out : natural;
variable C : natural;
variable M : natural;
variable D : natural;
begin
m := UTILS_FREQ_M(f_in_MHz, f_out_MHz);
f_in_hz := natural(f_in_MHz*1.0E6);
f_out_hz := natural(f_out_MHz*1.0E6);
d := m*f_in_hz/f_out_hz;
C := f_correct(f_out_MHz);
if C < 2 then
C := f_correct(f_in_MHz);
end if;
f_out := natural(ceil(real(C)*f_out_MHz));
f_in := natural(ceil(real(C)*f_in_MHz));
M := LCM(f_in, f_out)/f_in;
D := f_in/GCD(f_in, f_out);
assert (M*D) /= (f_in*f_out) report "Finding M and D failed!" severity failure;
if M = 1 then
D := 2*D;
end if;
return d;
return D;
end UTILS_FREQ_D;
function f_correct(f : real) return natural is
constant MAX_ITER : positive := 100;
constant MAX_ERR : real := 0.01;
variable fpart : real;
variable err : real;
begin
for i in 1 to MAX_ITER loop
fpart := real(i)*f - ceil(real(i)*f);
err := abs(fpart);
if err < max_err then
return i;
end if;
end loop;
end f_correct;
end utils_pkg;