OpenCores
URL https://opencores.org/ocsvn/ratpack/ratpack/trunk

Subversion Repositories ratpack

[/] [ratpack/] [trunk/] [rtl/] [vhdl/] [ratpack.vhd] - Rev 5

Compare with Previous | Blame | View Log

--------------------------------------------------------------------------------
-- Filename: ratpack.vhd
-- Purpose : Rational arithmetic package
-- Author  : Nikolaos Kavvadias <nikolaos.kavvadias@gmail.com>
-- Date    : 21-Feb-2014
-- Version : 0.1.0
-- Revision: 0.0.0 (2009/07/25)
--           Initial version. Added the definition of a rational number, and the
--           implementation of the "+", "-", "*", "/" operators on reduced
--           rational numbers (i.e. relative primes), the gcd(x,y) and the
--           mediant operator.
--           0.0.1 (2009/07/28)
--           Added: numerator, denominator, abs, relational operators (>, <, >=,
--           <=, =, /=, changed the int2rat to to_rational, new version of
--           int2rat (casting an integer to a rational).
--           0.0.2 (2010/11/17)
--           Added an iterative version for the gcd computation (gcditer).
--           0.0.3 (2012/02/11)
--           Added max, min.
--           0.1.0 (2014/02/21)
--           Upgraded to version 0.1.0.
-- License : Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 by Nikolaos Kavvadias
--           This program is free software. You can redistribute it and/or 
--           modify it under the terms of the GNU Lesser General Public License, 
--           either version 3 of the License, or (at your option) any later 
--           version. See COPYING.
--
--------------------------------------------------------------------------------
 
package ratpack is 
 
  -- A rational number is defined by the pair (numerator, denominator) where 
  -- both numbers. -- are in the range [-16384, 16383].
  constant numer : INTEGER := 0; -- numerator
  constant denom : INTEGER := 1; -- denominator
  type rational is array (natural range numer to denom) of 
    integer; -- range -16384 to 16383;
  constant RAT_ZERO : rational := (0, 1);
  constant RAT_ONE  : rational := (1, 1);
 
  function to_rational (a, b : integer) return rational;
  function int2rat (a : integer) return rational;
  function numerator (a : rational) return integer;
  function denominator (a : rational) return integer;
  function "+" (a, b : rational) return rational;
  function "-" (a, b : rational) return rational;
  function "*" (a, b : rational) return rational;
  function "/" (a, b : rational) return rational;
  function "abs" (a : rational)  return rational;
  function max (a, b : rational) return rational;
  function min (a, b : rational) return rational;
  function ">" (a, b : rational) return boolean;
  function "<" (a, b : rational) return boolean;
  function ">=" (a, b : rational) return boolean;
  function "<=" (a, b : rational) return boolean;
  function "=" (a, b : rational) return boolean;
  function "/=" (a, b : rational) return boolean;
  function gcd (a, b : integer)  return integer;
  function gcditer (a, b : integer)  return integer;
  function mediant (a, b : rational) return rational;
 
end ratpack;
 
 
package body ratpack is
 
  function to_rational (a, b : integer) return rational is
    variable r : rational;
  begin
    r(numer) := a;
    r(denom) := b;
    return r;
  end to_rational;
 
  function int2rat (a : integer) return rational is
    variable r : rational;
  begin
    r(numer) := a;
    r(denom) := 1;
    return r;
  end int2rat;
 
  function numerator (a : rational) return integer is
    variable n : integer;
  begin
    n := a(numer);
    return n;
  end numerator;
 
  function denominator (a : rational) return integer is
    variable d : integer;
  begin
    d := a(denom);
    return d;
  end denominator;
 
  function "+" (a, b : rational) return rational is
    variable r : rational;
    variable tn, td : integer;
  begin
    tn := a(numer)*b(denom) + a(denom)*b(numer);
    td := a(denom) * b(denom);
    if ( gcd(abs(tn), abs(td)) > 0 ) then
      r(numer) := tn / gcd(abs(tn), abs(td));
      r(denom) := td / gcd(abs(tn), abs(td));
    else
      r(numer) := tn;
      r(denom) := td;
    end if;
    return r;
  end "+";
 
  function "-" (a, b : rational) return rational is
    variable r : rational;
    variable tn, td : integer;
  begin
    tn := a(numer)*b(denom) - a(denom)*b(numer);
    td := a(denom) * b(denom);
    if ( gcd(abs(tn), abs(td)) > 0 ) then
      r(numer) := tn / gcd(abs(tn), abs(td));
      r(denom) := td / gcd(abs(tn), abs(td));
    else
      r(numer) := tn;
      r(denom) := td;
    end if;
    return r;
  end "-";
 
  function "*" (a, b : rational) return rational is
    variable r : rational;
    variable tn, td : integer;
  begin
    tn := a(numer) * b(numer);
    td := a(denom) * b(denom);
    if ( gcd(abs(tn), abs(td)) > 0 ) then
      r(numer) := tn / gcd(abs(tn), abs(td));
      r(denom) := td / gcd(abs(tn), abs(td));
    else
      r(numer) := tn;
      r(denom) := td;
    end if;
    return r;
  end "*";
 
  function "/" (a, b : rational) return rational is
    variable r : rational;
    variable tn, td : integer;
  begin
    tn := a(numer) * b(denom);
    td := a(denom) * b(numer);
    if ( gcd(abs(tn), abs(td)) > 0 ) then
      r(numer) := tn / gcd(abs(tn), abs(td));
      r(denom) := td / gcd(abs(tn), abs(td));
    else
      r(numer) := tn;
      r(denom) := td;
    end if;
    return r;
  end "/";
 
  function "abs" (a : rational) return rational is
    variable ta, tb, y : integer;
    variable r : rational;
  begin
    ta := a(numer);
    tb := a(denom);
    if (ta < 0) then
      ta := - a(numer);
    end if;
    if (tb < 0) then
      tb := - a(denom);
    end if;
    r := to_rational(ta, tb);
    return r;
  end "abs";
 
  function max (a, b : rational) return rational is
    variable w, x, y, z : integer;
    variable t1, t2 : integer;
    variable maxv : rational;
  begin
    w := numerator(a);
    x := denominator(a);
    y := numerator(b);
    z := denominator(b);
    t1 := w*z;
    t2 := x*y;
    if (t1 > t2) then
      maxv := a;
    else
      maxv := b;
    end if; 
    return maxv;
  end max;
 
  function min (a, b : rational) return rational is
    variable w, x, y, z : integer;
    variable t1, t2 : integer;
    variable minv : rational;
  begin
    w := numerator(a);
    x := denominator(a);
    y := numerator(b);
    z := denominator(b);
    t1 := w*z;
    t2 := x*y;
    if (t1 < t2) then
      minv := a;
    else
      minv := b;
    end if; 
    return minv;
  end min;  
 
  function ">" (a, b : rational) return boolean is
    variable diff : rational := a - b;
  begin
    return (((diff(numer) > 0) and (diff(denom) > 0)) or 
            ((diff(numer) < 0) and (diff(denom) < 0)));
  end ">";
 
  function "<" (a, b : rational) return boolean is
    variable diff : rational := a - b;
  begin
    return (((diff(numer) > 0) and (diff(denom) < 0)) or 
            ((diff(numer) < 0) and (diff(denom) > 0)));
  end "<";
 
  function ">=" (a, b : rational) return boolean is
    variable diff : rational := a - b;
  begin
    return (((diff(numer) >= 0) and (diff(denom) > 0)) or 
            ((diff(numer) <= 0) and (diff(denom) < 0)));
  end ">=";
 
  function "<=" (a, b : rational) return boolean is
    variable diff : rational := a - b;
  begin
    return (((diff(numer) >= 0) and (diff(denom) < 0)) or 
            ((diff(numer) <= 0) and (diff(denom) > 0)));
  end "<=";
 
  function "=" (a, b : rational) return boolean is
    variable diff : rational := a - b;
  begin
    return (diff(numer) = 0);
  end "=";
 
  function "/=" (a, b : rational) return boolean is
    variable diff : rational := a - b;
  begin
    return (diff(numer) /= 0);
  end "/=";
 
  function gcd (a, b : integer) return integer is
  begin
    if a = 0 then
      return b;
    end if;
    if b = 0 then
      return a;
    end if;
    if (a > b) then
      return gcd(b, a mod b);
    else
      return gcd(a, b mod a);
    end if;
  end gcd;
 
  function gcditer (a, b : integer) return integer is
    variable x, y : integer;
  begin
    x := a;
    y := b;
    if ((x = 0) and (y = 0)) then
      return 0;
    end if;
    while (x /= y) loop
      if (x >= y) then
        x := x - y;
      else
        y := y - x;
      end if;
    end loop;
    return x;
  end gcditer;
 
  function mediant (a, b : rational) return rational is
    variable r : rational;
    variable tn, td : integer;
  begin
    tn := a(numer) + b(numer);
    td := a(denom) + b(denom);
    if ( gcditer(abs(tn), abs(td)) > 0 ) then
      r(numer) := tn / gcditer(abs(tn), abs(td));
      r(denom) := td / gcditer(abs(tn), abs(td));
    else
      r(numer) := tn;
      r(denom) := td;
    end if;
    return r;
  end mediant;
 
end ratpack;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.