📄 fp_mult.vhd
字号:
-- 4. Multiply the mantissa using shift and add algorithm temp_product:=X"000000"&mant1; Cout:='0'; -- initialize for each multiplication p_result:=X"000000"; -- initialize for each multiplication FOR i IN mant1'REVERSE_RANGE LOOP p_addend := temp_product(temp_product'HIGH downto MNT_LENGTH); IF mant1(i)='1' THEN bit_add(mant2, p_addend, p_result, Cout); temp_product(temp_product'HIGH downto MNT_LENGTH):=p_result; END IF; shift_right1(Cout, temp_product); sticky_bit:= sticky_bit OR temp_product(MNT_LENGTH-3); Cout:='0'; END LOOP; -- 5. Normalize result and load round and sticky bit IF temp_product(temp_product'HIGH)='0' THEN temp_product:=shift_left1(temp_product); ELSE exp_product:=exp_product+1; sticky_bit:= sticky_bit OR temp_product(MNT_LENGTH-2); END IF; round_bit:= temp_product(MNT_LENGTH-1); -- 6. Round result, check overflow, underflow, denormal(subnormal) results -- and set flags round_result(sign_product, round_bit, sticky_bit, temp_product, exp_product, round_mode); mant_result:= temp_product(temp_product'HIGH-1 downto MNT_LENGTH); --***********up to here the value is correct -- Check overflow, halt operation if true ASSERT NOT(exp_product > MAX_EXP) REPORT "EXPONENT OVERFLOW RESULT FROM MULTIPLICATION, OPERATION HAS NO EFFECT ON OUTPUT!" SEVERITY WARNING; -- Check underflow, halt operation if true ASSERT NOT(exp_product < 0) REPORT "EXPONENT UNDERFLOW RESULT FROM MULTIPLICATION, OPERATION HAS NO EFFECT ON OUTPUT!" SEVERITY WARNING; if(exp_product>MAX_EXP) then fsr_overflow<='1'; end if; if(exp_product<0) then fsr_underflow<='1'; end if; -- overflow or underflow check IF (exp_product<0)or(exp_product>MAX_EXP) THEN over_under_flow:=true; END IF; -- set special flag IF exp_product = MAX_EXP THEN IF mant_result=B"0000000_00000000_00000000" THEN IF sign_product='0' THEN-- pos_inf<='1'; ELSE -- neg_inf<='1'; END IF; ELSE -- Nan <= '1'; END IF; ELSIF exp_product = 0 THEN -- check for denormal number ASSERT NOT(mant_result=B"0000000_00000000_00000000") REPORT "DENORMAL NUMBER RESULT FROM MULTIPLICATION" SEVERITY WARNING; IF mant_result=B"0000000_00000000_00000000" THEN -- zero <='1'; END IF; END IF; ELSE -- 7. Handle special input and set flags --========================================================================= ------------------------------------------ -- special operands operation table | ------------------------------------------ --op1\op2|| Zero | Nan | +Inf | -Inf | --======================================== -- zero || Zero | Nan | Zero | Zero | ------------------------------------------ -- Nan || Nan | Nan | Nan | Nan | ------------------------------------------ -- +Inf || Zero | Nan | +Inf | -Inf | ------------------------------------------ -- -Inf || Zero | Nan | -Inf | +Inf | ------------------------------------------ --========================================================================= IF Nan_flag1 OR Nan_flag2 THEN -- Nan <= '1'; IF Nan_flag1 THEN exp_product :=op1_exp; sign_product:=op1_sign; mant_result :=op1_mant; ELSE exp_product :=op2_exp; sign_product:=op2_sign; mant_result :=op2_mant; END IF; ELSIF zero_flag1 OR zero_flag2 THEN zero <= '1'; exp_product := 0; sign_product:=op1_sign XOR op2_sign; mant_result :=B"00000000000000000000000"; ELSIF inf_flag1 THEN exp_product := op1_exp; sign_product:= op1_sign XOR op2_sign; mant_result := op1_mant;-- IF sign_product='1' THEN neg_inf<='1'; -- ELSE pos_inf<='1'; --END IF; ELSE exp_product := op2_exp; sign_product:= op1_sign XOR op2_sign; mant_result := op2_mant; -- IF sign_product='1' THEN neg_inf<='1'; --ELSE pos_inf<='1'; --END IF; END IF; END IF; -- 8. Put result on the output if no overflow or underflow occurs IF NOT over_under_flow THEN res_sign := sign_product; res_exp := exp_product; res_mant := mant_result; ASSERT false REPORT vector_to_string(mant_result) SEVERITY warning; END IF; int_to_bits(res_exp,temp_exp);R1<= res_sign&temp_exp&res_mant; --neg_res<=res_sign;--wait until phi2='1';when multd=> fsr_out<=fsr_in; fsr_overflow<='0'; fsr_underflow<='0'; dop1:=Op1b & Op1; dop2:=Op2b & Op2; dop1_mant:=dop1(51 downto 0); dop2_mant:=dop2(51 downto 0); dop1_sign:=dop1(63); dop2_sign:=dop2(63); dop1_exp:=bits_to_uint(dop1(62 downto 52)); dop2_exp:=bits_to_uint(dop2(62 downto 52)); -- 1. Initialize the flags, check for special operands and load operands -- zero_flag1:=false; zero_flag2:=false; underflow:=false; overflow :=false; inf_flag1:=false; inf_flag2:=false; Nan_flag1:=false; Nan_flag2:=false; non_special1:=false; -- operand 1 is not special input if true non_special2:=false; -- operand 2 is not special input if true over_under_flow:=false; --flags<="0000"; sticky_bit:='0'; -- initialize sticky bit -- Load oprand1 and set internal flags IF dop1_exp=0 and bits_to_int(dop1_mant)=0 THEN zero_flag1:=true; ELSIF dop1_exp=dMAX_EXP THEN IF bits_to_int(dop1_mant)/=0 THEN Nan_flag1:= true; ELSE inf_flag1:=true; END IF; ELSE non_special1:= true; dsign1 := dop1_sign; dexp1 := dop1_exp; dmant1 := '1'&dop1_mant; END IF; -- Load oprand2 and set internal flags IF dop2_exp=0 and bits_to_int(dop2_mant)=0 THEN zero_flag2:=true; ELSIF dop2_exp=dMAX_EXP THEN IF bits_to_int(dop2_mant)/=0 THEN Nan_flag2:= true; ELSE inf_flag2:=true; END IF; ELSE non_special2:=true; dsign2 := dop2_sign; dexp2 := dop2_exp; dmant2 := '1'&dop2_mant; END IF; -- 2. Check Special operands -- If there are no special input (0, Nan, +/- Infinity) do step 3 through -- step 5; otherwise, skip to step 7 IF non_special1 and non_special2 THEN -- 3. Operate on the exponent and set product sign bit -- Check the product exponent overflow after result normalized in step 5 -- Add two exponent and subtract bias dexp_product:=dexp1+dexp2-1023; -- Set result sign bit IF dsign1=dsign2 THEN dsign_product:='0'; ELSE dsign_product:='1'; END IF; -- 4. Multiply the mantissa using shift and add algorithm dtemp_product:=b"00000000_00000000_00000000_00000000_00000000_00000000_00000"&dmant1; Cout:='0'; -- initialize for each multiplication int_to_bits(0,dp_result); -- initialize for each multiplication FOR i IN dmant1'REVERSE_RANGE LOOP dp_addend := dtemp_product(dtemp_product'HIGH downto dMNT_LENGTH); IF dmant1(i)='1' THEN bit_add(dmant2, dp_addend, dp_result, Cout); dtemp_product(dtemp_product'HIGH downto dMNT_LENGTH):=dp_result; END IF; shift_right1(Cout, dtemp_product); sticky_bit:= sticky_bit OR dtemp_product(dMNT_LENGTH-3); Cout:='0'; END LOOP; -- 5. Normalize result and load round and sticky bit IF dtemp_product(dtemp_product'HIGH)='0' THEN dtemp_product:=shift_left1(dtemp_product); ELSE dexp_product:=dexp_product+1; sticky_bit:= sticky_bit OR temp_product(MNT_LENGTH-2); END IF; round_bit:= dtemp_product(dMNT_LENGTH-1); -- 6. Round result, check overflow, underflow, denormal(subnormal) results -- and set flags dround_result(round_bit, sticky_bit, dtemp_product, dexp_product); dmant_result:= dtemp_product(dtemp_product'HIGH-1 downto dMNT_LENGTH); -- Check overflow, halt operation if true ASSERT NOT(dexp_product > dMAX_EXP) REPORT "EXPONENT OVERFLOW RESULT FROM MULTIPLICATION, OPERATION HAS NO EFFECT ON OUTPUT!" SEVERITY WARNING; -- Check underflow, halt operation if true ASSERT NOT(dexp_product < 0) REPORT "EXPONENT UNDERFLOW RESULT FROM MULTIPLICATION, OPERATION HAS NO EFFECT ON OUTPUT!" SEVERITY WARNING; if(exp_product>dMAX_EXP) then fsr_overflow<='1'; end if; if(exp_product<0) then fsr_underflow<='1'; end if; -- overflow or underflow check IF (dexp_product<0)or(dexp_product>dMAX_EXP) THEN over_under_flow:=true; END IF; -- set special flag IF dexp_product = dMAX_EXP THEN IF dmant_result=B"0000000_00000000_00000000_00000000_00000000_00000000_000000" THEN IF dsign_product='0' THEN-- pos_inf<='1'; ELSE -- neg_inf<='1'; END IF; ELSE -- Nan <= '1'; END IF; ELSIF dexp_product = 0 THEN -- check for denormal number ASSERT NOT(dmant_result=B"0000000_00000000_00000000_00000000_00000000_00000000_000000") REPORT "DENORMAL NUMBER RESULT FROM MULTIPLICATION" SEVERITY WARNING; IF dmant_result=B"0000000_00000000_00000000_00000000_00000000_00000000_000000" THEN -- zero <='1'; END IF; END IF; ELSE -- 7. Handle special input and set flags --========================================================================= ------------------------------------------ -- special operands operation table | ------------------------------------------ --op1\op2|| Zero | Nan | +Inf | -Inf | --======================================== -- zero || Zero | Nan | Zero | Zero | ------------------------------------------ -- Nan || Nan | Nan | Nan | Nan | ------------------------------------------ -- +Inf || Zero | Nan | +Inf | -Inf | ------------------------------------------ -- -Inf || Zero | Nan | -Inf | +Inf | ------------------------------------------ --========================================================================= IF Nan_flag1 OR Nan_flag2 THEN --Nan <= '1'; IF Nan_flag1 THEN dexp_product :=dop1_exp; dsign_product:=dop1_sign; dmant_result :=dop1_mant; ELSE dexp_product :=dop2_exp; dsign_product:=dop2_sign; dmant_result :=dop2_mant; END IF; ELSIF zero_flag1 OR zero_flag2 THEN zero <= '1'; dexp_product := 0; dsign_product:=dop1_sign XOR dop2_sign; dmant_result :=B"0000000000000000000000000000000000000000000000000000"; ELSIF inf_flag1 THEN dexp_product := dop1_exp; dsign_product:= dop1_sign XOR dop2_sign; dmant_result := dop1_mant; -- IF dsign_product='1' THEN neg_inf<='1'; --ELSE pos_inf<='1'; --END IF; ELSE dexp_product := dop2_exp; dsign_product:= dop1_sign XOR dop2_sign; dmant_result := dop2_mant;-- IF dsign_product='1' THEN neg_inf<='1'; -- ELSE pos_inf<='1'; --END IF; END IF; END IF; -- 8. Put result on the output if no overflow or underflow occurs IF NOT over_under_flow THEN dres_sign := dsign_product; dres_exp := dexp_product; dres_mant := dmant_result; END IF; int_to_bits(dres_exp,dtemp_exp);--ASSERT false REPORT vector_to_string(op1_mant) SEVERITY warning;R:=dres_sign&dtemp_exp&dres_mant;R1<=R(31 downto 0);R2<=R(63 downto 32);--neg_res<=R(63);when others=>end case;END process;END fmu_behavior;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -