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

📄 fpu_addsub.vhd

📁 Xilinx软核microblaze源码(VHDL)版本7.10
💻 VHD
📖 第 1 页 / 共 2 页
字号:
      mem_rot_mux2 <= mem_rot_mux1(mem_rot_mux1'right-3 to mem_rot_mux1'right) &                      mem_rot_mux1(mem_rot_mux1'left to mem_rot_mux1'right-4);    else --                   "11"      -- Rotate 6      mem_rot_mux2 <= mem_rot_mux1(mem_rot_mux1'right-5 to mem_rot_mux1'right) &                      mem_rot_mux1(mem_rot_mux1'left to mem_rot_mux1'right-6);    end if;  end process Stage3_Rotate_Mux2;  -- Select rotate 0, 8, 16, 24  mem_rot_mux3_sel <= MEM_Exp_absAsubB_2(MEM_Exp_absAsubB_2'right-4 to MEM_Exp_absAsubB_2'right-3);  ----------------------------------------  -- Stage3_Rotate_Mux3  -- Rotate 0, 8, 16, 24  -- Old name: mux3_3  ----------------------------------------  Stage3_Rotate_Mux3 : process (mem_rot_mux3_sel, mem_rot_mux2) is  begin -- process Stage3_Rotate_Mux3    if    (mem_rot_mux3_sel = "00") then      -- Rotate 0      mem_rot_mux3 <= mem_rot_mux2;    elsif (mem_rot_mux3_sel = "01") then      -- Rotate 8      mem_rot_mux3 <= mem_rot_mux2(mem_rot_mux2'right-7 to mem_rot_mux2'right) &                      mem_rot_mux2(mem_rot_mux2'left to mem_rot_mux2'right-8);    elsif (mem_rot_mux3_sel = "10") then      -- Rotate 16      mem_rot_mux3 <= mem_rot_mux2(mem_rot_mux2'right-15 to mem_rot_mux2'right) &                      mem_rot_mux2(mem_rot_mux2'left to mem_rot_mux2'right-16);    else --                   "11"      -- Rotate 24      mem_rot_mux3 <= mem_rot_mux2(mem_rot_mux2'right-23 to mem_rot_mux2'right) &                      mem_rot_mux2(mem_rot_mux2'left to mem_rot_mux2'right-24);    end if;  end process Stage3_Rotate_Mux3;  -- Get the mask of bits to use for the mantissa  -- This mask is used to convert rotated mantissa into shifted mantissa  mem_mant_mask_3_cmb <= get_mant_mask(MEM_Exp_absAsubB_2(MEM_Exp_absAsubB_2'right-4 to MEM_Exp_absAsubB_2'right));  -- Get the mask of bits required to calculate the sticky bits  mem_sticky_mask_3_cmb <= get_sticky_mask(MEM_Exp_absAsubB_2(MEM_Exp_absAsubB_2'right-4 to MEM_Exp_absAsubB_2'right));  ----------------------------------------  -- Stage3_Sticky  -- Calculate the sticky bit  -- This is an OR of the bits that have been rotated around past the round bit  -- carry_and_or  ----------------------------------------  Stage3_Sticky : process (mem_rot_mux3, mem_sticky_mask_3_cmb) is    variable temp_mant_sticky_or : FPU_MANT_I_TYPE;    variable temp_sticky : std_logic;  begin -- Stage3_Sticky    temp_mant_sticky_or := mem_rot_mux3(mem_sticky_mask_3_cmb'left to mem_sticky_mask_3_cmb'right) and mem_sticky_mask_3_cmb;    temp_sticky := '0';    for I in temp_mant_sticky_or'left to temp_mant_sticky_or'right loop      temp_sticky := temp_sticky or temp_mant_sticky_or(I);    end loop; -- I    mem_mant_sticky_3_cmb <= temp_sticky;  end process Stage3_Sticky;  -- If the shift is 26 or larger, it is a large shift and does not even have any rounding left  -- 1 for implicit bit  -- 23 bits for mantissa  -- 1 for guard bit  -- 1 for round bit  mem_large_shift_3_cmb <= ( (MEM_Exp_absAsubB_2(MEM_Exp_absAsubB_2'right-7) = '1') or -- 128   (MEM_Exp_absAsubB_2(MEM_Exp_absAsubB_2'right-6) = '1') or  -- 64   (MEM_Exp_absAsubB_2(MEM_Exp_absAsubB_2'right-5) = '1') or  -- 32                                                              -- 26-31   ((MEM_Exp_absAsubB_2(MEM_Exp_absAsubB_2'right-4 to MEM_Exp_absAsubB_2'right-3) = "11") and -- 24     ((MEM_Exp_absAsubB_2(MEM_Exp_absAsubB_2'right-2) = '1') or                               -- +4      (MEM_Exp_absAsubB_2(MEM_Exp_absAsubB_2'right-1) = '1'))));                              -- or +2  ----------------------------------------  -- MEM_AddOrSub_3_REG  -- Add or Subtract operation in stage 3  ----------------------------------------  MEM_AddOrSub_3_REG : process (Clk) is  begin -- process MEM_AddOrSub_3_REG    if Clk'event and Clk = '1' then  -- rising clock edge      if Reset = '1' then        mem_AddOrSub_3 <= false;      else        mem_AddOrSub_3 <= MEM_Add_Op_2 or MEM_Sub_Op_2;      end if;    end if;  end process MEM_AddOrSub_3_REG;  ----------------------------------------  -- Stage3_Mant_Sticky  -- Add the sticky bit  -- mem_MantA_3 is the larger operand's mantissa (with GRS)  -- mem_MantB_3 is the smaller operand's mantissa shifted (with GRS)  ----------------------------------------  Stage3_Mant_Sticky : process (Clk) is    variable temp_A : FPU_MANT_I_TYPE;  begin -- process Stage3_Mant_Sticky    if Clk'event and Clk = '1' then  -- rising clock edge      if Reset = '1' then        mem_MantA_3 <= (others => '0');        mem_MantB_3 <= (others => '0');      else        ------------        -- A        ------------        -- Select larger operand's mantissa        if (MEM_absAgtB_2) then          temp_A := MEM_MantA_2;        else          temp_A := MEM_MantB_2;        end if;        -- Take the larger operand's mantissa        mem_MantA_3(mem_MantA_3'left to temp_A'right)    <= temp_A;        -- Add guard, round, and sticky bits        mem_MantA_3(temp_A'right+1 to mem_MantA_3'right) <= "000";        ------------        -- B        ------------        -- Set sticky bit        MEM_MantB_3(FPU_MANT_STICKY_POS) <= mem_mant_sticky_3_cmb;        if (mem_large_shift_3_cmb) then          -- Above only looks at the right 5 bits of the difference in exponents          -- This check is used if there is a large difference in exponents          MEM_MantB_3(mem_MantB_3'left to mem_MantB_3'right-3) <= (others => '0');          -- Guard and rounding bits          MEM_MantB_3(FPU_MANT_GUARD_POS) <= '0';          MEM_MantB_3(FPU_MANT_ROUND_POS) <= '0';        else          -- Take the rotated result without the guard and rounding bits and mask it          -- to produce shifted mantissa          MEM_MantB_3(mem_MantB_3'left to mem_MantB_3'right-3) <= mem_rot_mux3(mem_rot_mux3'left to mem_rot_mux3'right-2) and mem_mant_mask_3_cmb;          -- Guard and rounding bits          MEM_MantB_3(FPU_MANT_GUARD_POS) <= mem_rot_mux3(FPU_MANT_GUARD_POS);          MEM_MantB_3(FPU_MANT_ROUND_POS) <= mem_rot_mux3(FPU_MANT_ROUND_POS);        end if;      end if;    end if;  end process Stage3_Mant_Sticky;  ----------------------------------------  -- MEM_Add_Mant_3_REG  -- Add or subtract mantissas?  -- Old name: Add_3  ----------------------------------------  MEM_Add_Mant_3_REG : process (Clk) is  begin -- process MEM_Add_Mant_REG    if Clk'event and Clk = '1' then  -- rising clock edge      -- if Reset = '1' then      --   mem_add_mant_3 <= false;      -- else        mem_add_mant_3 <= mem_add_mant_2;      -- end if;    end if;  end process MEM_Add_Mant_3_REG;  -----------------------------------------------------------------------------  -- Stage 4  -----------------------------------------------------------------------------  ----------------------------------------  -- MEM_AddSub_Res_4_PROC  -- Perform addition or subtraction on mantissa  -- Old name: Mant_AddSub_Res  ----------------------------------------  MEM_AddSub_Res_4_PROC : process (mem_add_mant_3, mem_MantA_3, mem_MantB_3) is    variable mem_MantA_4_cmb    : Mant_OIGRS_T;    variable mem_MantB_4_cmb    : Mant_OIGRS_T;    variable mem_add_mant_4_cmb : boolean;  begin -- process MEM_AddSub_Res_4_PROC    mem_MantA_4_cmb    := '0' & mem_MantA_3;    mem_MantB_4_cmb    := '0' & mem_MantB_3;    mem_add_mant_4_cmb := mem_add_mant_3;    if (mem_add_mant_4_cmb) then      -- Add      mem_AddSub_Res_4_cmb <= std_logic_vector(unsigned(mem_MantA_4_cmb) + unsigned(mem_MantB_4_cmb));    else      -- Subtract      mem_AddSub_Res_4_cmb <= std_logic_vector(unsigned(mem_MantA_4_cmb) - unsigned(mem_MantB_4_cmb));    end if;  end process MEM_AddSub_Res_4_PROC;  -- Remove overflow bit, rounding bit, and sticky bit  -- Implicit and guard bits are left  mem_AddSub_IG_4_cmb <= mem_AddSub_Res_4_cmb(mem_AddSub_IG_4_cmb'left to mem_AddSub_IG_4_cmb'right);  ----------------------------------------  -- MEM_Res_4_REG  -- Mantissa addition/subtraction result  -- Deal with overflow bit  -- Old Name: Res_4  ----------------------------------------  MEM_Res_4_REG : process (Clk) is    variable temp_sticky : std_logic;  begin -- process MEM_Res_4_REG    if Clk'event and Clk = '1' then      if (mem_AddSub_Res_4_cmb(Mant_Over_POS) = '1') then        -- Overflow bit set        -- Can only happen when adding two mant and the result is >= 2.0        -- Calculate the new sticky bit by ORing old rounding bit with old sticky bit        temp_sticky := mem_AddSub_Res_4_cmb(FPU_MANT_ROUND_POS) or                       mem_AddSub_Res_4_cmb(FPU_MANT_STICKY_POS);        -- Old overflow bit becomes implicit bit        -- Old guard bit becomes rounding bit        mem_res_4 <= mem_AddSub_Res_4_cmb(Mant_Over_POS to FPU_MANT_GUARD_POS) &                     temp_sticky;      else        -- Overflow bit not set        -- Drop the overflow bit        mem_res_4 <= mem_AddSub_Res_4_cmb(FPU_MANT_IMPL_POS to FPU_MANT_STICKY_POS);      end if;    end if;  end process MEM_Res_4_REG;  ----------------------------------------  -- Find_First_Bit_I  ----------------------------------------  Find_First_Bit_I: find_first_bit    port map (      MEM_Mant           => mem_AddSub_IG_4_cmb,      MEM_Mant_One_Pos   => mem_left_shift_4_cmb,      MEM_Mant_One_Found => mem_possible_zero_n_4_cmb    );  ----------------------------------------  -- Stage_4_Left_Shift_REG  -- Clock the left shift  ----------------------------------------  Stage_4_Left_Shift_REG : process (Clk) is  begin -- process Stage_4_Left_Shift_REG    if Clk'event and Clk = '1' then      mem_left_shift_4    <= (others => '0');      mem_possible_zero_4 <= false;      if (mem_AddOrSub_3) then        -- This is used later to subtract the exponent        -- Must be zero for non add/sub operations        if (mem_AddSub_Res_4_cmb(Mant_Over_POS) = '1') then          -- Overflow          -- Can only happen when adding two mant and the result is >= 2.0          -- Mant does not need to be shifted because the MSb is set          mem_left_shift_4    <= (others => '0');        else          mem_left_shift_4    <= mem_left_shift_4_cmb;          mem_possible_zero_4 <= mem_possible_zero_n_4_cmb = '0';        end if;      end if;    end if;  end process Stage_4_Left_Shift_Reg;  ----------------------------------------  -- Stage_4_Inc_Exp_REG  -- Increment the exponent on overflow  ----------------------------------------  Stage_4_Inc_Exp_REG : process (Clk) is  begin -- process Stage_4_Inc_Exp_REG    if Clk'event and Clk = '1' then      MEM_AddSub_Inc_Exp_4 <= false;      if (mem_AddOrSub_3) then        if (mem_AddSub_Res_4_cmb(Mant_Over_POS) = '1') then          -- Overflow          -- Can only happen when adding two mant and the result is >= 2.0          -- Mant does not need to be shifted because the MSb is set          MEM_AddSub_Inc_Exp_4 <= true;        end if;      end if;    end if;  end process Stage_4_Inc_Exp_REG;  -----------------------------------------------------------------------------  -- Stage 5  -----------------------------------------------------------------------------  -- Left shift selects  -- Shift 0, 1, 2, 3  mem_ls_sel1_5_cmb <= mem_left_shift_4(mem_left_shift_4'right-1 to mem_left_shift_4'right);  -- Shift 0, 4, 8, 12  mem_ls_sel2_5_cmb <= mem_left_shift_4(mem_left_shift_4'right-3 to mem_left_shift_4'right-2);  -- Shift 0, 16  mem_ls_sel3_5_cmb <= mem_left_shift_4(mem_left_shift_4'right-4);  ----------------------------------------  -- Left_Shift_Zero_Three  -- This mux selects between 0, 1, 2, and 3 bits shifted  -- Old name: mux5_1  ----------------------------------------  Left_Shift_Zero_Three : process (mem_res_4, mem_ls_sel1_5_cmb) is  begin -- process Left_Shift_Zero_Three    if    (mem_ls_sel1_5_cmb = "00") then      -- Shift 0      mem_ls_mux1_5_cmb <= mem_res_4;    elsif (mem_ls_sel1_5_cmb = "01") then      -- Shift 1      mem_ls_mux1_5_cmb <= mem_res_4(mem_res_4'left+1 to mem_res_4'right) & '0';    elsif (mem_ls_sel1_5_cmb = "10") then      -- Shift 2      mem_ls_mux1_5_cmb <= mem_res_4(mem_res_4'left+2 to mem_res_4'right) & "00";    else --                    "11"      -- Shift 3      mem_ls_mux1_5_cmb <= mem_res_4(mem_res_4'left+3 to mem_res_4'right) & "000";    end if;  end process Left_Shift_Zero_Three;  ----------------------------------------  -- Left_Shift_Zero_Twelve  -- This mux selects between 0, 4, 8, 12 bits shifted  -- Old name: mux5_2  ----------------------------------------  Left_Shift_Zero_Twelve : process (mem_ls_mux1_5_cmb, mem_ls_sel2_5_cmb) is  begin -- process Left_Shift_Zero_Twelve    if    (mem_ls_sel2_5_cmb = "00") then      -- Shift 0      mem_ls_mux2_5_cmb <= mem_ls_mux1_5_cmb;    elsif (mem_ls_sel2_5_cmb = "01") then      -- Shift 4      mem_ls_mux2_5_cmb <= mem_ls_mux1_5_cmb(mem_ls_mux1_5_cmb'left+4 to mem_ls_mux1_5_cmb'right) &                           "0000";    elsif (mem_ls_sel2_5_cmb = "10") then      -- Shift 8      mem_ls_mux2_5_cmb <= mem_ls_mux1_5_cmb(mem_ls_mux1_5_cmb'left+8 to mem_ls_mux1_5_cmb'right) &                           "00000000";    else --                    "11"      -- Shift 12      mem_ls_mux2_5_cmb <= mem_ls_mux1_5_cmb(mem_ls_mux1_5_cmb'left+12 to mem_ls_mux1_5_cmb'right) &                           "000000000000";    end if;  end process Left_Shift_Zero_Twelve;  ----------------------------------------  -- Registered outputs  ----------------------------------------  MEM_AddSub_Zero_4     <= mem_possible_zero_4;  MEM_AddSub_Sub_Exp_4  <= mem_left_shift_4;  ----------------------------------------  -- Non-registered outputs  ----------------------------------------  MEM_Mant_LS16_4       <= mem_ls_sel3_5_cmb;  MEM_Mant_AddSub_Res_4 <= mem_ls_mux2_5_cmb;end IMP;

⌨️ 快捷键说明

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