- 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:
+62
-21
@@ -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;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user