OpenCores
URL https://opencores.org/ocsvn/fpu_double/fpu_double/trunk

Subversion Repositories fpu_double

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/tags/arelease/fpu_double.PDF Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
tags/arelease/fpu_double.PDF Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/arelease/fpu_round.vhd =================================================================== --- tags/arelease/fpu_round.vhd (nonexistent) +++ tags/arelease/fpu_round.vhd (revision 4) @@ -0,0 +1,128 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + + LIBRARY ieee; + USE ieee.std_logic_1164.all; + USE ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + use ieee.std_logic_misc.all; + + + ENTITY fpu_round IS + + PORT( + clk, rst, enable : IN std_logic; + round_mode : IN std_logic_vector (1 DOWNTO 0); + sign_term : IN std_logic; + mantissa_term : IN std_logic_vector (55 DOWNTO 0); + exponent_term : IN std_logic_vector (11 DOWNTO 0); + round_out : OUT std_logic_vector (63 DOWNTO 0); + exponent_final : OUT std_logic_vector (11 DOWNTO 0) + ); + + END fpu_round; + + + architecture rtl of fpu_round is + + signal rounding_amount : std_logic_vector(55 downto 0); + signal round_nearest : std_logic; + signal round_to_zero : std_logic; + signal round_to_pos_inf : std_logic; + signal round_to_neg_inf : std_logic; + signal round_nearest_trigger : std_logic; + signal round_to_pos_inf_trigger : std_logic; + signal round_to_neg_inf_trigger : std_logic; + signal round_trigger : std_logic; + signal sum_round : std_logic_vector(55 downto 0); + signal sum_round_overflow : std_logic; + -- will be 0 if no carry, 1 if overflow from the rounding unit + -- overflow from rounding is extremely rare, but possible + signal sum_round_2 : std_logic_vector(55 downto 0); + signal exponent_round : std_logic_vector(11 downto 0); + signal exponent_final_2 : std_logic_vector(11 downto 0); + signal sum_final : std_logic_vector(55 downto 0); + + begin + + rounding_amount <= "00000000000000000000000000000000000000000000000000000100"; + round_nearest <= '1' when (round_mode = "00") else '0'; + round_to_zero <= '1' when (round_mode = "01") else '0'; + round_to_pos_inf <= '1' when (round_mode = "10") else '0'; + round_to_neg_inf <= '1' when (round_mode = "11") else '0'; + round_nearest_trigger <= '1' when round_nearest = '1' and mantissa_term(1) = '1' + else '0'; + round_to_pos_inf_trigger <= '1' when sign_term = '0' and + or_reduce(mantissa_term(1 downto 0)) = '1' else '0'; + round_to_neg_inf_trigger <= '1' when sign_term = '1' and + or_reduce(mantissa_term(1 downto 0)) = '1' else '0'; + round_trigger <= '1' when ( round_nearest = '1' and round_nearest_trigger = '1') + or (round_to_pos_inf = '1' and round_to_pos_inf_trigger = '1') + or (round_to_neg_inf = '1' and round_to_neg_inf_trigger = '1') + else '0'; + sum_round_overflow <= sum_round(55); + + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + sum_round <= (others =>'0'); + sum_round_2 <= (others =>'0'); + exponent_round <= (others =>'0'); + sum_final <= (others =>'0'); + exponent_final <= (others =>'0'); + exponent_final_2 <= (others =>'0'); + round_out <= (others =>'0'); + else + sum_round <= rounding_amount + mantissa_term; + if sum_round_overflow = '1' then + sum_round_2 <= shr(sum_round, conv_std_logic_vector('1', 56)); + exponent_round <= exponent_term + "000000000001"; + else + sum_round_2 <= sum_round; + exponent_round <= exponent_term; + end if; + if round_trigger = '1' then + sum_final <= sum_round_2; + exponent_final_2 <= exponent_round; + else + sum_final <= mantissa_term; + exponent_final_2 <= exponent_term; + end if; + exponent_final <= exponent_final_2; + round_out <= sign_term & exponent_final_2(10 downto 0) & sum_final(53 downto 2); + end if; + end process; + end rtl; \ No newline at end of file Index: tags/arelease/fpu_add.vhd =================================================================== --- tags/arelease/fpu_add.vhd (nonexistent) +++ tags/arelease/fpu_add.vhd (revision 4) @@ -0,0 +1,191 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; +USE ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_misc.all; + + +ENTITY fpu_add IS + + PORT( + clk : IN std_logic; + rst : IN std_logic; + enable : IN std_logic; + opa : IN std_logic_vector (63 DOWNTO 0); + opb : IN std_logic_vector (63 DOWNTO 0); + sign : OUT std_logic; + sum_3 : OUT std_logic_vector (55 DOWNTO 0); + exponent_2 : OUT std_logic_vector (10 DOWNTO 0) + ); + +-- Declarations + +END fpu_add; + +architecture rtl of fpu_add is + + +signal exponent_a : std_logic_vector(10 downto 0); +signal exponent_b : std_logic_vector(10 downto 0); +signal mantissa_a : std_logic_vector(51 downto 0); +signal mantissa_b : std_logic_vector(51 downto 0); +signal exponent_small : std_logic_vector(10 downto 0); +signal exponent_large : std_logic_vector(10 downto 0); +signal mantissa_small : std_logic_vector(51 downto 0); +signal mantissa_large : std_logic_vector(51 downto 0); +signal small_is_denorm : std_logic; +signal large_is_denorm : std_logic; +signal large_norm_small_denorm : std_logic_vector(10 downto 0); +signal exponent_diff : std_logic_vector(10 downto 0); +signal large_add : std_logic_vector(55 downto 0); +signal small_add : std_logic_vector(55 downto 0); +signal small_shift : std_logic_vector(55 downto 0); +signal small_shift_nonzero : std_logic; +signal small_is_nonzero : std_logic; +signal small_fraction_enable : std_logic; +signal small_shift_2 : std_logic_vector(55 downto 0); +signal small_shift_3 : std_logic_vector(55 downto 0); +signal sum : std_logic_vector(55 downto 0); +signal sum_2 : std_logic_vector(55 downto 0); +signal sum_overflow : std_logic; +signal exponent : std_logic_vector(10 downto 0); +signal sum_leading_one : std_logic; +signal denorm_to_norm : std_logic; + +signal exp_diff_int : integer; + +begin + +small_shift_nonzero <= or_reduce(small_shift); +small_is_nonzero <= or_reduce(exponent_small) or or_reduce(mantissa_small(51 downto 0)); +small_fraction_enable <= small_is_nonzero and not small_shift_nonzero; +small_shift_2 <= "00000000000000000000000000000000000000000000000000000001"; +sum_overflow <= sum(55); -- sum[55] will be 0 if there was no carry from adding the 2 numbers +sum_leading_one <= sum_2(54); -- this is where the leading one resides, unless denorm +--exp_diff_int <= to_integer(exponent_diff); + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + sign <= '0'; + exponent_a <= (others =>'0'); + exponent_b <= (others =>'0'); + mantissa_a <= (others =>'0'); + mantissa_b <= (others =>'0'); + exponent_small <= (others =>'0'); + exponent_large <= (others =>'0'); + mantissa_small <= (others =>'0'); + mantissa_large <= (others =>'0'); + small_is_denorm <= '0'; + large_is_denorm <= '0'; + large_norm_small_denorm <= (others =>'0'); + exponent_diff <= (others =>'0'); + large_add <= (others =>'0'); + small_add <= (others =>'0'); + small_shift <= (others =>'0'); + small_shift_3 <= (others =>'0'); + sum <= (others =>'0'); + sum_2 <= (others =>'0'); + sum_3 <= (others =>'0'); + exponent <= (others =>'0'); + denorm_to_norm <= '0'; + exponent_2 <= (others =>'0'); + elsif (enable = '1') then + sign <= opa(63); + exponent_a <= opa(62 downto 52); + exponent_b <= opb(62 downto 52); + mantissa_a <= opa(51 downto 0); + mantissa_b <= opb(51 downto 0); + if (exponent_a > exponent_b) then + exponent_small <= exponent_b; + exponent_large <= exponent_a; + mantissa_small <= mantissa_b; + mantissa_large <= mantissa_a; + else + exponent_small <= exponent_a; + exponent_large <= exponent_b; + mantissa_small <= mantissa_a; + mantissa_large <= mantissa_b; + end if; + if (exponent_small > 0) then + small_is_denorm <= '0'; + else + small_is_denorm <= '1'; + end if; + if (exponent_large > 0) then + large_is_denorm <= '0'; + else + large_is_denorm <= '1'; + end if; + if (small_is_denorm = '1' and large_is_denorm = '0') then + large_norm_small_denorm <= "00000000001"; + else + large_norm_small_denorm <= "00000000000"; + end if; + exponent_diff <= exponent_large - exponent_small - large_norm_small_denorm; + large_add <= '0' & not large_is_denorm & mantissa_large & "00"; + small_add <= '0' & not small_is_denorm & mantissa_small & "00"; + small_shift <= shr(small_add, exponent_diff); + if (small_fraction_enable = '1') then + small_shift_3 <= small_shift_2; + else + small_shift_3 <= small_shift; + end if; + sum <= large_add + small_shift_3; + if (sum_overflow = '1') then + sum_2 <= shr(sum, conv_std_logic_vector('1', 56)); + else + sum_2 <= sum; + end if; + sum_3 <= sum_2; + if (sum_overflow = '1') then + exponent <= exponent_large + 1; + else + exponent <= exponent_large; + end if; + denorm_to_norm <= sum_leading_one and large_is_denorm; + if (denorm_to_norm = '1') then + exponent_2 <= exponent + 1; + else + exponent_2 <= exponent; + end if; + end if; + end process; + + +end rtl; \ No newline at end of file Index: tags/arelease/fpu_sub.vhd =================================================================== --- tags/arelease/fpu_sub.vhd (nonexistent) +++ tags/arelease/fpu_sub.vhd (revision 4) @@ -0,0 +1,234 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + + LIBRARY ieee; + USE ieee.std_logic_1164.all; + USE ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + use ieee.std_logic_misc.all; + library work; + use work.fpupack.all; + + ENTITY fpu_sub IS + + PORT( + clk : IN std_logic; + rst : IN std_logic; + enable : IN std_logic; + opa : IN std_logic_vector (63 DOWNTO 0); + opb : IN std_logic_vector (63 DOWNTO 0); + fpu_op : IN std_logic_vector (2 DOWNTO 0); + sign : OUT std_logic; + diff_2 : OUT std_logic_vector (55 DOWNTO 0); + exponent_2 : OUT std_logic_vector (10 DOWNTO 0) + ); + + -- Declarations + + END fpu_sub; + + + architecture rtl of fpu_sub is + + signal fpu_op_add : std_logic; + signal diff_shift : std_logic_vector(5 downto 0); + signal diff_shift_2 : std_logic_vector(5 downto 0); + signal exponent_a : std_logic_vector(10 downto 0); + signal exponent_b : std_logic_vector(10 downto 0); + signal mantissa_a : std_logic_vector(51 downto 0); + signal mantissa_b : std_logic_vector(51 downto 0); + signal expa_gt_expb : std_logic; + signal expa_et_expb : std_logic; + signal mana_gtet_manb : std_logic; + signal a_gtet_b : std_logic; + signal exponent_small : std_logic_vector(10 downto 0); + signal exponent_large : std_logic_vector(10 downto 0); + signal mantissa_small : std_logic_vector(51 downto 0); + signal mantissa_large : std_logic_vector(51 downto 0); + signal small_is_denorm : std_logic; + signal large_is_denorm : std_logic; + signal large_norm_small_denorm : std_logic; + signal small_is_nonzero : std_logic; + signal exponent_diff : std_logic_vector(10 downto 0); + signal minuend : std_logic_vector(54 downto 0); + signal subtrahend : std_logic_vector(54 downto 0); + signal subtra_shift : std_logic_vector(54 downto 0); + signal subtra_shift_nonzero : std_logic; + signal subtra_fraction_enable : std_logic; + signal subtra_shift_2 : std_logic_vector(54 downto 0); + signal subtra_shift_3 : std_logic_vector(54 downto 0); + signal diff : std_logic_vector(54 downto 0); + signal diffshift_gt_exponent : std_logic; + signal diffshift_et_55 : std_logic; -- when the difference = 0 + signal diff_1 : std_logic_vector(54 downto 0); + signal exponent : std_logic_vector(10 downto 0); + signal in_norm_out_denorm : std_logic; + + begin + + subtra_shift_nonzero <= or_reduce(subtra_shift); + subtra_fraction_enable <= small_is_nonzero and not subtra_shift_nonzero; + subtra_shift_2 <= "0000000000000000000000000000000000000000000000000000001"; + in_norm_out_denorm <= or_reduce(exponent_large) and not or_reduce(exponent); + fpu_op_add <= '1' when fpu_op = "000" else '0'; + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + exponent_a <= (others =>'0'); + exponent_b <= (others =>'0'); + mantissa_a <= (others =>'0'); + mantissa_b <= (others =>'0'); + expa_gt_expb <= '0'; + expa_et_expb <= '0'; + mana_gtet_manb <= '0'; + a_gtet_b <= '0'; + exponent_small <= (others =>'0'); + exponent_large <= (others =>'0'); + mantissa_small <= (others =>'0'); + mantissa_large <= (others =>'0'); + sign <= '0'; + small_is_denorm <= '0'; + large_is_denorm <= '0'; + large_norm_small_denorm <= '0'; + small_is_nonzero <= '0'; + exponent_diff <= (others =>'0'); + minuend <= (others =>'0'); + subtrahend <= (others =>'0'); + subtra_shift <= (others =>'0'); + subtra_shift_3 <= (others =>'0'); + diff_shift_2 <= (others =>'0'); + diff <= (others =>'0'); + diffshift_gt_exponent <= '0'; + diffshift_et_55 <= '0'; + diff_1 <= (others =>'0'); + exponent <= (others =>'0'); + exponent_2 <= (others =>'0'); + diff_2 <= (others =>'0'); + elsif (enable = '1') then + exponent_a <= opa(62 downto 52); + exponent_b <= opb(62 downto 52); + mantissa_a <= opa(51 downto 0); + mantissa_b <= opb(51 downto 0); + if (exponent_a > exponent_b) then + expa_gt_expb <= '1'; + else + expa_gt_expb <= '0'; + end if; + if (exponent_a = exponent_b) then + expa_et_expb <= '1'; + else + expa_et_expb <= '0'; + end if; + if (mantissa_a >= mantissa_b) then + mana_gtet_manb <= '1'; + else + mana_gtet_manb <= '0'; + end if; + a_gtet_b <= expa_gt_expb or (expa_et_expb and mana_gtet_manb); + if (a_gtet_b = '1') then + exponent_small <= exponent_b; + exponent_large <= exponent_a; + mantissa_small <= mantissa_b; + mantissa_large <= mantissa_a; + sign <= opa(63); + else + exponent_small <= exponent_a; + exponent_large <= exponent_b; + mantissa_small <= mantissa_a; + mantissa_large <= mantissa_b; + sign <= (not opb(63)) xor fpu_op_add; + end if; + if (exponent_small > 0) then + small_is_denorm <= '0'; + else + small_is_denorm <= '1'; + end if; + if (exponent_large > 0) then + large_is_denorm <= '0'; + else + large_is_denorm <= '1'; + end if; + if (small_is_denorm = '1' and large_is_denorm = '0') then + large_norm_small_denorm <= '1'; + else + large_norm_small_denorm <= '0'; + end if; + small_is_nonzero <= (not small_is_denorm) or or_reduce(mantissa_small); + exponent_diff <= exponent_large - exponent_small - large_norm_small_denorm; + minuend <= not large_is_denorm & mantissa_large & "00"; + subtrahend <= not small_is_denorm & mantissa_small & "00"; + subtra_shift <= shr(subtrahend, exponent_diff); + if (subtra_fraction_enable = '1') then + subtra_shift_3 <= subtra_shift_2; + else + subtra_shift_3 <= subtra_shift; + end if; + diff <= minuend - subtra_shift_3; + diff_shift <= count_l_zeros(diff(54 downto 0)); + diff_shift_2 <= diff_shift; + if (diff_shift_2 > exponent_large) then + diffshift_gt_exponent <= '1'; + else + diffshift_gt_exponent <= '0'; + end if; + if (diff_shift_2 = "0110111") then -- 55 + diffshift_et_55 <= '1'; + else + diffshift_et_55 <= '0'; + end if; + if (diffshift_gt_exponent = '1') then + diff_1 <= shl(diff, exponent_large); + exponent <= "00000000000"; + else + diff_1 <= shl(diff, diff_shift_2); + exponent <= exponent_large - diff_shift_2; + end if; + if (diffshift_et_55 = '1') then + exponent_2 <= "00000000000"; + else + exponent_2 <= exponent; + end if; + if (in_norm_out_denorm = '1') then + diff_2 <= '0' & shr(diff_1,conv_std_logic_vector('1', 55)); + else + diff_2 <= '0' & diff_1; + end if; + end if; + end process; + + end rtl; + + Index: tags/arelease/fpu_double.vhd =================================================================== --- tags/arelease/fpu_double.vhd (nonexistent) +++ tags/arelease/fpu_double.vhd (revision 4) @@ -0,0 +1,349 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + + LIBRARY ieee; + USE ieee.std_logic_1164.all; + USE ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + use ieee.std_logic_misc.all; + library work; + use work.comppack.all; + use work.fpupack.all; + + ENTITY fpu_double IS + + PORT( + clk, rst, enable : IN std_logic; + rmode : IN std_logic_vector (1 DOWNTO 0); + fpu_op : IN std_logic_vector (2 DOWNTO 0); + opa, opb : IN std_logic_vector (63 DOWNTO 0); + out_fp: OUT std_logic_vector (63 DOWNTO 0); + ready, underflow, overflow, inexact : OUT std_logic; + exception, invalid : OUT std_logic + ); + + END fpu_double; + +-- FPU Operations (fpu_op): +--======================== +-- 0 = add +-- 1 = sub +-- 2 = mul +-- 3 = div + +--Rounding Modes (rmode): +--======================= +-- 0 = round_nearest_even +-- 1 = round_to_zero +-- 2 = round_up +-- 3 = round_down + + architecture rtl of fpu_double is + + signal opa_reg : std_logic_vector(63 downto 0); + signal opb_reg : std_logic_vector(63 downto 0); + signal fpu_op_reg : std_logic_vector(2 downto 0); + signal rmode_reg : std_logic_vector(1 downto 0); + signal enable_reg : std_logic; + signal enable_reg_1 : std_logic; -- high for one clock cycle + signal enable_reg_2 : std_logic; -- high for one clock cycle + signal enable_reg_3 : std_logic; -- high for two clock cycles + signal op_enable : std_logic; + signal count_cycles : std_logic_vector(6 downto 0); + signal count_ready : std_logic_vector(6 downto 0); + signal count_busy : std_logic; + signal ready_0 : std_logic; + signal ready_1 : std_logic; + signal underflow_0 : std_logic; + signal overflow_0 : std_logic; + signal inexact_0 : std_logic; + signal exception_0 : std_logic; + signal invalid_0 : std_logic; + + signal add_enable_0 : std_logic; + signal add_enable_1 : std_logic; + signal add_enable : std_logic; + signal sub_enable_0 : std_logic; + signal sub_enable_1 : std_logic; + signal sub_enable : std_logic; + signal mul_enable : std_logic; + signal div_enable : std_logic; + signal except_enable : std_logic; + signal sum_out : std_logic_vector(55 downto 0); + signal diff_out : std_logic_vector(55 downto 0); + signal addsub_out : std_logic_vector(55 downto 0); + signal mul_out : std_logic_vector(55 downto 0); + signal div_out : std_logic_vector(55 downto 0); + signal mantissa_round : std_logic_vector(55 downto 0); + signal exp_add_out : std_logic_vector(10 downto 0); + signal exp_sub_out : std_logic_vector(10 downto 0); + signal exp_mul_out : std_logic_vector(11 downto 0); + signal exp_div_out : std_logic_vector(11 downto 0); + signal exponent_round : std_logic_vector(11 downto 0); + signal exp_addsub : std_logic_vector(11 downto 0); + signal exponent_post_round : std_logic_vector(11 downto 0); + signal add_sign : std_logic; + signal sub_sign : std_logic; + signal mul_sign : std_logic; + signal div_sign : std_logic; + signal addsub_sign : std_logic; + signal sign_round : std_logic; + signal out_round : std_logic_vector(63 downto 0); + signal out_except : std_logic_vector(63 downto 0); + + begin + + i_fpu_add: fpu_add + port map ( + clk => clk , rst => rst , enable => add_enable , opa => opa_reg , opb => opb_reg , + sign => add_sign , sum_3 => sum_out , exponent_2 => exp_add_out); + + i_fpu_sub: fpu_sub + port map ( + clk => clk , rst => rst , enable => sub_enable , opa => opa_reg , opb => opb_reg , + fpu_op => fpu_op_reg , sign => sub_sign , diff_2 => diff_out , + exponent_2 => exp_sub_out); + + i_fpu_mul: fpu_mul + port map ( + clk => clk , rst => rst , enable => mul_enable , opa => opa_reg , opb => opb_reg , + sign => mul_sign , product_7 => mul_out , exponent_5 => exp_mul_out); + + i_fpu_div: fpu_div + port map ( + clk => clk , rst => rst , enable => div_enable , opa => opa_reg , opb => opb_reg , + sign => div_sign , mantissa_7 => div_out , exponent_out => exp_div_out); + + i_fpu_round: fpu_round + port map ( + clk => clk , rst => rst , enable => op_enable , round_mode => rmode_reg , + sign_term => sign_round , mantissa_term => mantissa_round , exponent_term => exponent_round , + round_out => out_round , exponent_final => exponent_post_round); + + i_fpu_exceptions: fpu_exceptions + port map ( + clk => clk , rst => rst , enable => op_enable , rmode => rmode_reg , + opa => opa_reg , opb => opb_reg , + in_except => out_round , exponent_in => exponent_post_round , + mantissa_in => mantissa_round(1 downto 0) , fpu_op => fpu_op_reg , out_fp => out_except , + ex_enable => except_enable , underflow => underflow_0 , overflow => overflow_0 , + inexact => inexact_0 , exception => exception_0 , invalid => invalid_0); + + count_busy <= '1' when (count_ready <= count_cycles) else '0'; + + add_enable_0 <= '1' when fpu_op_reg = "000" and (opa_reg(63) xor opb_reg(63)) = '0' else '0'; + add_enable_1 <= '1' when (fpu_op_reg = "001") and (opa_reg(63) xor opb_reg(63)) = '1' else '0'; + sub_enable_0 <= '1' when (fpu_op_reg = "000") and (opa_reg(63) xor opb_reg(63)) = '1' else '0'; + sub_enable_1 <= '1' when (fpu_op_reg = "001") and (opa_reg(63) xor opb_reg(63)) = '0' else '0'; + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + mantissa_round <= (others =>'0'); + exponent_round <= (others =>'0'); + sign_round <= '0'; + count_cycles <= (others =>'0'); + else + if (fpu_op_reg = "000") then -- add + mantissa_round <= addsub_out; + exponent_round <= exp_addsub; + sign_round <= addsub_sign; + count_cycles <= "0010100"; -- 20 + elsif (fpu_op_reg = "001") then -- subtract + mantissa_round <= addsub_out; + exponent_round <= exp_addsub; + sign_round <= addsub_sign; + count_cycles <= "0010101"; -- 21 + elsif (fpu_op_reg = "010") then + mantissa_round <= mul_out; + exponent_round <= exp_mul_out; + sign_round <= mul_sign; + count_cycles <= "0011000"; -- 24 + elsif (fpu_op_reg = "011") then + mantissa_round <= div_out; + exponent_round <= exp_div_out; + sign_round <= div_sign; + count_cycles <= "1000111"; -- 71 + else + mantissa_round <= (others =>'0'); + exponent_round <= (others =>'0'); + sign_round <= '0'; + count_cycles <= (others =>'0'); + end if; + end if; + end process; + + + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + add_enable <= '0'; + sub_enable <= '0'; + mul_enable <= '0'; + div_enable <= '0'; + addsub_out <= (others =>'0'); + addsub_sign <= '0'; + exp_addsub <= (others =>'0'); + else + if ((add_enable_0 = '1' or add_enable_1 = '1') and op_enable= '1') then + add_enable <= '1'; + else + add_enable <= '0'; + end if; + if ((sub_enable_0 = '1' or sub_enable_1 = '1') and op_enable = '1') then + sub_enable <= '1'; + else + sub_enable <= '0'; + end if; + if fpu_op_reg = "010" and op_enable = '1' then + mul_enable <= '1'; + else + mul_enable <= '0'; + end if; + if fpu_op_reg = "011" and op_enable = '1' and enable_reg_3 = '1' then + div_enable <= '1'; + else + div_enable <= '0'; + end if; -- div_enable needs to be high for two clock cycles + if add_enable = '1' then + addsub_out <= sum_out; + addsub_sign <= add_sign; + exp_addsub <= '0' & exp_add_out; + else + addsub_out <= diff_out; + addsub_sign <= sub_sign; + exp_addsub <= '0' & exp_sub_out; + end if; + end if; + end process; + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + count_ready <= (others =>'0'); + elsif (enable_reg_1 = '1') then + count_ready <= (others =>'0'); + elsif (count_busy = '1') then + count_ready <= count_ready + "0000001"; + end if; + end process; + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + enable_reg <= '0'; + enable_reg_1 <= '0'; + enable_reg_2 <= '0'; + enable_reg_3 <= '0'; + else + enable_reg <= enable; + if enable = '1' and enable_reg = '0' then + enable_reg_1 <= '1'; + else + enable_reg_1 <= '0'; + end if; + enable_reg_2 <= enable_reg_1; + if enable_reg_1 = '1' or enable_reg_2 = '1' then + enable_reg_3 <= '1'; + else + enable_reg_3 <= '0'; + end if; + end if; + end process; + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + opa_reg <= (others =>'0'); + opb_reg <= (others =>'0'); + fpu_op_reg <= (others =>'0'); + rmode_reg <= (others =>'0'); + op_enable <= '0'; + elsif (enable_reg_1 = '1') then + opa_reg <= opa; + opb_reg <= opb; + fpu_op_reg <= fpu_op; + rmode_reg <= rmode; + op_enable <= '1'; + end if; + end process; + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + ready_0 <= '0'; + ready_1 <= '0'; + ready <= '0'; + elsif (enable_reg_1 = '1') then + ready_0 <= '0'; + ready_1 <= '0'; + ready <= '0'; + else + ready_0 <= not count_busy; + ready_1 <= ready_0; + ready <= ready_1; + end if; + end process; + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + underflow <= '0'; + overflow <= '0'; + inexact <= '0'; + exception <= '0'; + invalid <= '0'; + out_fp <= (others =>'0'); + elsif (ready_1 = '1') then + underflow <= underflow_0; + overflow <= overflow_0; + inexact <= inexact_0; + exception <= exception_0; + invalid <= invalid_0; + if except_enable = '1' then + out_fp <= out_except; + else + out_fp <= out_round; + end if; + end if; + end process; + end rtl; Index: tags/arelease/fpu_mul.vhd =================================================================== --- tags/arelease/fpu_mul.vhd (nonexistent) +++ tags/arelease/fpu_mul.vhd (revision 4) @@ -0,0 +1,267 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + + LIBRARY ieee; + USE ieee.std_logic_1164.all; + USE ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + use ieee.std_logic_misc.all; + library work; + use work.fpupack.all; + + ENTITY fpu_mul IS + + PORT( + clk : IN std_logic; + rst : IN std_logic; + enable : IN std_logic; + opa : IN std_logic_vector (63 DOWNTO 0); + opb : IN std_logic_vector (63 DOWNTO 0); + sign : OUT std_logic; + product_7 : OUT std_logic_vector (55 DOWNTO 0); + exponent_5 : OUT std_logic_vector (11 DOWNTO 0) + ); + + END fpu_mul; + + + architecture rtl of fpu_mul is + + signal product_shift : std_logic_vector(5 downto 0); + signal product_shift_2 : std_logic_vector(5 downto 0); + signal mantissa_a : std_logic_vector(51 downto 0); + signal mantissa_b : std_logic_vector(51 downto 0); + signal exponent_a : std_logic_vector(11 downto 0); + signal exponent_b : std_logic_vector(11 downto 0); + signal a_is_norm : std_logic; + signal b_is_norm : std_logic; + signal a_is_zero : std_logic; + signal b_is_zero : std_logic; + signal in_zero : std_logic; + signal exponent_terms : std_logic_vector(11 downto 0); + signal exponent_gt_expoffset : std_logic; + signal exponent_under : std_logic_vector(11 downto 0); + signal exponent_1 : std_logic_vector(11 downto 0); + signal exponent : std_logic_vector(11 downto 0); + signal exponent_2 : std_logic_vector(11 downto 0); + signal exponent_gt_prodshift : std_logic; + signal exponent_3 : std_logic_vector(11 downto 0); + signal exponent_4 : std_logic_vector(11 downto 0); + signal exponent_et_zero : std_logic; + signal mul_a : std_logic_vector(52 downto 0); + signal mul_b : std_logic_vector(52 downto 0); + signal product_a : std_logic_vector(40 downto 0); + signal product_b : std_logic_vector(40 downto 0); + signal product_c : std_logic_vector(40 downto 0); + signal product_d : std_logic_vector(25 downto 0); + signal product_e : std_logic_vector(33 downto 0); + signal product_f : std_logic_vector(33 downto 0); + signal product_g : std_logic_vector(35 downto 0); + signal product_h : std_logic_vector(28 downto 0); + signal product_i : std_logic_vector(28 downto 0); + signal product_j : std_logic_vector(30 downto 0); + signal sum_0 : std_logic_vector(41 downto 0); + signal sum_1 : std_logic_vector(35 downto 0); + signal sum_2 : std_logic_vector(41 downto 0); + signal sum_3 : std_logic_vector(35 downto 0); + signal sum_4 : std_logic_vector(36 downto 0); + signal sum_5 : std_logic_vector(27 downto 0); + signal sum_6 : std_logic_vector(29 downto 0); + signal sum_7 : std_logic_vector(36 downto 0); + signal sum_8 : std_logic_vector(30 downto 0); + signal product : std_logic_vector(105 downto 0); + signal product_1 : std_logic_vector(105 downto 0); + signal product_2 : std_logic_vector(105 downto 0); + signal product_3 : std_logic_vector(105 downto 0); + signal product_4 : std_logic_vector(105 downto 0); + signal product_5 : std_logic_vector(105 downto 0); + signal product_6 : std_logic_vector(105 downto 0); + signal product_lsb : std_logic; + + begin + product_7 <= '0' & product_6(105 downto 52) & product_lsb; + exponent <= "000000000000"; + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + sign <= '0'; + mantissa_a <= (others =>'0'); + mantissa_b <= (others =>'0'); + exponent_a <= (others =>'0'); + exponent_b <= (others =>'0'); + a_is_norm <= '0'; + b_is_norm <= '0'; + a_is_zero <= '0'; + b_is_zero <= '0'; + in_zero <= '0'; + exponent_terms <= (others =>'0'); + exponent_gt_expoffset <= '0'; + exponent_under <= (others =>'0'); + exponent_1 <= (others =>'0'); + exponent_2 <= (others =>'0'); + exponent_gt_prodshift <= '0'; + exponent_3 <= (others =>'0'); + exponent_4 <= (others =>'0'); + exponent_et_zero <= '0'; + mul_a <= (others =>'0'); + mul_b <= (others =>'0'); + product_a <= (others =>'0'); + product_b <= (others =>'0'); + product_c <= (others =>'0'); + product_d <= (others =>'0'); + product_e <= (others =>'0'); + product_f <= (others =>'0'); + product_g <= (others =>'0'); + product_h <= (others =>'0'); + product_i <= (others =>'0'); + product_j <= (others =>'0'); + sum_0 <= (others =>'0'); + sum_1 <= (others =>'0'); + sum_2 <= (others =>'0'); + sum_3 <= (others =>'0'); + sum_4 <= (others =>'0'); + sum_5 <= (others =>'0'); + sum_6 <= (others =>'0'); + sum_7 <= (others =>'0'); + sum_8 <= (others =>'0'); + product <= (others =>'0'); + product_1 <= (others =>'0'); + product_2 <= (others =>'0'); + product_3 <= (others =>'0'); + product_4 <= (others =>'0'); + product_5 <= (others =>'0'); + product_6 <= (others =>'0'); + product_lsb <= '0'; + exponent_5 <= (others =>'0'); + product_shift <= (others =>'0'); + product_shift_2 <= (others =>'0'); + elsif (enable = '1') then + sign <= opa(63) xor opb(63); + exponent_a <= '0' & opa(62 downto 52); + exponent_b <= '0' & opb(62 downto 52); + mantissa_a <= opa(51 downto 0); + mantissa_b <= opb(51 downto 0); + a_is_norm <= or_reduce(exponent_a); + b_is_norm <= or_reduce(exponent_b); + a_is_zero <= not or_reduce(opa(62 downto 0)); + b_is_zero <= not or_reduce(opb(62 downto 0)); + in_zero <= a_is_zero or b_is_zero; + exponent_terms <= exponent_a + exponent_b + ( "0000000000" & not a_is_norm) + + ("0000000000" & not b_is_norm); + if (exponent_terms > "001111111101") then + exponent_gt_expoffset <= '1'; + else + exponent_gt_expoffset <= '0'; + end if; + exponent_under <= "001111111110" - exponent_terms; + exponent_1 <= exponent_terms - "001111111110"; + if (exponent_gt_expoffset = '1') then + exponent_2 <= exponent_1; + else + exponent_2 <= exponent; + end if; + if (exponent_2 > product_shift_2) then + exponent_gt_prodshift <= '1'; + else + exponent_gt_prodshift <= '0'; + end if; + exponent_3 <= exponent_2 - product_shift_2; + if (exponent_gt_prodshift = '1') then + exponent_4 <= exponent_3; + else + exponent_4 <= exponent; + end if; + if (exponent_4 = "000000000000") then + exponent_et_zero <= '1'; + else + exponent_et_zero <= '0'; + end if; + mul_a <= a_is_norm & mantissa_a; + mul_b <= b_is_norm & mantissa_b; + product_a <= mul_a(23 downto 0) * mul_b(16 downto 0); + product_b <= mul_a(23 downto 0) * mul_b(33 downto 17); + product_c <= mul_a(23 downto 0) * mul_b(50 downto 34); + product_d <= mul_a(23 downto 0) * mul_b(52 downto 51); + product_e <= mul_a(40 downto 24) * mul_b(16 downto 0); + product_f <= mul_a(40 downto 24) * mul_b(33 downto 17); + product_g <= mul_a(40 downto 24) * mul_b(52 downto 34); + product_h <= mul_a(52 downto 41) * mul_b(16 downto 0); + product_i <= mul_a(52 downto 41) * mul_b(33 downto 17); + product_j <= mul_a(52 downto 41) * mul_b(52 downto 34); + sum_0 <= product_a(40 downto 17) + ( '0' & product_b); + sum_1 <= ('0' & sum_0(41 downto 7)) + product_e; + sum_2 <= sum_1(35 downto 10) + ('0' & product_c); + sum_3 <= ( '0' & sum_2(41 downto 7)) + product_h; + sum_4 <= ( '0' & sum_3) + product_f; + sum_5 <= ('0' & sum_4(36 downto 10)) + product_d; + sum_6 <= sum_5(27 downto 7) + ('0' & product_i); + sum_7 <= sum_6 + ('0' & product_g); + sum_8 <= sum_7(36 downto 17) + product_j; + product <= sum_8 & sum_7(16 downto 0) & sum_5(6 downto 0) & sum_4(9 downto 0) & sum_2(6 downto 0) & + sum_1(9 downto 0) & sum_0(6 downto 0) & product_a(16 downto 0); + product_1 <= shr(product, exponent_under); + if (exponent_gt_prodshift = '1') then + product_5 <= product_3; + else + product_5 <= product_4; + end if; + if (exponent_gt_expoffset = '1') then + product_2 <= product; + else + product_2 <= product_1; + end if; + product_3 <= shl(product_2, product_shift_2); + product_4 <= shl(product_2, exponent_2); + if (exponent_gt_prodshift = '1') then + product_5 <= product_3; + else + product_5 <= product_4; + end if; + if (exponent_et_zero = '1') then + product_6 <= shr(product_5, conv_std_logic_vector('1', 106)); + else + product_6 <= product_5; + end if; + product_lsb <= or_reduce(product_6(51 downto 0)); + if (in_zero = '1') then + exponent_5 <= "000000000000"; + else + exponent_5 <= exponent_4; + end if; + product_shift <= count_zeros_mul(product(105 downto 0)); + product_shift_2 <= product_shift; + end if; + end process; + end rtl; \ No newline at end of file Index: tags/arelease/fpu_double_TB.vhd =================================================================== --- tags/arelease/fpu_double_TB.vhd (nonexistent) +++ tags/arelease/fpu_double_TB.vhd (revision 4) @@ -0,0 +1,751 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + +library ieee; +use work.fpupack.all; +use work.comppack.all; +use ieee.std_logic_misc.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_1164.all; + + +entity fpu_double_tb is +end fpu_double_tb; + +architecture TB_ARCHITECTURE of fpu_double_tb is + + component fpu_double + port( + clk : in std_logic; + rst : in std_logic; + enable : in std_logic; + rmode : in std_logic_vector(1 downto 0); + fpu_op : in std_logic_vector(2 downto 0); + opa : in std_logic_vector(63 downto 0); + opb : in std_logic_vector(63 downto 0); + out_fp : out std_logic_vector(63 downto 0); + ready : out std_logic; + underflow : out std_logic; + overflow : out std_logic; + inexact : out std_logic; + exception : out std_logic; + invalid : out std_logic ); + end component; + + signal clk : std_logic; + signal rst : std_logic; + signal enable : std_logic; + signal rmode : std_logic_vector(1 downto 0); + signal fpu_op : std_logic_vector(2 downto 0); + signal opa : std_logic_vector(63 downto 0); + signal opb : std_logic_vector(63 downto 0); + signal out_fp : std_logic_vector(63 downto 0); + + signal ready : std_logic; + signal underflow : std_logic; + signal overflow : std_logic; + signal inexact : std_logic; + signal exception : std_logic; + signal invalid : std_logic; + + signal END_SIM: BOOLEAN:=FALSE; + signal out_fp1 : std_logic_vector(63 downto 0); + + +begin + out_fp1 <= out_fp; + UUT : fpu_double + port map ( + clk => clk, + rst => rst, + enable => enable, + rmode => rmode, + fpu_op => fpu_op, + opa => opa, + opb => opb, + out_fp => out_fp, + ready => ready, + underflow => underflow, + overflow => overflow, + inexact => inexact, + exception => exception, + invalid => invalid + ); + + +STIMULUS: process +begin + + + + rst <= '1'; + wait for 20 ns; + rst <= '0'; +--inputA:4.0000000000e+000 +--inputB:-4.0000000000e+000 +enable <= '1'; +opa <= "0100000000010000000000000000000000000000000000000000000000000000"; +opb <= "1100000000010000000000000000000000000000000000000000000000000000"; +fpu_op <= "000"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:0.000000000000000e+000 +-- out_fp = 0000000000000000 +--inputA:3.0000000000e-312 +--inputB:1.0000000000e-025 +enable <= '1'; +opa <= "0000000000000000000000001000110101100000010101111101110111110010"; +opb <= "0011101010111110111100101101000011110101110110100111110111011001"; +fpu_op <= "011"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:3.000000000000337e-287 +-- out_fp = 047245C02F8B68C5 +--inputA:4.0000000000e-304 +--inputB:2.0000000000e-007 +enable <= '1'; +opa <= "0000000011110001100011100011101110011011001101110100000101101001"; +opb <= "0011111010001010110101111111001010011010101111001010111101001000"; +fpu_op <= "010"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:8.000000000000074e-311 +-- out_fp = 00000EBA09271E89 +--inputA:3.4445600000e+002 +--inputB:3.4445599000e+002 +enable <= '1'; +opa <= "0100000001110101100001110100101111000110101001111110111110011110"; +opb <= "0100000001110101100001110100101110111100001010111001010011011001"; +fpu_op <= "001"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.000000003159585e-005 +-- out_fp = 3EE4F8B58A000000 +--inputA:-8.8899000000e+002 +--inputB:7.8898020000e+002 +enable <= '1'; +opa <= "1100000010001011110001111110101110000101000111101011100001010010"; +opb <= "0100000010001000101001111101011101110011000110001111110001010000"; +fpu_op <= "000"; +rmode <= "11"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-1.000098000000000e+002 +-- out_fp = C05900A0902DE010 +--inputA:4.5600000000e+002 +--inputB:2.3700000000e+001 +enable <= '1'; +opa <= "0100000001111100100000000000000000000000000000000000000000000000"; +opb <= "0100000000110111101100110011001100110011001100110011001100110011"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.924050632911392e+001 +-- out_fp = 40333D91D2A2067B +--inputA:4.9990000000e+003 +--inputB:0.0000000000e+000 +enable <= '1'; +opa <= "0100000010110011100001110000000000000000000000000000000000000000"; +opb <= "0000000000000000000000000000000000000000000000000000000000000000"; +fpu_op <= "010"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:0.000000000000000e+000 +-- out_fp = 0000000000000000 +--inputA:-9.8883300000e+005 +--inputB:4.4444440000e+006 +enable <= '1'; +opa <= "1100000100101110001011010100001000000000000000000000000000000000"; +opb <= "0100000101010000111101000100011100000000000000000000000000000000"; +fpu_op <= "001"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-5.433277000000000e+006 +-- out_fp = C154B9EF40000000 +--inputA:-4.8000000000e-311 +--inputB:4.0000000000e-050 +enable <= '1'; +opa <= "1000000000000000000010001101011000000101011111011101111100011111"; +opb <= "0011010110101101111011100111101001001010110101001011100000011111"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-1.200000000000011e-261 +-- out_fp = 89C2E4AE4EAE705E +--inputA:1.9500000000e-308 +--inputB:1.8800000000e-308 +enable <= '1'; +opa <= "0000000000001110000001011010001000110110111111110101001011001101"; +opb <= "0000000000001101100001001100011001100110111010010000011110011111"; +fpu_op <= "000"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:3.830000000000000e-308 +-- out_fp = 001B8A689DE85A6C +--inputA:-3.0000000000e-309 +--inputB:9.0000000000e+100 +enable <= '1'; +opa <= "1000000000000010001010000100000001010111001110101111100100001100"; +opb <= "0101010011100100100100101110001011001010010001110101101111101101"; +fpu_op <= "010"; +rmode <= "11"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-2.700000000000001e-208 +-- out_fp = 94D630F25FC26702 +--inputA:3.0000000000e-308 +--inputB:2.9900000000e-308 +enable <= '1'; +opa <= "0000000000010101100100101000001101101000010011011011101001110111"; +opb <= "0000000000010101100000000001101011011100110111001101010001001011"; +fpu_op <= "001"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.000000000000046e-310 +-- out_fp = 000012688B70E62C +--inputA:-9.0000000000e-300 +--inputB:5.0000000000e+100 +enable <= '1'; +opa <= "1000000111011000000110111110001110111011010110000001000111000100"; +opb <= "0101010011010110110111000001100001101110111110011111010001011100"; +fpu_op <= "011"; +rmode <= "11"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-4.940656458412465e-324 +-- out_fp = 8000000000000001 +--inputA:4.0000000000e+100 +--inputB:3.0000000000e-090 +enable <= '1'; +opa <= "0101010011010010010010011010110100100101100101001100001101111101"; +opb <= "0010110101011000011100011100011001000110111001011001010110100111"; +fpu_op <= "010"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.200000000000000e+011 +-- out_fp = 423BF08EB0000001 +--inputA:-9.9000000000e-002 +--inputB:4.0220000000e+001 +enable <= '1'; +opa <= "1011111110111001010110000001000001100010010011011101001011110010"; +opb <= "0100000001000100000111000010100011110101110000101000111101011100"; +fpu_op <= "000"; +rmode <= "11"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:4.012100000000000e+001 +-- out_fp = 40440F7CED916872 +--inputA:9.0770000000e+001 +--inputB:-2.0330000000e+001 +enable <= '1'; +opa <= "0100000001010110101100010100011110101110000101000111101011100001"; +opb <= "1100000000110100010101000111101011100001010001111010111000010100"; +fpu_op <= "000"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:7.044000000000000e+001 +-- out_fp = 40519C28F5C28F5C +--inputA:4.9077000000e+002 +--inputB:-3.4434000000e+002 +enable <= '1'; +opa <= "0100000001111110101011000101000111101011100001010001111010111000"; +opb <= "1100000001110101100001010111000010100011110101110000101000111101"; +fpu_op <= "001"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:8.351100000000000e+002 +-- out_fp = 408A18E147AE147B +--inputA:9.0000000000e+034 +--inputB:2.7700000000e+000 +enable <= '1'; +opa <= "0100011100110001010101010101011110110100000110011100010111000010"; +opb <= "0100000000000110001010001111010111000010100011110101110000101001"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:3.249097472924188e+034 +-- out_fp = 471907B705EBEABE +--inputA:3.9999999989e-315 +--inputB:1.0000000000e-002 +enable <= '1'; +opa <= "0000000000000000000000000000000000110000010000011010011100110101"; +opb <= "0011111110000100011110101110000101000111101011100001010001111011"; +fpu_op <= "010"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:4.000000428704504e-317 +-- out_fp = 00000000007B895B +--inputA:-9.0000000000e+003 +--inputB:8.0000000000e+003 +enable <= '1'; +opa <= "1100000011000001100101000000000000000000000000000000000000000000"; +opb <= "0100000010111111010000000000000000000000000000000000000000000000"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-1.125000000000000e+000 +-- out_fp = BFF2000000000000 +--inputA:9.8440000000e+003 +--inputB:0.0000000000e+000 +enable <= '1'; +opa <= "0100000011000011001110100000000000000000000000000000000000000000"; +opb <= "0000000000000000000000000000000000000000000000000000000000000000"; +fpu_op <= "011"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.#INF00000000000e+000 +-- out_fp = 7FF0000000000000 +--inputA:4.4440000000e+002 +--inputB:-8.8800000000e+002 +enable <= '1'; +opa <= "0100000001111011110001100110011001100110011001100110011001100110"; +opb <= "1100000010001011110000000000000000000000000000000000000000000000"; +fpu_op <= "001"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.332400000000000e+003 +-- out_fp = 4094D1999999999A +--inputA:3.0000000000e-309 +--inputB:3.0000000000e+080 +enable <= '1'; +opa <= "0000000000000010001010000100000001010111001110101111100100001100"; +opb <= "0101000010100100001111011011001101111101011101001011110010000111"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:0.000000000000000e+000 +-- out_fp = 0000000000000000 +--inputA:4.9900000000e+002 +--inputB:-3.3000000000e-003 +enable <= '1'; +opa <= "0100000001111111001100000000000000000000000000000000000000000000"; +opb <= "1011111101101011000010001001101000000010011101010010010101000110"; +fpu_op <= "010"; +rmode <= "11"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-1.646700000000000e+000 +-- out_fp = BFFA58E219652BD4 +--inputA:9.0000000000e+034 +--inputB:4.0000000000e+023 +enable <= '1'; +opa <= "0100011100110001010101010101011110110100000110011100010111000010"; +opb <= "0100010011010101001011010000001011000111111000010100101011110110"; +fpu_op <= "000"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:9.000000000040000e+034 +-- out_fp = 47315557B41A1A76 +--inputA:4.0000000000e+080 +--inputB:3.0000000000e-002 +enable <= '1'; +opa <= "0101000010101010111111001110111101010001111100001111101101011111"; +opb <= "0011111110011110101110000101000111101011100001010001111010111000"; +fpu_op <= "000"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:4.000000000000001e+080 +-- out_fp = 50AAFCEF51F0FB60 +--inputA:-5.4770000000e+000 +--inputB:-8.9990000000e+000 +enable <= '1'; +opa <= "1100000000010101111010000111001010110000001000001100010010011100"; +opb <= "1100000000100001111111110111110011101101100100010110100001110011"; +fpu_op <= "011"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:6.086231803533726e-001 +-- out_fp = 3FE379D751E6915E +--inputA:-7.7000000000e+001 +--inputB:-8.8400000000e+001 +enable <= '1'; +opa <= "1100000001010011010000000000000000000000000000000000000000000000"; +opb <= "1100000001010110000110011001100110011001100110011001100110011010"; +fpu_op <= "010"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:6.806800000000001e+003 +-- out_fp = 40BA96CCCCCCCCCE +--inputA:4.0000000000e+009 +--inputB:3.0000000000e+008 +enable <= '1'; +opa <= "0100000111101101110011010110010100000000000000000000000000000000"; +opb <= "0100000110110001111000011010001100000000000000000000000000000000"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.333333333333333e+001 +-- out_fp = 402AAAAAAAAAAAAB +--inputA:9.0000000000e-311 +--inputB:8.0000000000e-311 +enable <= '1'; +opa <= "0000000000000000000100001001000101001010010011000000001001011010"; +opb <= "0000000000000000000011101011101000001001001001110001111010001001"; +fpu_op <= "000"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.700000000000010e-310 +-- out_fp = 00001F4B537320E3 +--inputA:1.9999777344e-320 +--inputB:5.0000000000e+099 +enable <= '1'; +opa <= "0000000000000000000000000000000000000000000000000000111111010000"; +opb <= "0101010010100010010010011010110100100101100101001100001101111101"; +fpu_op <= "010"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:9.999888671826831e-221 +-- out_fp = 124212D01E240533 +--inputA:4.4444000000e+004 +--inputB:3.3000000000e+001 +enable <= '1'; +opa <= "0100000011100101101100111000000000000000000000000000000000000000"; +opb <= "0100000001000000100000000000000000000000000000000000000000000000"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.346787878787879e+003 +-- out_fp = 40950B26C9B26C9B +--inputA:9.7730000000e+000 +--inputB:9.7720000000e+000 +enable <= '1'; +opa <= "0100000000100011100010111100011010100111111011111001110110110010"; +opb <= "0100000000100011100010110100001110010101100000010000011000100101"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.000102333196889e+000 +-- out_fp = 3FF0006B4DDBBE31 +--inputA:8.3345700000e+003 +--inputB:1.0000000000e+000 +enable <= '1'; +opa <= "0100000011000000010001110100100011110101110000101000111101011100"; +opb <= "0011111111110000000000000000000000000000000000000000000000000000"; +fpu_op <= "010"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:8.334570000000000e+003 +-- out_fp = 40C04748F5C28F5C +--inputA:-1.0000000000e+000 +--inputB:5.8990000000e+003 +enable <= '1'; +opa <= "1011111111110000000000000000000000000000000000000000000000000000"; +opb <= "0100000010110111000010110000000000000000000000000000000000000000"; +fpu_op <= "010"; +rmode <= "11"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-5.899000000000000e+003 +-- out_fp = C0B70B0000000000 +--inputA:6.1000000000e+000 +--inputB:-6.0990000000e+000 +enable <= '1'; +opa <= "0100000000011000011001100110011001100110011001100110011001100110"; +opb <= "1100000000011000011001010110000001000001100010010011011101001100"; +fpu_op <= "000"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:9.999999999994458e-004 +-- out_fp = 3F50624DD2F1A000 +--inputA:3.0000000000e-300 +--inputB:3.0000000000e-015 +enable <= '1'; +opa <= "0000000111000000000100101001011111010010001110101011011010000011"; +opb <= "0011110011101011000001011000011101101110010110110000000100100000"; +fpu_op <= "010"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:9.000000001157124e-315 +-- out_fp = 000000006C93B838 +--inputA:-9.0000000000e+088 +--inputB:4.0000000000e+084 +enable <= '1'; +opa <= "1101001001100110100111110000000010010101111101001101000000000000"; +opb <= "0101000110000000011110001110000100010001110000110101010101101101"; +fpu_op <= "000"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-8.999600000000000e+088 +-- out_fp = D2669EBEB27088F3 +--inputA:6.6210000000e+001 +--inputB:6.9892000000e+001 +enable <= '1'; +opa <= "0100000001010000100011010111000010100011110101110000101000111101"; +opb <= "0100000001010001011110010001011010000111001010110000001000001100"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:9.473187203113375e-001 +-- out_fp = 3FEE506F59540645 +--inputA:-5.0000000000e-309 +--inputB:4.0000000000e-310 +enable <= '1'; +opa <= "1000000000000011100110000110101100111100000011001111010001101001"; +opb <= "0000000000000000010010011010001000101101110000111001100010101100"; +fpu_op <= "000"; +rmode <= "11"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-4.600000000000001e-309 +-- out_fp = 80034EC90E495BBD +--inputA:8.8000000000e+001 +--inputB:0.0000000000e+000 +enable <= '1'; +opa <= "0100000001010110000000000000000000000000000000000000000000000000"; +opb <= "0000000000000000000000000000000000000000000000000000000000000000"; +fpu_op <= "011"; +rmode <= "01"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.#INF00000000000e+000 +-- out_fp = 7FEFFFFFFFFFFFFF +--inputA:4.5570000000e+002 +--inputB:3.4229100000e+003 +enable <= '1'; +opa <= "0100000001111100011110110011001100110011001100110011001100110011"; +opb <= "0100000010101010101111011101000111101011100001010001111010111000"; +fpu_op <= "000"; +rmode <= "01"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:3.878610000000000e+003 +-- out_fp = 40AE4D3851EB851E +--inputA:9.9440000000e+003 +--inputB:2.3000000000e+001 +enable <= '1'; +opa <= "0100000011000011011011000000000000000000000000000000000000000000"; +opb <= "0100000000110111000000000000000000000000000000000000000000000000"; +fpu_op <= "011"; +rmode <= "01"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:4.323478260869565e+002 +-- out_fp = 407B0590B21642C8 +--inputA:-9.0054400000e+005 +--inputB:-3.4445500000e+005 +enable <= '1'; +opa <= "1100000100101011011110111000000000000000000000000000000000000000"; +opb <= "1100000100010101000001100001110000000000000000000000000000000000"; +fpu_op <= "001"; +rmode <= "01"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:-5.560890000000000e+005 +-- out_fp = C120F87200000000 +--inputA:5.5500000000e-002 +--inputB:3.2444400000e+005 +enable <= '1'; +opa <= "0011111110101100011010100111111011111001110110110010001011010001"; +opb <= "0100000100010011110011010111000000000000000000000000000000000000"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.710618781669564e-007 +-- out_fp = 3E86F5A431628F6D +--inputA:1.2330000000e+000 +--inputB:1.5666600000e+000 +enable <= '1'; +opa <= "0011111111110011101110100101111000110101001111110111110011101110"; +opb <= "0011111111111001000100010000101000010011011111110011100011000101"; +fpu_op <= "010"; +rmode <= "10"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:1.931691780000000e+000 +-- out_fp = 3FFEE835A3D0D51B +--inputA:9.7770000000e-001 +--inputB:3.0000000000e+099 +enable <= '1'; +opa <= "0011111111101111010010010101000110000010101010011001001100001100"; +opb <= "0101010010010101111100100000001011111001111001011011011101100011"; +fpu_op <= "011"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:3.259000000000000e-100 +-- out_fp = 2B46CF7665DCED50 +--inputA:4.4000000000e+007 +--inputB:6.0000000000e+002 +enable <= '1'; +opa <= "0100000110000100111110110001100000000000000000000000000000000000"; +opb <= "0100000010000010110000000000000000000000000000000000000000000000"; +fpu_op <= "010"; +rmode <= "00"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:2.640000000000000e+010 +-- out_fp = 4218964020000000 +--inputA:3.9800000000e+000 +--inputB:3.7700000000e+000 +enable <= '1'; +opa <= "0100000000001111110101110000101000111101011100001010001111010111"; +opb <= "0100000000001110001010001111010111000010100011110101110000101001"; +fpu_op <= "000"; +rmode <= "01"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:7.750000000000000e+000 +-- out_fp = 401F000000000000 +--inputA:8.0400000000e+000 +--inputB:8.0395700000e+000 +enable <= '1'; +opa <= "0100000000100000000101000111101011100001010001111010111000010100"; +opb <= "0100000000100000000101000100001010000100110111111100111000110001"; +fpu_op <= "001"; +rmode <= "01"; +wait for 20ns; +enable <= '0'; +wait for 800 ns; +--Output:4.299999999997084e-004 +-- out_fp = 3F3C2E33EFF18000 + + + END_SIM <= TRUE; + + wait; +end process; + +CLOCK_clk : process +begin + + if END_SIM = FALSE then + clk <= '0'; + wait for 5 ns; + else + wait; + end if; + if END_SIM = FALSE then + clk <= '1'; + wait for 5 ns; + else + wait; + end if; +end process; + + + +end TB_ARCHITECTURE; + +configuration TESTBENCH_FOR_fpu_double of fpu_double_tb is + for TB_ARCHITECTURE + for UUT : fpu_double + use entity work.fpu_double(rtl); + end for; + end for; +end TESTBENCH_FOR_fpu_double; + Index: tags/arelease/fpupack.vhd =================================================================== --- tags/arelease/fpupack.vhd (nonexistent) +++ tags/arelease/fpupack.vhd (revision 4) @@ -0,0 +1,75 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +package fpupack is + + -- count the number of zeros starting from the left + function count_l_zeros (signal s_vector: std_logic_vector) return std_logic_vector; + function count_zeros_mul (signal s_vector: std_logic_vector) return std_logic_vector; + +end fpupack; + +package body fpupack is + + function count_l_zeros (signal s_vector: std_logic_vector) return std_logic_vector is + variable v_count : std_logic_vector(5 downto 0); + begin + v_count := "000000"; + for i in s_vector'range loop + case s_vector(i) is + when '0' => v_count := v_count + "000001"; + when others => exit; + end case; + end loop; + return v_count; + end count_l_zeros; + + -- count the zeros from the left for multiply + function count_zeros_mul (signal s_vector: std_logic_vector) return std_logic_vector is + variable v_count : std_logic_vector(5 downto 0); + begin + v_count := "000000"; + for i in 105 downto 52 loop + case s_vector(i) is + when '0' => v_count := v_count + "000001"; + when others => exit; + end case; + end loop; + return v_count; + end count_zeros_mul; +end fpupack; \ No newline at end of file Index: tags/arelease/Readme.txt =================================================================== --- tags/arelease/Readme.txt (nonexistent) +++ tags/arelease/Readme.txt (revision 4) @@ -0,0 +1,161 @@ +The following describes the IEEE-Standard-754 compliant, double-precision floating point unit, +written in VHDL. The module consists of the following files: + +1. fpu_double.vhd (top level) +2. fpu_add.vhd +3. fpu_sub.vhd +4. fpu_mul.vhd +5. fpu_div.vhd +6. fpu_round.vhd +7. fpu_exceptions.vhd +8. fpupack.vhd +9. comppack.vhd + +And a testbench file is included, containing 50 test-case operations: +1. fpu_double_TB.vhd + +This unit has been extensively simulated, covering all 4 operations, rounding modes, exceptions +like underflow and overflow, and even the obscure corner cases, like when overflowing from +denormalized to normalized, and vice-versa. + +The floating point unit supports denormalized numbers, +4 operations (add, subtract, multiply, divide), and 4 rounding +modes (nearest, zero, + inf, - inf). The unit was synthesized with an +estimated frequency of 185 MHz, for a Virtex5 target device. The synthesis results +are below. fpu_double.vhd is the top-level module, and it contains the input +and output signals from the unit. + +The input and output signals to the unit are the following: + +1. clk (global) +2. rst (global) +2. enable (set high, then low, to start operation) +3. rmode (rounding mode, 2 bits, 00 = nearest, 01 = zero, + 10 = pos inf, 11 = neg inf) +4. fpu_op (operation code, 3 bits, 000 = add, 001 = subtract, + 010 = multiply, 011 = divide, others are not used) +5. opa, opb (input operands, 64 bits, Big-endian order, + bit 63 = sign, bits 62-52 exponent, bits 51-0 mantissa) +6. out_fp (output from operation, 64 bits, Big-endian order, + same ordering as inputs) +7. ready (goes high when output is available) +8. underflow +9. overflow +10. inexact +11. exception - see IEEE 754 definition +12. invalid - see IEEE 754 definition + +The unit was designed to be synchronous with one global clock, and all of the +registers can be reset with an synchronous global reset. +When the inputs signals (a and b operands, fpu operation code, rounding mode code) are +available, set the enable input high, then set it low after 2 clock cycles. When the +operation is complete and the output is available, the ready signal will go high. To start +the next operation, set the enable input high. + +Each operation takes the following amount of clock cycles to complete: +1. addition : 20 clock cycles +2. subtraction: 21 clock cycles +3. multiplication: 24 clock cycles +4. division: 71 clock cycles + +This is longer than other floating point units, but supporting denormalized numbers +requires more signals and logic levels to accommodate gradual underflow. The supported +clock speed of 185 MHz makes up for the large number of clock cycles required for each +operation to complete. If you have a lower clock speed, the code can be changed to +reduce the number of registers and latency of each operation. I purposely increased the +number of logic levels to get the code to synthesize to a faster clock frequency, but of course, +this led to longer latency. I guess it depends on your application what is more important. + +The following output signals are also available: underflow, overflow, inexact, exception, +and invalid. They are compliant with the IEEE-754 definition of each signal. The unit +will handle QNaN and SNaN inputs per the standard. + +I'm planning on adding more operations, like square root, sin, cos, tan, etc., +so check back for updates. + +Multiply: +The multiply module is written specifically for a Virtex5 target device. The DSP48E slices +can perform a 25-bit by 18-bit Twos-complement multiply (24 by 17 unsigned multiply). I broke up the multiply to +fit these DSP48E slices. The breakdown is similar to the design in Figure 4-15 of the +Xilinx User Guide Document, "Virtex-5 FPGA XtremeDSP Design Considerations", also known as UG193. +You can find this document at xilinx.com by searching for "UG193". +Depending on your device, the multiply can be changed to match the bit-widths of the available +multipliers. A total of 9 DSP48E slices are used to do the 53-bit by 53-bit multiply of 2 +floating point numbers. + +If you have any questions, please email me at: davidklun@gmail.com + +Thanks, +David Lundgren + +----- + +Synthesis Results: + + + + +Performance Summary +******************* + + +Worst slack in design: -2.049 + + + Requested Estimated Requested Estimated Clock Clock +Starting Clock Frequency Frequency Period Period Slack Type Group +---------------------------------------------------------------------------------------------------------------------- +fpu_double|clk 300.0 MHz 185.8 MHz 3.333 5.382 -2.049 inferred Inferred_clkgroup_0 +====================================================================================================================== + + +--------------------------------------- +Resource Usage Report for fpu_double + +Mapping to part: xc5vsx95tff1136-2 +Cell usage: +DSP48E 9 uses +FD 3 uses +FDE 21 uses +FDR 587 uses +FDRE 3767 uses +FDRS 8 uses +FDRSE 51 uses +GND 6 uses +MUXCY 20 uses +MUXCY_L 598 uses +MUXF7 2 uses +VCC 6 uses +XORCY 497 uses +XORCY_L 5 uses +LUT1 187 uses +LUT2 742 uses +LUT3 1591 uses +LUT4 847 uses +LUT5 589 uses +LUT6 2613 uses + +I/O ports: 206 +I/O primitives: 205 +IBUF 135 uses +OBUF 70 uses + +BUFGP 1 use + +I/O Register bits: 0 +Register bits not including I/Os: 4437 (7%) + +Global Clock Buffers: 1 of 32 (3%) + +Total load per clock: + fpu_double|clk: 4446 + +Mapping Summary: +Total LUTs: 6569 (11%) + +Mapper successful! + + + + + Index: tags/arelease/fpu_exceptions.vhd =================================================================== --- tags/arelease/fpu_exceptions.vhd (nonexistent) +++ tags/arelease/fpu_exceptions.vhd (revision 4) @@ -0,0 +1,522 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + + LIBRARY ieee; + USE ieee.std_logic_1164.all; + USE ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + use ieee.std_logic_misc.all; + + ENTITY fpu_exceptions IS + + PORT( + clk, rst, enable : IN std_logic; + rmode : IN std_logic_vector (1 DOWNTO 0); + opa, opb, in_except : IN std_logic_vector (63 DOWNTO 0); + exponent_in : IN std_logic_vector (11 DOWNTO 0); + mantissa_in : IN std_logic_vector (1 DOWNTO 0); + fpu_op : IN std_logic_vector (2 DOWNTO 0); + out_fp : OUT std_logic_vector (63 DOWNTO 0); + ex_enable, underflow, overflow, inexact : OUT std_logic; + exception, invalid : OUT std_logic + ); + + END fpu_exceptions; + + + architecture rtl of fpu_exceptions is + + signal in_et_zero : std_logic; + signal opa_et_zero : std_logic; + signal opb_et_zero : std_logic; + signal add : std_logic; + signal subtract : std_logic; + signal multiply : std_logic; + signal divide : std_logic; + signal opa_QNaN : std_logic; + signal opb_QNaN : std_logic; + signal opa_SNaN : std_logic; + signal opb_SNaN : std_logic; + signal opa_pos_inf : std_logic; + signal opb_pos_inf : std_logic; + signal opa_neg_inf : std_logic; + signal opb_neg_inf : std_logic; + signal opa_inf : std_logic; + signal opb_inf : std_logic; + signal NaN_input : std_logic; + signal SNaN_input : std_logic; + signal a_NaN : std_logic; + signal div_by_0 : std_logic; + signal div_0_by_0 : std_logic; + signal div_inf_by_inf : std_logic; + signal div_by_inf : std_logic; + signal mul_0_by_inf : std_logic; + signal mul_inf : std_logic; + signal div_inf : std_logic; + signal add_inf : std_logic; + signal sub_inf : std_logic; + signal addsub_inf_invalid : std_logic; + signal addsub_inf : std_logic; + signal out_inf_trigger : std_logic; + signal out_pos_inf : std_logic; + signal out_neg_inf : std_logic; + signal round_nearest : std_logic; + signal round_to_zero : std_logic; + signal round_to_pos_inf : std_logic; + signal round_to_neg_inf : std_logic; + signal inf_round_down_trigger : std_logic; + signal mul_uf : std_logic; + signal div_uf : std_logic; + signal underflow_trigger : std_logic; + signal invalid_trigger : std_logic; + signal overflow_trigger : std_logic; + signal inexact_trigger : std_logic; + signal except_trigger : std_logic; + signal enable_trigger : std_logic; + signal NaN_out_trigger : std_logic; + signal SNaN_trigger : std_logic; + + + signal exp_2047 : std_logic_vector(10 downto 0); + signal exp_2046 : std_logic_vector(10 downto 0); + signal NaN_output_0 : std_logic_vector(62 downto 0); + signal NaN_output : std_logic_vector(62 downto 0); + signal mantissa_max : std_logic_vector(51 downto 0); + signal inf_round_down : std_logic_vector(62 downto 0); + signal out_inf : std_logic_vector(62 downto 0); + signal out_0 : std_logic_vector(63 downto 0); + signal out_1 : std_logic_vector(63 downto 0); + signal out_2 : std_logic_vector(63 downto 0); + + begin + + exp_2047 <= "11111111111"; + exp_2046 <= "11111111110"; + mantissa_max <= "1111111111111111111111111111111111111111111111111111"; + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + in_et_zero <= '0'; + opa_et_zero <= '0'; + opb_et_zero <= '0'; + add <= '0'; + subtract <= '0'; + multiply <= '0'; + divide <= '0'; + opa_QNaN <= '0'; + opb_QNaN <= '0'; + opa_SNaN <= '0'; + opb_SNaN <= '0'; + opa_pos_inf <= '0'; + opb_pos_inf <= '0'; + opa_neg_inf <= '0'; + opb_neg_inf <= '0'; + opa_inf <= '0'; + opb_inf <= '0'; + NaN_input <= '0'; + SNaN_input <= '0'; + a_NaN <= '0'; + div_by_0 <= '0'; + div_0_by_0 <= '0'; + div_inf_by_inf <= '0'; + div_by_inf <= '0'; + mul_0_by_inf <= '0'; + mul_inf <= '0'; + div_inf <= '0'; + add_inf <= '0'; + sub_inf <= '0'; + addsub_inf_invalid <= '0'; + addsub_inf <= '0'; + out_inf_trigger <= '0'; + out_pos_inf <= '0'; + out_neg_inf <= '0'; + round_nearest <= '0'; + round_to_zero <= '0'; + round_to_pos_inf <= '0'; + round_to_neg_inf <= '0'; + inf_round_down_trigger <= '0'; + mul_uf <= '0'; + div_uf <= '0'; + underflow_trigger <= '0'; + invalid_trigger <= '0'; + overflow_trigger <= '0'; + inexact_trigger <= '0'; + except_trigger <= '0'; + enable_trigger <= '0'; + NaN_out_trigger <= '0'; + SNaN_trigger <= '0'; + NaN_output_0 <= (others =>'0'); + NaN_output <= (others =>'0'); + inf_round_down <= (others =>'0'); + out_inf <= (others =>'0'); + out_0 <= (others =>'0'); + out_1 <= (others =>'0'); + out_2 <= (others =>'0'); + elsif (enable = '1') then + if or_reduce(in_except(62 downto 0)) = '0' then + in_et_zero <= '1'; + else + in_et_zero <= '0'; + end if; + if or_reduce(opa(62 downto 0)) = '0' then + opa_et_zero <= '1'; + else + opa_et_zero <= '0'; + end if; + if or_reduce(opb(62 downto 0)) = '0' then + opb_et_zero <= '1'; + else + opb_et_zero <= '0'; + end if; + if fpu_op = "000" then + add <= '1'; + else + add <= '0'; + end if; + if fpu_op = "001" then + subtract <= '1'; + else + subtract <= '0'; + end if; + if fpu_op = "010" then + multiply <= '1'; + else + multiply <= '0'; + end if; + if fpu_op = "011" then + divide <= '1'; + else + divide <= '0'; + end if; + if opa(62 downto 52) = "11111111111" and or_reduce(opa(51 downto 0)) = '1' and + opa(51) = '1' then + opa_QNaN <= '1'; + else + opa_QNaN <= '0'; + end if; + if opb(62 downto 52) = "11111111111" and or_reduce(opb(51 downto 0)) = '1' and + opb(51) = '1' then + opb_QNaN <= '1'; + else + opb_QNaN <= '0'; + end if; + if opa(62 downto 52) = "11111111111" and or_reduce(opa(51 downto 0)) = '1' and + opa(51) = '0' then + opa_SNaN <= '1'; + else + opa_SNaN <= '0'; + end if; + if opb(62 downto 52) = "11111111111" and or_reduce(opb(51 downto 0)) = '1' and + opb(51) = '0' then + opb_SNaN <= '1'; + else + opb_SNaN <= '0'; + end if; + if opa(62 downto 52) = "11111111111" and or_reduce(opa(51 downto 0)) = '0' and + opa(63) = '0' then + opa_pos_inf <= '1'; + else + opa_pos_inf <= '0'; + end if; + if opb(62 downto 52) = "11111111111" and or_reduce(opb(51 downto 0)) = '0' and + opb(63) = '0' then + opb_pos_inf <= '1'; + else + opb_pos_inf <= '0'; + end if; + if opa(62 downto 52) = "11111111111" and or_reduce(opa(51 downto 0)) = '0' and + opa(63) = '1' then + opa_neg_inf <= '1'; + else + opa_neg_inf <= '0'; + end if; + if opb(62 downto 52) = "11111111111" and or_reduce(opb(51 downto 0)) = '0' and + opb(63) = '1' then + opb_neg_inf <= '1'; + else + opb_neg_inf <= '0'; + end if; + if opa(62 downto 52) = "11111111111" and or_reduce(opa(51 downto 0)) = '0' then + opa_inf <= '1'; + else + opa_inf <= '0'; + end if; + if opb(62 downto 52) = "11111111111" and or_reduce(opb(51 downto 0)) = '0' then + opb_inf <= '1'; + else + opb_inf <= '0'; + end if; + if opa_QNaN = '1' or opb_QNaN = '1' or opa_SNaN = '1' or opb_SNaN = '1' then + NaN_input <= '1'; + else + NaN_input <= '0'; + end if; + if opa_SNaN = '1' or opb_SNaN = '1' then + SNaN_input <= '1'; + else + SNaN_input <= '0'; + end if; + if opa_SNaN = '1' or opa_QNaN = '1' then + a_NaN <= '1'; + else + a_NaN <= '0'; + end if; + if divide = '1' and opb_et_zero = '1' and opa_et_zero = '0' then + div_by_0 <= '1'; + else + div_by_0 <= '0'; + end if; + if divide = '1' and opb_et_zero = '1' and opa_et_zero = '1' then + div_0_by_0 <= '1'; + else + div_0_by_0 <= '0'; + end if; + if divide = '1' and opa_inf = '1' and opb_inf = '1' then + div_inf_by_inf <= '1'; + else + div_inf_by_inf <= '0'; + end if; + if divide = '1' and opa_inf = '0' and opb_inf = '1' then + div_by_inf <= '1'; + else + div_by_inf <= '0'; + end if; + if multiply = '1' and ((opa_inf = '1' and opb_et_zero = '1') or + (opa_et_zero = '1' and opb_inf = '1')) then + mul_0_by_inf <= '1'; + else + mul_0_by_inf <= '0'; + end if; + if multiply = '1' and (opa_inf = '1' or opb_inf = '1') and + mul_0_by_inf = '0' then + mul_inf <= '1'; + else + mul_inf <= '0'; + end if; + if divide = '1' and opa_inf = '1' and opb_inf = '0' then + div_inf <= '1'; + else + div_inf <= '0'; + end if; + if add = '1' and (opa_inf = '1' or opb_inf = '1') then + add_inf <= '1'; + else + add_inf <= '0'; + end if; + if subtract = '1' and (opa_inf = '1' or opb_inf = '1') then + sub_inf <= '1'; + else + sub_inf <= '0'; + end if; + if (add = '1' and opa_pos_inf = '1' and opb_neg_inf = '1') or + (add = '1' and opa_neg_inf = '1' and opb_pos_inf = '1') or + (subtract = '1' and opa_pos_inf = '1' and opb_pos_inf = '1') or + (subtract = '1' and opa_neg_inf = '1' and opb_neg_inf = '1') then + addsub_inf_invalid <= '1'; + else + addsub_inf_invalid <= '0'; + end if; + if (add_inf = '1' or sub_inf = '1') and addsub_inf_invalid = '0' then + addsub_inf <= '1'; + else + addsub_inf <= '0'; + end if; + if addsub_inf = '1' or mul_inf = '1' or div_inf = '1' or div_by_0 = '1' + or (exponent_in > "011111111110") then -- 2046 + out_inf_trigger <= '1'; + else + out_inf_trigger <= '0'; + end if; + if out_inf_trigger = '1' and in_except(63) = '0' then + out_pos_inf <= '1'; + else + out_pos_inf <= '0'; + end if; + if out_inf_trigger = '1' and in_except(63) = '1' then + out_neg_inf <= '1'; + else + out_neg_inf <= '0'; + end if; + if rmode = "00" then + round_nearest <= '1'; + else + round_nearest <= '0'; + end if; + if rmode = "01" then + round_to_zero <= '1'; + else + round_to_zero <= '0'; + end if; + if rmode = "10" then + round_to_pos_inf <= '1'; + else + round_to_pos_inf <= '0'; + end if; + if rmode = "11" then + round_to_neg_inf <= '1'; + else + round_to_neg_inf <= '0'; + end if; + if (out_pos_inf = '1' and round_to_neg_inf = '1') or + (out_neg_inf = '1' and round_to_pos_inf = '1') or + (out_inf_trigger = '1' and round_to_zero = '1') then + inf_round_down_trigger <= '1'; + else + inf_round_down_trigger <= '0'; + end if; + if multiply = '1' and opa_et_zero = '0' and opb_et_zero = '0' and + in_et_zero = '1' then + mul_uf <= '1'; + else + mul_uf <= '0'; + end if; + if divide = '1' and opa_et_zero = '0' and in_et_zero = '1' then + div_uf <= '1'; + else + div_uf <= '0'; + end if; + if div_by_inf = '1' or mul_uf = '1' or div_uf = '1' then + underflow_trigger <= '1'; + else + underflow_trigger <= '0'; + end if; + if SNaN_input = '1' or addsub_inf_invalid = '1' or mul_0_by_inf = '1' or + div_0_by_0 = '1' or div_inf_by_inf = '1' then + invalid_trigger <= '1'; + else + invalid_trigger <= '0'; + end if; + if div_by_inf = '1' or mul_uf = '1' or div_uf = '1' then + underflow_trigger <= '1'; + else + underflow_trigger <= '0'; + end if; + if out_inf_trigger = '1' and NaN_input = '0' then + overflow_trigger <= '1'; + else + overflow_trigger <= '0'; + end if; + if (or_reduce(mantissa_in(1 downto 0)) = '1' or out_inf_trigger = '1' or + underflow_trigger = '1') and NaN_input = '0' then + inexact_trigger <= '1'; + else + inexact_trigger <= '0'; + end if; + if (invalid_trigger = '1' or overflow_trigger = '1' or + underflow_trigger = '1' or inexact_trigger = '1') then + except_trigger <= '1'; + else + except_trigger <= '0'; + end if; + if (invalid_trigger = '1' or overflow_trigger = '1' or + underflow_trigger = '1' or inexact_trigger = '1') then + except_trigger <= '1'; + else + except_trigger <= '0'; + end if; + if (except_trigger = '1' or out_inf_trigger = '1' or + NaN_input = '1') then + enable_trigger <= '1'; + else + enable_trigger <= '0'; + end if; + if (NaN_input = '1' or invalid_trigger = '1') then + NaN_out_trigger <= '1'; + else + NaN_out_trigger <= '0'; + end if; + if (invalid_trigger = '1' and SNaN_input = '0') then + SNaN_trigger <= '1'; + else + SNaN_trigger <= '0'; + end if; + if a_NaN = '1' then + NaN_output_0 <= exp_2047 & '1' & opa(50 downto 0); + else + NaN_output_0 <= exp_2047 & '1' & opb(50 downto 0); + end if; + if SNaN_trigger = '1' then + NaN_output <= exp_2047 & "01" & opa(49 downto 0); + else + NaN_output <= NaN_output_0; + end if; + inf_round_down <= exp_2046 & mantissa_max; + if inf_round_down_trigger = '1' then + out_inf <= inf_round_down; + else + out_inf <= exp_2047 & "0000000000000000000000000000000000000000000000000000"; + end if; + if underflow_trigger = '1' then + out_0 <= in_except(63) & "000000000000000000000000000000000000000000000000000000000000000"; + else + out_0 <= in_except; + end if; + if out_inf_trigger = '1' then + out_1 <= in_except(63) & out_inf; + else + out_1 <= out_0; + end if; + if NaN_out_trigger = '1' then + out_2 <= in_except(63) & NaN_output; + else + out_2 <= out_1; + end if; + end if; + end process; + + + process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + ex_enable <= '0'; + underflow <= '0'; + overflow <= '0'; + inexact <= '0'; + exception <= '0'; + invalid <= '0'; + out_fp <= (others =>'0'); + elsif (enable = '1') then + ex_enable <= enable_trigger; + underflow <= underflow_trigger; + overflow <= overflow_trigger; + inexact <= inexact_trigger; + exception <= except_trigger; + invalid <= invalid_trigger; + out_fp <= out_2; + end if; + end process; + end rtl; Index: tags/arelease/fpu_div.vhd =================================================================== --- tags/arelease/fpu_div.vhd (nonexistent) +++ tags/arelease/fpu_div.vhd (revision 4) @@ -0,0 +1,409 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + + LIBRARY ieee; + USE ieee.std_logic_1164.all; + USE ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + use ieee.std_logic_misc.all; + use IEEE.numeric_std.all; + library work; + use work.fpupack.all; + + ENTITY fpu_div IS + + PORT( + clk, rst, enable : IN std_logic; + opa, opb : IN std_logic_vector (63 DOWNTO 0); + sign : OUT std_logic; + mantissa_7 : OUT std_logic_vector (55 DOWNTO 0); + exponent_out : OUT std_logic_vector (11 DOWNTO 0) + ); + + END fpu_div; + + architecture rtl of fpu_div is + + signal dividend_signal : std_logic_vector(53 downto 0); + signal divisor_signal : std_logic_vector(53 downto 0); + signal enable_signal : std_logic; + signal enable_signal_2 : std_logic; + signal enable_signal_a : std_logic; + signal enable_signal_b : std_logic; + signal enable_signal_c : std_logic; + signal enable_signal_d : std_logic; + signal enable_signal_e : std_logic; + signal dividend_shift : std_logic_vector(5 downto 0); + signal dividend_shift_2 : std_logic_vector(5 downto 0); + signal divisor_shift : std_logic_vector(5 downto 0); + signal divisor_shift_2 : std_logic_vector(5 downto 0); + signal count_out : std_logic_vector(5 downto 0); + signal mantissa_a : std_logic_vector(51 downto 0); + signal mantissa_b : std_logic_vector(51 downto 0); + signal expon_a : std_logic_vector(10 downto 0); + signal expon_b : std_logic_vector(10 downto 0); + signal a_is_norm : std_logic; + signal b_is_norm : std_logic; + signal a_is_zero : std_logic; + signal exponent_a : std_logic_vector(11 downto 0); + signal exponent_b : std_logic_vector(11 downto 0); + signal dividend_a : std_logic_vector(51 downto 0); + signal dividend_a_shifted : std_logic_vector(51 downto 0); + signal dividend_denorm : std_logic_vector(52 downto 0); + signal dividend_1 : std_logic_vector(53 downto 0); + signal divisor_b : std_logic_vector(51 downto 0); + signal divisor_b_shifted : std_logic_vector(51 downto 0); + signal divisor_denorm : std_logic_vector(52 downto 0); + signal divisor_1 : std_logic_vector(53 downto 0); + signal count_index : std_logic_vector(5 downto 0); + signal count_nonzero : std_logic; + signal quotient : std_logic_vector(53 downto 0); + signal quotient_out : std_logic_vector(53 downto 0); + signal remainder : std_logic_vector(53 downto 0); + signal remainder_out : std_logic_vector(53 downto 0); + signal remainder_msb : std_logic; + signal count_nonzero_signal : std_logic; + signal count_nonzero_signal_2 : std_logic; + signal expon_term : std_logic_vector(11 downto 0); + signal expon_uf_1 : std_logic; + signal expon_uf_term_1 : std_logic_vector(11 downto 0); + signal expon_final_1 : std_logic_vector(11 downto 0); + signal expon_final_2 : std_logic_vector(11 downto 0); + signal expon_shift_a : std_logic_vector(11 downto 0); + signal expon_shift_b : std_logic_vector(11 downto 0); + signal expon_uf_2 : std_logic; + signal expon_uf_term_2 : std_logic_vector(11 downto 0); + signal expon_uf_term_3 : std_logic_vector(11 downto 0); + signal expon_uf_gt_maxshift : std_logic; + signal expon_uf_term_4 : std_logic_vector(11 downto 0); + signal expon_final_3 : std_logic_vector(11 downto 0); + signal expon_final_4 : std_logic_vector(11 downto 0); + signal quotient_msb : std_logic; + signal expon_final_4_et0 : std_logic; + signal expon_final_4_term : std_logic; + signal expon_final_5 : std_logic_vector(11 downto 0); + signal mantissa_1 : std_logic_vector(51 downto 0); + signal mantissa_2 : std_logic_vector(51 downto 0); + signal mantissa_3 : std_logic_vector(51 downto 0); + signal mantissa_4 : std_logic_vector(51 downto 0); + signal mantissa_5 : std_logic_vector(51 downto 0); + signal mantissa_6 : std_logic_vector(51 downto 0); + signal remainder_a : std_logic_vector(107 downto 0); + signal remainder_shift_term : std_logic_vector(11 downto 0); + signal remainder_b : std_logic_vector(107 downto 0); + signal remainder_1 : std_logic_vector(55 downto 0); + signal remainder_2 : std_logic_vector(55 downto 0); + signal remainder_3 : std_logic_vector(55 downto 0); + signal remainder_4 : std_logic_vector(55 downto 0); + signal remainder_5 : std_logic_vector(55 downto 0); + signal remainder_6 : std_logic_vector(55 downto 0); + signal m_norm : std_logic; + signal rem_lsb : std_logic; + + begin + sign <= opa(63) xor opb(63); + expon_a <= opa(62 downto 52); + expon_b <= opb(62 downto 52); + a_is_norm <= or_reduce(expon_a); + b_is_norm <= or_reduce(expon_b); + a_is_zero <= not or_reduce(opa(62 downto 0)); + exponent_a <= '0' & expon_a; + exponent_b <= '0' & expon_b; + dividend_denorm <= dividend_a_shifted & '0'; + dividend_1 <= "01" & dividend_a when a_is_norm = '1' else '0' & dividend_denorm; + divisor_denorm <= divisor_b_shifted & '0'; + divisor_1 <= "01" & divisor_b when b_is_norm = '1' else '0' & divisor_denorm; + count_nonzero <= '0' when count_index = "000000" else '1'; + count_index <= count_out; + quotient_msb <= quotient_out(53); + mantissa_2 <= quotient_out(52 downto 1); + mantissa_3 <= quotient_out(51 downto 0); + mantissa_4 <= mantissa_2 when quotient_msb = '1' else mantissa_3; + mantissa_5 <= mantissa_2 when expon_final_4 = "000000000001" else mantissa_4; + mantissa_6 <= mantissa_1 when expon_final_4_et0 = '1' else mantissa_5; + remainder_a <= quotient_out(53 downto 0) & remainder_msb & remainder_out(52 downto 0); + remainder_1 <= remainder_b(107 downto 52); + remainder_2 <= quotient_out(0) & remainder_msb & remainder_out(52 downto 0) & '0' ; + remainder_3 <= remainder_msb & remainder_out(52 downto 0) & "00" ; + remainder_4 <= remainder_2 when quotient_msb = '1' else remainder_3; + remainder_5 <= remainder_2 when expon_final_4 = "000000000001" else remainder_4; + remainder_6 <= remainder_1 when expon_final_4_et0 = '1' else remainder_5; + m_norm <= or_reduce(expon_final_5); + rem_lsb <= or_reduce(remainder_6(54 downto 0)); + mantissa_7 <= '0' & m_norm & mantissa_6 & remainder_6(55) & rem_lsb ; + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + exponent_out <= (others =>'0'); + else + if (a_is_zero = '1') then + exponent_out <= "000000000000"; + else + exponent_out <= expon_final_5; + end if; + end if; + end process; + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + count_out <= (others =>'0'); + elsif (enable_signal = '1') then + count_out <= "110101"; -- 53 + elsif (count_nonzero = '1') then + count_out <= count_out - "000001"; + end if; + end process; + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + quotient_out <= (others =>'0'); + remainder_out <= (others =>'0'); + else + quotient_out <= quotient; + remainder_out <= remainder; + end if; + end process; + + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + quotient <= (others =>'0'); + elsif (count_nonzero_signal = '1') then + if (divisor_signal > dividend_signal) then + quotient(conv_integer(count_index)) <= '0'; + else + quotient(conv_integer(count_index)) <= '1'; + end if; + end if; + end process; + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + remainder <= (others =>'0'); + remainder_msb <= '0'; + elsif ((not count_nonzero_signal and count_nonzero_signal_2) = '1') then + remainder <= dividend_signal; + if (divisor_signal > dividend_signal) then + remainder_msb <= '0'; + else + remainder_msb <= '1'; + end if; + end if; + end process; + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + dividend_signal <= (others =>'0'); + divisor_signal <= (others =>'0'); + elsif (enable_signal_e = '1') then + dividend_signal <= dividend_1; + divisor_signal <= divisor_1; + elsif (count_nonzero_signal = '1') then + if (divisor_signal > dividend_signal) then + dividend_signal <= shl(dividend_signal, conv_std_logic_vector('1', 54)); + else + dividend_signal <= shl(dividend_signal - divisor_signal, conv_std_logic_vector('1', 54)); + end if; + end if; + end process; + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + expon_term <= (others =>'0'); + expon_uf_1 <= '0'; + expon_uf_term_1 <= (others =>'0'); + expon_final_1 <= (others =>'0'); + expon_final_2 <= (others =>'0'); + expon_shift_a <= (others =>'0'); + expon_shift_b <= (others =>'0'); + expon_uf_2 <= '0'; + expon_uf_term_2 <= (others =>'0'); + expon_uf_term_3 <= (others =>'0'); + expon_uf_gt_maxshift <= '0'; + expon_uf_term_4 <= (others =>'0'); + expon_final_3 <= (others =>'0'); + expon_final_4 <= (others =>'0'); + expon_final_4_et0 <= '0'; + expon_final_4_term <= '0'; + expon_final_5 <= (others =>'0'); + mantissa_a <= (others =>'0'); + mantissa_b <= (others =>'0'); + dividend_a <= (others =>'0'); + divisor_b <= (others =>'0'); + dividend_shift <= (others =>'0'); + divisor_shift <= (others =>'0'); + dividend_shift_2 <= (others =>'0'); + divisor_shift_2 <= (others =>'0'); + remainder_shift_term <= (others =>'0'); + remainder_b <= (others =>'0'); + dividend_a_shifted <= (others =>'0'); + divisor_b_shifted <= (others =>'0'); + mantissa_1 <= (others =>'0'); + elsif (enable_signal_2 = '1') then + expon_term <= exponent_a + "001111111111"; -- 1023 + if (exponent_b > expon_term) then + expon_uf_1 <= '1'; + else + expon_uf_1 <= '0'; + end if; + if (expon_uf_1 = '1') then + expon_uf_term_1 <= exponent_b - expon_term; + expon_final_2 <= (others =>'0'); + else + expon_uf_term_1 <= (others =>'0'); + expon_final_2 <= expon_final_1; + end if; + expon_final_1 <= expon_term - exponent_b; + if (expon_uf_1 = '1') then + expon_uf_term_1 <= exponent_b - expon_term; + else + expon_uf_term_1 <= (others =>'0'); + end if; + if (a_is_norm = '1') then + expon_shift_a <= (others =>'0'); + else + expon_shift_a <= "000000" & dividend_shift_2; + end if; + if (b_is_norm = '1') then + expon_shift_b <= (others =>'0'); + else + expon_shift_b <= "000000" & divisor_shift_2; + end if; + if (expon_shift_a > expon_final_2) then + expon_uf_2 <= '1'; + else + expon_uf_2 <= '0'; + end if; + if (expon_uf_2 = '1') then + expon_uf_term_2 <= expon_shift_a - expon_final_2; + else + expon_uf_term_2 <= (others =>'0'); + end if; + expon_uf_term_3 <= expon_uf_term_2 + expon_uf_term_1; + if (expon_uf_term_3 > "000000110011") then -- 51 + expon_uf_gt_maxshift <= '1'; + else + expon_uf_gt_maxshift <= '0'; + end if; + if (expon_uf_gt_maxshift = '1') then + expon_uf_term_4 <= "000000110100"; --52 + else + expon_uf_term_4 <= expon_uf_term_3; + end if; + if (expon_uf_2 = '1') then + expon_final_3 <= (others =>'0'); + else + expon_final_3 <= expon_final_2 - expon_shift_a; + end if; + expon_final_4 <= expon_final_3 + expon_shift_b; + if (expon_final_4 = "000000000000") then + expon_final_4_et0 <= '1'; + else + expon_final_4_et0 <= '0'; + end if; + if (expon_final_4_et0 = '1') then + expon_final_4_term <= '0'; + else + expon_final_4_term <= '1'; + end if; + if (quotient_msb = '1') then + expon_final_5 <= expon_final_4; + else + expon_final_5 <= expon_final_4 - expon_final_4_term; + end if; + mantissa_a <= opa(51 downto 0); + mantissa_b <= opb(51 downto 0); + dividend_a <= mantissa_a; + divisor_b <= mantissa_b; + dividend_shift <= count_l_zeros(dividend_a); + divisor_shift <= count_l_zeros(divisor_b); + dividend_shift_2 <= dividend_shift; + divisor_shift_2 <= divisor_shift; + remainder_shift_term <= "000000110100" - expon_uf_term_4; -- 52 + remainder_b <= shl(remainder_a, remainder_shift_term); + dividend_a_shifted <= shl(dividend_a, dividend_shift_2); + divisor_b_shifted <= shl(divisor_b, divisor_shift_2); + mantissa_1 <= shr(quotient_out(53 downto 2), expon_uf_term_4); + end if; + end process; + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + count_nonzero_signal <= '0'; + count_nonzero_signal_2 <= '0'; + enable_signal <= '0'; + enable_signal_a <= '0'; + enable_signal_b <= '0'; + enable_signal_c <= '0'; + enable_signal_d <= '0'; + enable_signal_e <= '0'; + else + count_nonzero_signal <= count_nonzero; + count_nonzero_signal_2 <= count_nonzero_signal; + enable_signal <= enable_signal_e; + enable_signal_a <= enable; + enable_signal_b <= enable_signal_a; + enable_signal_c <= enable_signal_b; + enable_signal_d <= enable_signal_c; + enable_signal_e <= enable_signal_d; + end if; + end process; + +process + begin + wait until clk'event and clk = '1'; + if (rst = '1') then + enable_signal_2 <= '0'; + elsif (enable = '1') then + enable_signal_2 <= '1'; + end if; + end process; + + end rtl; \ No newline at end of file Index: tags/arelease/comppack.vhd =================================================================== --- tags/arelease/comppack.vhd (nonexistent) +++ tags/arelease/comppack.vhd (revision 4) @@ -0,0 +1,125 @@ +--------------------------------------------------------------------- +---- ---- +---- FPU ---- +---- Floating Point Unit (Double precision) ---- +---- ---- +---- Author: David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2009 David Lundgren ---- +---- davidklun@gmail.com ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +library work; +use work.fpupack.all; + +package comppack is + + +--- Component Declarations --- + + component fpu_add is + PORT( + clk : IN std_logic; + rst : IN std_logic; + enable : IN std_logic; + opa : IN std_logic_vector (63 DOWNTO 0); + opb : IN std_logic_vector (63 DOWNTO 0); + sign : OUT std_logic; + sum_3 : OUT std_logic_vector (55 DOWNTO 0); + exponent_2 : OUT std_logic_vector (10 DOWNTO 0) + ); + end component; + + component fpu_sub is + PORT( + clk : IN std_logic; + rst : IN std_logic; + enable : IN std_logic; + opa : IN std_logic_vector (63 DOWNTO 0); + opb : IN std_logic_vector (63 DOWNTO 0); + fpu_op : IN std_logic_vector (2 DOWNTO 0); + sign : OUT std_logic; + diff_2 : OUT std_logic_vector (55 DOWNTO 0); + exponent_2 : OUT std_logic_vector (10 DOWNTO 0) + ); + end component; + + component fpu_mul is + port( + clk : IN std_logic; + rst : IN std_logic; + enable : IN std_logic; + opa : IN std_logic_vector (63 DOWNTO 0); + opb : IN std_logic_vector (63 DOWNTO 0); + sign : OUT std_logic; + product_7 : OUT std_logic_vector (55 DOWNTO 0); + exponent_5 : OUT std_logic_vector (11 DOWNTO 0) + ); + end component; + + component fpu_div is + port( + clk, rst, enable : IN std_logic; + opa, opb : IN std_logic_vector (63 DOWNTO 0); + sign : OUT std_logic; + mantissa_7 : OUT std_logic_vector (55 DOWNTO 0); + exponent_out : OUT std_logic_vector (11 DOWNTO 0) + ); + end component; + + component fpu_round is + port( + clk, rst, enable : IN std_logic; + round_mode : IN std_logic_vector (1 DOWNTO 0); + sign_term : IN std_logic; + mantissa_term : IN std_logic_vector (55 DOWNTO 0); + exponent_term : IN std_logic_vector (11 DOWNTO 0); + round_out : OUT std_logic_vector (63 DOWNTO 0); + exponent_final : OUT std_logic_vector (11 DOWNTO 0) + ); + end component; + + component fpu_exceptions is + port( + clk, rst, enable : IN std_logic; + rmode : IN std_logic_vector (1 DOWNTO 0); + opa, opb, in_except : IN std_logic_vector (63 DOWNTO 0); + exponent_in : IN std_logic_vector (11 DOWNTO 0); + mantissa_in : IN std_logic_vector (1 DOWNTO 0); + fpu_op : IN std_logic_vector (2 DOWNTO 0); + out_fp : OUT std_logic_vector (63 DOWNTO 0); + ex_enable, underflow, overflow, inexact : OUT std_logic; + exception, invalid : OUT std_logic + ); + end component; + + + +end comppack; \ No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.