⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fpu.vhd

📁 Xilinx软核microblaze源码(VHDL)版本7.10
💻 VHD
📖 第 1 页 / 共 5 页
字号:
            ----------------------------------------------------------------------          -- NaN          ----------------------------------------------------------------------            -- A NaN has an exponent of 255, an a non-zero mantissa          -- The MSb of the mantissa determines quiet or signaling            mem_NanA_2    <= ex_A_NaN_2_cmb;          mem_NanB_2    <= ex_B_NaN_2_cmb;            -- For quiet if the MSb of the mantissa is 1,          -- then by definition the mantissa is non-zero          mem_QNanA_2   <= ex_ExpA_Ones_2_cmb and (ex_a(FPU_NAN_POS) = FPU_NAN_QUIET);          mem_QNanB_2   <= ex_ExpB_Ones_2_cmb and (ex_b(FPU_NAN_POS) = FPU_NAN_QUIET);            mem_SNanA_2   <= ex_A_NaN_2_cmb and (ex_a(FPU_NAN_POS) = FPU_NAN_SIG);          mem_SNanB_2   <= ex_B_NaN_2_cmb and (ex_b(FPU_NAN_POS) = FPU_NAN_SIG);            ----------------------------------------------------------------------          -- Denormalized          ----------------------------------------------------------------------            -- Exponent is physical zero/logical -127 (our reserved value)          -- Mantissa is non-zero          -- The implicit MSb of the mantissa is zero          mem_DeNormA_2 <= ex_ExpA_Zero_2_cmb and not ex_MantA_Zero_2_cmb;          mem_DeNormB_2 <= ex_ExpB_Zero_2_cmb and not ex_MantB_Zero_2_cmb;            ----------------------------------------------------------------------          -- Infinity          ----------------------------------------------------------------------            -- Exponent is 255          -- Mantissa is zero          mem_InfA_2 <= ex_ExpA_Ones_2_cmb and ex_MantA_Zero_2_cmb;          mem_InfB_2 <= ex_ExpB_Ones_2_cmb and ex_MantB_Zero_2_cmb;            ----------------------------------------------------------------------          -- Zero          ----------------------------------------------------------------------            -- Exponent is zero          -- Mantissa is zero          mem_ZeroA_2 <= ex_A_Zero_2_cmb;          mem_ZeroB_2 <= ex_B_Zero_2_cmb;                  end if;      end if;    end process Stage2_Input_Types;      ----------------------------------------    -- MEM_Abs_AgtB_2_REG    -- Which abs(OpA) or abs(OpB) is greater    -- old name: Op1_Is_A    ----------------------------------------    MEM_Abs_AgtB_2_REG : process (Clk) is    begin -- process MEM_Abs_AgtB_2_REG      if Clk'event and Clk = '1' then  -- rising clock edge        if Reset = '1' then          mem_absAgtB_2 <= false;        elsif (EX_PipeRun) then          if (ex_absBgtA_2_cmb) then            -- B is greater            mem_absAgtB_2 <= false;          else            -- A is greater            mem_absAgtB_2 <= true;          end if;        end if;      end if;    end process MEM_Abs_AgtB_2_REG;      ----------------------------------------    -- MEM_Exp_Res_2_PROC    -- Select the exponent for the result    -- For add or subtract use the larger exponent    -- For mul, add the exponents    -- For div, subtract the exponents    -- cmp does not care    -- flt, int, sqrt are not implemented    ----------------------------------------    MEM_Exp_Res_2_REG : process (Clk) is      variable temp_1 : Exp_Plus2_T;      variable temp_2 : Exp_Plus2_T;    begin -- process MEM_Exp_Res_2_PROC      if Clk'event and Clk = '1' then  -- rising clock edge        temp_1        := "00" & ex_ExpA_1;        temp_2        := "00" & ex_ExpB_1;        if Reset = '1' then          mem_Exp_Res_2 <= (others => '0');        elsif (EX_PipeRun) then          if (ex_add_op or ex_sub_op) then            if (not ex_Exp_Equal_2_cmb and ex_Exp_BgtA_2_cmb) then              -- Exponent for B is greater              mem_Exp_Res_2 <= temp_2;            else              -- Exponent for A is greater or equal              mem_Exp_Res_2 <= temp_1;            end if;          elsif (ex_mul_op) then            mem_Exp_Res_2 <= std_logic_vector(unsigned(temp_1) + unsigned(temp_2));          else -- ex_div_op            mem_Exp_Res_2 <= ex_Exp_AsubB_2_i;          end if;        end if;      end if;    end process MEM_Exp_Res_2_REG;      ----------------------------------------    -- MEM_Add_Mant_2_REG    -- Add or subtract mantissa    -- (old name: Add_2)    ----------------------------------------    MEM_Add_Mant_2_REG : process (Clk) is    begin -- process MEM_Add_Mant_2_REG      if Clk'event and Clk = '1' then  -- rising clock edge        if Reset = '1' then          mem_add_mant_2 <= false;        elsif (EX_PipeRun) then          -- FPU_OP_ADDSUB_POS: 1 for subtract          -- SignA: 1 for negative          -- SignB: 1 for negative          -- If 1 or 3 of these conditions are true, subtract          -- Otherwise add (0 or 2)          if ((ex_fpu_op_1(FPU_OP_ADDSUB_POS) xor ex_SignA_1 xor ex_SignB_1) = '1') then            mem_add_mant_2 <= false;          else            mem_add_mant_2 <= true;          end if;        end if;      end if;    end process MEM_Add_Mant_2_REG;      ----------------------------------------    -- MEM_Res_Sign_2_REG    -- Calculate the result sign    -- Old name: Res_Sign_2    ----------------------------------------    MEM_Res_Sign_2_REG : process (Clk) is    begin -- process MEM_Res_Sign_2_REG      if Clk'event and Clk = '1' then  -- rising clock edge        if Reset = '1' then          mem_Res_Sign_2 <= '0';        elsif (EX_PipeRun) then          if (ex_add_op or ex_sub_op) then            if (ex_absBgtA_2_cmb) then              -- B is greater              -- If B is positive: adding positive, subtracting negative              -- If B is negative: adding negative, subtracting positive              mem_Res_Sign_2 <= ex_fpu_op_1(FPU_OP_ADDSUB_POS) xor ex_SignB_1;            else              -- A is greater              -- Use the sign of A              mem_Res_Sign_2 <= ex_SignA_1;            end if;          else -- ex_mul_op or ex_div_op            i            -- For multiply or divide, opposite signs is negative            -- Otherwise positive            mem_Res_Sign_2 <= ex_SignA_1 xor ex_SignB_1;                          if ((C_USE_FPU = 2) and ex_sqrt_op) then              mem_Res_Sign_2 <= '0';            end if;            if ((C_USE_FPU = 2) and ex_flt_op) then              mem_Res_Sign_2 <= ex_signB_1;            end if;          end if;        end if;      end if;    end process MEM_Res_Sign_2_REG;      ----------------------------------------    -- MEM_Stage2_Cmp_REG    -- Evaluate comparisons    ----------------------------------------    MEM_Stage2_Cmp_REG : process (Clk) is    begin -- process MEM_Stage2_Cmp_REG      if Clk'event and Clk = '1' then  -- rising clock edge        if Reset = '1' then          mem_cmp_eq_2 <= false;          mem_cmp_lt_2 <= false;          mem_cmp_gt_2 <= false;          mem_cmp_un_2 <= false;        elsif (EX_PipeRun) then          -- Default assignments          mem_cmp_eq_2 <= false;          mem_cmp_lt_2 <= false;          mem_cmp_gt_2 <= false;          mem_cmp_un_2 <= false;            if (ex_cmp_op) then            if (ex_SignA_1 = '0' and ex_SignB_1 = '1') then              -- A positive, B negative              -- A > B              mem_cmp_gt_2 <= true;            elsif (ex_SignA_1 = '1' and ex_SignB_1 = '0') then              -- A negative, B positive              -- A < B              mem_cmp_lt_2 <= true;              -- Signs are the same at this point            -- ex_SignA_1 = ex_SignB_1              elsif (ex_Exp_Mant_Equal_2_cmb) then              -- Numbers are equal              mem_cmp_eq_2 <= true;            elsif (ex_absBgtA_2_cmb) then              -- abs(A) < abs(B)              mem_cmp_lt_2 <= (ex_SignA_1 = '0');              mem_cmp_gt_2 <= (ex_SignA_1 = '1');            else              -- abs(A) > abs(B)              mem_cmp_lt_2 <= (ex_SignA_1 = '1');              mem_cmp_gt_2 <= (ex_SignA_1 = '0');            end if;              -- Handle both zero (equal)            -- This overrides the above logic            if (ex_A_Zero_2_cmb and ex_B_Zero_2_cmb) then              mem_cmp_eq_2 <= true;              mem_cmp_lt_2 <= false;              mem_cmp_gt_2 <= false;            end if;              -- If either operand is a NaN            if (ex_A_NaN_2_cmb or ex_B_NaN_2_cmb) then              -- Comparison is unordered              mem_cmp_eq_2 <= false;              mem_cmp_lt_2 <= false;              mem_cmp_gt_2 <= false;              mem_cmp_un_2 <= true;            end if;          end if;        end if;      end if;    end process MEM_Stage2_Cmp_REG;      -----------------------------------------------------------------------------    -- Stage 3    -- Addition/Subtraction and Multiplication/Division    -----------------------------------------------------------------------------    ----------------------------------------    -- MEM_MUL_Op_3_REG    -- Stage 3 is multiply operation?    ----------------------------------------    MEM_MUL_Op_3_REG : process (Clk) is    begin -- process MEM_MUL_Op_3_REG      if Clk'event and Clk = '1' then        mem_mul_op_3 <= mem_mul_op_2;      end if;    end process MEM_MUL_Op_3_REG;      ----------------------------------------    -- MEM_DIV_Op_3_REG    -- Stage 3 is division operation?    ----------------------------------------    MEM_DIV_Op_3_REG : process (Clk) is    begin  -- process MEM_DIV_Op_3_REG      if Clk'event and Clk = '1' then        mem_div_op_3  <= mem_div_op_2;        mem_sqrt_op_3 <= mem_sqrt_op_2;        mem_flt_op_3 <= mem_flt_op_2;        mem_int_op_3 <= mem_int_op_2;      end if;    end process MEM_DIV_Op_3_REG;      ----------------------------------------    -- MEM_ADDSUB_Op_3_REG    -- Stage 3 is add/subtract operation?    ----------------------------------------    MEM_ADDSUB_Op_3_REG : process (Clk) is    begin -- process MEM_ADDSUB_Op_3_REG      if Clk'event and Clk = '1' then        mem_addsub_op_3 <= mem_add_op_2 or mem_sub_op_2;      end if;    end process MEM_ADDSUB_Op_3_REG;    ----------------------------------------    -- FPU_ADDSUB_I    -- Add/Subtract mantissas    ----------------------------------------    FPU_ADDSUB_I : FPU_ADDSUB      generic map (        C_TARGET              => C_TARGET                   -- [TARGET_FAMILY_TYPE]      )      port map (        Clk                   => Clk,                       -- [in  std_logic]        Reset                 => Reset,                     -- [in  std_logic]        MEM_Add_Op_2          => mem_add_op_2,              -- [in  boolean]        MEM_Sub_Op_2          => mem_sub_op_2,              -- [in  boolean]        MEM_Add_Mant_2        => mem_add_mant_2,            -- [in  boolean]        MEM_MantA_2           => mem_MantA_2,               -- [in  FPU_MANT_I_TYPE]        MEM_MantB_2           => mem_MantB_2,               -- [in  FPU_MANT_I_TYPE]        MEM_absAgtB_2         => mem_absAgtB_2,             -- [in  boolean]        MEM_Exp_absAsubB_2    => mem_Exp_absAsubB_2,        -- [in  FPU_EXP_TYPE]        MEM_AddSub_Zero_4     => mem_addsub_zero_4,         -- [out boolean]        MEM_AddSub_Inc_Exp_4  => mem_addsub_inc_exp_4,      -- [out boolean]        MEM_AddSub_Sub_Exp_4  => mem_addsub_sub_exp_4,      -- [out FPU_EXP_LS_TYPE]        MEM_Mant_LS16_4       => mem_mant_ls16_5_cmb,       -- [out std_logic]        MEM_Mant_AddSub_Res_4 => mem_mant_addsub_res_5_cmb  -- [out FPU_MANT_IGRS_TYPE]      );      ----------------------------------------    -- Stage3_Add_Sub_With_Const_PROC    -- Adjust Exponent Result    -- -127 for multiplication    -- -128 for division    -- Old name: Res_Exp_3_AddSub    ----------------------------------------    Stage3_Add_Sub_With_Const : block is      signal addsub_sel   : Exp_Plus2_T;      signal addsub_di    : Exp_Plus2_T;      signal addsub_carry : std_logic_vector(addsub_sel'left to addsub_sel'right + 1);      signal addsub       : std_logic;      signal add          : std_logic;      signal temp         : Exp_Plus2_T;    begin  -- block Stage3_Add_Sub_With_Const      temp(temp'left to temp'right-7)  <= (others => '0');      temp(temp'right-6 to temp'right) <= (others => '1');      addsub <= '1' when mem_mul_op_2 or mem_div_op_2 else '0';      add    <= '1' when mem_div_op_2                 else '0';            addsub_carry(addsub_carry'right) <= '1' when mem_mul_op_2 else '0';      AddSub_Pass : for I in addsub_sel'right downto addsub_sel'left generate        -------------------------------------------------------------------------        --                   bit 1 0        --   bit 3 2         addsub,Exp_Res        -- temp(I), add     00 01 11 10        --        00         0  1  0  1 = 0110        --        01         -  -  1  0 = 1010        --        11         -  -  0  1 = 0110        --        10         0  1  1  0 = 1010        -- Init = 0110 1010 1010 0110 = 6AA6        -------------------------------------------------------------------------        I_ALU_LUT : LUT4

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -