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;