📄 fpurt_lib.vhd
字号:
-- end if; cexc := "00000"; res := s5; end if; end; procedure fitoq(rs1 : std_logic_vector; res: inout quad) is begin res.sign := rs1(31); if (rs1(31 downto 0) = ext("0",32)) then res.v := Zero; else res.v := Norm; end if; res.exp := conv_unsigned(16383,15); if (rs1(31) = '1') then res.man := unsigned(ext("0",26)) & (0 - unsigned(rs1(31 downto 0))) & unsigned(ext("0",55)); else res.man := unsigned(ext("0",26)) & unsigned(rs1(31 downto 0)) & unsigned(ext("0",55)); end if; Normalize(res); end fitoq; procedure fqtoi(q : quad; res : inout std_logic_vector) is variable tmp : std_logic_vector(0 downto 0); variable q1 : quad; begin q1 := q; if (q1.v = Inf) or (q1.exp > 16383 + 30) then if q1.sign = '0' then cexc(4) := '1'; -- Invalid end if; tmp(0) := not q1.sign; res(31 downto 0) := q1.sign & sxt(tmp, 31); elsif (q1.v = Zero) then res(31 downto 0) := ext("0",32); else if (q1.exp < 16383) then res(31 downto 0) := ext("0",32); cexc(0) := '1'; -- Inexact elsif (q1.exp > 16383 + 30) then res(31 downto 0) := '0' & sxt("1",31); if q1.sign = '1' then res(31 downto 0) := not res(31 downto 0); end if; cexc(0) := '1'; -- Inexact else q1.man := shl(q1.man,q1.exp-16383); if q1.man(54 downto 0) /= unsigned(ext("0",55)) then cexc(0) := '1'; -- Inexact end if; if (q1.sign = '1') then q1.man(55+31 downto 55) := 0 - q1.man(55+31 downto 55); end if; res(31 downto 0) := std_logic_vector(q1.man(55+31 downto 55)); end if; end if; res (63 downto 32) := res(31 downto 0); end fqtoi; variable FpInst : std_logic_vector(9 downto 0); variable LRes : std_logic_vector(63 downto 0); variable opcase : std_logic_vector(2 downto 0); variable lfcc : std_logic_vector(1 downto 0) := "11"; variable SP : boolean; variable Unimp : boolean := false; begin FpInst := FPbitInst(19) & FPbitInst(13 downto 5); FPexcVector := (others => FALSE); SP := FPbitInst(5) = '1'; cexc := "00000"; tfcc := "00"; opcase := (FPbitInst(12 downto 11) & FPbitInst(5)); case opcase is when "000" | "110" => qs2 := DToQuad(RS2vec); if qs2.v = QNan then LRes(63 downto 0) := RS2vec; elsif qs2.v = SNan then LRes(63 downto 0) := DPNan; if FPbitInst(12) = '0' then cexc(4) := '1'; -- Invalid exception end if; end if; when "001" | "111" => qs2 := SToQuad(RS2vec); if qs2.v = QNan then LRes(63 downto 0) := RS2vec(31 downto 0) & RS2vec(31 downto 0); elsif qs2.v = SNan then LRes(63 downto 0) := SPNan & SPNan; if FPbitInst(12) = '0' then cexc(4) := '1'; -- Invalid exception end if; end if; when "010" => qs1 := DToQuad(RS1vec); qs2 := DToQuad(RS2vec); if (qs1.v = SNan) or (qs2.v = SNan) then LRes(63 downto 0) := DPNan; cexc(4) := '1'; -- Invalid exception elsif qs1.v = QNan then LRes(63 downto 0) := RS1vec; elsif qs2.v = QNan then LRes(63 downto 0) := RS2vec; end if; when "011" => qs1 := SToQuad(RS1vec); qs2 := SToQuad(RS2vec); if (qs1.v = SNan) or (qs2.v = SNan) then LRes(63 downto 0) := SPNan & SPNan; cexc(4) := '1'; -- Invalid exception elsif qs1.v = QNan then LRes(63 downto 0) := RS1vec(31 downto 0) & RS1vec(31 downto 0); elsif qs2.v = QNan then LRes(63 downto 0) := RS2vec(31 downto 0) & RS2vec(31 downto 0); end if; when others => null; end case; case FpInst is when "0000001001" => -- fabss if (qs2.v > SNaN) then LRes(63 downto 32) := '0' & RS2vec(30 downto 0); end if; NbCycles := 2; when "0001000001" | "0001000010" => -- fadds/d if (qs1.v > SNan) and (qs2.v > SNaN) then faddsub(qs1, qs2, qres, true); FPround(qres, LRes, SP); end if; NbCycles := 5; when "1001010001" | "1001010010" => -- fcmps/d if (qs1.v <= SNaN) or (qs2.v <= SNaN) then tfcc := "11"; else fcmp(qs1, qs2, tfcc); end if; NbCycles := 5; when "1001010101" | "1001010110" => -- fcmpes/d if (qs1.v <= SNaN) or (qs2.v <= SNaN) then tfcc := "11"; else fcmp(qs1, qs2, lfcc); end if; if lfcc = "11" then cexc(4) := '1'; end if; NbCycles := 5; tfcc := lfcc; when "0001001101" | "0001001110" => -- fdivs/d if (qs1.v > SNaN) and (qs2.v > SNaN) then if (qs1.v = Zero and qs2.v = Zero) or ((qs1.v = Inf) and (qs1.v = Inf)) then cexc(4) := '1'; -- Invalid operation qres.v := SNaN; elsif (qs2.v = Zero) then cexc(1) := '1'; -- Divide by zero qres.v := SNaN; else fdiv(qs1, qs2, qres); end if; FPround(qres, LRes, SP); end if; if SP then NbCycles := 21; else NbCycles := 36; end if; when "0000000001" => -- fmovs LRes(63 downto 0) := RS2vec(31 downto 0) & RS2vec(31 downto 0); cexc := "00000"; NbCycles := 2; when "0001001001" | "0001001010" => -- fmuls/d if ((qs1.v > SNaN) and (qs2.v > SNaN)) then if (qs1.v = Zero and qs2.v = Inf) or (qs1.v = Inf and qs2.v = Zero) then qres.v := QNaN; else fmul(qs1, qs2, qres); end if; FPround(qres, LRes, SP); end if; if SP then NbCycles := 6; else NbCycles := 10; end if; when "0000000101" => -- fnegs if qs2.v > SNaN then LRes(63 downto 32) := not(RS2vec(31)) & RS2vec(30 downto 0); Lres(31 downto 0) := LRes(63 downto 32); end if; NbCycles := 2; when "0000101001" | "0000101010" => -- fsqrs/d NbCycles := 66; if (qs2.v > SNaN) then if (qs2.sign = '1') then cexc(4) := '1'; -- Invalid operation qres.v := SNaN; NbCycles := 7; elsif qs2.v = Zero then NbCycles := 7; qres := qs2; elsif qs2.v = Inf then NbCycles := 7; qres := qs2; elsif qs2.v = norm then if SP then NbCycles := 38; else NbCycles := 66; end if; fsqrt(qs2, qres,SP); end if; FPround(qres, LRes, SP); end if; when "0001000101" | "0001000110" => -- fsub/d if (qs1.v > SNan) and (qs2.v > SNaN) then faddsub(qs1, qs2, qres, false); FPround(qres, LRes, SP); end if; NbCycles := 5; when "0011010010" => -- fdtoi if (qs2.v <= SNan) then cexc(4) := '1'; LRes(31 downto 0) := '1' & ext("0",31); if qs2.sign = '0' then LRes(31 downto 0) := not LRes(31 downto 0); end if; LRes(63 downto 32) := LRes(31 downto 0); else fqtoi(qs2, LRes); end if; NbCycles := 8; when "0011000110" => -- fdtos if qs2.v <= SNan then LRes(63 downto 0) := SPNan & SPNan; if qs2.v = SNan then cexc(4) := '1'; end if; else FPround(qs2, LRes, true); end if; NbCycles := 4; when "0011001000" => -- fitod cexc := "00000"; fitoq(rs2vec,qs2); FPround(qs2, LRes, false); NbCycles := 7; when "0011000100" => -- fitos cexc := "00000"; fitoq(rs2vec,qs2); FPround(qs2, LRes, true); NbCycles := 7; when "0011001001" => -- fstod if qs2.v = QNan then LRes(63 downto 0) := DPNan; LRes(51 downto 51 - 22) := RS2vec(22 downto 0); else if qs2.v = SNan then cexc(4) := '1'; end if; FPround(qs2, LRes, false); end if; NbCycles := 3; when "0011010001" => -- fstoi if (qs2.v <= SNan) then cexc(4) := '1'; LRes(31 downto 0) := '1' & ext("0",31); if qs2.sign = '0' then LRes(31 downto 0) := not LRes(31 downto 0); end if; LRes(63 downto 32) := LRes(31 downto 0); else fqtoi(qs2, LRes); end if; NbCycles := 7; when others => Unimp := true; NbCycles := 2; end case; Result := LRes; texc := cexc; if cexc /= "00000" then FPexcVector(FP_EXC_DETECTED) := TRUE; FPexcVector(IEEE_EXC) := TRUE; elsif Unimp then FPexcVector(FP_EXC_DETECTED) := TRUE; FPexcVector(UNIMPLEMENTED_FPOP) := TRUE; end if; end ExecuteFPop; -- procedure end FPURTPck; -- package body--------------------------------------------------------------------------------- File name : fpurt_gen_beh.vhd-- Title : FPURTGeneric (architecture Behave)-- project : SPARC-- Library : FPURT_LIB-- Author(s) : Maxime ROCCA-- Purpose : definition of architecture Behave for FPURTGeneric. It is a beha--- -vioral description of the FPURT at the highest level.---- notes : The entity FPURTGeneric is defined in the file fpurt_gen_ent.vhd.-- --------------------------------------------------------------------------------- Modification history :--------------------------------------------------------------------------------- Version No : | Author | Date | Changes made :--------------------------------------------------------------------------------- v 1.0 | MR | 94-03-04 | first version.-- Compliant with the FPU-RT Device Specification, issue 4++ (i.e certain -- features implemented in this version of the FPU-RT model will only appear in -- the next issue of the FPU-RT Device Specification), except that the copro- -- -cessor interface is not implemented in this version.--.............................................................................-- v 1.1 | MR | 94-05-03 | 2nd version-- + FPURT model is made sensitive to the signals CCCV and CHOLD_N-- + bug fix about LDFSR handling when FINS1/2 is late.-- + bug fix about FEXC_N when STDFQ while FQ empty-- + bug fix on FNULL and FLUSH.-- + bug fix on generation of FCCV when in exception mode-- + generation of FHOLD_N when FCMP(E)q is in W stage (particular case)-- + modif. logical condition in parity bit checking + modif. generation of -- FIPAR-- + bug fix for XHOLD cases on FP store.-- + bug fix: modif. condition for FCCV generation.-- + change name of tap controller-- + modelling of buffers slightly modified.--.............................................................................-- v 1.2 | MR | 94-05-27 | 3rd version-- + modify setup and hold time checkers.--.............................................................................-- v 1.3 | RC | 95-12-11 | 4th version-- + modify data drivers.--.............................................................................-- v 1.4 | JG | 96-02-27 | 5th version-- + bug fix: INST latching-- + bug fix: MDS properly handled-- + bug fix: STDF and STDFQ driving of data bus during second data cycle--.............................................................................-- v 1.5 | JG | 96-03-13 | 6th version-- + bug fix: de-assert FHOLD even if MHOLD is asserted--.............................................................................-- v 1.6 | JG | 96-04-24 | 7th version-- + Changed FHOLD/FCCV generation to FPU rev.B imlpementation-- + Modified pipeline handling during XHOLD-- + Instruction timing should be identical to FPU rev.B--.............................................................................-- v 1.7 | JG | 96-10-01 | 8th version-- + Fixed problem with ldf/fpop inte
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -