-------------------------------------------------------------------------------- -- 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 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 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;