📄 fpu_arch.vhd
字号:
LIBRARY ieee ;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_arith.ALL;USE ieee.std_logic_misc.ALL;USE ieee.std_logic_unsigned.ALL;LIBRARY work;----------------------------------------------------------------------------- FPU Operations (fpu_op):-- 0 = add-- 1 = sub-- 2 = mul-- 3 = div-- 4 =-- 5 =-- 6 =-- 7 =-------------------------------------------------------------------------------------------------------------------------------------------------------- Rounding Modes (rmode):-- 0 = round_nearest_even-- 1 = round_to_zero-- 2 = round_up-- 3 = round_down--------------------------------------------------------------------------- ENTITY fpu IS PORT( clk : IN std_logic ; fpu_op : IN std_logic_vector (2 downto 0) ; opa : IN std_logic_vector (31 downto 0) ; opb : IN std_logic_vector (31 downto 0) ; rmode : IN std_logic_vector (1 downto 0) ; div_by_zero : OUT std_logic ; fpout : OUT std_logic_vector (31 downto 0) ; ine : OUT std_logic ; inf : OUT std_logic ; overflow : OUT std_logic ; qnan : OUT std_logic ; snan : OUT std_logic ; underflow : OUT std_logic ; zero : OUT std_logic );END fpu ;ARCHITECTURE arch OF fpu IS signal opa_r, opb_r : std_logic_vector (31 downto 0); signal signa, signb : std_logic ; signal sign_fasu : std_logic ; signal fracta, fractb : std_logic_vector (26 downto 0); signal exp_fasu : std_logic_vector (7 downto 0); signal exp_r : std_logic_vector (7 downto 0); signal fract_out_d : std_logic_vector (26 downto 0); signal co : std_logic ; signal fract_out_q : std_logic_vector (27 downto 0); signal out_d : std_logic_vector (30 downto 0); signal overflow_d, underflow_d : std_logic ; signal mul_inf, div_inf : std_logic ; signal mul_00, div_00 : std_logic ; signal inf_d, ind_d, qnan_d, snan_d, opa_nan, opb_nan : std_logic ; signal opa_00, opb_00 : std_logic ; signal opa_inf, opb_inf : std_logic ; signal opa_dn, opb_dn : std_logic ; signal nan_sign_d, result_zero_sign_d : std_logic ; signal sign_fasu_r : std_logic ; signal exp_mul : std_logic_vector (7 downto 0); signal sign_mul : std_logic ; signal sign_mul_r : std_logic ; signal fracta_mul, fractb_mul : std_logic_vector (23 downto 0); signal inf_mul : std_logic ; signal inf_mul_r : std_logic ; signal exp_ovf : std_logic_vector (1 downto 0); signal exp_ovf_r : std_logic_vector (1 downto 0); signal sign_exe : std_logic ; signal sign_exe_r : std_logic ; signal underflow_fmul1_p1, underflow_fmul1_p2, underflow_fmul1_p3 : std_logic ; signal underflow_fmul_d : std_logic_vector (2 downto 0); signal prod : std_logic_vector (47 downto 0); signal quo : std_logic_vector (49 downto 0); signal fdiv_opa : std_logic_vector (49 downto 0); signal remainder : std_logic_vector (49 downto 0); signal remainder_00 : std_logic ; signal div_opa_ldz_d, div_opa_ldz_r1, div_opa_ldz_r2 : std_logic_vector (4 downto 0); signal ine_d : std_logic ; signal fract_denorm : std_logic_vector (47 downto 0); signal fract_div : std_logic_vector (47 downto 0); signal sign_d : std_logic ; signal sign : std_logic ; signal opa_r1 : std_logic_vector (30 downto 0); signal fract_i2f : std_logic_vector (47 downto 0); signal opas_r1, opas_r2 : std_logic ; signal f2i_out_sign : std_logic ; signal fasu_op_r1, fasu_op_r2 : std_logic ; signal out_fixed : std_logic_vector (30 downto 0); signal output_zero_fasu : std_logic ; signal output_zero_fdiv : std_logic ; signal output_zero_fmul : std_logic ; signal inf_mul2 : std_logic ; signal overflow_fasu : std_logic ; signal overflow_fmul : std_logic ; signal overflow_fdiv : std_logic ; signal inf_fmul : std_logic ; signal sign_mul_final : std_logic ; signal out_d_00 : std_logic ; signal sign_div_final : std_logic ; signal ine_mul, ine_mula, ine_div, ine_fasu : std_logic ; signal underflow_fasu, underflow_fmul, underflow_fdiv : std_logic ; signal underflow_fmul1 : std_logic ; signal underflow_fmul_r : std_logic_vector (2 downto 0); signal opa_nan_r : std_logic ; signal mul_uf_del : std_logic ; signal uf2_del, ufb2_del, ufc2_del, underflow_d_del : std_logic ; signal co_del : std_logic ; signal out_d_del : std_logic_vector (30 downto 0); signal ov_fasu_del, ov_fmul_del : std_logic ; signal fop : std_logic_vector (2 downto 0); signal ldza_del : std_logic_vector (4 downto 0); signal quo_del : std_logic_vector (49 downto 0); signal rmode_r1, rmode_r2, rmode_r3 : std_logic_vector (1 downto 0); signal fpu_op_r1, fpu_op_r2, fpu_op_r3 : std_logic_vector (2 downto 0); signal fpu_op_r1_0_not : std_logic ; signal fasu_op, co_d : std_logic ; signal post_norm_output_zero : std_logic ; CONSTANT INF_VAL : std_logic_vector(31 DOWNTO 0) := X"7f800000"; CONSTANT QNAN_VAL : std_logic_vector(31 DOWNTO 0) := X"7fc00001"; CONSTANT SNAN_VAL : std_logic_vector(31 DOWNTO 0) := X"7f800001"; COMPONENT add_sub27 PORT( add : IN std_logic ; opa : IN std_logic_vector (26 downto 0) ; opb : IN std_logic_vector (26 downto 0) ; co : OUT std_logic ; sum : OUT std_logic_vector (26 downto 0) ); END COMPONENT; COMPONENT div_r2 PORT( clk : IN std_logic ; opa : IN std_logic_vector (49 downto 0) ; opb : IN std_logic_vector (23 downto 0) ; quo : OUT std_logic_vector (49 downto 0) ; remainder : OUT std_logic_vector (49 downto 0) ); END COMPONENT; COMPONENT except IS PORT( clk : IN std_logic ; opa : IN std_logic_vector (31 downto 0) ; opb : IN std_logic_vector (31 downto 0) ; ind : OUT std_logic ; inf : OUT std_logic ; opa_00 : OUT std_logic ; opa_dn : OUT std_logic ; opa_inf : OUT std_logic ; opa_nan : OUT std_logic ; opb_00 : OUT std_logic ; opb_dn : OUT std_logic ; opb_inf : OUT std_logic ; opb_nan : OUT std_logic ; qnan : OUT std_logic ; snan : OUT std_logic ); END COMPONENT ; COMPONENT mul_r2 IS PORT( clk : IN std_logic ; opa : IN std_logic_vector (23 downto 0) ; opb : IN std_logic_vector (23 downto 0) ; prod : OUT std_logic_vector (47 downto 0) ); END COMPONENT; COMPONENT post_norm IS PORT( clk : IN std_logic ; div_opa_ldz : IN std_logic_vector (4 downto 0) ; exp_in : IN std_logic_vector (7 downto 0) ; exp_ovf : IN std_logic_vector (1 downto 0) ; fpu_op : IN std_logic_vector (2 downto 0) ; fract_in : IN std_logic_vector (47 downto 0) ; opa_dn : IN std_logic ; opas : IN std_logic ; opb_dn : IN std_logic ; output_zero : IN std_logic ; rem_00 : IN std_logic ; rmode : IN std_logic_vector (1 downto 0) ; sign : IN std_logic ; f2i_out_sign : OUT std_logic ; fpout : OUT std_logic_vector (30 downto 0) ; ine : OUT std_logic ; overflow : OUT std_logic ; underflow : OUT std_logic ); END COMPONENT; COMPONENT pre_norm IS PORT( add : IN std_logic ; clk : IN std_logic ; opa : IN std_logic_vector (31 downto 0) ; opa_nan : IN std_logic ; opb : IN std_logic_vector (31 downto 0) ; opb_nan : IN std_logic ; rmode : IN std_logic_vector (1 downto 0) ; exp_dn_out : OUT std_logic_vector (7 downto 0) ; fasu_op : OUT std_logic ; fracta_out : OUT std_logic_vector (26 downto 0) ; fractb_out : OUT std_logic_vector (26 downto 0) ; nan_sign : OUT std_logic ; result_zero_sign : OUT std_logic ; sign : OUT std_logic ); END COMPONENT; COMPONENT pre_norm_fmul IS PORT( clk : IN std_logic ; fpu_op : IN std_logic_vector (2 downto 0) ; opa : IN std_logic_vector (31 downto 0) ; opb : IN std_logic_vector (31 downto 0) ; exp_out : OUT std_logic_vector (7 downto 0) ; exp_ovf : OUT std_logic_vector (1 downto 0) ; fracta : OUT std_logic_vector (23 downto 0) ; fractb : OUT std_logic_vector (23 downto 0) ; inf : OUT std_logic ; sign : OUT std_logic ; sign_exe : OUT std_logic ; underflow : OUT std_logic_vector (2 downto 0) ); END COMPONENT; BEGIN PROCESS (clk) BEGIN IF clk'event AND clk = '1' THEN opa_r <= opa; opb_r <= opb; rmode_r1 <= rmode; rmode_r2 <= rmode_r1; rmode_r3 <= rmode_r2; fpu_op_r1 <= fpu_op; fpu_op_r2 <= fpu_op_r1; fpu_op_r3 <= fpu_op_r2; END IF; END PROCESS; --------------------------------------------------------------------------- -- Exceptions block --------------------------------------------------------------------------- u0 : except PORT MAP ( clk => clk, opa => opa_r, opb => opb_r, inf => inf_d, ind => ind_d, qnan => qnan_d, snan => snan_d, opa_nan => opa_nan, opb_nan => opb_nan, opa_00 => opa_00, opb_00 => opb_00, opa_inf => opa_inf, opb_inf => opb_inf, opa_dn => opa_dn, opb_dn => opb_dn ); --------------------------------------------------------------------------- -- Pre-Normalize block -- Adjusts the numbers to equal exponents and sorts them -- determine result sign -- determine actual operation to perform (add or sub) --------------------------------------------------------------------------- fpu_op_r1_0_not <= NOT fpu_op_r1(0); u1 : pre_norm PORT MAP ( clk => clk, -- System Clock rmode => rmode_r2, -- Roundin Mode add => fpu_op_r1_0_not, -- Add/Sub Input opa => opa_r, opb => opb_r, -- Registered OP Inputs opa_nan => opa_nan, -- OpA is a NAN indicator opb_nan => opb_nan, -- OpB is a NAN indicator fracta_out => fracta, -- Equalized and sorted fraction fractb_out => fractb, -- outputs (Registered exp_dn_out => exp_fasu, -- Selected exponent output (registered; sign => sign_fasu, -- Encoded output Sign (registered) nan_sign => nan_sign_d, -- Output Sign for NANs (registered) result_zero_sign => result_zero_sign_d, -- Output Sign for zero result (registered) fasu_op => fasu_op -- Actual fasu operation output (registered) ); u2 : pre_norm_fmul PORT MAP ( clk => clk, fpu_op => fpu_op_r1, opa => opa_r, opb => opb_r, fracta => fracta_mul, fractb => fractb_mul, exp_out => exp_mul, -- FMUL exponent output => registered) sign => sign_mul, -- FMUL sign output (registered) sign_exe => sign_exe, -- FMUL exception sign output (registered) inf => inf_mul, -- FMUL inf output (registered) exp_ovf => exp_ovf, -- FMUL exponnent overflow output (registered) underflow => underflow_fmul_d ); PROCESS (clk) BEGIN IF clk'event AND clk = '1' THEN sign_mul_r <= sign_mul; sign_exe_r <= sign_exe; inf_mul_r <= inf_mul; exp_ovf_r <= exp_ovf; sign_fasu_r <= sign_fasu; END IF; END PROCESS;---------------------------------------------------------------------------- Add/Sub-- u3 : add_sub27 PORT MAP ( add => fasu_op, -- Add/Sub opa => fracta, -- Fraction A input opb => fractb, -- Fraction B Input sum => fract_out_d, -- SUM output co => co_d ); -- Carry Output PROCESS (clk) BEGIN IF clk'event AND clk = '1' THEN fract_out_q <= co_d & fract_out_d; END IF; END PROCESS;---------------------------------------------------------------------------- Mul-- u5 : mul_r2 PORT MAP (clk => clk, opa => fracta_mul, opb => fractb_mul, prod => prod);---------------------------------------------------------------------------- Divide--PROCESS (fracta_mul)BEGIN IF fracta_mul(22) = '1' THEN div_opa_ldz_d <= conv_std_logic_vector(1,5); ELSIF fracta_mul(22 DOWNTO 21) = "01" THEN div_opa_ldz_d <= conv_std_logic_vector(2,5); ELSIF fracta_mul(22 DOWNTO 20) = "001" THEN div_opa_ldz_d <= conv_std_logic_vector(3,5); ELSIF fracta_mul(22 DOWNTO 19) = "0001" THEN div_opa_ldz_d <= conv_std_logic_vector(4,5); ELSIF fracta_mul(22 DOWNTO 18) = "00001" THEN div_opa_ldz_d <= conv_std_logic_vector(5,5); ELSIF fracta_mul(22 DOWNTO 17) = "000001" THEN div_opa_ldz_d <= conv_std_logic_vector(6,5); ELSIF fracta_mul(22 DOWNTO 16) = "0000001" THEN div_opa_ldz_d <= conv_std_logic_vector(7,5); ELSIF fracta_mul(22 DOWNTO 15) = "00000001" THEN div_opa_ldz_d <= conv_std_logic_vector(8,5); ELSIF fracta_mul(22 DOWNTO 14) = "000000001" THEN div_opa_ldz_d <= conv_std_logic_vector(9,5); ELSIF fracta_mul(22 DOWNTO 13) = "0000000001" THEN div_opa_ldz_d <= conv_std_logic_vector(10,5); ELSIF fracta_mul(22 DOWNTO 12) = "00000000001" THEN div_opa_ldz_d <= conv_std_logic_vector(11,5); ELSIF fracta_mul(22 DOWNTO 11) = "000000000001" THEN div_opa_ldz_d <= conv_std_logic_vector(12,5); ELSIF fracta_mul(22 DOWNTO 10) = "0000000000001" THEN div_opa_ldz_d <= conv_std_logic_vector(13,5); ELSIF fracta_mul(22 DOWNTO 9) = "00000000000001" THEN div_opa_ldz_d <= conv_std_logic_vector(14,5); ELSIF fracta_mul(22 DOWNTO 8) = "000000000000001" THEN div_opa_ldz_d <= conv_std_logic_vector(15,5);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -