📄 fpu_lth.vhd
字号:
--------------------------------------------------------------------------------- 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 + -