Floating Point Unit - ALU block
prepared by P. Bakowski (designer G. Ramstein)
back
to main text
note : non synthetisable
-- ALU ENTITY
use WORK.bitvector_pkg.ALL;
use WORK.signvector_pkg.ALL;
use WORK.float40_pkg.ALL;
entity Alu_Nty is
- port( -- Donnees
- Asx2f, Asy2f : in BV40_Typ; -- Deux operandes
- PS_AC1f : in Bit; -- Carry
- Ar2f, Sr2f : out BV40_Typ; -- Resultats (Sr2f/=0 que pour addsub(f)
- AL_Stat2F : out BV8_Typ; -- Controle
- RF_Alsd2f : in Bit; -- Selection d'une operation de l'ALU
- RF_Asopd2f : in BV8_Typ; -- Code d'operation
- PS_rnd321f : in Bit; -- arrondi
- PS_Trunc1f : in Bit; -- troncature
- PS_Alusat1f : in Bit; -- saturation point fixe
- Ck : in Bit; -- horloge processeur
- Hldb : in Bit; -- hold processeur
- Rst : in Bit; -- reset processeur
- Cen : in Bit); -- bus driver enable
end ALU_Nty;
-- ALU ARCHITECTURE
-- Sequencement en deux phases -- Phase 2 (Ck='0') : envoi du resultat
de la phase 1 precedente
-- et lecture des signaux de controle (code op,...) -- Phase 1
(Ck='1') : lecture des operandes et calcul.
architecture Alu_a of Alu_Nty is
- subtype CodOp_Typ is bit_vector(7 downto 0);
- constant Op_add : CodOp_Typ :=X"01";
- constant Op_sub : CodOp_Typ :=X"02";
- constant Op_addsub : CodOp_Typ :=X"70";
- constant Op_addc : CodOp_Typ :=X"05";
- constant Op_subc : CodOp_Typ :=X"06";
- constant Op_av : CodOp_Typ :=X"79";
- constant Op_comp : CodOp_Typ :=X"0a";
- constant Op_carry : CodOp_Typ :=X"25";
- constant Op_borrow : CodOp_Typ :=X"26";
- constant Op_inc : CodOp_Typ :=X"29";
- constant Op_dec : CodOp_Typ :=X"2a";
- constant Op_neg : CodOp_Typ :=X"22";
- constant Op_abso : CodOp_Typ :=X"30";
- constant Op_pass : CodOp_Typ :=X"21";
- constant Op_and : CodOp_Typ :=X"40";
- constant Op_or : CodOp_Typ :=X"41";
- constant Op_xor : CodOp_Typ :=X"42";
- constant Op_not : CodOp_Typ :=X"43";
- constant Op_min : CodOp_Typ :=X"61";
- constant Op_max : CodOp_Typ :=X"62";
- constant Op_clip : CodOp_Typ :=X"63";
- constant Op_addf : CodOp_Typ :=X"81";
- constant Op_subf : CodOp_Typ :=X"82";
- constant Op_addsubf : CodOp_Typ :=X"f0";
- constant Op_addabsf : CodOp_Typ :=X"91";
- constant Op_subabsf : CodOp_Typ :=X"92";
- constant Op_avf : CodOp_Typ :=X"89";
- constant Op_compf : CodOp_Typ :=X"8a";
- constant Op_negf : CodOp_Typ :=X"a2";
- constant Op_absf : CodOp_Typ :=X"b0";
- constant Op_passf : CodOp_Typ :=X"a1";
- constant Op_rnd : CodOp_Typ :=X"a5";
- constant Op_csignf : CodOp_Typ :=X"e0";
- constant Op_logb : CodOp_Typ :=X"c1";
- constant Op_scalb : CodOp_Typ :=X"bd";
- constant Op_mantf : CodOp_Typ :=X"ad";
- constant Op_fixs : CodOp_Typ :=X"d9";
- constant Op_fix : CodOp_Typ :=X"c9";
- constant Op_float : CodOp_Typ :=X"da";
- constant Op_floats : CodOp_Typ :=X"ca";
- constant Op_minf : CodOp_Typ :=X"e1";
- constant Op_maxf : CodOp_Typ :=X"e2";
- constant Op_clipf : CodOp_Typ :=X"e3";
- constant Op_recips : CodOp_Typ :=X"c4";
- constant Op_rsqrts : CodOp_Typ :=X"c5";
begin
Alu_process : process(Ck)
- use WORK.Float40_Pkg.all;
- variable Op, Op_m : CodOp_Typ;
- variable Rx, Ry, Res, Sres : Fix_Typ;
- variable Cry : Bit;
- variable Fx, Fy, Fres, Fsres : Float_Typ;
- variable Stat : BV8_Typ;
- variable lexe, lexem, ldrv : Boolean;
- variable FlOp, FlpOutp : Boolean;
- variable rnd32_m, Trunc_m, Alusat_m : Bit;
- variable rnd32, Trunc, Alusat : Bit;
begin
- if Ck='1' then
- lexe:=lexem; -- Lecture du code operation
- lexem:= RF_Alsd2f='1';
- if lexe then
- Op := RF_Asopd2f; rnd32:=PS_rnd321f; Trunc:=PS_Trunc1f; Alusat:=
PS_Alusat1f; FlOp:= Op(7)='1'; -- Lecture des operandes
- if not FlOp then -- operande Fix
- Rx:=Fix_Typ(Asx2f(39 downto 8)); Ry:=Fix_Typ(Asy2f(39 downto 8));
Cry :=PS_Ac1f;
- else Fx:=Float_Typ(Asx2f); Fy:=Float_Typ(Asy2f);
- end if;
- if not FlOp then
- -- Operation sur Fix
- case Op is
- when Op_add => Add(Rx, Ry, Alusat , Res, Stat);
- when Op_sub => Sub(Rx, Ry, Alusat , Res, Stat);
- when Op_addsub => Addsub(Rx, Ry, Alusat , Res, Sres, Stat);
- when Op_addc => Addc(Rx, Ry, Alusat , Cry, Res, Stat);
- when Op_subc => Subc(Rx, Ry, Alusat , Cry, Res, Stat);
- when Op_av => Av(Rx, Ry, Trunc , Res, Stat);
- when Op_comp => Comp(Rx, Ry, Res, Stat);
- when Op_carry => Carry(Rx, Alusat , Cry, Res, Stat);
- when Op_borrow => Borrow(Rx, Alusat , Cry, Res, Stat);
- when Op_inc => Inc(Rx, Alusat , Res, Stat);
- when Op_dec => Dec(Rx, Alusat , Res, Stat);
- when Op_neg => Neg(Rx, Alusat , Res, Stat);
- when Op_abso => Abso(Rx, Alusat , Res, Stat);
- when Op_pass => Pass(Rx, Res, Stat);
- when Op_and => And_op(Rx, Ry, Res, Stat);
- when Op_or => Or_op(Rx, Ry, Res, Stat);
- when Op_xor => Xor_op(Rx, Ry, Res, Stat);
- when Op_not => Not_op(Rx, Res, Stat);
- when Op_min => Mini(Rx, Ry, Res, Stat);
- when Op_max => Max(Rx, Ry, Res, Stat);
- when Op_clip => Clip(Rx, Ry, Res, Stat);
- when others => assert FALSE report "ALU Operation Code
unknown" severity failure;
- end case;
- else -- Operation sur Float
- case Op is
- when Op_addf => Addf(Fx, Fy, rnd32 , trunc , Fres, Stat);
- when Op_subf => Subf(Fx,Fy, rnd32 , trunc , Fres, Stat);
- when Op_addabsf => Addabsf(Fx,Fy, rnd32 , trunc , Fres, Stat);
- when Op_subabsf => Subabsf(Fx,Fy, rnd32 , trunc , Fres, Stat);
- when Op_addsubf => Addsubf(Fx,Fy, rnd32 , trunc , Fres, Fsres,
Stat);
- when Op_avf => Avf(Fx,Fy, rnd32 , trunc , Fres, Stat);
- when Op_rnd => Rnd(Fx, rnd32 , trunc , Fres, Stat);
- when Op_compf => Compf(Fx,Fy, rnd32, Fres, Stat);
- when Op_minf => Minf(Fx,Fy, rnd32 , Fres, Stat);
- when Op_maxf => Maxf(Fx,Fy, rnd32 , Fres, Stat);
- when Op_clipf => Clipf(Fx,Fy, rnd32 , Fres, Stat);
- when Op_negf => Negf(Fx, rnd32 , Fres, Stat);
- when Op_absf => Absf(Fx, rnd32 , Fres, Stat);
- when Op_passf => Passf(Fx, rnd32 , Fres, Stat);
- when Op_csignf => Csignf(Fx, Fy, rnd32 , Fres, Stat);
- when Op_logb => Logb(Fx, rnd32 , Alusat , Res, Fres, flpoutp,
Stat);
- when Op_scalb => Ry:=Fix_Typ(Fy(39 downto 8)); Scalb(Fx, Ry,
rnd32 , trunc , Fres, Stat);
- when Op_mantf => Mantf(Fx, rnd32 , Res, Fres, flpoutp, Stat);
- when Op_fix => Fix(Fx, rnd32 , trunc , Alusat , Res, Fres, flpoutp,
Stat);
- when Op_fixs => Ry:=Fix_Typ(Fy(39 downto 8)); Fixs(Fx, Ry, rnd32
, trunc , Alusat , Res, Fres, flpoutp, Stat);
- when Op_float => Rx:=Fix_Typ(Fx(39 downto 8)); Floatf(Rx, trunc
, Fres, Stat);
- when Op_floats => Rx:=Fix_Typ(Fx(39 downto 8)); Ry:=Fix_Typ(Fy(39
downto 8)); Floatsf(Rx, Ry, trunc , Fres, Stat);
- when Op_recips => Recips(Fx, rnd32 , Fres, Stat);
- when Op_rsqrts => Rsqrts(Fx, rnd32 , Fres, Stat);
- when others => assert FALSE report "ALU Operation Code
unknown" severity failure;
- end case;
- end if; -- not FlOp
- end if; -- lexe
- if Rst='0' then
- else ldrv:=FALSE;
- end if;
- -- Ecriture du resultat --------------------------------
- if ldrv and Cen='1' then
- if not FlOp or ((Op=Op_fix or Op=Op_fixs or Op=Op_logb or Op=Op_mantf)
and not FlpOutp) then
- -- Fix
- Ar2f<=BV40_Typ(Shl(Extend(Res,40),8));
- if Op=Op_addsub then
- Sr2f<=BV40_Typ(Shl(Extend(Sres,40),8));
- else Sr2f<=X"0000000000";
- end if;
- else -- Float Ar2f<=BV40_Typ(Fres);
- if Op = Op_addsubf then
- Sr2f<=BV40_Typ(Fsres);
- else Sr2f<=X"0000000000";
- end if;
- end if; -- not FlOp
- else Ar2f<=X"0000000000";
- -- Release
- Sr2f<=X"0000000000"; -- Release
- end if;
- -- ldrv
- AL_Stat2F<=Stat;
- end if;
- -- Ck=' '
end process;
end Alu_a;
back
to main text