📄 fpurt_lib.vhd
字号:
end FPURTPck; -- package----------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------------------------------------------------package body FPURTPck is subtype single is unsigned(31 downto 0); subtype double is unsigned(63 downto 0); subtype fpexc is std_logic_vector(4 downto 0); ------------------------------ constant IsFPopRdDouble : MnemoTableType := ( FiTOd => TRUE, FsTOd => TRUE, FqTOd => TRUE, FSQRTd => TRUE, FADDd => TRUE, FSUBd => TRUE, FMULd => TRUE, FsMULd => TRUE, -- SPARC v.8 only for FsMULd FDIVd => TRUE, others => FALSE ); ------------------------------ constant IsFPopSourceRegDouble : MnemoTableType := ( FdTOi => TRUE, FdTOs => TRUE, FdTOq => TRUE, FSQRTd => TRUE, FADDd => TRUE, FSUBd => TRUE, FMULd => TRUE, FdMULq => TRUE, -- SPARC v.8 only for FsMULd & FdMULq FDIVd => TRUE, FCMPd => TRUE, FCMPEd => TRUE, others => FALSE ); ------------------------------ constant IsFPopUnimp : MnemoTableType := ( FiTOq => TRUE, FqTOi => TRUE, FsTOq => TRUE, FdTOq => TRUE, FqTOs => TRUE, FqTOd => TRUE, FSQRTq => TRUE, FADDq => TRUE, FSUBq => TRUE, FMULq => TRUE, FsMULd => TRUE, FdMULq => TRUE, -- SPARC v.8 only for FsMULd & FdMULq FDIVq => TRUE, FCMPq => TRUE, FCMPEq => TRUE, others => FALSE ); ------------------------------ function FPtranscribe(A : std_logic_vector) return FPInstruction is constant L : natural := A'length; variable Inst : Instruction; variable Result : FPInstruction; begin assert L = 32 report "(FPtranscribe): invalid vector length!" severity error; Inst := Transcribe(A); Result.Mnemo := Inst.Mnemo; Result.rs1 := Inst.rs1; Result.rs2 := Inst.rs2; Result.rd := Inst.rd; Result.BitInstruction := A; return Result; end FPtranscribe; -- function ------------------------------ function FPop_LDF(signal FPinst : FPInstruction; RegD : natural ) return boolean is begin if IsFPop(FPinst.Mnemo) and (FPinst.rs2 = RegD or (FPURs1IsIn(FPinst.Mnemo) and FPinst.rs1 = RegD) or (not(IsFCMP(FPinst.Mnemo)) and FPinst.rd = RegD) or (IsFPopRdDouble(FPinst.Mnemo) and ( ((FPinst.rd/2)*2) = RegD or ((FPinst.rd/2)*2 + 1) = RegD ) ) or (IsFPopSourceRegDouble(FPinst.Mnemo) and ( ((FPinst.rs2/2)*2) = RegD or ((FPinst.rs2/2)*2 + 1) = RegD or (FPURs1IsIn(FPinst.Mnemo) and ( ((FPinst.rs1/2)*2) = RegD or ((FPinst.rs1/2)*2 + 1) = RegD ) ) ) ) ) then return TRUE; end if; return FALSE; end FPop_LDF; ------------------------------ function FPop_STF(signal FPinst : FPInstruction; RegD : natural ) return boolean is begin if IsFPop(FPinst.Mnemo) and ((not(IsFCMP(FPinst.Mnemo)) and FPinst.rd = RegD) or (IsFPopRdDouble(FPinst.Mnemo) and ( ((FPinst.rd/2)*2) = RegD or ((FPinst.rd/2)*2 + 1) = RegD ) ) ) then return TRUE; end if; return FALSE; end FPop_STF; ------------------------------ function LDF_FPop(signal W : FPInstruction; ID : FPInstruction ) return boolean is begin if W.Mnemo = LDF and (W.rd = ID.rs2 or (FPURs1IsIn(ID.Mnemo) and W.rd = ID.rs1) or (IsFPopSourceRegDouble(ID.Mnemo) and (W.rd = ((ID.rs2/2)*2) or W.rd = ((ID.rs2/2)*2 + 1) or (FPURs1IsIn(ID.Mnemo) and (W.rd = ((ID.rs1/2)*2) or W.rd = ((ID.rs1/2)*2 + 1) ) ) ) ) ) then return TRUE; end if; return FALSE; end LDF_FPop; ------------------------------ function LDDF_FPop(W1 : FPInstruction; ID : FPInstruction ) return boolean is begin if W1.Mnemo = LDDF and -- dependency on both rd and rd+1 of LDDF ((W1.rd = ID.rs2 or (FPURs1IsIn(ID.Mnemo) and W1.rd = ID.rs1) or (IsFPopSourceRegDouble(ID.Mnemo) and (W1.rd = ((ID.rs2/2)*2) or W1.rd = ((ID.rs2/2)*2 + 1) or (FPURs1IsIn(ID.Mnemo) and (W1.rd = ((ID.rs1/2)*2) or W1.rd = ((ID.rs1/2)*2 + 1) ) ) ) ) ) or (W1.rd+1 = ID.rs2 or (FPURs1IsIn(ID.Mnemo) and W1.rd+1 = ID.rs1) or (IsFPopSourceRegDouble(ID.Mnemo) and (W1.rd+1 = ((ID.rs2/2)*2) or W1.rd+1 = ((ID.rs2/2)*2 + 1) or (FPURs1IsIn(ID.Mnemo) and (W1.rd+1 = ((ID.rs1/2)*2) or W1.rd+1 = ((ID.rs1/2)*2 + 1) ) ) ) ) ) ) then return TRUE; end if; return FALSE; end LDDF_FPop; ------------------------------ function FHOLDcondition(signal FINS1 : std_logic; signal FINS2 : std_logic; signal ID1 : FPInstruction; signal ID2 : FPInstruction; signal E : FPInstruction; signal W : FPInstruction; W1 : FPInstruction; signal FQ : FPInstruction ) return natural is variable ID : FPInstruction; variable W1rd_ev : natural; variable W1rd_od : natural; variable IDrd_ev : natural; variable IDrd_od : natural; begin if FINS1 = '1' then ID := ID1; elsif FINS2 = '1' then ID := ID2; else return 0; end if; ---- if (IsFPop(ID.Mnemo) or ID.Mnemo = LDFSR or ID.Mnemo = STFSR) and (IsFPop(E.Mnemo) or IsFPop(W.Mnemo) or IsFPop(FQ.Mnemo)) then return 1; end if; ---- if (ID.Mnemo = LDF or ID.Mnemo = LDDF) and ( FPop_LDF(E, ID.rd) or FPop_LDF(W, ID.rd) or FPop_LDF(FQ, ID.rd) ) then return 1; end if; if ID.Mnemo = LDDF and ( FPop_LDF(E, ID.rd + 1) or FPop_LDF(W, ID.rd + 1) or FPop_LDF(FQ, ID.rd + 1) ) then return 1; end if; ---- if ID.Mnemo = STF and (FPop_STF(E, ID.rd) or FPop_STF(W, ID.rd) or FPop_STF(FQ, ID.rd) ) then return 1; end if; IDrd_ev := (ID.rd/2)*2; IDrd_od := IDrd_ev + 1; if ID.Mnemo = STDF and (FPop_STF(E, IDrd_ev) or FPop_STF(W, IDrd_ev) or FPop_STF(FQ, IDrd_ev) or FPop_STF(E, IDrd_od) or FPop_STF(W, IDrd_od) or FPop_STF(FQ, IDrd_od) ) then return 1; end if; --- if ID.Mnemo = STDFQ and (IsFPop(E.Mnemo) or IsFPop(W.Mnemo) or IsFPop(FQ.Mnemo)) then return 1; end if; ---- if IsFPinst(ID.Mnemo) and not(IsFBfcc(ID.Mnemo)) and (IsFPopUnimp(E.Mnemo) or IsFPopUnimp(W.Mnemo) or IsFPopUnimp(FQ.Mnemo)) then return 1; end if; ---- if (W.Mnemo = LDFSR or W1.Mnemo = LDFSR) and (ID.Mnemo = LDFSR or ID.Mnemo = STFSR or IsFPop(ID.Mnemo)) then return 2; end if; ---- $$$$ WARNING: this condition is fuzzy: to be finalized. $$$$$$$ W1rd_ev := (W1.rd/2)*2; W1rd_od := W1rd_ev + 1; IDrd_ev := (ID.rd/2)*2; IDrd_od := IDrd_ev + 1; if (IsFPop(ID.Mnemo) and (LDF_FPop(W, ID) or LDDF_FPop(W1, ID)) ) or (ID.Mnemo = STF and W.Mnemo = LDF and W.rd = ID.rd) or (ID.Mnemo = STF and W1.Mnemo = LDDF and (ID.rd = W1rd_ev or ID.rd = W1rd_od) ) or (ID.Mnemo = STDF and W.Mnemo = LDF and (W.rd = IDrd_ev or W.rd = IDrd_od) ) or (ID.Mnemo = STDF and W1.Mnemo = LDDF and (W1rd_ev = IDrd_ev or W1rd_ev = IDrd_od or W1rd_od = IDrd_ev or W1rd_od = IDrd_od) ) then return 2; end if; return 0; end FHOLDcondition; ----------------------------- -- Behavioral FP functions to replace structural model -- Jiri Gaisler, 19-09-1996 ------------------------------ procedure ExecuteFPop(FPbitInst : std_logic_vector; RS1vec : std_logic_vector; RS2vec : std_logic_vector; RD : std_logic_vector; TEM2 : std_logic; DEBUG_FLAG : boolean := FALSE; TestNb : integer; Result : out std_logic_vector; tfcc : out std_logic_vector; texc : out std_logic_vector; FPexcVector : out FPexcVectorType; NbCycles : out integer; Fdebug : out text; FCtDebug : out text ) is type Ftype is (QNan, SNan, Zero, Inf, Norm); type Quad is record sign : std_logic; exp : unsigned(14 downto 0); man : unsigned(112 downto 0); v : Ftype; end record; constant SPInf : std_logic_vector(30 downto 0) := "1111111100000000000000000000000"; constant DPInf : std_logic_vector(62 downto 0) := "111111111110000000000000000000000000000000000000000000000000000"; constant SPNaN : std_logic_vector(31 downto 0) := "01111111111111110000000000000000"; constant DPNaN : std_logic_vector(63 downto 0) := "0111111111111111111000000000000000000000000000000000000000000000"; variable cexc : std_logic_vector(4 downto 0); variable dres : std_logic_vector(63 downto 0); variable ns : boolean; variable qs1, qs2, qres : quad; function SIsInf(f1 : std_logic_vector) return boolean is begin return ((f1(30 downto 23) = std_logic_vector'("11111111")) and (f1(22 downto 0) = "00000000000000000000000")); end SIsInf; function DIsInf(f1 : std_logic_vector) return boolean is begin return ((f1(62 downto 52) = std_logic_vector'("11111111111")) and (f1(51 downto 0) = "0000000000000000000000000000000000000000000000000000")); end DIsInf; function SIsZero(f1 : std_logic_vector) return boolean is begin return (f1(30 downto 0) = ext("0",31)); end SIsZero; function DIsZero(f1 : std_logic_vector) return boolean is begin return (f1(62 downto 0) = ext("0",63)); end DIsZero; function SIsNaN(f1 : std_logic_vector) return boolean is begin return ((f1(30 downto 23) = std_logic_vector'("11111111")) and (f1(22 downto 0) /= "00000000000000000000000")); end SIsNaN; function DIsNaN(f1 : std_logic_vector) return boolean is begin return ((f1(62 downto 52) = std_logic_vector'("11111111111")) and (f1(51 downto 0) /= "0000000000000000000000000000000000000000000000000000")); end DIsNaN; function SToQuad(f1: std_logic_vector) return Quad is variable q1 : Quad; begin q1.sign := f1(31); q1.exp := unsigned(ext(f1(30 downto 23),15)) + 16383 - 127; q1.man := unsigned(ext(('1'& f1(22 downto 0) & "00000000000000000000000000000000"),113)); q1.v := Norm; if SIsNaN(f1) then if f1(22) = '1' then q1.v := QNaN; else q1.v := SNaN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -