Float40 package
prepared by P. Bakowski
(designer G. Ramstein)
back
to introduction
--------------------------------------------------------------------------------
-- Project : DSP21020
-- Laboratory : SEI/IRESTE
-- File name : Float40.vhd
-- Title : Float40_Pkg
-- Description : Types et sous-programmes pour l'arithmetique
-- des points fixes 32 bits et flottants 40 bits.
-- Ce paquetage decrit les operations utiles pour
-- l'ALU, le multiplieur et le decaleur.
-- Design Library : DSP2120.lib
-- Analysis Dependency : Non
-- Initialization : Non
-- Notes : Modele non synthetisable
-- Simulator : Vantage
--------------------------------------------------------------------------------
-- Revisions :
-- Date Author Revision Comments
-- 1/12/95 G. Ramstein 1.0 Creation
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- FLOAT40_PKG SPECIFICATION
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
package Float40_Pkg is
use WORK.bitvector_pkg.ALL;
use WORK.signvector_pkg.ALL;
constant WORDLENGTH : integer := 40;
constant EXPONTPOS : integer := 31;
constant EXPONTLENGTH : integer := WORDLENGTH-2-EXPONTPOS;
--------------------------------------------------------------------------
-- Flottant : Type Float_Typ (40 bits non signes)
--------------------------------------------------------------------------
-- Format interne de description du flottant:
--
-- Type FloatR_Typ segmente les champs utiles
-- signe (bit WORDLENGTH-1)
-- + mantisse (bit EXPONTPOS a 0)
-- Le bit de rang EXPONTPOS est ajoute
-- a la conversion (il vaut '1' implicitement).
-- + exposant (bit WORDLENGTH-2 a EXPONENTPOS)
--
-- Les types precedents sont non signes.
-- Certaines procedures (scaleb,...) operent sur l'exposant vu
comme un entier
-- signe: une variable interne realise la conversion non signe
-> signe.
--
--------------------------------------------------------------------------
-- Point Fixe : Type Fix-Typ (32 bits signes en complement a 2)
--------------------------------------------------------------------------
-- Signaux de Controle
--------------------------------------------------------------------------
-- lrb : RND, soit calcul sur mantisse de 32/24 bits (resp. lrb=0/1)
-- lrm : Trunc, mode d'arrondi, au plus pret/troncature (resp.
lrm=0/1)
-- lfs : Alusat, mode sature pour l'ALU
--------------------------------------------------------------------------
-- Drapeaux : Type BV8_Typ
--------------------------------------------------------------------------
-- 0 : zero
-- 1 : underflow
-- 2 : valeur negative
-- 3 : overflow
-- 4 : carry (point fixe)
-- 5 : signe en entree
-- 6 : NaN (flottant)
-- 7 : Sortie de type flottant
--------------------------------------------------------------------------
subtype BV40_Typ is bit_vector(WORDLENGTH-1 downto 0);
subtype Float_Typ is BV40_typ;
subtype mantis_Typ is bit_vector(EXPONTPOS downto 0);
subtype expont_Typ is bit_vector(EXPONTLENGTH downto 0);
subtype Fix_Typ is signed_vector(31 downto 0);
type FloatR_Typ is record
sgn : bit;
mnts : mantis_Typ;
expnt : expont_Typ;
end record;
subtype BV8_Typ is bit_vector(7 downto 0); -- Drapeaux pour l'ALU
subtype Inste_Typ is bit_vector(7 downto 0); -- Drapeaux propres
au Multiplieur
function Float_To_FloatR(F_v : Float_Typ) return FloatR_Typ;
function FloatR_To_Float(F_v : FloatR_Typ) return Float_Typ;
function Float_to_String(F_v : Float_Typ) return String;
function String_To_Float(S_v : String) return Float_Typ;
function Fix_to_String(R_v : Fix_Typ) return String;
function String_To_Fix(S_v : String) return Fix_Typ;
---------------------------------------------------------------------
-- Procedure Add
-- realise une addition de points fixes.
---------------------------------------------------------------------
procedure Add(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Sub
-- realise une soustraction de points fixes.
---------------------------------------------------------------------
procedure Sub(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Addsub
-- realise une addition et une soustraction de points fixes.
---------------------------------------------------------------------
procedure Addsub(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Resadd, Ressub : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Addc
-- realise une addition de points fixes.
---------------------------------------------------------------------
procedure Addc(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Carry : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Subc
-- realise une soustraction de points fixes.
---------------------------------------------------------------------
procedure Subc(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Carry : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Av
-- realise une moyenne de points fixes.
---------------------------------------------------------------------
procedure Av(Rx,Ry : in Fix_Typ;
lrm : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Carry
-- realise une addition de la carry
---------------------------------------------------------------------
procedure Carry(Rx : in Fix_Typ;
lfs : in Bit;
Cary : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Borrow
---------------------------------------------------------------------
procedure Borrow(Rx : in Fix_Typ;
lfs : in Bit;
Carry : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Pass
---------------------------------------------------------------------
procedure Pass(Rx : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Inc
---------------------------------------------------------------------
procedure Inc(Rx : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Dec
---------------------------------------------------------------------
procedure Dec(Rx : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Neg
---------------------------------------------------------------------
procedure Neg(Rx : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Abso
---------------------------------------------------------------------
procedure Abso(Rx : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Min
---------------------------------------------------------------------
procedure Mini(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Max
---------------------------------------------------------------------
procedure Max(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Clip
---------------------------------------------------------------------
procedure Clip(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Comp
---------------------------------------------------------------------
procedure Comp(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure And_op
---------------------------------------------------------------------
procedure And_op(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Or_op
---------------------------------------------------------------------
procedure Or_op(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Xor_op
---------------------------------------------------------------------
procedure Xor_op(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Not_op
---------------------------------------------------------------------
procedure Not_op(Rx : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Mul
-- realise une multiplication de fix, avec ou sans add/soustr.
---------------------------------------------------------------------
procedure Mul(X,Y : in Fix_Typ;
Inste : in Inste_Typ;
Res0, Res1, Res2 : inout Mantis_Typ;
MN, MI, MU, MV, MF : out bit);
---------------------------------------------------------------------
-- OPERATIONS SUR DES FLOTTANTS --
---------------------------------------------------------------------
-- Procedure Addf
-- realise une addition de floats.
-- Si lrb est a 1, l'addition se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Addf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Subf
-- realise une soustraction de floats.
-- Si lrb est a 1, la soustraction se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Subf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Addabsf
-- realise la valeur absolue d'une addition de floats.
-- Si lrb est a 1, l'addition se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Addabsf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Subabsf
-- realise la valeur absolue de la soustraction de floats.
-- Si lrb est a 1, la soustraction se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Subabsf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Addsubf
-- realise addition et soustraction de floats.
-- Si lrb est a 1, l'operation se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Addsubf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
AddRes, SubRes : out Float_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Avf
-- realise une moyenne de floats.
-- Si lrb est a 1, l'addition se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Avf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Rnd
-- realise un arrondi de floats sur 32 bits
-- Si lrb est a 1, l'arrondi se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Rnd(Fx : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
);
---------------------------------------------------------------------
-- Procedure Compf
-- compare deux flottants
-- met un drapeau si egalite et un autre si Fx < Fy
---------------------------------------------------------------------
procedure Compf(Fx,Fy : in Float_Typ;
lrb : in Bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure Minf
-- donne le minimum de deux flottants
---------------------------------------------------------------------
procedure Minf(Fx,Fy : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure Maxf
-- donne le maximum de deux flottants
---------------------------------------------------------------------
procedure Maxf(Fx,Fy : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
-----
----- FIN PARTIE TESTEE
-----
---------------------------------------------------------------------
-- Procedure Clipf
---------------------------------------------------------------------
procedure Clipf(Fx,Fy : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Negf
-- calcule -F
---------------------------------------------------------------------
procedure Negf(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Absf
-- calcule abs(F)
---------------------------------------------------------------------
procedure Absf(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Passf
---------------------------------------------------------------------
procedure Passf(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Csignf
-- Attribue le signe de Fy et la valeur de Fx
---------------------------------------------------------------------
procedure Csignf(Fx, Fy : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Logb
-- Convertit l'exposant de Fx en un point fixe
---------------------------------------------------------------------
procedure Logb(Fx : in Float_Typ;
lrb, lfs : in bit;
Res : out Fix_Typ;
Fres : out Float_Typ;
flpoutp : out Boolean;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Scalb
---------------------------------------------------------------------
procedure Scalb(Fx : in Float_Typ;
Y : in Fix_Typ;
lrb, lrm : in bit;
Fres : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Mantf
---------------------------------------------------------------------
procedure Mantf(Fx : in Float_Typ;
lrb : in bit;
Res : out Fix_Typ;
Fres : out Float_Typ;
flpoutp : out Boolean;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Fix
-- Conversion de Float en Fix
---------------------------------------------------------------------
procedure Fix(Fx : in Float_Typ;
lrb, lrm, lfs : in bit;
Res : out Fix_Typ;
Fres : out Float_Typ;
flpoutp : out Boolean;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Fixs
-- Conversion de Float en Fix
---------------------------------------------------------------------
procedure Fixs(Fx : in Float_Typ;
Y : in Fix_Typ;
lrb, lrm, lfs : in bit;
Res : out Fix_Typ;
Fres : out Float_Typ;
flpoutp : out Boolean;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Floatf
-- Conversion de Fix en Float
---------------------------------------------------------------------
procedure Floatf(Rx : in Fix_Typ;
lrm : in bit;
Fres : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Floatsf
-- Conversion de Fix en Float
---------------------------------------------------------------------
procedure Floatsf(Rx, Y : in Fix_Typ;
lrm : in bit;
Fres : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Recips
---------------------------------------------------------------------
procedure Recips(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure : Rsqrts
---------------------------------------------------------------------
procedure Rsqrts(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ);
---------------------------------------------------------------------
-- Procedure Mulf
-- realise une multiplication de floats.
-- Si lrb est a 1, la multiplication se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Mulf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
MN, MI, MU, MV, MF : out bit);
end Float40_Pkg;
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- FLOAT40_PKG BODY
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
package body Float40_Pkg is
-------------------------------------------------------------------------
-- Function : Float_To_String
-- convertit un Float(bit_vector) en une chaine de STRINGLENGTH
caracteres
-------------------------------------------------------------------------
function Float_to_String(F_v : Float_Typ) return String is
variable Res : String(1 to 10);
variable dep : natural :=0;
variable fin : natural :=3;
variable octale : natural;
begin
for I in 1 to 10 loop
octale:=BVtoI(F_V(fin downto dep));
case octale is
when 0 => Res(11-I) :='0';
when 1 => Res(11-I) :='1';
when 2 => Res(11-I) :='2';
when 3 => Res(11-I) :='3';
when 4 => Res(11-I) :='4';
when 5 => Res(11-I) :='5';
when 6 => Res(11-I) :='6';
when 7 => Res(11-I) :='7';
when 8 => Res(11-I) :='8';
when 9 => Res(11-I) :='9';
when 10 => Res(11-I) :='a';
when 11 => Res(11-I) :='b';
when 12 => Res(11-I) :='c';
when 13 => Res(11-I) :='d';
when 14 => Res(11-I) :='e';
when 15 => Res(11-I) :='f';
when others => null;
end case;
dep:=dep+4;
fin:=fin+4;
end loop;
return Res;
end;
-------------------------------------------------------------------------
-- Function : String_To_Float
-- convertit une chaine de STRINGLENGTH caracteres en Float
-------------------------------------------------------------------------
function String_To_Float(S_v : String ) return Float_Typ is
variable Res : Float_Typ;
variable deb : integer :=WORDLENGTH-4;
variable fin : integer :=WORDLENGTH-1;
begin
for I in 1 to 10 loop
case S_V(I) is
when '0' => Res(fin downto deb) :="0000";
when '1' => Res(fin downto deb) :="0001";
when '2' => Res(fin downto deb) :="0010";
when '3' => Res(fin downto deb) :="0011";
when '4' => Res(fin downto deb) :="0100";
when '5' => Res(fin downto deb) :="0101";
when '6' => Res(fin downto deb) :="0110";
when '7' => Res(fin downto deb) :="0111";
when '8' => Res(fin downto deb) :="1000";
when '9' => Res(fin downto deb) :="1001";
when 'a' => Res(fin downto deb) :="1010";
when 'b' => Res(fin downto deb) :="1011";
when 'c' => Res(fin downto deb) :="1100";
when 'd' => Res(fin downto deb) :="1101";
when 'e' => Res(fin downto deb) :="1110";
when 'f' => Res(fin downto deb) :="1111";
when others => null;
end case;
deb:=deb-4;
fin:=fin-4;
end loop;
return Res;
end;
-------------------------------------------------------------------------
-- Function : Fix_To_String
-------------------------------------------------------------------------
function Fix_to_String(R_v : Fix_Typ) return String is
variable Res : String(1 to 8);
variable dep : natural :=0;
variable fin : natural :=3;
variable octale : natural;
begin
for I in 1 to 8 loop
octale:=BVtoI(bit_vector(R_V(fin downto dep)));
case octale is
when 0 => Res(9-I) :='0';
when 1 => Res(9-I) :='1';
when 2 => Res(9-I) :='2';
when 3 => Res(9-I) :='3';
when 4 => Res(9-I) :='4';
when 5 => Res(9-I) :='5';
when 6 => Res(9-I) :='6';
when 7 => Res(9-I) :='7';
when 8 => Res(9-I) :='8';
when 9 => Res(9-I) :='9';
when 10 => Res(9-I) :='a';
when 11 => Res(9-I) :='b';
when 12 => Res(9-I) :='c';
when 13 => Res(9-I) :='d';
when 14 => Res(9-I) :='e';
when 15 => Res(9-I) :='f';
when others => null;
end case;
dep:=dep+4;
fin:=fin+4;
end loop;
return Res;
end;
-------------------------------------------------------------------------
-- Function : String_To_Fix
-------------------------------------------------------------------------
function String_To_Fix(S_v : String ) return Fix_Typ is
variable Res : Fix_Typ;
variable deb : integer :=WORDLENGTH-12;
variable fin : integer :=WORDLENGTH-9;
begin
for I in 1 to 8 loop
case S_V(I) is
when '0' => Res(fin downto deb) :="0000";
when '1' => Res(fin downto deb) :="0001";
when '2' => Res(fin downto deb) :="0010";
when '3' => Res(fin downto deb) :="0011";
when '4' => Res(fin downto deb) :="0100";
when '5' => Res(fin downto deb) :="0101";
when '6' => Res(fin downto deb) :="0110";
when '7' => Res(fin downto deb) :="0111";
when '8' => Res(fin downto deb) :="1000";
when '9' => Res(fin downto deb) :="1001";
when 'a' => Res(fin downto deb) :="1010";
when 'b' => Res(fin downto deb) :="1011";
when 'c' => Res(fin downto deb) :="1100";
when 'd' => Res(fin downto deb) :="1101";
when 'e' => Res(fin downto deb) :="1110";
when 'f' => Res(fin downto deb) :="1111";
when others => null;
end case;
deb:=deb-4;
fin:=fin-4;
end loop;
return Res;
end;
---------------------------------------------------------------------
-- Function : Float_To_FloatR
-- convertit un Float(bit_vector) en un FloatR(signe+mantisse+exposant)
---------------------------------------------------------------------
function Float_To_FloatR(F_v : Float_Typ)
return FloatR_Typ is
variable Res_v : FloatR_Typ;
begin
Res_v.sgn := F_v(WORDLENGTH-1);
Res_v.mnts(EXPONTPOS-1 downto 0) := F_v(EXPONTPOS-1 downto 0);
Res_v.mnts(EXPONTPOS):='1'; -- bit implicite
Res_v.expnt := F_v(WORDLENGTH-2 downto EXPONTPOS);
return Res_v;
end Float_To_FloatR;
---------------------------------------------------------------------
-- Function : FloatR_To_Float
-- convertit un FloatR(signe+mantisse+exposant) en un Float(bit_vector)
---------------------------------------------------------------------
function FloatR_To_Float(F_v : FloatR_Typ)
return Float_Typ is
variable Res_v : Float_Typ;
begin
Res_v(WORDLENGTH-1) := F_v.sgn;
Res_v(EXPONTPOS-1 downto 0):=F_v.mnts(EXPONTPOS-1 downto 0);
Res_v(WORDLENGTH-2 downto EXPONTPOS):=
F_v.expnt(WORDLENGTH-EXPONTPOS-2 downto 0);
return Res_v;
end FloatR_To_Float;
----------------------------------------------------------------------
-- Detection de l'overflow
----------------------------------------------------------------------
function Aovf(Rx, Ry: Fix_Typ) return Boolean is
variable sum : Fix_Typ;
begin
sum:=Rx+Ry;
return ((Rx(31)='1' and Ry(31)='1') and sum(31)='0') or
((Rx(31)='0' and Ry(31)='0') and sum(31)='1');
end Aovf;
----------------------------------------------------------------------
-- Detection du carry
----------------------------------------------------------------------
function Acry(Rx, Ry: Fix_Typ) return Bit is
variable sum : Fix_Typ;
begin
sum:=Rx+Ry;
if ((Rx(31)='1' xor Ry(31)='1') and (sum(31)='0')) or
(Rx(31)='1' and Ry(31)='1')
then return '1'; else return '0'; end if;
end Acry;
---------------------------------------------------------------------
-- Procedure Add
-- realise une addition de points fixes.
---------------------------------------------------------------------
procedure Add(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx + Ry;
ovf:=Aovf(Rx,Ry);
cry:=Acry(Rx,Ry);
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Add;
---------------------------------------------------------------------
-- Procedure Sub
-- realise une soustraction de points fixes.
---------------------------------------------------------------------
procedure Sub(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx + not Ry +X"00000001";
ovf:=Aovf(Rx, not Ry) xor Aovf (Rx + not Ry, X"00000001");
cry:=Acry(Rx, not Ry) or Acry (Rx + not Ry, X"00000001");
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Sub;
---------------------------------------------------------------------
-- Procedure Addsub
-- realise une addition et une soustraction de points fixes.
---------------------------------------------------------------------
procedure Addsub(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Resadd, Ressub : out Fix_Typ;
Stat : out BV8_Typ
) is
variable Statadd, Statsub : BV8_Typ;
begin
Add(Rx,Ry,lfs, Resadd,Statadd);
Sub(Rx,Ry,lfs, Ressub,Statsub);
Stat:=Statadd or Statsub;
end Addsub;
---------------------------------------------------------------------
-- Procedure Addc
-- realise une addition de points fixes.
---------------------------------------------------------------------
procedure Addc(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Carry : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable CarryFix, Result : Fix_Typ;
begin
if Carry='1' then CarryFix :=X"00000001"; else CarryFix:=X"00000000";
end if;
Result:=Rx + Ry + CarryFix;
ovf:=Aovf(Rx,Ry) xor Aovf(Rx+Ry,CarryFix);
cry:=Acry(Rx,Ry) or Acry(Rx+Ry,CarryFix);
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Addc;
---------------------------------------------------------------------
-- Procedure Subc
-- realise une soustraction de points fixes.
---------------------------------------------------------------------
procedure Subc(Rx,Ry : in Fix_Typ;
lfs : in Bit;
Carry : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable CarryFix, Result : Fix_Typ;
begin
if Carry='1' then CarryFix :=X"00000001"; else CarryFix:=X"00000000";
end if;
Result:=Rx + not Ry + CarryFix;
ovf:=Aovf(Rx, not Ry) xor Aovf (Rx + not Ry, CarryFix);
cry:=Acry(Rx, not Ry) or Acry (Rx + not Ry, CarryFix);
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Subc;
---------------------------------------------------------------------
-- Procedure Av
-- realise une moyenne de points fixes.
---------------------------------------------------------------------
procedure Av(Rx,Ry : in Fix_Typ;
lrm : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx + Ry;
ovf:=False;
if (Result(0)='1' and Result(1)='1') and lrm='0' then
if not ( Aovf(Rx,Ry) xor Aovf(Rx+Ry,X"00000001")) then
Result:=Shr(Result+"00000001",1);
else
Result:=Shr(Result+"00000001",1) xor X"80000000";
end if;
cry:=Acry(Rx,Ry) or Acry(Rx+Ry,X"00000001");
else
if not Aovf(Rx,Ry) then
Result:=Shr(Result,1);
else
Result:=Shr(Result,1) xor X"80000000";
end if;
cry:=Acry(Rx,Ry);
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Av;
---------------------------------------------------------------------
-- Procedure Carry
-- realise une addition de la carry
---------------------------------------------------------------------
procedure Carry(Rx : in Fix_Typ;
lfs : in Bit;
Cary : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable CarryFix, Result : Fix_Typ;
begin
if Cary='1' then CarryFix :=X"00000001"; else CarryFix:=X"00000000";
end if;
Result:=Rx + CarryFix;
ovf:=Aovf(Rx,CarryFix);
cry:=Acry(Rx,CarryFix);
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Carry;
---------------------------------------------------------------------
-- Procedure Borrow
---------------------------------------------------------------------
procedure Borrow(Rx : in Fix_Typ;
lfs : in Bit;
Carry : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable CarryFix, Result : Fix_Typ;
begin
if Carry='1' then CarryFix :=X"00000001"; else CarryFix:=X"00000000";
end if;
Result:=Rx + ( CarryFix - "00000001");
ovf:=Aovf(Rx,X"FFFFFFFF") xor Aovf(Rx+X"FFFFFFFF",CarryFix);
cry:=Acry(Rx,X"FFFFFFFF") or Acry(Rx+X"FFFFFFFF",CarryFix);
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Borrow;
---------------------------------------------------------------------
-- Procedure Pass
---------------------------------------------------------------------
procedure Pass(Rx : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx;
cry:='0';
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
Stat(3):='0';
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Pass;
---------------------------------------------------------------------
-- Procedure Inc
---------------------------------------------------------------------
procedure Inc(Rx : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx+X"00000001";
ovf:=Aovf(Rx,X"00000001");
cry:=Acry(Rx,X"00000001");
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Inc;
---------------------------------------------------------------------
-- Procedure Dec
---------------------------------------------------------------------
procedure Dec(Rx : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx-X"00000001";
ovf:=Aovf(Rx,X"FFFFFFFF");
cry:=Acry(Rx,X"FFFFFFFF");
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Dec;
---------------------------------------------------------------------
-- Procedure Neg
---------------------------------------------------------------------
procedure Neg(Rx : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=not Rx+X"00000001";
ovf:=Aovf(not Rx,X"00000001");
cry:=Acry(not Rx,X"00000001");
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Neg;
---------------------------------------------------------------------
-- Procedure Abso
---------------------------------------------------------------------
procedure Abso(Rx : in Fix_Typ;
lfs : in Bit;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
if Rx(31)='1' then
Result:=not Rx +X"00000001";
ovf:=Aovf(not Rx,X"00000001");
cry:=Acry(not Rx,X"00000001");
else
Result:=Rx;
ovf:=FALSE;
cry:='0';
end if;
-- Saturation
if ovf and lfs='1' then
if Result(31)='1' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Abso;
---------------------------------------------------------------------
-- Procedure Min
---------------------------------------------------------------------
procedure Mini(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
if Rx <= Ry then
Result:=Rx;
else
Result:=Ry;
end if;
ovf:=FALSE;
cry:='0';
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Mini;
---------------------------------------------------------------------
-- Procedure Max
---------------------------------------------------------------------
procedure Max(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
if Rx >= Ry then
Result:=Rx;
else
Result:=Ry;
end if;
ovf:=FALSE;
cry:='0';
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Max;
---------------------------------------------------------------------
-- Procedure Clip
---------------------------------------------------------------------
procedure Clip(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable bool,zero,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
bool:=(Rx>="0" and Ry>="0") and Rx <=
Ry;
bool:= bool or ((Rx< "0" and Ry< "0")
and Rx >= Ry);
bool:= bool or ((Rx>="0" and Ry< "0")
and ("0"- Rx) <= Ry);
bool:= bool or ((Rx< "0" and Ry>="0")
and Rx >= "0"- Ry);
if bool then
Result:=Rx;
else
if (Rx>="0" and Ry>="0") or (Rx<"0"
and Ry<"0") then
Result:=Ry;
else
Result:= "0"- Ry;
end if;
end if;
cry:='0';
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
Stat(3):='0';
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Clip;
---------------------------------------------------------------------
-- Procedure Comp
---------------------------------------------------------------------
procedure Comp(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,uvf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx+not Ry+X"00000001";
ovf:=FALSE;
cry:='0';
zero:= Result=X"00000000";
sgn:=Result(31)='1';
sgn:=sgn xor Aovf(Rx, not Ry);
sgn:=sgn xor Aovf(Rx+not Ry,X"00000001");
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Comp;
---------------------------------------------------------------------
-- Procedure And_op
---------------------------------------------------------------------
procedure And_op(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx and Ry;
ovf:=FALSE;
cry:='0';
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end And_op;
---------------------------------------------------------------------
-- Procedure Or_op
---------------------------------------------------------------------
procedure Or_op(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx or Ry;
ovf:=FALSE;
cry:='0';
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Or_op;
---------------------------------------------------------------------
-- Procedure Xor_op
---------------------------------------------------------------------
procedure Xor_op(Rx, Ry : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=Rx xor Ry;
ovf:=FALSE;
cry:='0';
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Xor_op;
---------------------------------------------------------------------
-- Procedure Not_op
---------------------------------------------------------------------
procedure Not_op(Rx : in Fix_Typ;
Res : out Fix_Typ;
Stat : out BV8_Typ
) is
variable zero,ovf,sgn : boolean;
variable cry : bit;
variable Result : Fix_Typ;
begin
Result:=not Rx;
ovf:=FALSE;
cry:='0';
zero:= Result=X"00000000";
sgn:=Result(31)='1';
Res:=Result;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='0';
end Not_op;
---------------------------------------------------------------------
-- Procedure Mul
-- realise une multiplication de fix, avec ou sans add/soustr.
---------------------------------------------------------------------
procedure Mul(X,Y : in Fix_Typ;
Inste : in Inste_Typ;
Res0, Res1, Res2 : inout Mantis_Typ;
MN, MI, MU, MV, MF : out bit) is
variable xx, yy : Mantis_Typ;
variable negx, negy : Boolean;
variable A, sum : bit_vector(79 downto 0);
begin
MN:='0';
MI:='0';
MU:='0';
MV:='0';
MF:='0';
if Inste(4)='1' and X(31)='1' then
negx:=TRUE;
xx:=bit_vector(not X +"00000001");
else
negx:=FALSE;
xx:=bit_vector(X);
end if;
if Inste(5)='1' and Y(31)='1' then
negy:=TRUE;
yy:=bit_vector(not Y +"00000001");
else
negy:=FALSE;
yy:=bit_vector(Y);
end if;
-- Calcul du produit
-----------------------------------------
sum:=Extend(xx*yy,80);
if negx/=negy then
sum:=not sum +'1';
end if;
-- Fractions signes: bit redondant a enlever
-----------------------------------------------
if Inste(3)='1' and Inste(4)='1' and Inste(5)='1' then
sum:=Shl(sum,1);
end if;
if Inste(7)='1' then -- accumulation
A(31 downto 0):=Res0;
A(63 downto 32):=Res1;
A(79 downto 64):=Res2(15 downto 0);
if Inste(6)='0' then -- addition cumulative
sum:=A+sum;
else
sum:=A-sum; -- soustraction cumulative
end if;
end if;
Res0 :=sum(31 downto 0);
Res1 :=sum(63 downto 32);
Res2 :=extend(sum(79 downto 64),32);
if Inste(0)='1' and Inste(3)='1' then --arrondi
if Res0 > X"80000000" or (Res0=X"80000000"
and Res1(0)='1') then
if Res1=X"FFFFFFFF" then
Res1:=X"00000000";
Res2:=Res2+'1';
else
Res1:=Res1+'1';
end if;
end if;
Res0:=X"00000000";
end if;
-- Underflow
-----------------------
if Inste(3)='0' or (Inste(0)='1'and Inste(3)='1') then
MU:='0';
else -- Fractionnaire
if Inste(5)='1' or Inste(4)='1' then -- Signe
if ((Res2(15 downto 0)=X"FFFF" and Res1=X"FFFFFFFF")
or
(Res2(15 downto 0)=X"0000" and Res1=X"00000000"))
and
Res0/=X"00000000" then
MU:='1';
else
MU:='0';
end if;
else -- non signe
if (Res2(15 downto 0)=X"0000" and Res1=X"00000000"
and
Res0/=X"00000000") then
MU:='1';
else
MU:='0';
end if;
end if;
end if;
-- Overflow
-----------------------
if Inste(5)='1' or Inste(4)='1' then -- signe
if Inste(3)='0' then -- Entier
if Res0(31)='0' then --Positif
if Res2(15 downto 0)=X"0000" and Res1=X"00000000"
then
MV:='0';
else
MV:='1';
end if;
else -- Negatif
if Res2(15 downto 0)=X"FFFF" and Res1=X"FFFFFFFF"
then
MV:='0';
else
MV:='1';
end if;
end if;
else -- Fractionnaire
if Res1(31)='0' then --Positif
if Res2(15 downto 0)=X"0000" then
MV:='0';
else
MV:='1';
end if;
else -- Negatif
if Res2(15 downto 0)=X"FFFF" then
MV:='0';
else
MV:='1';
end if;
end if;
end if;
else -- Non Signe
if Inste(3)='0' then -- Entier
if Res2(15 downto 0)=X"0000" and Res1=X"00000000"
then
MV:='0';
else
MV:='1';
end if;
else -- Fractionnaire
if Res2(15 downto 0)=X"0000" then
MV:='0';
else
MV:='1';
end if;
end if;
end if;
MN:=Res2(15);
Res2(31 downto 16):=(others=>Res2(15)); -- etendu au signe
end Mul;
---------------------------------------------------------------------
-- Procedure Addf
-- realise une addition de floats.
-- Si lrb est a 1, l'addition se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Addf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
) is
variable infinp,invinp,zero,ovf,uvf,sgn : boolean;
variable exposant : Fix_Typ;
variable x,y,r : FloatR_Typ;
variable xexpint, yexpint, rexpint : natural;
variable decalexp : natural;
variable bool : boolean;
variable rext : mantis_Typ;
variable cptr : natural;
variable cry : bit;
variable sum: bit_vector(EXPONTPOS+1 downto 0);
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
y:=Float_To_FloatR(Fy);
xexpint:=BVtoI(x.expnt);
yexpint:=BVtoI(y.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
y.mnts:=y.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
if yexpint=0 then y.mnts:=X"00000000"; end if;
-- Entrees infinies
------------------------------
infinp:= (x.expnt=X"FF"
and x.mnts = X"80000000") or
(y.expnt=X"FF"
and y.mnts = X"80000000");
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000")
or
(y.expnt=X"FF"
and y.mnts /= X"80000000")
or
((x.expnt=X"FF" and y.expnt=X"FF") and
((x.sgn xor y.sgn)='1'));
-- Signe du resultat
-------------------------------
bool := (x.sgn xor y.sgn)='0' and x.sgn='1';
bool := bool or ( (not x.sgn and y.sgn)='1'
and ( x.expnt < y.expnt
or
(x.expnt=y.expnt and x.mnts
);
bool := bool or ( ( x.sgn and not y.sgn)='1'
and ( y.expnt < x.expnt
or
(x.expnt=y.expnt and y.mnts
);
if bool
then r.sgn:='1';
else r.sgn:='0';
end if;
-- Cas ou exposant de x > exposant de y
----------------------------------------
-- initialisation de rext pour l'arrondi
if x.expnt > y.expnt then
decalexp:=xexpint-yexpint;
r.expnt:=x.expnt;
if decalexp >=2*EXPONTPOS+1 then
if y.mnts /=X"00000000" then rext:=X"00000001";
else rext:=X"00000000";
end if;
else if decalexp>=EXPONTPOS+1 then
rext:=shr(y.mnts,decalexp-32);
if 2*EXPONTPOS+1-decalexp /=0
then rext:=rext or shl(y.mnts,1);
else rext:=rext or y.mnts;
end if;
else rext:=shl(y.mnts,EXPONTPOS+1-decalexp);
end if;
end if;
-- r est initialise a y decale de decalexp
if decalexp >=EXPONTPOS+1 then r.mnts:=X"00000000";
else r.mnts:=shr(y.mnts, decalexp);
end if;
-- calcul de r
if not ((x.sgn xor y.sgn)='1')
then
sum:= Extend(x.mnts, EXPONTPOS+2) + r.mnts;
cry := sum(EXPONTPOS+1);
r.mnts:=r.mnts+x.mnts;
else
sum:=Extend(not rext, EXPONTPOS+2) + '1';
r.mnts:=x.mnts+ not r.mnts + sum(EXPONTPOS+1);
rext:=not rext +"1";
cry:='0';
end if;
end if;
-- Cas ou exposant de x < exposant de y
----------------------------------------
-- initialisation de rext pour l'arrondi
if x.expnt < y.expnt then
decalexp:=yexpint-xexpint;
r.expnt:=y.expnt;
if decalexp >=2*EXPONTPOS+1 then
if x.mnts /=X"00000000" then rext:=X"00000001";
else rext:=X"00000000";
end if;
else if decalexp>=EXPONTPOS+1 then
rext:=shr(x.mnts,decalexp-32);
if 2*EXPONTPOS+1-decalexp /=0
then rext:=rext or shl(x.mnts,1);
else rext:=rext or x.mnts;
end if;
else rext:=shl(x.mnts,EXPONTPOS+1-decalexp);
end if;
end if;
-- r est initialise a x decale de decalexp
if decalexp >=EXPONTPOS+1 then r.mnts:=X"00000000";
else r.mnts:=shr(x.mnts, decalexp);
end if;
-- calcul de r
if not ((x.sgn xor y.sgn)='1')
then
sum:= Extend(y.mnts, EXPONTPOS+2) + r.mnts;
cry := sum(EXPONTPOS+1);
r.mnts:=r.mnts+y.mnts;
else
sum:=Extend(not rext, EXPONTPOS+2) + '1';
r.mnts:=y.mnts+ not r.mnts + sum(EXPONTPOS+1);
rext:=not rext +"1";
cry:='0';
end if;
end if;
-- Cas ou exposant de x = exposant de y
----------------------------------------
-- initialisation de rext pour l'arrondi
if x.expnt = y.expnt then
r.expnt:=x.expnt;
rext:=X"00000000";
-- calcul de r
if not ((x.sgn xor y.sgn)='1')
then
sum:= Extend(x.mnts, EXPONTPOS+2) + y.mnts;
cry := sum(EXPONTPOS+1);
r.mnts:=y.mnts+x.mnts;
else
if x.mnts >= y.mnts then
r.mnts:=x.mnts+ not y.mnts + '1';
cry:='0';
else
r.mnts:=y.mnts+ not x.mnts + '1';
cry:='0';
end if;
end if;
end if;
-- pre-round normalisation
-----------------------------------------------
exposant:=signed_vector(Extend(r.expnt,32));
if cry='1' then
if rext(0)='1' then
rext:=shl(r.mnts,EXPONTPOS) or shr(rext,1)
or extend("1",EXPONTPOS+1);
else
rext:=shl(r.mnts,EXPONTPOS) or shr(rext,1)
or extend("0",EXPONTPOS+1);
end if;
r.mnts:=shr(r.mnts,1) or shl(extend("1",EXPONTPOS+1),EXPONTPOS);
exposant:=exposant+X"00000001";
end if;
cptr:=0;
while cptr <= EXPONTPOS and r.mnts(EXPONTPOS)='0' loop
exposant:=exposant -X"00000001";
r.mnts:=shl(r.mnts,1) or shr(rext,EXPONTPOS);
rext:=shl(rext,1);
cptr:=cptr+1;
end loop;
-- arrondi au plus pret , version 40 bits
-----------------------------------------------
if lrm='0' and lrb='0' then
if rext(EXPONTPOS)='1' and
( shl(rext,1) /= Extend("0", EXPONTPOS+1) or
(rext(EXPONTPOS)='1' and r.mnts(0)='1')) then
if r.mnts /=X"ffffffff" then
r.mnts:=r.mnts+'1';
else
r.mnts:=X"80000000";
exposant:=exposant+X"00000001";
end if;
end if;
end if;
-- arrondi au plus pret , version 32 bits
-----------------------------------------------
if lrm='0' and lrb='1' then
if r.mnts(7)='1' and
( ((r.mnts and Extend(X"7f",EXPONTPOS+1)) or rext) /=X"00000000"
or
(r.mnts(7)='1' and r.mnts(8)='1')) then
r.mnts:=r.mnts and X"ffffff00";
if r.mnts /=X"ffffff00" then
r.mnts:=r.mnts+X"100";
else
r.mnts:=X"80000000";
exposant:=exposant+X"00000001";
end if;
else
r.mnts:=r.mnts and X"ffffff00";
end if;
end if;
-- arrondi a zero , 32 bits
-----------------------------------------------
if lrm='1' and lrb='1' then
r.mnts:=r.mnts and X"ffffff00";
end if;
-- drapeaux
-----------------------------------------------
zero:=( exposant <=X"00000000" or r.mnts=X"00000000")
and not (infinp or invinp);
ovf:=(exposant>=X"000000FF") and not (infinp or invinp);
uvf:=(exposant<=X"00000000" and r.mnts /= X"00000000")
and not (infinp or invinp);
sgn:= (r.sgn='1') and not invinp;
r.expnt:=bit_vector(exposant(7 downto 0));
-- Traitement des cas particuliers
-------------------------------------------------
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"ffffffff";
else
r.mnts:=X"ffffff00";
end if;
end if;
if not invinp and ((ovf and (lrm='0')) or infinp) then
r.expnt:=X"FF";
r.mnts:=X"00000000";
end if;
if not invinp and ovf and (lrm='1') then
r.expnt:=X"FE";
if lrb='0' then
r.mnts:=X"ffffffff";
else
r.mnts:=X"ffffff00";
end if;
end if;
if zero then
r.expnt:=X"00";
r.mnts:=X"00000000";
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Res:=FloatR_To_Float(r);
end Addf;
---------------------------------------------------------------------
-- Procedure Subf
-- realise une soustraction de floats.
-- Si lrb est a 1, la soustraction se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Subf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
) is
variable SubStat : BV8_Typ;
variable SubY, SubRes : Float_Typ;
begin
-- Changement de signe p/r a l'addition
----------------------------------------
SubY:=FY;
SubY(WORDLENGTH-1):= not SubY(WORDLENGTH-1);
Addf(Fx, SubY, lrb, lrm, SubRes, SubStat);
Res:=SubRes;
Stat:=SubStat;
end Subf;
---------------------------------------------------------------------
-- Procedure Addabsf
-- realise la valeur absolue d'une addition de floats.
-- Si lrb est a 1, l'addition se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Addabsf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
) is
variable AddStat : BV8_Typ;
variable AddRes : Float_Typ;
begin
Addf(Fx, FY, lrb, lrm, AddRes, AddStat);
Res:=AddRes;
Res(WORDLENGTH-1):='0';
Stat:=AddStat;
end Addabsf;
---------------------------------------------------------------------
-- Procedure Subabsf
-- realise la valeur absolue de la soustraction de floats.
-- Si lrb est a 1, la soustraction se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Subabsf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
) is
variable SubStat : BV8_Typ;
variable SubRes : Float_Typ;
begin
Subf(Fx, FY, lrb, lrm, SubRes, SubStat);
Res:=SubRes;
Res(WORDLENGTH-1):='0';
Stat:=SubStat;
end Subabsf;
---------------------------------------------------------------------
-- Procedure Addsubf
-- realise addition et soustraction de floats.
-- Si lrb est a 1, l'operation se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Addsubf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
AddRes, SubRes : out Float_Typ;
Stat : out BV8_Typ
) is
variable AddStat, SubStat : BV8_Typ;
begin
Addf(Fx, Fy, lrb, lrm, AddRes, AddStat);
Subf(Fx, FY, lrb, lrm, SubRes, SubStat);
Stat:=AddStat or SubStat;
end AddSubf;
---------------------------------------------------------------------
-- Procedure Avf
-- realise une moyenne de floats.
-- Si lrb est a 1, l'addition se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Avf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
) is
variable
infinp,
invinp,
zero,
ovf,
uvf,
sgn : boolean;
variable exposant : Fix_Typ;
variable x,y,r : FloatR_Typ;
variable xexpint, yexpint, rexpint : natural;
variable decalexp : natural;
variable bool : boolean;
variable rext : mantis_Typ;
variable cptr : natural;
variable cry : bit;
variable sum: bit_vector(EXPONTPOS+1 downto 0);
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
y:=Float_To_FloatR(Fy);
xexpint:=BVtoI(x.expnt);
yexpint:=BVtoI(y.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
y.mnts:=y.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
if yexpint=0 then y.mnts:=X"00000000"; end if;
-- Entrees infinies
------------------------------
infinp:= (x.expnt=X"FF"
and x.mnts = X"80000000") or
(y.expnt=X"FF"
and y.mnts = X"80000000");
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000")
or
(y.expnt=X"FF"
and y.mnts /= X"80000000")
or
((x.expnt=X"FF" and y.expnt=X"FF") and
((x.sgn xor y.sgn)='1'));
-- Signe du resultat
-------------------------------
bool := (x.sgn xor y.sgn)='0' and x.sgn='1';
bool := bool or ( (not x.sgn and y.sgn)='1'
and ( x.expnt < y.expnt
or
(x.expnt=y.expnt and x.mnts
);
bool := bool or ( ( x.sgn and not y.sgn)='1'
and ( y.expnt < x.expnt
or
(x.expnt=y.expnt and y.mnts
);
if bool
then r.sgn:='1';
else r.sgn:='0';
end if;
-- Cas ou exposant de x > exposant de y
----------------------------------------
-- initialisation de rext pour l'arrondi
if x.expnt > y.expnt then
decalexp:=xexpint-yexpint;
r.expnt:=x.expnt;
if decalexp >=2*EXPONTPOS+1 then
if y.mnts /=X"00000000" then rext:=X"00000001";
else rext:=X"00000000";
end if;
else if decalexp>=EXPONTPOS+1 then
rext:=shr(y.mnts,decalexp-32);
if 2*EXPONTPOS+1-decalexp /=0
then rext:=rext or shl(y.mnts,1);
else rext:=rext or y.mnts;
end if;
else rext:=shl(y.mnts,EXPONTPOS+1-decalexp);
end if;
end if;
-- r est initialise a y decale de decalexp
if decalexp >=EXPONTPOS+1 then r.mnts:=X"00000000";
else r.mnts:=shr(y.mnts, decalexp);
end if;
-- calcul de r
if not ((x.sgn xor y.sgn)='1')
then
sum:= Extend(x.mnts, EXPONTPOS+2) + r.mnts;
cry := sum(EXPONTPOS+1);
r.mnts:=r.mnts+x.mnts;
else
sum:=Extend(not rext, EXPONTPOS+2) + '1';
r.mnts:=x.mnts+ not r.mnts + sum(EXPONTPOS+1);
rext:=not rext +"1";
cry:='0';
end if;
end if;
-- Cas ou exposant de x < exposant de y
----------------------------------------
-- initialisation de rext pour l'arrondi
if x.expnt < y.expnt then
decalexp:=yexpint-xexpint;
r.expnt:=y.expnt;
if decalexp >=2*EXPONTPOS+1 then
if x.mnts /=X"00000000" then rext:=X"00000001";
else rext:=X"00000000";
end if;
else if decalexp>=EXPONTPOS+1 then
rext:=shr(x.mnts,decalexp-32);
if 2*EXPONTPOS+1-decalexp /=0
then rext:=rext or shl(x.mnts,1);
else rext:=rext or x.mnts;
end if;
else rext:=shl(x.mnts,EXPONTPOS+1-decalexp);
end if;
end if;
-- r est initialise a x decale de decalexp
if decalexp >=EXPONTPOS+1 then r.mnts:=X"00000000";
else r.mnts:=shr(x.mnts, decalexp);
end if;
-- calcul de r
if not ((x.sgn xor y.sgn)='1')
then
sum:= Extend(y.mnts, EXPONTPOS+2) + r.mnts;
cry := sum(EXPONTPOS+1);
r.mnts:=r.mnts+y.mnts;
else
sum:=Extend(not rext, EXPONTPOS+2) + '1';
r.mnts:=y.mnts+ not r.mnts + sum(EXPONTPOS+1);
rext:=not rext +"1";
cry:='0';
end if;
end if;
-- Cas ou exposant de x = exposant de y
----------------------------------------
-- initialisation de rext pour l'arrondi
if x.expnt = y.expnt then
r.expnt:=x.expnt;
rext:=X"00000000";
-- calcul de r
if not ((x.sgn xor y.sgn)='1')
then
sum:= Extend(x.mnts, EXPONTPOS+2) + y.mnts;
cry := sum(EXPONTPOS+1);
r.mnts:=y.mnts+x.mnts;
else
if x.mnts >= y.mnts then
r.mnts:=x.mnts+ not y.mnts + '1';
cry:='0';
else
r.mnts:=y.mnts+ not x.mnts + '1';
cry:='0';
end if;
end if;
end if;
-- pre-round normalisation
-----------------------------------------------
exposant:=signed_vector(Extend(r.expnt,32));
if cry='1' then
if rext(0)='1' then
rext:=shl(r.mnts,EXPONTPOS) or shr(rext,1)
or extend("1",EXPONTPOS+1);
else
rext:=shl(r.mnts,EXPONTPOS) or shr(rext,1)
or extend("0",EXPONTPOS+1);
end if;
r.mnts:=shr(r.mnts,1) or shl(extend("1",EXPONTPOS+1),EXPONTPOS);
exposant:=exposant+X"00000001";
end if;
cptr:=0;
while cptr <= EXPONTPOS and r.mnts(EXPONTPOS)='0' loop
exposant:=exposant -X"00000001";
r.mnts:=shl(r.mnts,1) or shr(rext,EXPONTPOS);
rext:=shl(rext,1);
cptr:=cptr+1;
end loop;
-- arrondi au plus pret , version 40 bits
-----------------------------------------------
if lrm='0' and lrb='0' then
if rext(EXPONTPOS)='1' and
( shl(rext,1) /= Extend("0", EXPONTPOS+1) or
(rext(EXPONTPOS)='1' and r.mnts(0)='1')) then
if r.mnts /=X"ffffffff" then
r.mnts:=r.mnts+'1';
else
r.mnts:=X"80000000";
exposant:=exposant+X"00000001";
end if;
end if;
end if;
-- arrondi au plus pret , version 32 bits
-----------------------------------------------
if lrm='0' and lrb='1' then
if r.mnts(7)='1' and
( ((r.mnts and Extend(X"7f",EXPONTPOS+1)) or rext) /=X"00000000"
or
(r.mnts(7)='1' and r.mnts(8)='1')) then
r.mnts:=r.mnts and X"ffffff00";
if r.mnts /=X"ffffff00" then
r.mnts:=r.mnts+X"100";
else
r.mnts:=X"80000000";
exposant:=exposant+X"00000001";
end if;
else
r.mnts:=r.mnts and X"ffffff00";
end if;
end if;
-- arrondi a zero , 32 bits
-----------------------------------------------
if lrm='1' and lrb='1' then
r.mnts:=r.mnts and X"ffffff00";
end if;
-- Calcul de la moyenne par division par 2
-----------------------------------------------
exposant:=exposant-X"00000001";
-- drapeaux
-----------------------------------------------
zero:=( exposant <=X"00000000" or r.mnts=X"00000000")
and not (infinp or invinp);
ovf:=(exposant>=X"000000FF") and not (infinp or invinp);
uvf:=(exposant<=X"00000000" and r.mnts /= X"00000000")
and not (infinp or invinp);
sgn:= (r.sgn='1') and not invinp;
r.expnt:=bit_vector(exposant(7 downto 0));
-- Traitement des cas particuliers
-------------------------------------------------
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"ffffffff";
else
r.mnts:=X"ffffff00";
end if;
end if;
if not invinp and ((ovf and (lrm='0')) or infinp) then
r.expnt:=X"FF";
r.mnts:=X"00000000";
end if;
if not invinp and ovf and (lrm='1') then
r.expnt:=X"FE";
if lrb='0' then
r.mnts:=X"ffffffff";
else
r.mnts:=X"ffffff00";
end if;
end if;
if zero then
r.expnt:=X"00";
r.mnts:=X"00000000";
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Res:=FloatR_To_Float(r);
end Avf;
---------------------------------------------------------------------
-- Procedure Rnd
-- realise un arrondi de floats sur 32 bits
-- Si lrb est a 1, l'arrondi se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Rnd(Fx : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ
) is
variable
infinp,
invinp,
zero,
ovf,
uvf,
sgn : boolean;
variable x,r : FloatR_Typ;
variable xexpint, rexpint : natural;
variable exposant : Fix_Typ;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
xexpint:=BVtoI(x.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
-- Entrees infinies
------------------------------
infinp:= (x.expnt=X"FF"
and x.mnts = X"80000000");
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000");
-- Valeur premiere du resultat
-------------------------------
r:=x;
exposant:=signed_vector(Extend(r.expnt,32));
-- arrondi au plus pret , version 32 bits
-----------------------------------------------
if lrm='0' then
if r.mnts(7)='1' and
( ((r.mnts and Extend(X"7f",EXPONTPOS+1)) ) /=X"00000000"
or
(r.mnts(7)='1' and r.mnts(8)='1')) then
r.mnts:=r.mnts and X"ffffff00";
if r.mnts /=X"ffffff00" then
r.mnts:=r.mnts+X"100";
else
r.mnts:=X"80000000";
exposant:=exposant+X"00000001";
end if;
else
r.mnts:=r.mnts and X"ffffff00";
end if;
else
-- arrondi a zero , 32 bits
-----------------------------------------------
r.mnts:=r.mnts and X"ffffff00";
end if;
-- drapeaux
-----------------------------------------------
zero:=( exposant <=X"00000000" or r.mnts=X"00000000")
and not (infinp or invinp);
ovf:=(exposant>=X"000000FF") and not (infinp or invinp);
uvf:=(exposant<=X"00000000" and r.mnts /= X"00000000")
and not (infinp or invinp);
sgn:= (r.sgn='1') and not invinp;
r.expnt:=bit_vector(exposant(7 downto 0));
-- Traitement des cas particuliers
-------------------------------------------------
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
r.mnts:=X"ffffff00";
end if;
if not invinp and ((ovf and (lrm='0')) or infinp) then
r.expnt:=X"FF";
r.mnts:=X"00000000";
end if;
if not invinp and ovf and (lrm='1') then
r.expnt:=X"FE";
r.mnts:=X"ffffff00";
end if;
if zero then
r.expnt:=X"00";
r.mnts:=X"00000000";
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Res:=FloatR_To_Float(r);
end Rnd;
---------------------------------------------------------------------
-- Procedure Compf
-- compare deux flottants
---------------------------------------------------------------------
procedure Compf(Fx,Fy : in Float_Typ;
lrb : in Bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable
infinp,
invinp,
zero,
ovf,
uvf,
sgn : boolean;
variable x,y,r : FloatR_Typ;
variable xexpint, yexpint, rexpint : natural;
variable bool : boolean;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
y:=Float_To_FloatR(Fy);
xexpint:=BVtoI(x.expnt);
yexpint:=BVtoI(y.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
y.mnts:=y.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
if yexpint=0 then y.mnts:=X"00000000"; end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000")
or
(y.expnt=X"FF"
and y.mnts /= X"80000000");
-- drapeaux
-------------------------------
zero := (x=y) or ((x.expnt=X"00" and y.expnt=X"00")
and not invinp);
ovf := FALSE;
uvf := FALSE;
bool := x.sgn='1' and y.sgn='0';
bool := bool or (
(x.sgn='0' and y.sgn='0') and
((xexpint < yexpint) or
(xexpint=yexpint and x .mnts < y.mnts)) );
bool := bool or (
(x.sgn='1' and y.sgn='1') and
((xexpint > yexpint) or
(xexpint=yexpint and x .mnts > y.mnts)) );
sgn := (bool and not invinp ) and not zero;
-- Sortie
---------------------
Res :=X"0000000000";
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
end Compf;
---------------------------------------------------------------------
-- Procedure Minf
-- donne le minimum de deux flottants
---------------------------------------------------------------------
procedure Minf(Fx,Fy : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable infinp, invinp, zero, ovf, uvf, sgn : boolean;
variable x,y,r : FloatR_Typ;
variable xexpint, yexpint, rexpint : natural;
variable bool : boolean;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
y:=Float_To_FloatR(Fy);
xexpint:=BVtoI(x.expnt);
yexpint:=BVtoI(y.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
y.mnts:=y.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
if yexpint=0 then y.mnts:=X"00000000"; end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000")
or
(y.expnt=X"FF"
and y.mnts /= X"80000000");
-- Determination de Fx < Fy
-------------------------------------------------
-- bool est a vrai si Fx < Fy
bool := x.sgn='1' and y.sgn='0';
bool := bool or (
(x.sgn='0' and y.sgn='0') and
((xexpint < yexpint) or
(xexpint=yexpint and x .mnts < y.mnts)) );
bool := bool or (
(x.sgn='1' and y.sgn='1') and
((xexpint > yexpint) or
(xexpint=yexpint and x .mnts > y.mnts)) );
-- Resultat
---------------------
if bool then
r:=x;
else
r:=y;
end if;
Res:=FloatR_To_Float(r);
-- drapeaux
-------------------------------
zero := (r.expnt=X"00" and not invinp);
ovf := FALSE;
uvf := FALSE;
sgn := r.sgn='1' and not invinp;
-- Cas Particuliers
-------------------------------
if invinp then
if lrb='0' then
Res:=X"ffffffffff";
else
Res:=X"ffffffff00";
end if;
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
end Minf;
---------------------------------------------------------------------
-- Procedure Maxf
-- donne le maximum de deux flottants
---------------------------------------------------------------------
procedure Maxf(Fx,Fy : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable infinp, invinp, zero, ovf, uvf, sgn : boolean;
variable x,y,r : FloatR_Typ;
variable xexpint, yexpint, rexpint : natural;
variable bool : boolean;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
y:=Float_To_FloatR(Fy);
xexpint:=BVtoI(x.expnt);
yexpint:=BVtoI(y.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
y.mnts:=y.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
if yexpint=0 then y.mnts:=X"00000000"; end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000")
or
(y.expnt=X"FF"
and y.mnts /= X"80000000");
-- Determination de Fx < Fy
-------------------------------------------------
-- bool est a vrai si Fx < Fy
bool := x.sgn='1' and y.sgn='0';
bool := bool or (
(x.sgn='0' and y.sgn='0') and
((xexpint < yexpint) or
(xexpint=yexpint and x .mnts < y.mnts)) );
bool := bool or (
(x.sgn='1' and y.sgn='1') and
((xexpint > yexpint) or
(xexpint=yexpint and x .mnts > y.mnts)) );
-- Resultat
---------------------
if bool then
r:=y;
else
r:=x;
end if;
Res:=FloatR_To_Float(r);
-- drapeaux
-------------------------------
zero := (r.expnt=X"00" and not invinp);
ovf := FALSE;
uvf := FALSE;
sgn := r.sgn='1' and not invinp;
-- Cas Particuliers
-------------------------------
if invinp then
if lrb='0' then
Res:=X"ffffffffff";
else
Res:=X"ffffffff00";
end if;
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
end Maxf;
---------------------------------------------------------------------
-- Procedure Clipf
---------------------------------------------------------------------
procedure Clipf(Fx,Fy : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable infinp, invinp, zero, ovf, uvf, sgn : boolean;
variable x,y,r : FloatR_Typ;
variable xexpint, yexpint, rexpint : natural;
variable bool : boolean;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
y:=Float_To_FloatR(Fy);
xexpint:=BVtoI(x.expnt);
yexpint:=BVtoI(y.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
y.mnts:=y.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
if yexpint=0 then y.mnts:=X"00000000"; end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000")
or
(y.expnt=X"FF"
and y.mnts /= X"80000000");
-- Determination de Fx < Fy
-------------------------------------------------
bool := ((xexpint < yexpint) or
(xexpint=yexpint and x .mnts < y.mnts)) ;
-- Resultat
---------------------
if bool then
r:=x;
else
r:=y;
r.sgn:=x.sgn;
end if;
Res:=FloatR_To_Float(r);
-- drapeaux
-------------------------------
zero := (r.expnt=X"00" and not invinp);
ovf := FALSE;
uvf := FALSE;
sgn := r.sgn='1' and not invinp;
-- Cas Particuliers
-------------------------------
if invinp then
if lrb='0' then
Res:=X"ffffffffff";
else
Res:=X"ffffffff00";
end if;
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
end Clipf;
---------------------------------------------------------------------
-- Procedure : Negf
-- calcule -F
---------------------------------------------------------------------
procedure Negf(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable infinp, invinp, zero, ovf, uvf, sgn : boolean;
variable x,r : FloatR_Typ;
variable xexpint, rexpint : natural;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
xexpint:=BVtoI(x.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000");
infinp:= (x.expnt=X"FF") and (x.mnts=X"80000000");
-- Resultat
---------------------
r.sgn:=not x.sgn;
r.expnt:=x.expnt;
r.mnts:=x.mnts;
-- drapeaux
-------------------------------
zero := (r.expnt=X"00");
ovf := FALSE;
uvf := FALSE;
sgn := r.sgn='1' and not invinp;
-- Cas Particuliers
-------------------------------
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"ffffffff";
else
r.mnts:=X"ffffff00";
end if;
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Res:=FloatR_To_Float(r);
end Negf;
---------------------------------------------------------------------
-- Procedure : Absf
-- calcule -F
---------------------------------------------------------------------
procedure Absf(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable infinp, invinp, zero, ovf, uvf, sgn : boolean;
variable x,r : FloatR_Typ;
variable xexpint, rexpint : natural;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
xexpint:=BVtoI(x.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000");
infinp:= (x.expnt=X"FF") and (x.mnts=X"80000000");
-- Resultat
---------------------
r.sgn:='0';
r.expnt:=x.expnt;
r.mnts:=x.mnts;
-- drapeaux
-------------------------------
zero := (r.expnt=X"00");
ovf := FALSE;
uvf := FALSE;
sgn := r.sgn='1' and not invinp;
-- Cas Particuliers
-------------------------------
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"ffffffff";
else
r.mnts:=X"ffffff00";
end if;
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
if (x.sgn='1') and not invinp then
Stat(5):='1' ;
else
Stat(5):='0' ;
end if;
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Res:=FloatR_To_Float(r);
end Absf;
---------------------------------------------------------------------
-- Procedure : Passf
---------------------------------------------------------------------
procedure Passf(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable infinp, invinp, zero, ovf, uvf, sgn : boolean;
variable x,r : FloatR_Typ;
variable xexpint, rexpint : natural;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
xexpint:=BVtoI(x.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000");
infinp:= (x.expnt=X"FF") and (x.mnts=X"80000000");
-- Resultat
---------------------
r.sgn:=x.sgn;
r.expnt:=x.expnt;
r.mnts:=x.mnts;
-- drapeaux
-------------------------------
zero := (r.expnt=X"00");
ovf := FALSE;
uvf := FALSE;
sgn := r.sgn='1' and not invinp;
-- Cas Particuliers
-------------------------------
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"ffffffff";
else
r.mnts:=X"ffffff00";
end if;
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Res:=FloatR_To_Float(r);
end Passf;
---------------------------------------------------------------------
-- Procedure : Csignf
-- Attribue le signe de Fy et la valeur de Fx
---------------------------------------------------------------------
procedure Csignf(Fx, Fy : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable infinp, invinp, zero, ovf, uvf, sgn : boolean;
variable x,y,r : FloatR_Typ;
variable xexpint, yexpint, rexpint : natural;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
y:=Float_To_FloatR(Fy);
xexpint:=BVtoI(x.expnt);
yexpint:=BVtoI(y.expnt);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
y.mnts:=y.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if xexpint=0 then x.mnts:=X"00000000"; end if;
if yexpint=0 then y.mnts:=X"00000000"; end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000") or
(y.expnt=X"FF"
and y.mnts /= X"80000000");
infinp:= (x.expnt=X"FF") and (x.mnts=X"80000000");
-- Resultat
---------------------
r.sgn:=y.sgn;
r.expnt:=x.expnt;
r.mnts:=x.mnts;
-- drapeaux
-------------------------------
zero := (r.expnt=X"00");
ovf := FALSE;
uvf := FALSE;
sgn := r.sgn='1' and not invinp;
-- Cas Particuliers
-------------------------------
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"ffffffff";
else
r.mnts:=X"ffffff00";
end if;
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Res:=FloatR_To_Float(r);
end Csignf;
---------------------------------------------------------------------
-- Procedure : Logb
---------------------------------------------------------------------
procedure Logb(Fx : in Float_Typ;
lrb, lfs : in bit;
Res : out Fix_Typ;
Fres : out Float_Typ;
flpoutp : out Boolean;
Stat : out BV8_Typ) is
variable infinp, invinp, zerinp, zero, ovf, uvf, sgn : boolean;
variable x, r : FloatR_Typ;
variable Result : Fix_Typ;
variable flpout: Boolean;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if x.expnt=X"00" then x.mnts:=X"00000000";
end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000");
infinp:= (x.expnt=X"FF") and (x.mnts=X"80000000");
zerinp:= (x.expnt=X"00");
-- Logb
----------------------
Result:=signed_vector(Extend(x.expnt,Result'LENGTH));
Result:= Result - X"7F";
-- Cas Particuliers
-------------------------------
if invinp or ( (infinp or zerinp) and (lfs='0')) then
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:= X"FFFFFFFF";
else
r.mnts:= X"FFFFFF00";
end if;
end if;
if infinp then
r.sgn:='0';
r.expnt:=X"FF";
r.mnts:= X"00000000";
end if;
if zerinp then
r.sgn:='1';
r.expnt:=X"FF";
r.mnts:= X"00000000";
end if;
flpout:=TRUE;
else
if infinp then
Result:=X"7FFFFFFF";
end if;
if zerinp then
Result:=X"80000000";
end if;
flpout:=FALSE;
end if;
-- drapeaux
-------------------------------
if invinp or ( (infinp or zerinp) and (lfs='0')) then
zero := FALSE;
ovf := infinp or zerinp;
uvf := FALSE;
sgn := r.sgn='1' and not invinp;
else
ovf := infinp or zerinp;
uvf := FALSE;
sgn := Result(31)='1';
end if;
-- Status
---------------------------------
if flpout then -- resultat Float
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
else -- resultat Fix
if Result=X"00000000" then Stat(0):='1'; else Stat(0):='0';
end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
Stat(6):='0';
Stat(7):='1';
end if;
Fres:=FloatR_To_Float(r);
Res := Result;
flpoutp:=flpout;
end Logb;
---------------------------------------------------------------------
-- Procedure : Scalb
---------------------------------------------------------------------
procedure Scalb(Fx : in Float_Typ;
Y : in Fix_Typ;
lrb, lrm : in bit;
Fres : out Float_Typ;
Stat : out BV8_Typ) is
variable infinp, invinp, zerinp, zero, ovf, uvf, sgn : boolean;
variable x, r : FloatR_Typ;
variable sum : Fix_Typ;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if x.expnt=X"00" then x.mnts:=X"00000000";
end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000");
infinp:= (x.expnt=X"FF") and (x.mnts=X"80000000");
zerinp:= (x.expnt=X"00");
-- Scalb
----------------------
r.sgn:=x.sgn;
sum:=signed_vector(Extend(x.expnt,32))+Y;
if (Y(31)='0' and sum(31)='1') then
if Y < X"00000000" then
sum:=X"80000000";
else
sum:=X"7FFFFFFF";
end if;
end if;
if ((lrm ='0') and sum=X"00000000") and
((lrb='1' and x.mnts=X"FFFFFF00") or (lrb='0' and x.mnts=X"FFFFFFFF"))
then
r.expnt:=X"01";
r.mnts:=X"80000000";
uvf:=TRUE;
else
r.mnts:=x.mnts;
uvf:= (sum <= X"00000000" and r.mnts /=X"00000000")
and not (invinp or infinp);
end if;
r.expnt:=bit_vector(sum(7 downto 0));
-- drapeaux
-------------------------------
zero := (sum <=X"00000000" and not (invinp or infinp)
) or zerinp;
ovf := sum >=X"0000000FF" and not (invinp or (infinp
or zerinp));
sgn := r.sgn='1' and not invinp;
-- Cas Particuliers
-------------------------------
if (ovf and lrm='0') or infinp then
r.sgn:=x.sgn;
r.expnt:=X"FF";
r.mnts:=X"00000000";
end if;
if ovf and lrm='1' then
r.sgn:=x.sgn;
r.expnt:=X"FE";
if lrb='0' then
r.mnts:=X"FFFFFFFF";
else
r.mnts:=X"FFFFFF00";
end if;
end if;
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"FFFFFFFF";
else
r.mnts:=X"FFFFFF00";
end if;
end if;
if zero then
r.sgn:=x.sgn;
r.expnt:=X"00";
r.mnts:= X"00000000";
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Fres:=FloatR_To_Float(r);
end Scalb;
---------------------------------------------------------------------
-- Procedure : Mantf
---------------------------------------------------------------------
procedure Mantf(Fx : in Float_Typ;
lrb : in bit;
Res : out Fix_Typ;
Fres : out Float_Typ;
flpoutp : out Boolean;
Stat : out BV8_Typ) is
variable infinp, invinp, zerinp, zero, ovf, uvf, sgn : boolean;
variable x, r : FloatR_Typ;
variable Result : Fix_Typ;
variable flpout : Boolean;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if x.expnt=X"00" then x.mnts:=X"00000000";
end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF"
and x.mnts /= X"80000000");
infinp:= (x.expnt=X"FF") and (x.mnts=X"80000000");
zerinp:= (x.expnt=X"00");
-- Mant
----------------------
Result:=signed_vector(x.mnts);
-- Cas Particuliers
-------------------------------
flpout:=FALSE;
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"FFFFFFFF";
else
r.mnts:=X"FFFFFF00";
end if;
flpout:=TRUE;
end if;
if zero then
Result:=X"00000000";
end if;
-- drapeaux
-------------------------------
if invinp then
zero:=FALSE;
ovf:=FALSE;
uvf:=FALSE;
sgn:=FALSE;
else
ovf:=infinp;
uvf:=FALSE;
sgn:=FALSE;
end if;
-- Status
---------------------------------
if flpout then -- resultat Float
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
else -- resultat Fix
if Result=X"00000000" then Stat(0):='1'; else Stat(0):='0';
end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):=x.sgn;
Stat(6):='0';
Stat(7):='1';
end if;
flpoutp:=flpout;
Fres:=FloatR_To_Float(r);
Res := Result;
end Mantf;
---------------------------------------------------------------------
-- Procedure : Fix
-- Conversion de Float en Fix
---------------------------------------------------------------------
procedure Fix(Fx : in Float_Typ;
lrb, lrm, lfs : in bit;
Res : out Fix_Typ;
Fres : out Float_Typ;
flpoutp : out Boolean;
Stat : out BV8_Typ) is
variable infinp, invinp, zerinp, zero, ovf, uvf, sgn : boolean;
variable cry : Bit;
variable x, r : FloatR_Typ;
variable sum, Result : Fix_Typ;
variable sumint : integer;
variable flpout : Boolean;
variable rext : mantis_Typ;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if x.expnt=X"00" then x.mnts:=X"00000000";
end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF") and x.mnts /= X"80000000";
infinp:= (x.expnt=X"FF") and (x.mnts=X"80000000");
zerinp:= (x.expnt=X"00");
-- Fix
----------------------
r.sgn:=x.sgn;
sum:=signed_vector(Extend(x.expnt,32));
sum:=sum-X"0000009E";
r.mnts:=x.mnts;
sumint:=to_integer(sum(30 downto 0));
if sumint < 0 then
if sumint <= -63 then
if x.mnts/=X"00000000" then rext:=X"00000001";
else rext:=X"00000000"; end if;
else if (-sumint)>=32 then
if Shl(x.mnts,63+sumint) /=X"00000000" then
rext:= Shr(x.mnts,(-sumint-32)) or X"00000001";
else
rext:= Shr(x.mnts,(-sumint-32));
end if;
else
rext:= Shl(x.mnts,(sumint+32));
end if;
end if;
if sumint <= -32 then
r.mnts:=X"00000000";
uvf:=TRUE;
else
r.mnts:=Shr(x.mnts,-sumint);
uvf:=FALSE;
end if;
if r.sgn='1' then
r.mnts:=not r.mnts+ Acry(signed_vector(not rext), X"00000001");
rext:=not rext + "1";
end if;
if ((lrm='0' and r.mnts(0)='1') and rext(31)='1') or
(rext(31)='1' and Shl(rext,1)/=X"00000000") then
r.mnts:=r.mnts+"1";
end if;
else
if r.sgn='1' then
r.mnts:=not r.mnts+"1";
uvf:=FALSE;
end if;
end if;
Result:=signed_vector(r.mnts);
ovf:=sumint>0 or
(sumint=0 and (r.sgn='0' or (r.sgn='1' and r.mnts/=X"80000000")));
ovf:=ovf or
(sumint=-1 and (r.sgn='0' and r.mnts(31)='1'));
ovf:=(ovf or infinp) and not (invinp or zerinp);
-- Cas Particuliers
-------------------------------
flpout:=FALSE;
if invinp or ((infinp or ovf) and lfs='0') then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"FFFFFFFF";
else
r.mnts:=X"FFFFFF00";
end if;
flpout:=TRUE;
end if;
if (infinp or ovf) and lfs='1' then
if r.sgn='0' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
-- drapeaux
-------------------------------
if invinp or ((infinp or ovf) and lfs='0') then
zero:=FALSE;
uvf:=FALSE;
else
uvf:=(uvf and not zerinp) and (not infinp and not ovf);
sgn:=Result(31)='1';
cry:='0';
end if;
-- Status
---------------------------------
if flpout then -- resultat Float
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
else -- resultat Fix
if Result=X"00000000" then Stat(0):='1'; else Stat(0):='0';
end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='1';
end if;
Fres:=FloatR_To_Float(r);
Res := Result;
flpoutp:=flpout;
end Fix;
---------------------------------------------------------------------
-- Procedure : Fixs
-- Conversion de Float en Fix
---------------------------------------------------------------------
procedure Fixs(Fx : in Float_Typ;
Y : in Fix_Typ;
lrb, lrm, lfs : in bit;
Res : out Fix_Typ;
Fres : out Float_Typ;
flpoutp : out Boolean;
Stat : out BV8_Typ) is
variable infinp, invinp, zerinp, zero, ovf, uvf, sgn : boolean;
variable cry : Bit;
variable x, r : FloatR_Typ;
variable sum, Result : Fix_Typ;
variable sumint : integer;
variable flpout : Boolean;
variable rext : mantis_Typ;
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees denormalisees
---------------------------------------------
if x.expnt=X"00" then x.mnts:=X"00000000";
end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF") and x.mnts /= X"80000000";
infinp:= (x.expnt=X"FF") and (x.mnts=X"80000000");
zerinp:= (x.expnt=X"00");
-- Fixs
----------------------
r.sgn:=x.sgn;
sum:=signed_vector(Extend(x.expnt,32));
sum:=sum-X"0000009E";
r.mnts:=x.mnts;
if not Aovf(sum, Y) then
sum:=sum+Y;
else
if Y(31)='1' then
sum:=X"80000000";
else
sum:=X"7FFFFFFF";
end if;
end if;
sumint:=to_integer(sum(30 downto 0));
if sumint < 0 then
if sumint <= -63 then
if x.mnts/=X"00000000" then rext:=X"00000001";
else rext:=X"00000000"; end if;
else if (-sumint)>=32 then
if Shl(x.mnts,63+sumint) /=X"00000000" then
rext:= Shr(x.mnts,(-sumint-32)) or X"00000001";
else
rext:= Shr(x.mnts,(-sumint-32));
end if;
else
rext:= Shl(x.mnts,(sumint+32));
end if;
end if;
if sumint <= -32 then
r.mnts:=X"00000000";
uvf:=TRUE;
else
r.mnts:=Shr(x.mnts,-sumint);
uvf:=FALSE;
end if;
if r.sgn='1' then
r.mnts:=not r.mnts+ Acry(signed_vector(not rext), X"00000001");
rext:=not rext + "1";
end if;
if ((lrm='0' and r.mnts(0)='1') and rext(31)='1') or
(rext(31)='1' and Shl(rext,1)/=X"00000000") then
r.mnts:=r.mnts+"1";
end if;
else
if r.sgn='1' then
r.mnts:=not r.mnts+"1";
uvf:=FALSE;
end if;
end if;
Result:=signed_vector(r.mnts);
ovf:=sumint>0 or
(sumint=0 and (r.sgn='0' or (r.sgn='1' and r.mnts/=X"80000000")));
ovf:=ovf or
(sumint=-1 and (r.sgn='0' and r.mnts(31)='1'));
ovf:=(ovf or infinp) and not (invinp or zerinp);
-- Cas Particuliers
-------------------------------
flpout:=FALSE;
if invinp or ((infinp or ovf) and lfs='0') then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"FFFFFFFF";
else
r.mnts:=X"FFFFFF00";
end if;
flpout:=TRUE;
end if;
if (infinp or ovf) and lfs='1' then
if r.sgn='0' then
Result:=X"7FFFFFFF";
else
Result:=X"80000000";
end if;
end if;
-- drapeaux
-------------------------------
if invinp or ((infinp or ovf) and lfs='0') then
zero:=FALSE;
uvf:=FALSE;
else
uvf:=(uvf and not zerinp) and (not infinp and not ovf);
sgn:=Result(31)='1';
cry:='0';
end if;
-- Status
---------------------------------
if flpout then -- resultat Float
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
else -- resultat Fix
if Result=X"00000000" then Stat(0):='1'; else Stat(0):='0';
end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):=cry;
Stat(5):='0';
Stat(6):='0';
Stat(7):='1';
end if;
Fres:=FloatR_To_Float(r);
Res := Result;
flpoutp:=flpout;
end Fixs;
---------------------------------------------------------------------
-- Procedure : Floatf
-- Conversion de Fix en Float
---------------------------------------------------------------------
procedure Floatf(Rx : in Fix_Typ;
lrm : in bit;
Fres : out Float_Typ;
Stat : out BV8_Typ) is
variable invinp, zerinp, zero, ovf, uvf, sgn : boolean;
variable r : FloatR_Typ;
variable sum: Fix_Typ;
variable sumint : integer;
begin
-- Entree particuliere
---------------------------------------------
zerinp:= (Rx=X"00000000");
-- signe, mantisse et exposant
----------------------
r.sgn:=Rx(31);
if r.sgn='1' then
r.mnts:=bit_vector(not Rx +X"00000001");
else
r.mnts:=bit_vector(Rx);
end if;
sum:=X"0000009E";
-- Normalisation
-------------------------------
if not zerinp then
while r.mnts(31)='0' loop
sum:=sum-X"00000001";
r.mnts:=Shl(r.mnts,1);
end loop;
end if;
r.expnt:=bit_vector(sum(7 downto 0));
-- drapeaux
-------------------------------
ovf:=FALSE;
uvf:=FALSE;
zero:=uvf or zerinp;
sgn:=r.sgn='1';
invinp:=FALSE;
-- Cas Particuliers
-------------------------------
if zerinp or uvf then
r.expnt:=X"00";
r.mnts:=X"00000000";
end if;
if ovf and lrm='0' then
r.expnt:=X"FF";
r.mnts:=X"00000000";
end if;
if ovf and lrm='1' then
r.expnt:=X"FE";
r.mnts:=X"FFFFFFFF";
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
Stat(1):='0';
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
Stat(3):='0';
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Fres:=FloatR_To_Float(r);
end Floatf;
---------------------------------------------------------------------
-- Procedure : Floatsf
-- Conversion de Fix en Float
---------------------------------------------------------------------
procedure Floatsf(Rx, Y : in Fix_Typ;
lrm : in bit;
Fres : out Float_Typ;
Stat : out BV8_Typ) is
variable invinp, zerinp, zero, ovf, uvf, sgn : boolean;
variable r : FloatR_Typ;
variable sum: Fix_Typ;
variable sumint : integer;
begin
-- Entree particuliere
---------------------------------------------
zerinp:= (Rx=X"00000000");
-- signe, mantisse et exposant
----------------------
r.sgn:=Rx(31);
if r.sgn='1' then
r.mnts:=bit_vector(not Rx +X"00000001");
else
r.mnts:=bit_vector(Rx);
end if;
if not Aovf(X"0000009E",Y) then
sum:=X"0000009E"+Y;
else
if Y(31)='1' then
sum:=X"80000000";
else
sum:=X"7FFFFFFF";
end if;
end if;
-- Normalisation
-------------------------------
if not zerinp then
while r.mnts(31)='0' loop
sum:=sum-X"00000001";
r.mnts:=Shl(r.mnts,1);
end loop;
end if;
r.expnt:=bit_vector(sum(7 downto 0));
-- drapeaux
-------------------------------
ovf:=sum >=X"000000FF" and not zerinp;
uvf:=sum <=X"00000000" and not zerinp;
zero:=uvf or zerinp;
sgn:=r.sgn='1';
invinp:=FALSE;
-- Cas Particuliers
-------------------------------
if zerinp or uvf then
r.expnt:=X"00";
r.mnts:=X"00000000";
end if;
if ovf and lrm='0' then
r.expnt:=X"FF";
r.mnts:=X"00000000";
end if;
if ovf and lrm='1' then
r.expnt:=X"FE";
r.mnts:=X"FFFFFFFF";
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
Stat(6):='0';
Stat(7):='1';
Fres:=FloatR_To_Float(r);
end Floatsf;
---------------------------------------------------------------------
-- Procedure : Recips
-- exemple d'utilisation : division F0=F0/F12 (F11=2.0).
-- F0=Recips F12, F7=F0;
-- F12=F0*F12;
-- F7=F0*F7; F0=F11-F12;
-- F12=F0*F12;
-- F7=F0*F7; F0=F11-F12;
-- F12=F0*F12;
-- F7=F0*F7; F0=F11-F12;
-- F0=F0*F7;
---------------------------------------------------------------------
procedure Recips(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable invinp, infinp, zerinp, zero, ovf, uvf, sgn : boolean;
variable x, r : FloatR_Typ;
variable sum : Fix_Typ;
type Trecip is array(0 to 127) of Mantis_Typ;
variable recis: Trecip:=
(X"000000FF",X"000000FC",X"000000F8",X"000000F4",X"000000F0",X"000000EC",X"000000E8",X"000000E4",
X"000000E0",X"000000DE",X"000000DA",X"000000D6",X"000000D4",X"000000D0",X"000000CC",X"000000CA",
X"000000C6",X"000000C2",X"000000C0",X"000000BC",X"000000BA",X"000000B6",X"000000B4",X"000000B2",
X"000000AE",X"000000AC",X"000000A8",X"000000A6",X"000000A4",X"000000A0",X"0000009E",X"0000009C",
X"00000098",X"00000096",X"00000094",X"00000092",X"0000008E",X"0000008C",X"0000008A",X"00000088",
X"00000086",X"00000082",X"00000080",X"0000007E",X"0000007C",X"0000007A",X"00000078",X"00000076",
X"00000074",X"00000072",X"00000070",X"0000006E",X"0000006C",X"0000006A",X"00000068",X"00000066",
X"00000064",X"00000062",X"00000060",X"0000005E",X"0000005C",X"0000005A",X"00000058",X"00000056",
X"00000054",X"00000052",X"00000050",X"00000050",X"0000004E",X"0000004C",X"0000004A",X"00000048",
X"00000046",X"00000046",X"00000044",X"00000042",X"00000040",X"0000003E",X"0000003E",X"0000003C",
X"0000003A",X"00000038",X"00000038",X"00000036",X"00000034",X"00000032",X"00000032",X"00000030",
X"0000002E",X"0000002E",X"0000002C",X"0000002A",X"00000028",X"00000028",X"00000026",X"00000024",
X"00000024",X"00000022",X"00000020",X"00000020",X"0000001E",X"0000001E",X"0000001C",X"0000001A",
X"0000001A",X"00000018",X"00000018",X"00000016",X"00000014",X"00000014",X"00000012",X"00000012",
X"00000010",X"0000000E",X"0000000E",X"0000000C",X"0000000C",X"0000000A",X"0000000A",X"00000008",
X"00000008",X"00000006",X"00000006",X"00000004",X"00000004",X"00000002",X"00000002",X"00000000");
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF") and x.mnts /= X"80000000";
infinp:= (x.expnt=X"FF" and x.mnts=X"80000000")
or
(x.expnt=X"FE" or x.expnt=X"FD");
zerinp:= (x.expnt=X"00");
-- Recips
----------------------
r.sgn:=x.sgn;
sum:=signed_vector(Extend(x.expnt,32));
sum:=not (sum-X"0000007F")+ X"0000007F";
r.expnt:=bit_vector(sum(7 downto 0));
r.mnts:=Shr(x.mnts,24) and X"0000007F";
r.mnts:=recis(BVtoI(Shl(r.mnts,23))) or X"80000000";
-- drapeaux
-------------------------------
ovf:= zerinp;
uvf:= FALSE;
zero:=infinp and x.sgn='0';
sgn:=r.sgn='1';
invinp:=invinp or (x.sgn='1' and not zerinp);
-- Cas Particuliers
-------------------------------
if zerinp then
r.expnt:=X"FF";
r.mnts:=X"00000000";
end if;
if infinp and x.sgn='0' then
r.expnt:=X"00";
r.mnts:=X"00000000";
end if;
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"FFFFFFFF";
else
r.mnts:=X"FFFFFF00";
end if;
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Res:=FloatR_To_Float(r);
end Recips;
---------------------------------------------------------------------
-- Procedure : Rsqrts
---------------------------------------------------------------------
procedure Rsqrts(Fx : in Float_Typ;
lrb : in bit;
Res : out Float_Typ;
Stat : out BV8_Typ) is
variable invinp, infinp, zerinp, zero, ovf, uvf, sgn : boolean;
variable x, r : FloatR_Typ;
variable sum : Fix_Typ;
type Troots is array(0 to 127) of Mantis_Typ;
variable roots: Troots:=
(X"0000006A",X"00000066",X"00000064",X"00000060",X"0000005E",X"0000005C",X"0000005A",X"00000056",
X"00000054",X"00000052",X"00000050",X"0000004E",X"0000004C",X"0000004A",X"00000046",X"00000044",
X"00000042",X"00000040",X"0000003E",X"0000003C",X"0000003C",X"0000003A",X"00000038",X"00000036",
X"00000034",X"00000032",X"00000030",X"0000002E",X"0000002C",X"0000002C",X"0000002A",X"00000028",
X"00000026",X"00000026",X"00000024",X"00000022",X"00000020",X"00000020",X"0000001E",X"0000001C",
X"0000001C",X"0000001A",X"00000018",X"00000016",X"00000016",X"00000014",X"00000014",X"00000012",
X"00000010",X"00000010",X"0000000E",X"0000000E",X"0000000C",X"0000000A",X"0000000A",X"00000008",
X"00000008",X"00000006",X"00000006",X"00000004",X"00000004",X"00000002",X"00000002",X"00000000",
X"000000FF",X"000000FC",X"000000F8",X"000000F4",X"000000F0",X"000000EC",X"000000E8",X"000000E6",
X"000000E2",X"000000DE",X"000000DC",X"000000D8",X"000000D4",X"000000D2",X"000000CE",X"000000CC",
X"000000C8",X"000000C6",X"000000C4",X"000000C0",X"000000BE",X"000000BC",X"000000B8",X"000000B6",
X"000000B4",X"000000B2",X"000000AE",X"000000AC",X"000000AA",X"000000A8",X"000000A6",X"000000A4",
X"000000A2",X"0000009E",X"0000009C",X"0000009A",X"00000098",X"00000096",X"00000094",X"00000092",
X"00000090",X"0000008E",X"0000008C",X"0000008A",X"0000008A",X"00000088",X"00000086",X"00000084",
X"00000082",X"00000080",X"0000007E",X"0000007C",X"0000007C",X"0000007A",X"00000078",X"00000076",
X"00000074",X"00000074",X"00000072",X"00000070",X"0000006E",X"0000006E",X"0000006C",X"0000006A");
begin
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
end if;
-- Entrees invalides NaN
------------------------------
invinp:= (x.expnt=X"FF") and x.mnts /= X"80000000";
infinp:= (x.expnt=X"FF" and x.mnts=X"80000000");
zerinp:= (x.expnt=X"00");
-- Rsqrts
----------------------
if zerinp then r.sgn:='0'; else r.sgn:=x.sgn; end if;
sum:=signed_vector(Extend(x.expnt,32));
sum:=not (Shr(sum-X"0000007F",1))+ X"0000007F";
r.expnt:=bit_vector(sum(7 downto 0));
r.mnts:=Shr(x.mnts,25) and X"0000003F";
r.mnts:=r.mnts or Shl((Extend(x.expnt,32) and X"00000001"),6);
r.mnts:=roots(BVtoI(Shl(r.mnts,23))) or X"80000000";
-- drapeaux
-------------------------------
ovf:= zerinp;
uvf:= x.expnt=X"000000FE" or x.expnt=X"000000FD";
zero:=infinp;
sgn:=r.sgn='1' and not invinp;
-- Cas Particuliers
-------------------------------
if zerinp then
r.expnt:=X"FF";
r.mnts:=X"00000000";
end if;
if infinp then
r.expnt:=X"00";
r.mnts:=X"00000000";
end if;
if invinp then
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"FFFFFFFF";
else
r.mnts:=X"FFFFFF00";
end if;
end if;
-- Status
---------------------------------
if zero then Stat(0):='1'; else Stat(0):='0'; end if;
if uvf then Stat(1):='1'; else Stat(1):='0'; end if;
if sgn then Stat(2):='1'; else Stat(2):='0'; end if;
if ovf then Stat(3):='1'; else Stat(3):='0'; end if;
Stat(4):='0';
Stat(5):='0';
if invinp then Stat(6):='1'; else Stat(6):='0'; end if;
Stat(7):='1';
Res:=FloatR_To_Float(r);
end Rsqrts;
---------------------------------------------------------------------
-- Procedure Mulf
-- realise une multiplication de floats.
-- Si lrb est a 1, la multiplication se fait sur simple precision
-- Si lrm est a 1, il y a simple troncature et non arrondi au plus
pret
---------------------------------------------------------------------
procedure Mulf(Fx,Fy : in Float_Typ;
lrb, lrm : in bit;
Res : out Float_Typ;
MN,MI,MU,MV,MF : out bit
) is
variable nanx,nany,infx,infy,zerx,zery,inval,infin,zero, bool :
boolean;
variable x,y,r : FloatR_Typ;
variable exposant : Mantis_Typ;
variable mantisse : bit_vector(63 downto 0);
variable mantl, manth : Mantis_Typ;
begin
MN:='0'; MI:='0'; MU:='0'; MV:='0';
MF:='1';
-- Recopie des entrees sous forme FloatR_Typ
x:=Float_To_FloatR(Fx);
y:=Float_To_FloatR(Fy);
-- Troncature pour les entrees a mettre sur 32 bits
---------------------------------------------------------
if lrb='1' then
x.mnts:=x.mnts and X"ffffff00";
y.mnts:=y.mnts and X"ffffff00";
end if;
-- Signe
--------------------------------------------
r.sgn:=x.sgn xor y.sgn;
-- Drapeaux
---------------------------------------------
infx:= (x.expnt=X"FF"
and x.mnts = X"80000000");
infy:=(y.expnt=X"FF"
and y.mnts = X"80000000");
nanx:= (x.expnt=X"FF"
and x.mnts /= X"80000000");
nany:= (y.expnt=X"FF"
and y.mnts /= X"80000000");
zerx:=x.expnt=X"00";
zery:=y.expnt=X"00";
if nanx or nany or (infx and zery) or (infy and zerx) then
inval:=TRUE;
MN:='0';
MI:='1';
r.sgn:='1';
r.expnt:=X"FF";
if lrb='0' then
r.mnts:=X"FFFFFFFF";
else
r.mnts:=X"FFFFFF00";
end if;
else
inval:=FALSE;
MN:=r.sgn;
MI:='0';
end if;
if (infx or infy) and not inval then
infin:=TRUE;
MN:=r.sgn;
MI:='0';
r.mnts:=X"80000000";
r.expnt:=X"FF";
else
infin:=FALSE;
end if;
if (zerx or zery) and not inval then
zero:=TRUE;
MN:=r.sgn;
MI:='0';
r.mnts:=X"80000000";
r.expnt:=X"00";
else
zero:=FALSE;
end if;
if (not inval) and (not infin) and (not zero) then
-- Exposant
------------------------
exposant:=Extend(x.expnt,32);
exposant:=exposant+Extend(y.expnt,32)-X"7F";
-- Mantisse
-------------------------
mantisse:=x.mnts*y.mnts;
manth:=mantisse(63 downto 32);
mantl:=mantisse(31 downto 0);
-- Arrondi et Ajustement de l'exposant
------------------------------------------------
if lrm='0' then -- Arrondi au plus pres
if lrb='0' then -------------- 40 Bits -----------------
if exposant=X"00000000" and
manth=X"7FFFFFFF" and
mantl(31 downto 30)="10" then
exposant:=X"00000001";
r.expnt:=X"00";
r.mnts :=X"80000000";
MU:='1';
else if manth >=X"80000000" then
exposant:=exposant+'1';
if mantl>X"80000000"
or (manth(0)='1' and mantl=X"80000000") then
manth:=manth+'1';
end if;
r.expnt:=exposant(7 downto 0);
r.mnts:=manth;
else
if ((mantl and X"7FFFFFFF") > X"40000000")
or mantl=X"C0000000" then
if mantl >=X"80000000" then
mantl:=mantl and X"7FFFFFFF";
manth:=manth+'1';
else
mantl:=mantl or X"80000000";
end if;
end if;
if manth >=X"80000000" then
exposant:=exposant+'1';
r.expnt:=exposant(7 downto 0);
r.mnts :=manth;
else
r.mnts(0):=mantl(31);
r.mnts(31 downto 1):=manth(30 downto 0);
r.expnt:=exposant(7 downto 0);
end if;
end if;
end if;
else -------------------- 32 Bits ---------------------------
if exposant=X"00000000" and
((manth and X"FFFFFFC0")=X"7FFFFF80") then
exposant:=X"00000001";
r.expnt:=X"00";
r.mnts :=X"80000000";
MU:='1';
else if manth >=X"80000000" then
exposant:=exposant+'1';
bool:=manth(7)='1';
bool:=bool and (mantl/=X"00000000" or
(manth and X"0000007F")/=X"00000000");
bool:=bool or (mantl=X"00000000" and
(manth and X"000001FF")/=X"00000180");
if bool then
manth:=manth +X"100";
end if;
r.expnt:=exposant(7 downto 0);
r.mnts(31 downto 8):=manth(31 downto 8);
r.mnts(7 downto 0) :=X"00";
else
bool:=manth(6)='1';
bool:=bool and (mantl/=X"00000000" or
(manth and X"0000003F")/=X"00000000");
bool:=bool or (mantl=X"00000000" and
(manth and X"000000FF")/=X"000000C0");
if bool then
manth:=manth +X"80";
end if;
if manth >=X"80000000" then
exposant:=exposant+'1';
r.expnt:=exposant(7 downto 0);
r.mnts(31 downto 8):=manth(31 downto 8);
r.mnts(7 downto 0) :=X"00";
else
r.mnts(7 downto 0) :=X"00";
r.mnts(31 downto 8):=manth(30 downto 7);
r.expnt:=exposant(7 downto 0);
end if;
end if;
end if;
end if;
else ------------- Troncature ------------------------------------
if lrb='0' then -------------- 40 Bits -----------------
if manth >=X"80000000" then
exposant:=exposant+'1';
r.expnt:=exposant(7 downto 0);
r.mnts :=manth;
else
r.mnts(0):=mantl(31);
r.mnts(31 downto 1):=manth(30 downto 0);
r.expnt:=exposant(7 downto 0);
end if;
else -------------------- 32 Bits ---------------------------
if manth >=X"80000000" then
exposant:=exposant+'1';
r.expnt:=exposant(7 downto 0);
r.mnts(31 downto 8):=manth(31 downto 8);
r.mnts(7 downto 0) :=X"00";
else
r.mnts(7 downto 0) :=X"00";
r.mnts(31 downto 8):=manth(30 downto 7);
r.expnt:=exposant(7 downto 0);
end if;
end if;
end if; -- arrondi ou troncature
if exposant > X"000000FE" and exposant < X"00000180"
then -- overflow
if lrm='0' then
r.expnt:=X"FF";
r.mnts:=X"80000000";
else
r.expnt:=X"FE";
if lrb='0' then
r.mnts:=X"FFFFFFFF";
else
r.mnts:=X"FFFFFF00";
end if;
end if;
MV:='1';
end if; --ovf
if exposant > X"0000017F" or exposant = X"00000000"
then -- underflow
r.expnt:=X"00";
r.mnts:=X"00000000";
MU:='1';
end if;
end if; -- not inval and not infin and not zero
Res:=FloatR_To_Float(r);
end Mulf;
end Float40_Pkg;
back
to introduction