📄 fpu.vhd
字号:
generic map( INIT => X"6AA6" ) port map ( O => addsub_sel(I), -- [out] I0 => mem_Exp_Res_2(I), -- [in] I1 => addsub, -- [in] I2 => add, -- [in] I3 => temp(I)); -- [in] -- Confirm that Op2 is '1' for carry calculation AddSub_MULT_AND : MULT_AND port map ( I0 => mem_Exp_Res_2(I), -- [in] I1 => addsub, -- [in] LO => addsub_di(I)); -- [out] AddSub_MUXCY : MUXCY_L port map ( DI => addsub_di(I), -- [in std_logic] CI => addsub_carry(I+1), -- [in std_logic] S => addsub_sel(I), -- [in std_logic] LO => addsub_carry(I)); -- [out std_logic] AddSub_XORCY : XORCY port map ( LI => addsub_sel(I), -- [in std_logic] CI => addsub_carry(I+1), -- [in std_logic] O => mem_Exp_AddSub_3_cmb(I)); -- [out std_logic] end generate AddSub_Pass; end block Stage3_Add_Sub_With_Const; -- Stage3_Add_Sub_With_Const_PROC : process (mem_Exp_Res_2, mem_mul_op_2, mem_div_op_2) is-- -- variable mul_or_div : boolean;-- variable temp : Exp_Plus2_T;-- begin -- process Stage3_Add_Sub_With_Const_PROC-- -- mul_or_div := mem_mul_op_2 or mem_div_op_2; -- -- 127-- temp := (others => '0');-- temp(temp'right-6 to temp'right) := (others => '1'); -- if (mem_mul_op_2) then-- -- For multiplication, we added the two exponents-- -- As both exponents were biased, this result is double biased-- -- So here we subtract one of the biases-- -- -127-- mem_Exp_AddSub_3_cmb <= std_logic_vector(unsigned(mem_Exp_Res_2) - unsigned(temp));-- elsif (mem_div_op_2) then-- -- For divide, we subtracted the exponents-- -- As both exponents were biased, the biases cancel out-- -- So here we add back the bias-- -- +127-- mem_Exp_AddSub_3_cmb <= std_logic_vector(unsigned(mem_Exp_Res_2) + unsigned(temp));-- else-- -- For addition and subtraction we use the larger exponent-- -- The exponent is already properly biased-- mem_Exp_AddSub_3_cmb <= mem_Exp_Res_2;-- end if; -- end process Stage3_Add_Sub_With_Const_PROC; ---------------------------------------- -- MEM_Exp_Res_3_REG -- Stage 3 exponent result -- Old name: Res_Exp_3 ---------------------------------------- MEM_Exp_Res_3_REG : process (Clk) is begin -- process MEM_Exp_Res_3_REG if Clk'event and Clk = '1' then -- rising clock edge -- if Reset = '1' then -- mem_Exp_Res_3 <= (others => '0'); -- else mem_Exp_Res_3 <= mem_Exp_AddSub_3_cmb; -- end if; end if; end process MEM_Exp_Res_3_REG; ---------------------------------------- -- MEM_Res_Sign_3_REG -- Stage 3 sign of result -- Old name: Res_Sign_3 ---------------------------------------- MEM_Res_Sign_3_REG : process (Clk) is begin -- process MEM_Res_Sign_3_REG if Clk'event and Clk = '1' then -- rising clock edge -- if Reset = '1' then -- mem_Res_Sign_3 <= '0'; -- else mem_Res_Sign_3 <= mem_Res_Sign_2; if (mem_add_op_2 or mem_sub_op_2) then if (mem_ZeroA_2 and mem_ZeroB_2) then -- Both zeros must be negative to produce negative zero -- -0 + -0 = -0 -- -0 - +0 = -0 -- otherwise +0 mem_Res_Sign_3 <= mem_SignA_2 and (mem_SignB_2 xor mem_addsub_sel_2); end if; end if; -- Sqrt(+0) => +0 but Sqrt(-0) = -0 if ((C_USE_FPU = 2) and mem_sqrt_op_2) then if (mem_ZeroB_2) then mem_Res_Sign_3 <= mem_SignB_2; end if; end if; -- end if; end if; end process MEM_Res_Sign_3_REG; ---------------------------------------- -- MEM_Normal_Res_3_REG -- Normal result (no special flags set) -- Old name: Normal_Res_3 ---------------------------------------- MEM_Normal_Res_3_REG : process (Clk) is begin -- MEM_Normal_Res_3_PROC if Clk'event and Clk = '1' then -- rising clock edge mem_Normal_Res_3 <= true; if (mem_InfA_2 or mem_InfB_2) then -- Invalid or Inf result mem_Normal_Res_3 <= false; end if; if (mem_add_op_2 or mem_sub_op_2) then if (mem_ZeroA_2 and mem_ZeroB_2) then -- Zero_Res mem_Normal_Res_3 <= false; end if; else -- mem_mul_op_2 or mem_div_op_2 if (mem_ZeroA_2 or mem_ZeroB_2) then -- For mem_mul_op_2: Zero_Res -- For mem_div_op_2: Invalid (0/0), Div_by_Zero (x/0), or Zero (0/x) mem_Normal_Res_3 <= false; end if; end if; -- All NaN will generate a NaN result if (mem_NanA_2 or mem_NanB_2) then -- Invalid for signaling -- NaN for quiet mem_Normal_Res_3 <= false; end if; -- All DeNorm inputs wil not generate the correct result if (mem_DeNormA_2 or mem_DeNormB_2) then -- DeNorm mem_Normal_Res_3 <= false; end if; end if; end process MEM_Normal_Res_3_REG; ---------------------------------------- -- MEM_Res_Type_3_REG -- Result type bits -- (Invalid, NaN, Divide_by_Zero, Overflow, Underflow, DeNorm, Inf, Zero) -- All bits zero means normal -- Old name: Result_Type_3 ---------------------------------------- MEM_Res_Type_3_REG : process (Clk) is begin -- MEM_Res_Type_3_PROC if Clk'event and Clk = '1' then -- rising clock edge -- Default to normal result if (mem_float_operation_2) then mem_Res_Type_3 <= (others => '0'); if (mem_add_op_2 or mem_sub_op_2) then if (mem_InfA_2 and mem_InfB_2) then if ((mem_SignA_2 xor mem_SignB_2 xor mem_addsub_sel_2) = '1') then -- Invalid infinity -- +Inf + -Inf -- -Inf + +Inf -- +Inf - +Inf -- -Inf - -Inf mem_Res_Type_3(Result_Invalid_POS) <= '1'; else -- Infinity -- +Inf + +Inf -- +Inf - -Inf -- -Inf + -Inf -- -Inf - +Inf mem_Res_Type_3(Result_Inf_POS) <= '1'; end if; elsif (mem_InfA_2 or mem_InfB_2) then -- Inf +/- x -- x +/- Inf mem_Res_Type_3(Result_Inf_POS) <= '1'; end if; -- Exclusive condition if (mem_ZeroA_2 and mem_ZeroB_2) then -- Zero + Zero mem_Res_Type_3(Result_Zero_POS) <= '1'; end if; elsif (mem_mul_op_2) then if ((mem_InfA_2 and mem_ZeroB_2) or (mem_InfB_2 and mem_ZeroA_2)) then -- Inf * Zero mem_Res_Type_3(Result_Invalid_POS) <= '1'; elsif (mem_InfA_2 or mem_InfB_2) then -- Infinity -- Inf * x -- x * Inf mem_Res_Type_3(Result_Inf_POS) <= '1'; elsif (mem_ZeroA_2 or mem_ZeroB_2) then -- Zero -- x * zero -- zero * x mem_Res_Type_3(Result_Zero_POS) <= '1'; end if; else -- mem_div_op_2 if ((C_USE_FPU = 2) and mem_sqrt_op_2) then --Negative value for square-root => NaN (unless it's -0) if (mem_ZeroB_2) then mem_Res_Type_3(Result_Zero_POS) <= '1'; elsif (mem_SignB_2 = '1') then mem_Res_Type_3(Result_Invalid_POS) <= '1'; elsif (mem_infB_2) then mem_Res_Type_3(Result_Inf_POS) <= '1'; end if; elsif ((C_USE_FPU = 2) and mem_flt_op_2) then if (mem_ZeroB_2 and (mem_SignB_2 = '0')) then mem_Res_Type_3(Result_Zero_POS) <= '1'; end if; elsif ((C_USE_FPU = 2) and mem_int_op_2) then -- Infinity can't be represented as an INTEGER if (mem_infB_2) then mem_Res_Type_3(Result_Invalid_POS) <= '1'; end if; else if (mem_InfA_2 and mem_InfB_2) then -- Inf / Inf => Invalid mem_Res_Type_3(Result_Invalid_POS) <= '1'; elsif (mem_InfA_2) then -- Inf / something => Inf mem_Res_Type_3(Result_Inf_POS) <= '1'; elsif (mem_InfB_2) then -- Something / Inf => Zero mem_Res_Type_3(Result_Zero_POS) <= '1'; elsif (mem_ZeroA_2 and mem_ZeroB_2) then -- 0 / 0 => Invalid mem_Res_Type_3(Result_Invalid_POS) <= '1'; elsif (mem_ZeroB_2) then -- Something / 0 => Div_by_Zero mem_Res_Type_3(Result_Div0_POS) <= '1'; elsif (mem_ZeroA_2) then -- 0 / something = Zero mem_Res_Type_3(Result_Zero_POS) <= '1'; end if; end if; end if; if ((C_USE_FPU = 2) and mem_flt_op_2) then -- All NaN will generate a NaN result elsif (mem_SNanA_2 or mem_SNanB_2) then -- Invalid mem_Res_Type_3 <= (others => '0'); -- clear previously set bits mem_Res_Type_3(Result_Invalid_POS) <= '1'; elsif (mem_QNanA_2 or mem_QNanB_2) then -- NaN mem_Res_Type_3 <= (others => '0'); -- clear previously set bits if ((C_USE_FPU = 2) and mem_int_op_2) then mem_Res_Type_3(Result_Invalid_POS) <= '1'; else mem_Res_Type_3(Result_Nan_POS) <= '1'; end if; end if; -- All DeNorm inputs will not generate the correct result -- Set the DeNorm flag if ((C_USE_FPU = 2) and mem_flt_op_2) then else if (mem_DeNormA_2 or mem_DeNormB_2) then mem_Res_Type_3 <= (others => '0'); -- clear previously set bits mem_Res_Type_3(Result_DeNorm_POS) <= '1'; end if; end if; end if; end if; end process MEM_Res_Type_3_REG; --------------------------- -- Multiplication --------------------------- FPU_MUL_I : FPU_MUL generic map ( C_TARGET => C_TARGET -- [TARGET_FAMILY_TYPE] ) port map ( Clk => Clk, -- [in std_logic] Reset => Reset, -- [in std_logic] EX_MantA_1 => ex_MantA_1, -- [in FPU_MANT_TYPE] EX_MantB_1 => ex_MantB_1, -- [in FPU_MANT_TYPE] EX_PipeRun => EX_PipeRun, -- [in boolean] MEM_Mul_Res_4 => mem_mant_mul_res_5_cmb, -- [out FPU_MANT_IGRS_TYPE] MEM_Mul_Inc_Exp_4 => mem_mul_inc_exp_5_cmb -- [out boolean] ); ----------------------------------------------------------------------------- -- Division part (Non-pipelined design) ----------------------------------------------------------------------------- FPU_DIV_I : FPU_DIV generic map ( C_TARGET => C_TARGET -- [TARGET_FAMILY_TYPE] ) port map ( Clk => Clk, -- [in std_logic] Reset => Reset, -- [in std_logic] EX_MantA_1 => ex_MantA_1, -- [in FPU_MANT_TYPE] EX_MantB_1 => ex_MantB_1, -- [in FPU_MANT_TYPE] EX_Start_FPU => EX_Start_FPU, -- [in boolean] EX_Div_Op => ex_div_op, -- [in boolean] EX_PipeRun => EX_PipeRun, -- [in boolean] Mem_Not_Div_Op => Mem_Not_Div_Op, -- [in boolean] MEM_Div_Done => mem_fpu_div_done, -- [out boolean] MEM_Div_Res_4 => mem_mant_div_res_4, -- [out FPU_MANT_IGRS_TYPE] MEM_Div_Dec_Exp_4 => mem_div_dec_exp_4 -- [out boolean] ); Using_FPU_Extended: if (C_USE_FPU = 2) generate --------------------------------------------------------------------------- -- Square-root (Non-pipelined) --------------------------------------------------------------------------- fpu_sqrt_I1: fpu_sqrt port map ( Clk => Clk, -- [in std_logic] Reset => Reset, -- [in std_logic] EX_Op1 => EX_Op1, -- [in DATA_TYPE] EX_Sqrt_Op => EX_Sqrt_Op, -- [in boolean] EX_Start_fpu => EX_Start_fpu, -- [in bo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -