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

📄 fpu_lth.vhd

📁 ARM7的源代码
💻 VHD
📖 第 1 页 / 共 3 页
字号:
---------------------------------------------------------------------------------  Copyright (C) 2002 Martin Kasprzyk <m_kasprzyk@altavista.com>----  This library is free software; you can redistribute it and/or--  modify it under the terms of the GNU Lesser General Public--  License as published by the Free Software Foundation; either--  version 2 of the License, or (at your option) any later version.----------------------------------------------------------------------------------- File       : fpu.vhd-- Author     : Martin Kasprzyk <e00mk@efd.lth.se>--------------------------------------------------------------------------------- Description: A IEEE754 floating point unit for the LEON SPARC processor--------------------------------------------------------------------------------- Modfied by Jiri Gaisler to:-- * be VHDL-87 compatible -- * remove ambiguity for std_logic +,-, and > operands.-- * supress 'X' warnings from std_logic_arith packages-- * added bug fixes from Albert Wang (5 Dec 2002)-- * added bug fixes from Albert Wang (16 Dec 2002)-------------------------------------------------------------------------------library IEEE;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned."-";use ieee.std_logic_unsigned."+";use ieee.std_logic_unsigned.">";use work.leon_iface.all;use work.sparcv8.all;entity fpu_lth is  port(    ss_clock        : in  std_logic;    FpInst          : in  std_logic_vector(9 downto 0);    FpOp            : in  std_logic;    FpLd            : in  std_logic;    Reset           : in  std_logic;    fprf_dout1      : in  std_logic_vector(63 downto 0);    fprf_dout2      : in  std_logic_vector(63 downto 0);    RoundingMode    : in  std_logic_vector(1 downto 0);    FpBusy          : out std_logic;    FracResult      : out std_logic_vector(54 downto 3);    ExpResult       : out std_logic_vector(10 downto 0);    SignResult      : out std_logic;    SNnotDB         : out std_logic;                            -- Not used    Excep           : out std_logic_vector(5 downto 0);    ConditionCodes  : out std_logic_vector(1 downto 0);    ss_scan_mode    : in  std_logic;                            -- Not used    fp_ctl_scan_in  : in  std_logic;                            -- Not used    fp_ctl_scan_out : out std_logic                             -- Not used  );end;architecture rtl of fpu_lth is  constant zero : std_logic_vector(63 downto 0) := (others => '0');--------------------------------------------------------------------------------- Leading zero counter.-------------------------------------------------------------------------------  procedure lz_counter (    in_vect       : in  std_logic_vector(55 downto 0);    leading_zeros : out std_logic_vector(5 downto 0)) is     variable pos_mask : std_logic_vector(55 downto 0);    variable neg_mask : std_logic_vector(55 downto 0);    variable leading_one : std_logic_vector(55 downto 0);    variable nr_zeros : std_logic_vector(5 downto 0);  begin    -- Find leading one e.g. if in_vect = 00101101 then pos_mask = 00111111    -- and neg_mask = "11100000, performing and gives leading_one = 00100000    pos_mask(55) := in_vect(55);    for i in 54 downto 0 loop      pos_mask(i) := pos_mask(i+1) or in_vect(i);    end loop;    neg_mask := "1" & (not pos_mask(55 downto 1));    leading_one := pos_mask and neg_mask;    -- Get number of leading zeros from the leading_one vector    nr_zeros := "000000";     for i in 1 to 55 loop      if (i / 32) /= 0 then        nr_zeros(5) := nr_zeros(5) or leading_one(55-i);      end if;      if ((i mod 32) / 16) /= 0  then        nr_zeros(4) := nr_zeros(4) or leading_one(55-i);      end if;      if (((i mod 32) mod 16) / 8) /= 0 then        nr_zeros(3) := nr_zeros(3) or leading_one(55-i);      end if;      if ((((i mod 32) mod 16) mod 8) / 4) /= 0 then        nr_zeros(2) := nr_zeros(2) or leading_one(55-i);      end if;      if (((((i mod 32) mod 16) mod 8) mod 4) / 2) /= 0 then        nr_zeros(1) := nr_zeros(1) or leading_one(55-i);      end if;            if (i mod 2) /= 0 then        nr_zeros(0) := nr_zeros(0) or leading_one(55-i);      end if;    end loop;    -- Return result    leading_zeros := nr_zeros;  end lz_counter;  --------------------------------------------------------------------------------- Variable amount right shifter with sticky bit calculation.-------------------------------------------------------------------------------  procedure right_shifter_sticky (    in_vect    : in  std_logic_vector(54 downto 0);    amount     : in  std_logic_vector(5 downto 0);    out_vect   : out std_logic_vector(54 downto 0);    sticky_bit : out std_logic) is    variable after32  : std_logic_vector(54 downto 0);    variable after16  : std_logic_vector(54 downto 0);    variable after8   : std_logic_vector(54 downto 0);    variable after4   : std_logic_vector(54 downto 0);    variable after2   : std_logic_vector(54 downto 0);    variable after1   : std_logic_vector(54 downto 0);    variable sticky32 : std_logic;    variable sticky16 : std_logic;    variable sticky8  : std_logic;    variable sticky4  : std_logic;    variable sticky2  : std_logic;    variable sticky1  : std_logic;  begin    -- If amount(5) = '1' then shift vector 32 positions right    if amount(5) = '1' then      after32 := zero(31 downto 0) & in_vect(54 downto 32);      if in_vect(31 downto 0) /= zero(31 downto 0) then        sticky32 := '1';      else        sticky32 := '0';      end if;    else      after32 := in_vect;      sticky32 := '0';    end if;    -- If amount(4) = '1' then shift vector 16 positions right    if amount(4) = '1' then      after16 := zero(15 downto 0) & after32(54 downto 16);      if after32(15 downto 0) /= zero(15 downto 0) then        sticky16 := '1';      else        sticky16 := '0';      end if;    else      after16 := after32;      sticky16 := '0';    end if;    -- If amount(3) = '1' then shift vector 8 positions right    if amount(3) = '1' then      after8 := zero(7 downto 0) & after16(54 downto 8);      if after16(7 downto 0) /= zero(7 downto 0) then        sticky8 := '1';      else        sticky8 := '0';      end if;    else      after8 := after16;      sticky8 := '0';    end if;    -- If amount(2) = '1' then shift vector 4 positions right    if amount(2) = '1' then      after4 := zero(3 downto 0) & after8(54 downto 4);      if after8(3 downto 0) /= zero(3 downto 0) then        sticky4 := '1';      else        sticky4 := '0';      end if;    else      after4 := after8;      sticky4 := '0';    end if;    -- If amount(1) = '1' then shift vector 2 positions right    if amount(1) = '1' then      after2 := "00" & after4(54 downto 2);      if after4(1 downto 0) /= "00" then        sticky2 := '1';      else        sticky2 := '0';      end if;    else      after2 := after4;      sticky2 := '0';    end if;    -- If amount(0) = '1' then shift vector 1 positions right    if amount(0) = '1' then      after1 := "0" & after2(54 downto 1);      sticky1 := after2(0);    else      after1 := after2;      sticky1 := '0';    end if;    -- Return values    out_vect := after1;    sticky_bit := sticky32 or sticky16 or sticky8 or sticky4 or sticky2 or                 sticky1;  end right_shifter_sticky;--------------------------------------------------------------------------------- Variable amount left shifter-------------------------------------------------------------------------------  procedure left_shifter (    in_vect  : in  std_logic_vector(56 downto 0);    amount   : in  std_logic_vector(5 downto 0);    out_vect : out std_logic_vector(56 downto 0)) is    variable after32 : std_logic_vector(56 downto 0);    variable after16 : std_logic_vector(56 downto 0);    variable after8  : std_logic_vector(56 downto 0);    variable after4  : std_logic_vector(56 downto 0);    variable after2  : std_logic_vector(56 downto 0);    variable after1  : std_logic_vector(56 downto 0);  begin    -- If amount(5) = '1' then shift vector 32 positions left    if amount(5) = '1' then      after32 := in_vect(24 downto 0) & zero(31 downto 0);    else      after32 := in_vect;    end if;    -- If amount(4) = '1' then shift vector 16 positions left    if amount(4) = '1' then      after16 :=  after32(40 downto 0) & zero(15 downto 0);    else      after16 := after32;    end if;    -- If amount(3) = '1' then shift vector 8 positions left    if amount(3) = '1' then      after8 := after16(48 downto 0) & zero(7 downto 0);    else      after8 := after16;    end if;    -- If amount(2) = '1' then shift vector 4 positions left    if amount(2) = '1' then      after4 := after8(52 downto 0) & zero(3 downto 0);    else      after4 := after8;    end if;    -- If amount(1) = '1' then shift vector 2 positions left    if amount(1) = '1' then      after2 := after4(54 downto 0) & "00";    else      after2 := after4;    end if;    -- If amount(0) = '1' then shift vector 1 positions left    if amount(0) = '1' then      after1 := after2(55 downto 0) & "0";    else      after1 := after2;    end if;    -- Return value    out_vect := after1;  end left_shifter;  --------------------------------------------------------------------------------- Declaration of record types used to pass signals between pipeline stages.-------------------------------------------------------------------------------type op_decode_stage_type is record     -- input <-> op_decode  opcode : std_logic_vector(9 downto 0);end record;type prenorm_stage_type is record       -- op_decode <-> prenorm  sign1      : std_logic;  exp1       : std_logic_vector(10 downto 0);  frac1     : std_logic_vector(51 downto 0);  sign2      : std_logic;  exp2       : std_logic_vector(10 downto 0);  frac2     : std_logic_vector(51 downto 0);  single     : std_logic;               -- Single precision  comp       : std_logic;               -- Compare and set cc  gen_ex     : std_logic;               -- Generate exception if unordered   op1_denorm : std_logic;  op2_denorm : std_logic;  op1_inf    : std_logic;  op2_inf    : std_logic;  op1_NaN    : std_logic;  op2_NaN    : std_logic;  op1_SNaN   : std_logic;  op2_SNaN   : std_logic;end record;type addsub_stage_type is record        -- prenorm <-> addsub  sign_a   : std_logic;  a        : std_logic_vector(56 downto 0);  sign_b   : std_logic;  b        : std_logic_vector(56 downto 0);  exp      : std_logic_vector(10 downto 0);  single   : std_logic;                 -- Single precision  comp     : std_logic;                 -- Compare and set cc  gen_ex   : std_logic;                 -- Generate exception if unordered   swaped   : std_logic;                 -- Operands swaped during pre_norm  op1_inf  : std_logic;  op2_inf  : std_logic;  op1_NaN  : std_logic;  op2_NaN  : std_logic;  op1_SNaN : std_logic;  op2_SNaN : std_logic;end record;type postnorm_stage_type is record      -- addsub <-> postnorm  frac     : std_logic_vector(56 downto 0);  exp      : std_logic_vector(10 downto 0);  sign     : std_logic;  single   : std_logic;                         -- Single precision  comp     : std_logic;                         -- Compare and set cc    cc       : std_logic_vector(1 downto 0);      -- Condition codes  exc      : std_logic_vector(4 downto 0);      -- Exceptions  res_inf  : std_logic;  res_NaN  : std_logic;  res_SNaN : std_logic;  res_zero : std_logic;end record;type roundnorm_stage_type is record     -- postnorm <-> roundnorm  frac     : std_logic_vector(56 downto 0);  exp      : std_logic_vector(10 downto 0);  sign     : std_logic;  single   : std_logic;                         -- Single precision  comp     : std_logic;                         -- Compare and set cc    cc       : std_logic_vector(1 downto 0);      -- Condition codes  exc      : std_logic_vector(4 downto 0);      -- Exceptions  res_inf  : std_logic;  res_NaN  : std_logic;  res_SNaN : std_logic;end record;

⌨️ 快捷键说明

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