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