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

📄 fpu_div.vhd

📁 Xilinx软核microblaze源码(VHDL)版本7.10
💻 VHD
字号:
--SINGLE_FILE_TAG--------------------------------------------------------------------------------- $Id: fpu_div.vhd,v 1.1 2007/10/12 09:11:36 stefana Exp $--------------------------------------------------------------------------------- FPU_DIV - entity/architecture----------------------------------------------------------------------------------- ****************************************************************************-- ** Copyright(C) 2005 by Xilinx, Inc. All rights reserved.-- **-- ** This text contains proprietary, confidential information of-- ** Xilinx, Inc. , is distributed by under license from Xilinx, Inc.,-- ** and may be used, copied and/or disclosed only pursuant to the-- ** terms of a valid license agreement with Xilinx, Inc. -- **-- ** Unmodified source code is guaranteed to place and route, -- ** function and run at speed according to the datasheet-- ** specification. Source code is provided "as-is", with no-- ** obligation on the part of Xilinx to provide support.-- **-- ** Xilinx Hotline support of source code IP shall only include-- ** standard level Xilinx Hotline support, and will only address-- ** issues and questions related to the standard released Netlist-- ** version of the core (and thus indirectly, the original core source-- **-- ** The Xilinx Support Hotline does not have access to source-- ** code and therefore cannot answer specific questions related-- ** to source HDL. The Xilinx Support Hotline will only be able-- ** to confirm the problem in the Netlist version of the core.-- **-- ** This copyright and support notice must be retained as part-- ** of this text at all times.-- ****************************************************************************----------------------------------------------------------------------------------- Filename:        fpu_div.vhd-- Version:         v2.00a-- Description:     Implements a divider for the FPU--                  --------------------------------------------------------------------------------- Structure:   --              fpu_div.vhd----------------------------------------------------------------------------------- Author:          stassart-- History:--   BJS    2005-10-19    First Version----------------------------------------------------------------------------------- Naming Conventions:--      active low signals:                     "*_n"--      clock signals:                          "clk", "*_clk"--      reset signals:                          "rst", "*_rst", "reset"--      generics:                               All uppercase, starting with: "C_"--      constants:                              All uppercase, not starting with: "C_"--      state machine next state:               "*_next_state"--      state machine current state:            "*_curr_state"--      pipelined signals:                      "*_d#"--      counter signals:                        "*_cnt_*" , "*_counter_*", "*_count_*"--      internal version of output port:        "*_i"--      ports:                                  Names begin with uppercase--      component instantiations:               "<ENTITY_>I_<#|FUNC>" , "ENTITY>_I#" ---- Signals starting with IF, OF, EX, MEM, or WB indicate that they start in that-- stage:----    IF                                -- instruction fetch--    OF                                -- operand fetch--    EX                                -- execute--    MEM                               -- memory--    WB                                -- write back-------------------------------------------------------------------------------library IEEE;use IEEE.std_logic_1164.all;use IEEE.numeric_std.all;---------------------------------------------------------------------------- Include MicroBlaze package for data types and ISA constants--------------------------------------------------------------------------library Microblaze_v7_10_a;use Microblaze_v7_10_a.MicroBlaze_ISA.all;use Microblaze_v7_10_a.MicroBlaze_Types.all;-- pragma xilinx_rtl_offlibrary unisim;use unisim.vcomponents.all;-- pragma xilinx_rtl_on--------------------------------------------------------------------------------- Port declarations-------------------------------------------------------------------------------entity FPU_DIV is  generic (    C_TARGET          : TARGET_FAMILY_TYPE  );  port (    Clk               : in  std_logic;          -- Clock    Reset             : in  std_logic;          -- Reset    EX_MantA_1        : in  FPU_MANT_TYPE;      -- Operand A mantissa    EX_MantB_1        : in  FPU_MANT_TYPE;      -- Operand B mantissa    EX_Start_FPU      : in  boolean;            -- Start the FPU    EX_Div_Op         : in  boolean;            -- Is division operation?    EX_PipeRun        : in  boolean;            -- Move the execute stage    Mem_Not_Div_Op    : in  boolean;    MEM_Div_Done      : out boolean;            -- FPU divider is done the next cycle    MEM_Div_Res_4     : out FPU_MANT_IGRS_TYPE; -- FPU mantissa multiplicaiton result    MEM_Div_Dec_Exp_4 : out boolean             -- Div decrement exponent  );end FPU_DIV;--------------------------------------------------------------------------------- Architecture section-------------------------------------------------------------------------------architecture IMP of FPU_DIV is  subtype Mant_OverImpl_T is std_logic_vector(FPU_MANT_TYPE'left-2 to FPU_MANT_TYPE'right);  signal mem_div_iterate : boolean;  signal mem_div_end     : boolean;  signal mem_div_delay   : std_logic_vector(0 to 2);  signal mem_div_done_i  : boolean;  signal mem_reset_Q     : std_logic;  signal mem_diff_cmb    : Mant_OverImpl_T;  signal mem_res_neg_cmb : std_logic;  signal mem_R           : Mant_OverImpl_T := (others => '0');  signal mem_D           : Mant_OverImpl_T := (others => '0');  signal mem_Q           : Mant_OverImpl_T;  signal mem_next_sub    : std_logic;  signal mem_div_sticky_bit_cmb : std_logic;  signal mem_start_div   : boolean;begin  -----------------------------------------------------------------------------  -- Decode logic  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------  -- MEM_Div_Iterate_DFF  -- Old name: Div_Count_Handle  -----------------------------------------------------------------------------  MEM_Div_Iterate_DFF : process (Clk) is  begin -- process MEM_Div_Iterate_DFF    if Clk'event and Clk = '1' then     -- rising clock edge      if Reset = '1' then            -- synchronous reset (active high)        mem_div_iterate <= false;      elsif EX_Start_FPU and EX_PipeRun then        mem_div_iterate <= EX_Div_Op;      elsif mem_div_end then        mem_div_iterate <= false;      end if;    end if;  end process MEM_Div_Iterate_DFF;  -----------------------------------------------------------------------------  -- MEM_Div_Delay_REG  -- Delay till done with divide operation  -- Shift to the right  -----------------------------------------------------------------------------  MEM_Div_Delay_REG : process (Clk) is  begin -- process MEM_Div_Delay_REG    if Clk'event and Clk = '1' then     -- rising clock edge      if (mem_div_iterate and mem_Q(mem_Q'left+2) = '1') then        mem_div_end <= true;      elsif mem_reset_Q = '1' then        mem_div_end <= false;      end if;            if (mem_div_end and mem_div_iterate) then        mem_div_delay(0) <= '1';      else        mem_div_delay(0) <= '0';      end if;      mem_div_delay(1 to mem_div_delay'right) <= mem_div_delay(0 to mem_div_delay'right-1);    end if;  end process MEM_Div_Delay_REG;    mem_div_done_i <= mem_div_delay(mem_div_delay'right) = '1';  -- Reset Q?  mem_reset_Q <= '1' when Reset = '1' else                 '1' when mem_div_done_i else '0';  -----------------------------------------------------------------------------  -- Data logic  -----------------------------------------------------------------------------  -- Add/Subtract operation per iteration  mem_diff_cmb <= std_logic_vector(unsigned(mem_R) - unsigned(mem_D)) when mem_next_sub = '1' else                  std_logic_vector(unsigned(mem_R) + unsigned(mem_D));  -- Is the result negative?  mem_res_neg_cmb <= mem_diff_cmb(mem_diff_cmb'left);  -----------------------------------------------------------------------------  -- MEM_R_DFF  -- The R register  -- Is loaded with EX_MantA_1 (Op2) on start of division  -- "01" adds positive sign bit and implicit bit  -- During the iteration, the add/sub result is left shifted one bit  -- '0' is shifted in because the mantissa is always positive  -----------------------------------------------------------------------------  MEM_R_DFF : process (Clk) is  begin  -- process MEM_R_DFF    if Clk'event and Clk = '1' then     -- rising clock edge      if EX_PipeRun and EX_Start_FPU then        mem_R <= "01" & EX_MantA_1;      elsif mem_div_iterate then        mem_R <= mem_diff_cmb(mem_diff_cmb'left+1 to mem_diff_cmb'right) & '0';      end if;    end if;  end process MEM_R_DFF;  -----------------------------------------------------------------------------  -- MEM_D_DFF  -- The D register  -- Just loaded with EX_MantB_1 (Op1), never changes during the iteration  -- "01" adds positive sign bit and implicit bit  -----------------------------------------------------------------------------  MEM_D_DFF : process (Clk) is  begin  -- process MEM_D_DFF    if Clk'event and Clk = '1' then     -- rising clock edge      if EX_PipeRun and EX_Start_FPU then        mem_D <= "01" & EX_MantB_1;      end if;    end if;  end process MEM_D_DFF;  -----------------------------------------------------------------------------  -- MEM_Q_DFF  -- Left shift Q each iteration  -- Shift in 1 if the previous operation was positive  -- Shift in 0 if the previous operation was negative  -----------------------------------------------------------------------------  MEM_Q_DFF : process (Clk) is  begin  -- process MEM_Q_DFF    if Clk'event and Clk = '1' then     -- rising clock edge      if (mem_reset_Q = '1') then        mem_Q <= (others => '0');      elsif (mem_div_iterate) then        mem_Q <= mem_Q(mem_Q'left+1 to mem_Q'right) & not mem_res_neg_cmb;      end if;    end if;  end process MEM_Q_DFF;  -----------------------------------------------------------------------------  -- MEM_Next_Sub_DFF  -- Is the next operation subtraction?  -----------------------------------------------------------------------------  MEM_Next_Sub_DFF : process (Clk) is  begin  -- process MEM_Next_Sub_DFF    if Clk'event and Clk = '1' then  -- rising clock edge      if Reset = '1' then            -- synchronous reset (active high)        mem_next_sub <= '1';      else        if EX_PipeRun and EX_Start_FPU then          -- Start with a subtraction          mem_next_sub <= '1';        elsif (mem_div_iterate) then          mem_next_sub <= not mem_res_neg_cmb;        end if;      end if;    end if;  end process MEM_Next_Sub_DFF;  ----------------------------------------  -- MEM_Div_Sticky  -- Calculate the sticky bit  -- Old name: div_carry_or_I1  ----------------------------------------  MEM_Div_Sticky : process (mem_R) is    variable temp_sticky : std_logic;  begin -- process MEM_Div_Sticky    temp_sticky := '0';    -- mem_R'left is the round bit    -- start at the following bit    for I in mem_R'left+1 to mem_R'right loop      temp_sticky := temp_sticky or mem_R(I);    end loop; -- I    mem_div_sticky_bit_cmb <= temp_sticky;  end process MEM_Div_Sticky;  -----------------------------------------------------------------------------  -- MEM_Start_Div_DFF  -- Signal indicating start of divider  -----------------------------------------------------------------------------  MEM_Start_Div_DFF : process (Clk) is  begin    if Clk'event and Clk = '1' then  -- rising clock edge      if Reset = '1' then            -- synchronous reset (active high)        mem_start_div <= false;      else        if EX_PipeRun then          mem_start_div <= EX_Start_FPU and ex_div_op;        else          mem_start_div <= false;        end if;      end if;    end if;  end process MEM_Start_Div_DFF;  -----------------------------------------------------------------------------  -- Outputs  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------  -- MEM_Dec_Exp_DFF  -- Need to decrement the exponent?  -- This is not pipelined  -- Old name: detect_adjust  -----------------------------------------------------------------------------  MEM_Dec_Exp_DFF : process (Clk) is    variable start_div_1 : boolean;  begin -- process MEM_Dec_Exp_DFF    if Clk'event and Clk = '1' then  -- rising clock edge      if (Reset = '1') or (Mem_Not_Div_Op) then            -- synchronous reset (active high)        MEM_Div_Dec_Exp_4 <= false;      else        if mem_start_div then          if (mem_res_neg_cmb = '1') then            MEM_Div_Dec_Exp_4 <= true;          else            MEM_Div_Dec_Exp_4 <= false;          end if;        end if;      end if;    end if;  end process MEM_Dec_Exp_DFF;  -----------------------------------------------------------------------------  -- MEM_Div_Res_4_DFF  -- Divider result  -----------------------------------------------------------------------------  MEM_Div_Res_4_DFF : process (Clk) is  begin -- process MEM_Div_Res_4_DFF    if Clk'event and Clk = '1' then  -- rising clock edge      if (Reset = '1') or (Mem_Not_Div_Op) then            -- synchronous reset (active high)        MEM_Div_Res_4 <= (others => '0');      else        -- Implicit through guard bit        MEM_Div_Res_4(MEM_Div_Res_4'left to MEM_Div_Res_4'right-2) <= mem_Q;        MEM_Div_Res_4(FPU_MANT_ROUND_POS)                          <= mem_R(mem_R'left);        MEM_Div_Res_4(FPU_MANT_STICKY_POS)                         <= mem_div_sticky_bit_cmb;              end if;    end if;  end process MEM_Div_Res_4_DFF;  -- Divider is done  MEM_Div_Done <= mem_div_done_i;end IMP;

⌨️ 快捷键说明

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