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

📄 fpu_arch.vhd

📁 使用VHDL语言描述的单精度浮点处理器。源代码来自国外网站。可实现单精度浮点数的加减乘运算。
💻 VHD
📖 第 1 页 / 共 2 页
字号:
        ELSIF fracta_mul(22 DOWNTO 7) = "0000000000000001" THEN  div_opa_ldz_d <= conv_std_logic_vector(16,5);        ELSIF fracta_mul(22 DOWNTO 6) = "00000000000000001" THEN  div_opa_ldz_d <= conv_std_logic_vector(17,5);        ELSIF fracta_mul(22 DOWNTO 5) = "000000000000000001" THEN  div_opa_ldz_d <= conv_std_logic_vector(18,5);        ELSIF fracta_mul(22 DOWNTO 4) = "0000000000000000001" THEN  div_opa_ldz_d <= conv_std_logic_vector(19,5);        ELSIF fracta_mul(22 DOWNTO 3) = "00000000000000000001" THEN  div_opa_ldz_d <= conv_std_logic_vector(20,5);        ELSIF fracta_mul(22 DOWNTO 2) = "000000000000000000001" THEN  div_opa_ldz_d <= conv_std_logic_vector(21,5);        ELSIF fracta_mul(22 DOWNTO 1) = "0000000000000000000001" THEN  div_opa_ldz_d <= conv_std_logic_vector(22,5);        ELSIF fracta_mul(22 DOWNTO 1) = "0000000000000000000000" THEN  div_opa_ldz_d <= conv_std_logic_vector(23,5);        ELSE div_opa_ldz_d <= (OTHERS => 'X');        END IF;END PROCESS;        fdiv_opa <= ((SHL(fracta_mul,div_opa_ldz_d)) &                     "00" & X"000000") WHEN                    ((or_reduce(opa_r(30 DOWNTO 23)))='0') ELSE                    (fracta_mul & "00" & X"000000");        u6 : div_r2 PORT MAP (clk => clk, opa => fdiv_opa, opb => fractb_mul,                              quo => quo,                              remainder => remainder);        remainder_00 <= NOT or_reduce(remainder);                 PROCESS (clk)        BEGIN             IF clk'event AND clk = '1' THEN                div_opa_ldz_r1 <= div_opa_ldz_d;                div_opa_ldz_r2 <= div_opa_ldz_r1;            END IF;        END PROCESS;---------------------------------------------------------------------------- Normalize Result--    PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            CASE fpu_op_r2 IS                 WHEN "000" => exp_r <= exp_fasu;                WHEN "001" => exp_r <= exp_fasu;                WHEN "010" => exp_r <= exp_mul;                WHEN "011" => exp_r <= exp_mul;                WHEN "100" => exp_r <= (others => '0');                WHEN "101" => exp_r <= opa_r1(30 downto 23);                WHEN OTHERS  => exp_r <= (others => '0');            END case;        END IF;    END PROCESS;    fract_div <= quo(49 DOWNTO 2) WHEN (opb_dn = '1') ELSE                 (quo(26 DOWNTO 0) & '0' & X"00000");    PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            opa_r1 <= opa_r(30 DOWNTO 0);            IF fpu_op_r2="101" THEN                IF sign_d = '1' THEN                    fract_i2f <= conv_std_logic_vector(1,48)-(X"000000" &                                    (or_reduce(opa_r1(30 downto 23))) &                                    opa_r1(22 DOWNTO 0))-conv_std_logic_vector(1,48);                ELSE                    fract_i2f <= (X"000000" &                                  (or_reduce(opa_r1(30 downto 23))) &                                  opa_r1(22 DOWNTO 0));                END IF;            ELSE                IF sign_d = '1' THEN                    fract_i2f <= conv_std_logic_vector(1,48) - (opa_r1 & X"0000" & '1');                ELSE                    fract_i2f <= (opa_r1 & '0' & X"0000");                END IF;            END IF;        END IF;    END PROCESS;    PROCESS (fpu_op_r3,fract_out_q,prod,fract_div,fract_i2f)    BEGIN         CASE fpu_op_r3 IS             WHEN "000" => fract_denorm <= (fract_out_q & X"00000");            WHEN "001" => fract_denorm <= (fract_out_q & X"00000");            WHEN "010" => fract_denorm <= prod;            WHEN "011" => fract_denorm <= fract_div;            WHEN "100" => fract_denorm <= fract_i2f;            WHEN "101" => fract_denorm <= fract_i2f;            WHEN OTHERS  => fract_denorm <= (others => '0');        END case;    END PROCESS;    PROCESS (clk, opa_r(31),opas_r1,rmode_r2,sign_d)    BEGIN         IF clk'event AND clk = '1' THEN            opas_r1 <= opa_r(31);            opas_r2 <= opas_r1;            IF rmode_r2="11" THEN                sign <= NOT sign_d;            ELSE                sign <= sign_d;              END IF;        END if;     END PROCESS;    sign_d <= sign_mul WHEN (fpu_op_r2(1) = '1') ELSE sign_fasu;    post_norm_output_zero <= mul_00 or div_00;    u4 : post_norm    PORT MAP (        clk => clk,                 -- System Clock        fpu_op => fpu_op_r3,             -- Floating Point Operation        opas => opas_r2,                 -- OPA Sign        sign => sign,                    -- Sign of the result        rmode => rmode_r3,               -- Rounding mode        fract_in => fract_denorm,        -- Fraction Input        exp_ovf => exp_ovf_r,            -- Exponent Overflow        exp_in => exp_r,                 -- Exponent Input        opa_dn => opa_dn,                -- Operand A Denormalized        opb_dn => opb_dn,                -- Operand A Denormalized        rem_00 => remainder_00,          -- Diveide Remainder is zero        div_opa_ldz => div_opa_ldz_r2,   -- Divide opa leading zeros count        output_zero => post_norm_output_zero,  -- Force output to Zero        fpout => out_d,                    -- Normalized output (un-registered)        ine => ine_d,                    -- Result Inexact output (un-registered)        overflow => overflow_d,          -- Overflow output (un-registered)        underflow => underflow_d,        -- Underflow output (un-registered)        f2i_out_sign => f2i_out_sign     -- F2I Output Sign        );---------------------------------------------------------------------------- FPU Outputs--    PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            fasu_op_r1 <= fasu_op;            fasu_op_r2 <= fasu_op_r1;            IF exp_mul = X"ff" THEN                inf_mul2 <= '1';            ELSE                inf_mul2 <= '0';            END IF;        END IF;    END PROCESS;    -- Force pre-set values for non numerical output    mul_inf <= '1' WHEN ((fpu_op_r3="010") and ((inf_mul_r or inf_mul2)='1') and                         (rmode_r3="00")) else '0';              div_inf <= '1' WHEN ((fpu_op_r3="011") and                         ((opb_00 or opa_inf)='1')) ELSE '0';    mul_00 <= '1' WHEN ((fpu_op_r3="010") and ((opa_00 or opb_00)='1')) ELSE '0';    div_00 <= '1' WHEN ((fpu_op_r3="011") and ((opa_00 or opb_inf)='1')) else '0';    out_fixed <= QNAN_VAL(30 DOWNTO 0) WHEN                  (((qnan_d OR snan_d) OR (ind_d AND NOT fasu_op_r2) OR                    ((NOT fpu_op_r3(2) AND fpu_op_r3(1) AND fpu_op_r3(0)) AND opb_00 AND opa_00) OR                   (((opa_inf AND opb_00) OR (opb_inf AND opa_00 )) AND                    (NOT fpu_op_r3(2) AND fpu_op_r3(1) AND NOT fpu_op_r3(0)))                   )='1')                    ELSE INF_VAL(30 DOWNTO 0);         PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            IF ( ((mul_inf='1') or (div_inf='1') or                  ((inf_d='1') and (fpu_op_r3/="011") and (fpu_op_r3/="101")) or                  (snan_d='1') or (qnan_d='1')) and (fpu_op_r3/="100"))  THEN                fpout(30 DOWNTO 0) <= out_fixed;            ELSE                fpout(30 DOWNTO 0) <= out_d;            END IF;        END IF;    END PROCESS;    out_d_00 <= NOT or_reduce(out_d);    sign_mul_final <= NOT sign_mul_r WHEN                      ((sign_exe_r AND  ((opa_00 AND opb_inf) OR                                      (opb_00 AND opa_inf)))='1')                      ELSE sign_mul_r;    sign_div_final <= NOT sign_mul_r WHEN                      ((sign_exe_r and (opa_inf and opb_inf))='1')                      ELSE (sign_mul_r or (opa_00 and opb_00));    PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            If ((fpu_op_r3="101") and (out_d_00='1')) THEN                fpout(31) <= (f2i_out_sign and not(qnan_d OR snan_d) );            ELSIF ((fpu_op_r3="010") and ((snan_d or qnan_d)='0')) THEN                fpout(31) <= sign_mul_final;            ELSIF ((fpu_op_r3="011") and ((snan_d or qnan_d)='0')) THEN                fpout(31) <= sign_div_final;            ELSIF ((snan_d or qnan_d or ind_d) = '1') THEN                fpout(31) <= nan_sign_d;            ELSIF (output_zero_fasu = '1') THEN                fpout(31) <= result_zero_sign_d;            ELSE                fpout(31) <= sign_fasu_r;            END IF;        END IF;    END PROCESS;-- Exception Outputs    ine_mula <= ((inf_mul_r OR inf_mul2 OR opa_inf OR opb_inf) AND                 (NOT rmode_r3(1) AND rmode_r3(0)) and                  NOT ((opa_inf AND opb_00) OR (opb_inf AND opa_00 )) AND fpu_op_r3(1));    ine_mul <= (ine_mula OR ine_d OR inf_fmul OR out_d_00 OR overflow_d OR underflow_d) AND               NOT opa_00 and NOT opb_00 and NOT (snan_d OR qnan_d OR inf_d);    ine_div <= (ine_d OR  overflow_d OR  underflow_d) AND NOT (opb_00 OR snan_d OR qnan_d OR inf_d);    ine_fasu <= (ine_d OR overflow_d OR underflow_d) AND NOT (snan_d OR qnan_d OR inf_d);    PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            IF fpu_op_r3(2) = '1' THEN                ine <= ine_d;            ELSIF fpu_op_r3(1) = '0' THEN                ine <= ine_fasu;            ELSIF fpu_op_r3(0)='1' THEN                ine <= ine_div;            ELSE               ine <= ine_mul;            END IF;        END IF;    END PROCESS;    overflow_fasu <= overflow_d AND NOT (snan_d OR qnan_d OR inf_d);    overflow_fmul <= NOT inf_d AND                     (inf_mul_r OR inf_mul2 OR overflow_d) AND                     NOT (snan_d OR qnan_d);        overflow_fdiv <= (overflow_d AND NOT (opb_00 OR inf_d OR snan_d OR qnan_d));    PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            underflow_fmul_r <= underflow_fmul_d;            IF fpu_op_r3(2) ='1' THEN                overflow <= '0';            ELSIF fpu_op_r3(1) = '0' THEN                overflow <= overflow_fasu;            ELSIF fpu_op_r3(0) = '1' THEN                overflow <= overflow_fdiv;            ELSE                overflow <= overflow_fmul;                                END IF;        END IF;    END PROCESS;    underflow_fmul1_p1 <= '1' WHEN (out_d(30 DOWNTO 23) = X"00") else '0';    underflow_fmul1_p2 <= '1' WHEN (out_d(22 DOWNTO 0) = ("000" & X"00000")) else '0';     underflow_fmul1_p3 <= '1' WHEN (prod/=conv_std_logic_vector(0,48)) else '0';        underflow_fmul1 <= underflow_fmul_r(0) or                       (underflow_fmul_r(1) and underflow_d ) or                       ((opa_dn or opb_dn) and out_d_00 and (underflow_fmul1_p3) and sign) or                        (underflow_fmul_r(2) AND                         ((underflow_fmul1_p1) or (underflow_fmul1_p2)));    underflow_fasu <= underflow_d AND  NOT (inf_d or snan_d or qnan_d);    underflow_fmul <= underflow_fmul1 AND NOT (snan_d or qnan_d or inf_mul_r);    underflow_fdiv <= underflow_fasu AND NOT opb_00;    PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            IF fpu_op_r3(2) = '1' THEN                underflow <= '0';            ELSIF fpu_op_r3(1) = '0' THEN                underflow <= underflow_fasu;            ELSIF fpu_op_r3(0) = '1' THEN                underflow <= underflow_fdiv;            ELSE                underflow <= underflow_fmul;            END IF;            snan <= snan_d;        END IF;    END PROCESS;-- Status Outputs    PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            IF fpu_op_r3(2)='1' THEN                qnan <= '0';            ELSE                qnan <= snan_d OR qnan_d OR (ind_d AND NOT fasu_op_r2) OR                         (opa_00 AND  opb_00 AND                         (NOT fpu_op_r3(2) AND fpu_op_r3(1) AND fpu_op_r3(0))) OR                         (((opa_inf AND opb_00) OR (opb_inf AND opa_00 )) AND                         (NOT fpu_op_r3(2) AND fpu_op_r3(1) AND NOT fpu_op_r3(0)));                                    END IF;        END IF;    END PROCESS;    inf_fmul <= (((inf_mul_r OR inf_mul2) AND (NOT rmode_r3(1) AND NOT rmode_r3(0)))                 OR opa_inf OR opb_inf) AND                 NOT ((opa_inf AND opb_00) OR (opb_inf AND opa_00)) AND                 (NOT fpu_op_r3(2) AND fpu_op_r3(1) AND NOT fpu_op_r3(0));        PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            IF fpu_op_r3(2) = '1' THEN                inf <= '0';            ELSE                inf <= (NOT (qnan_d OR snan_d) AND                         (((and_reduce(out_d(30 DOWNTO 23))) AND                          NOT (or_reduce(out_d(22 downto 0))) AND                          NOT(opb_00 AND NOT fpu_op_r3(2) AND fpu_op_r3(1) AND fpu_op_r3(0))) OR                          (inf_d AND NOT (ind_d AND NOT fasu_op_r2) AND NOT fpu_op_r3(1)) OR                         inf_fmul OR                          (NOT opa_00 AND  opb_00 AND                          NOT fpu_op_r3(2) AND fpu_op_r3(1) AND fpu_op_r3(0)) or                         (NOT fpu_op_r3(2) AND fpu_op_r3(1) AND fpu_op_r3(0) AND                          opa_inf AND  NOT opb_inf)                         )                               );            END IF;        END IF;    END PROCESS;    output_zero_fasu <= out_d_00 AND NOT (inf_d OR snan_d OR qnan_d);    output_zero_fdiv <= (div_00 OR (out_d_00 AND NOT opb_00)) AND NOT (opa_inf AND opb_inf) AND                        NOT (opa_00 AND opb_00) AND NOT (qnan_d OR snan_d);    output_zero_fmul <= (out_d_00 OR opa_00 OR opb_00) AND                         NOT (inf_mul_r OR inf_mul2 OR opa_inf OR opb_inf OR                             snan_d OR qnan_d) AND                         NOT (opa_inf AND opb_00) AND NOT (opb_inf AND opa_00);        PROCESS (clk)    BEGIN         IF clk'event AND clk = '1' THEN            IF fpu_op_r3="101" THEN                zero <= out_d_00 and NOT (snan_d or qnan_d);            ELSIF fpu_op_r3="011" THEN                zero <= output_zero_fdiv;            ELSIF fpu_op_r3="010" THEN                zero <= output_zero_fmul;            ELSE                zero <= output_zero_fasu;            END IF;            IF (opa_nan = '0') AND (fpu_op_r2="011") THEN                opa_nan_r <= '1';            ELSE                opa_nan_r <= '0';            END IF;            div_by_zero <= opa_nan_r AND NOT opa_00 AND NOT opa_inf AND opb_00;        END IF;    END PROCESS;END arch;

⌨️ 快捷键说明

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