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

📄 fp_adder.vhd

📁 DLX CPU VHDL CODE UNIVERSITY
💻 VHD
📖 第 1 页 / 共 3 页
字号:
    end case;    RETURN;    END round_result;-- IEEE 754 standard, default rounding mode, round to nearest/even PROCEDURE dround_result (    sign : in bit;    prelim_result : inout bit_vector;    exp_result : inout dexp;    round_mode : in bit_2) is    variable r : bit;          -- round bit    variable s : bit;          -- sticky bit    variable i : integer;	    variable carry: boolean := true;	    BEGIN      case round_mode is             when rn=> 	IF (prelim_result(1)='1')  then 		  if((prelim_result(0)='1') or  (prelim_result(2)='1')) then	     if prelim_result((dADDEND_LENGTH - 2) - 1 downto 3) =   "1111111111111111111111111111111111111111111111111111" then             --overflow     	          prelim_result((dADDEND_LENGTH -2) -1  downto 3) := "0000000000000000000000000000000000000000000000000000";	          exp_result := exp_result + 1;	     else		  carry:=true;	          FOR i IN 3 to ((dADDEND_LENGTH-2)-1) LOOP	            IF carry THEN		      IF prelim_result(i) = '0' THEN		        prelim_result(i) := '1';		        carry := false;		      ELSE		        prelim_result(i) := '0';		      END IF;	            END IF;		          END LOOP;             end if;           end if;	end if;    when rz=>        --dont round, just truncate    when rm=>                if(sign='1' and( prelim_result(1)='1' or prelim_result(0)='1')) then          --subtract one, but actually add it since mant is negative	     if prelim_result((dADDEND_LENGTH - 2) - 1 downto 3) =   "1111111111111111111111111111111111111111111111111111" then             --overflow     	          prelim_result((dADDEND_LENGTH -2) -1  downto 3) := "0000000000000000000000000000000000000000000000000000";	          exp_result := exp_result + 1;	     else		  carry:=true;	          FOR i IN 3 to ((dADDEND_LENGTH-2)-1) LOOP	            IF carry THEN		      IF prelim_result(i) = '0' THEN		        prelim_result(i) := '1';		        carry := false;		      ELSE		        prelim_result(i) := '0';		      END IF;	            END IF;		          END LOOP;             end if;	else 	  --nothing to do, truncation	end if;    when rp=>	        if(sign='0' and (prelim_result(1)='1' or prelim_result(0)='1')) then          -- add one	     if prelim_result((dADDEND_LENGTH - 2) - 1 downto 3) =   "1111111111111111111111111111111111111111111111111111" then             --overflow     	          prelim_result((dADDEND_LENGTH -2) -1  downto 3) := "0000000000000000000000000000000000000000000000000000";	          exp_result := exp_result + 1;	     else		  carry:=true;	          FOR i IN 3 to ((dADDEND_LENGTH-2)-1) LOOP	            IF carry THEN		      IF prelim_result(i) = '0' THEN		        prelim_result(i) := '1';		        carry := false;		      ELSE		        prelim_result(i) := '0';		      END IF;	            END IF;		          END LOOP;             end if; 	else 	  --nothing to do, truncation	end if;     end case;    RETURN;    END dround_result;	BEGINmain_proc : process    variable dmnt1          : dmnt;            variable dmnt2          : dmnt;           variable dexp1          : dexp;          variable dexp2          : dexp;         variable dsign1         : bit;    variable dsign2         : bit;    variable dsign_result   : bit;    variable dexp_diff      : integer;    variable daddend1       : daddend;    variable daddend2       : daddend;    variable dprelim_result : daddend;    variable doverflow      : boolean;    variable dexp_result    : dexp;    variable dtrue_subtract : boolean;    variable dswapped       : boolean;    variable mnt1          : mnt;          variable mnt2          : mnt;         variable exp1          : exp;         variable exp2          : exp;         variable sign1         : bit;    variable sign2         : bit;    variable sign_result   : bit;    variable exp_diff      : integer;    variable addend1       : addend;    variable addend2       : addend;    variable prelim_result : addend;    variable overflow      : boolean;    variable exp_result    : exp;    variable true_subtract : boolean;    variable swapped       : boolean;    variable pos_inf_flag1 : boolean;    variable neg_inf_flag1 : boolean;    variable pos_inf_flag2 : boolean;    variable neg_inf_flag2 : boolean;    variable nan_flag      : boolean;    variable special_flag  : boolean;    variable temp_exp : bit_vector (7 downto 0);	 variable op1_sign  : bit;	 variable op1_exp   : exp;	 variable op1_mant  : mantissa;	 variable op2_sign  : bit;	 variable op2_exp   : exp;	 variable op2_mant  : mantissa;         variable res_sign  : bit;	 variable res_exp   : exp;         variable res_mant  : mantissa;    alias fsr_cond    : bit is fsr_out(12);    alias round_mode  : bit_vector (31 downto 30) is fsr_in(31 downto 30);    variable z,n: bit:='0';  variable double1, double2, double3 : bit_64;     alias d1L:bit_32 is double1(31 downto 0);  alias d1H:bit_32 is double1(63 downto 32);  alias d2L:bit_32 is double2(31 downto 0);  alias d2H:bit_32 is double2(63 downto 32);  alias d3L:bit_32 is double3(31 downto 0);  alias d3H:bit_32 is double3(63 downto 32);    alias v: bit is fsr_out (3);  alias u: bit is fsr_out (2);  alias dz: bit is fsr_out (1);  alias av: bit is fsr_out (7);  alias au: bit is fsr_out (6);  alias d1_mant:bit_52 is double1(51 downto 0);  alias d1_sign:bit is double1(63);  alias d1_exp:bit_11 is double1(62 downto 52);  alias d2_mant:bit_52 is double2(51 downto 0);  alias d2_sign:bit is double2(63);  alias d2_exp:bit_11 is double2(62 downto 52);  alias d3_mant:bit_52 is double3(51 downto 0);  alias d3_sign:bit is double3(63);  alias d3_exp:bit_11 is double3(62 downto 52);  BEGIN  case operation is        when add_d | subtract_d | ltd | gtd | led | ged | eqd | ned=>	fsr_out<=fsr_in;  u<='0';  v<='0';  dz<='0';	d1L:=Op1;	d1H:=Op1b;	d2L:=Op2;	d2H:=Op2b;--    wait until phi1= '0';--    IF (phi1 = '1' ) THEN        -- Step 1: Load operands and set flags        dexp1:=bits_to_uint(d1_exp);        dexp2:=bits_to_uint( d2_exp);	    -- Add the 1 (hidden 1) assumed in the representation.            -- Actually, should not do this for any input which is             -- denormalized. ( Both input assumed to be nomalized. )	IF (dexp1 = 0) AND (bits_to_uint(d1_mant) = 0) THEN	    dmnt1 := "0" & d1_mant;	    dexp1 := dexp2;	ELSE            dmnt1 := "1" & d1_mant;        END IF;	IF (dexp2 = 0) AND (bits_to_uint(d2_mant) =0) THEN            dmnt2 := "0" & d2_mant;            dexp2 := dexp1;	ELSE	    dmnt2 := "1" & d2_mant;	END IF;		dsign1 := d1_sign;        dsign2 := d2_sign;        pos_inf_flag1 := false;        neg_inf_flag1 := false;        pos_inf_flag2 := false;        neg_inf_flag2 := false;        nan_flag      := false;        special_flag  := false;--	fsr_flags <= "0000000";        -- Step 2: Check for special inputs ( +/- Infinity,  NaN)         IF (bits_to_uint(d1_exp) = dMAX_EXP) THEN	    dexp_result := dexp1;	    special_flag := true;	    IF (bits_to_uint(d1_mant) = 0) THEN	        IF d1_sign = '0' THEN		    pos_inf_flag1 := true;	        ELSE 		    neg_inf_flag1 := true;		END IF;	    ELSE 		nan_flag := true;	    END IF;	END IF;	IF (bits_to_uint(d2_exp) = dMAX_EXP) then	    dexp_result := dexp2;	    special_flag := true;	    IF (bits_to_uint(d2_mant) = 0) THEN	        IF d2_sign = '0' THEN		    pos_inf_flag2 := true;	        ELSE 		    neg_inf_flag2 := true;		END IF;	    ELSE 		nan_flag := true;	    END IF;    	END IF;	-- Step 3: Compare exponents.  Swap the operands of exp1 < exp2        --         or of (dexp1 = dexp2 AND mnt1 < mnt2)	dswapped  := false;	IF (dexp1 < dexp2 OR (dexp1 = dexp2 AND dmnt1 < dmnt2)) THEN	    swap_ints(dexp1, dexp2);	    swap_bvs(dmnt1, dmnt2);	    swap_bits(sign1, sign2);	    dswapped := true;	END IF;	dexp_diff := dexp1 - dexp2;	dexp_result := dexp1;	dsign_result := dsign1;	IF (dexp_diff > (dADDEND_LENGTH - 2)) THEN       	    ASSERT (dexp_diff <= (dADDEND_LENGTH -2)) 	        REPORT "Precision lost in exponent difference"	    	      SEVERITY warning;	    dexp_diff := dADDEND_LENGTH -2;	END IF;	-- Step 4: Shift the mantissa corresponding to the smaller exponent,         -- and extend precision by three bits to the right.	IF (dexp_diff > 0) THEN	    daddend1 := "0" & dmnt1 & "000";	    form_extended_operand(dmnt2, daddend2, dexp_diff);	ELSE	    daddend1 := "0" & dmnt1 & "000";	    daddend2 := "0" & dmnt2 & "000";	END IF;	--  Step 5: Add or subtract the mantissas.	IF (operation /= add_d) THEN	    IF dswapped THEN	        dsign_result := NOT(dsign_result);	    END IF;	    IF (dsign1 = dsign2) THEN 	        true_subtract := true;	    ELSE 	        true_subtract := false;	    END IF;	ELSIF (dsign1 /= dsign2 and operation = add_d) THEN	    true_subtract := true;	ELSE	    true_subtract := false;	END IF;	IF true_subtract THEN	    daddend2 := twos_complement(daddend2);	END IF;		IF (special_flag = false) THEN	    bv_add(dprelim_result, daddend1, daddend2, overflow);	END IF;        -- Step 6: Normalize the result.	IF (special_flag = false) THEN	    IF (bits_to_uint(dprelim_result) = 0) AND (overflow = false) THEN	        dsign_result := '0';	        dexp_result:= 0;	--	zero_res <= '1';     	    ELSIF overflow THEN	        IF dexp_result >= (dMAX_EXP - 1) THEN		    if(dsign_result='0') then 			v<='1';		    else			u<='1';		    end if;		    av<='1';		    int_to_bits(0,dprelim_result);		    dexp_result := dMAX_EXP;--		    pos_inf_res <= '1';	        ELSE        	    dexp_result := exp_result + 1;                    right_shift(reg_val => dprelim_result, shift_amt => 1);	        END IF; 	    ELSE    	    -- Shift left until normalized.  Normalized when the value to the             -- left of the decimal point is 1.	                  normalize(dprelim_result((dADDEND_LENGTH-2) downto 0), 			  dexp_result);	    END IF; 	END IF; --        ASSERT false REPORT vector_to_string(round_mode) SEVERITY warning;        -- Step 7: Round the result.        IF (special_flag = false) THEN		dround_result(dsign_result,dprelim_result, dexp_result, round_mode);		END IF;        -- Step 8: Put sum onto output.	IF (special_flag = false) THEN		d3_sign := dsign_result;		n:=dsign_result;			int_to_bits(dexp_result,d3_exp);  		d3_mant := dprelim_result((dADDEND_LENGTH - 2) - 1 downto 3);                  -- leaves off "hidden 1" and most significant bit(reserved for                 -- overflow earlier)	ELSIF (nan_flag = true) THEN		d3_sign := '0';		n:='0';			int_to_bits( dexp1,d3_exp); 		d3_mant := dmnt1(51 downto 0);--		nan_res <= '1';--  The rest of the code is to set the flag for the boundry conditions.-- --  Following truth table is for the boundry condition for setting the Flags--  "ctrl" refer to the conditional control for the hightest levels of ELSIF--  --  pos_inf_f1  pos_inf_f2  neg_inf_f1  neg_inf_f2  add  sub  Zero  +INF  -INF--  **********  **********  **********  **********  ***  ***  ****  ****  ****--  ctrl=1          1            0           0       0    1    1      0     0--  ctrl=1          0            0           1       1    0    1      0     0--  ctrl=1          0            0           0       X    X    0      1     0----      0       ctrl=1           1           0       1    0    1      0     0--      0       ctrl=1           0           0       0    1    0      0     1--      0       ctrl=1           1           0       0    1    0      0     1----      0           0        ctrl=1          1       0    1    1      0     0--      0           0        ctrl=1          1       1    0    0      0     1--      0           0        ctrl=1          0       0    1    0      0     1----      0           0            0       ctrl=1      0    1    0      1     0--      0           0            0       ctrl=1      1    0    0      0     1----     	ELSIF (pos_inf_flag1 = true) THEN		d3_sign := '0';

⌨️ 快捷键说明

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