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

📄 fp_adder.vhd

📁 DLX CPU VHDL CODE UNIVERSITY
💻 VHD
📖 第 1 页 / 共 3 页
字号:
		n:='0';		        d3_mant := dmnt1(51 downto 0);	        IF (pos_inf_flag2 = true) AND (operation /= add_d) THEN		    int_to_bits(0,d3_exp);   		  z:='1';		--     zero_res <= '1';		    	ELSIF (neg_inf_flag2 = true) AND (operation = add_d) THEN		    int_to_bits(0,d3_exp);   		  z:='1';		--    zero_res <= '1';	    	ELSE		    int_to_bits( MAX_EXP,d3_exp);		--    pos_inf_res <= '1';            	END IF;    	ELSIF (pos_inf_flag2 = true) THEN	        d3_mant := d2_mant;	        int_to_bits( dMAX_EXP,d3_exp);	        IF (neg_inf_flag1 = true) AND (operation = add_d) THEN		    int_to_bits(0,d3_exp);		    d3_sign := '0';		n:='0';	   		  z:='1';		--    zero_res <= '1';		ELSIF (operation /= add_d) THEN		    d3_sign := '1';		--    neg_inf_res <= '1';		n:='1';		        ELSE		    d3_sign := '0';		n:='0';			--    pos_inf_res <= '1';                END IF;        ELSIF (neg_inf_flag1 = true) THEN	        d3_sign := '1';	        d3_mant := d1_mant;	        IF (neg_inf_flag2 = true) AND (operation /=add_d) THEN		    int_to_bits(0,d3_exp);   		  z:='1';		n:='0';			    d3_sign := '0';	--	    zero_res <= '1';			        ELSE		    int_to_bits( dMAX_EXP,d3_exp); 	--	    neg_inf_res <= '1';                END IF;       ELSIF (neg_inf_flag2 = true) THEN	        d3_mant := d2_mant;	        int_to_bits( dMAX_EXP,d3_exp); 	        IF (operation /= add_d) THEN		    d3_sign := '0';		n:='0';		--	    pos_inf_res <= '1';	        ELSE		    d3_sign := '1';		n:='1';	--		    neg_inf_res <= '1';                END IF;      END IF;    when others => --****************************	fsr_out<=fsr_in;  u<='0';  v<='0';  dz<='0';    op1_mant:=Op1(22 downto 0);    op2_mant:=Op2(22 downto 0);    op1_sign:=Op1(31);    op2_sign:=Op2(31);    op1_exp:=bits_to_uint(Op1(30 downto 23));    op2_exp:=bits_to_uint(Op2(30 downto 23));--    wait until phi1= '0';--    IF (phi1 = '1' ) THEN        -- Step 1: Load operands and set flags        exp1 := op1_exp; --bits_to_int(op1_exp);        exp2 := op2_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 (exp1 = 0) AND (op1_mant = "00000000000000000000000") THEN	    mnt1 := "0" & op1_mant;	    exp1 := exp2;	ELSE            mnt1 := "1" & op1_mant;        END IF;	IF (exp2 = 0) AND (op2_mant = "00000000000000000000000") THEN            mnt2 := "0" & op2_mant;            exp2 := exp1;	ELSE	    mnt2 := "1" & op2_mant;	END IF;		sign1 := op1_sign;        sign2 := op2_sign;        pos_inf_flag1 := false;        neg_inf_flag1 := false;        pos_inf_flag2 := false;        neg_inf_flag2 := false;        nan_flag      := false;        special_flag  := false;	fsr_out (4 downto 1) <= "0000";        -- Step 2: Check for special inputs ( +/- Infinity,  NaN)         IF (op1_exp = MAX_EXP) THEN	    exp_result := exp1;	    special_flag := true;	    IF op1_mant = "00000000000000000000000" THEN	        IF op1_sign = '0' THEN		    pos_inf_flag1 := true;	        ELSE 		    neg_inf_flag1 := true;		END IF;	    ELSE 		nan_flag := true;	    END IF;	END IF;	IF (op2_exp = MAX_EXP) then	    exp_result := exp2;	    special_flag := true;	    IF op2_mant = "00000000000000000000000" THEN	        IF op2_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 (exp1 = exp2 AND mnt1 < mnt2)	swapped  := false;	IF (exp1 < exp2 OR (exp1 = exp2 AND mnt1 < mnt2)) THEN	    swap_ints(exp1, exp2);	    swap_bvs(mnt1, mnt2);	    swap_bits(sign1, sign2);	    swapped := true;	END IF;	exp_diff := exp1 - exp2;	exp_result := exp1;	sign_result := sign1;	IF (exp_diff > (ADDEND_LENGTH - 2)) THEN       	    ASSERT (exp_diff <= (ADDEND_LENGTH -2)) 	        REPORT "Precision lost in exponent difference"	    	      SEVERITY warning;	    exp_diff := ADDEND_LENGTH -2;	END IF;	-- Step 4: Shift the mantissa corresponding to the smaller exponent,         -- and extend precision by three bits to the right.	IF (exp_diff > 0) THEN	    addend1 := "0" & mnt1 & "000";	    form_extended_operand(mnt2, addend2, exp_diff);	ELSE	    addend1 := "0" & mnt1 & "000";	    addend2 := "0" & mnt2 & "000";	END IF;	--  Step 5: Add or subtract the mantissas.	IF (operation /= add) THEN	    IF swapped THEN	        sign_result := NOT(sign_result);	    END IF;	    IF (sign1 = sign2) THEN 	        true_subtract := true;	    ELSE 	        true_subtract := false;	    END IF;	ELSIF (sign1 /= sign2 and operation = add) THEN	    true_subtract := true;	ELSE	    true_subtract := false;	END IF;	IF true_subtract THEN	    addend2 := twos_complement(addend2);	END IF;		IF (special_flag = false) THEN	    bv_add(prelim_result, addend1, addend2, overflow);	END IF;        -- Step 6: Normalize the result.	IF (special_flag = false) THEN	    IF (prelim_result = "0000000000000000000000000000") AND 		(overflow = false) THEN	        sign_result := '0';	        exp_result:= 0;--		zero_res <= '1';     	    ELSIF overflow THEN	        IF exp_result >= (MAX_EXP - 1) THEN		    prelim_result := "0000000000000000000000000000";		    if(dsign_result='0') then 			v<='1';		    else			u<='1';		    end if;		    av<='1';		    exp_result := MAX_EXP;--		    pos_inf_res <= '1';	        ELSE        	    exp_result := exp_result + 1;                    right_shift(reg_val => prelim_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(prelim_result((ADDEND_LENGTH-2) downto 0), 			  exp_result);	    END IF; 	END IF;         -- Step 7: Round the result.        IF (special_flag = false) THEN		round_result(sign_result,prelim_result, exp_result, round_mode);		END IF;        -- Step 8: Put sum onto output.	IF (special_flag = false) THEN		res_sign := sign_result;		n:=sign_result;			res_exp  := exp_result;		res_mant := prelim_result((ADDEND_LENGTH - 2) - 1 downto 3);                  -- leaves off "hidden 1" and most significant bit(reserved for                 -- overflow earlier)	ELSIF (nan_flag = true) THEN		res_sign := '0';		res_exp := exp1;		n:='0';			res_mant := mnt1(22 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		res_sign := '0';	        res_mant := mnt1(22 downto 0);	        IF (pos_inf_flag2 = true) AND (operation /= add) THEN		    res_exp := 0;   		  z:='1';		   -- zero_res <= '1';		    	ELSIF (neg_inf_flag2 = true) AND (operation = add) THEN		    res_exp := 0;   		  z:='1';		  ---  zero_res <= '1';	    	ELSE		    res_exp := MAX_EXP;		   -- pos_inf_res <= '1';            	END IF;    	ELSIF (pos_inf_flag2 = true) THEN	        res_mant := op2_mant;	        res_exp := MAX_EXP;	        IF (neg_inf_flag1 = true) AND (operation = add) THEN		    res_exp := 0;   		  z:='1';		    res_sign := '0';		n:='0';			   -- zero_res <= '1';		ELSIF (operation /= add) THEN		    res_sign := '1';		n:='1';			   -- neg_inf_res <= '1';	        ELSE		n:='0';			    res_sign := '0';		  --  pos_inf_res <= '1';                END IF;        ELSIF (neg_inf_flag1 = true) THEN	        res_sign := '1';	        res_mant := op1_mant;	        IF (neg_inf_flag2 = true) AND (operation /= add) THEN   		  z:='1';		    res_exp := 0;		    res_sign := '0';		   -- zero_res <= '1';				n:='0';		        ELSE		    res_exp := MAX_EXP;		  --  neg_inf_res <= '1';                END IF;       ELSIF (neg_inf_flag2 = true) THEN	        res_mant := op2_mant;	        res_exp := MAX_EXP;	        IF (operation /= add) THEN		    res_sign := '0';		n:='0';			--    pos_inf_res <= '1';	        ELSE		    res_sign := '1';		n:='1';		  --  neg_inf_res <= '1';                END IF;      END IF;  end case;case operation is	when add | subtract =>	    int_to_bits(res_exp,temp_exp);	    R<= res_sign&temp_exp&res_mant;--	    neg_res<=res_sign;	when add_d | subtract_d =>	--    neg_res<=d3H(31);	    R<=d3L;	    Rb<=d3H;		when eqf|eqd =>		    fsr_out<=fsr_in;       	   -- ASSERT false REPORT "eqf or eqd" SEVERITY warning;	    if(z='1') then	       fsr_cond<='1';        	--    ASSERT false REPORT "zero_res=1" SEVERITY warning;	    else 	       fsr_cond<='0';		    end if;        when gtf|gtd=>	    fsr_out<=fsr_in;       	 --   ASSERT false REPORT "gt" SEVERITY warning;            if( n='0' and z='0') then               fsr_cond<='1';	    else 	       fsr_cond<='0';		    end if;        when lef|led=>	    fsr_out<=fsr_in;       	--    ASSERT false REPORT "le" SEVERITY warning;            if( n='1' or z='1')  then               fsr_cond<='1';	    else 	       fsr_cond<='0';		    end if;        when ltf|ltd=>	    fsr_out<=fsr_in;      -- 	    ASSERT false REPORT "lt" SEVERITY warning;            if( n='1' and z='0') then               fsr_cond<='1';	    else 	       fsr_cond<='0';		    end if;        when gef|ged=>	    fsr_out<=fsr_in;    --   	    ASSERT false REPORT "ge" SEVERITY warning;            if( n='0'or z='1') then               fsr_cond<='1';	    else 	       fsr_cond<='0';		    end if;        when nef|ned=>		    fsr_out<=fsr_in;  --     	    ASSERT false REPORT "ne" SEVERITY warning;            if(  z='0') then               fsr_cond<='1';	    else 	       fsr_cond<='0';		    end if;	when others =>	    fsr_out<=fsr_in;--       	    ASSERT false REPORT "others" SEVERITY warning;	end case;wait until phi2='1';END PROCESS;END fau_behavior;

⌨️ 快捷键说明

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