@ -157,7 +157,7 @@ architecture behaviour of fpu is
constant BIN_ZERO : std_ulogic_vector(1 downto 0) := "00";
constant BIN_ZERO : std_ulogic_vector(1 downto 0) := "00";
constant BIN_R : std_ulogic_vector(1 downto 0) := "01";
constant BIN_R : std_ulogic_vector(1 downto 0) := "01";
constant BIN_MASK : std_ulogic_vector(1 downto 0) := "10";
constant BIN_RND : std_ulogic_vector(1 downto 0) := "10";
constant BIN_PS6 : std_ulogic_vector(1 downto 0) := "11";
constant BIN_PS6 : std_ulogic_vector(1 downto 0) := "11";
constant RES_SUM : std_ulogic_vector(1 downto 0) := "00";
constant RES_SUM : std_ulogic_vector(1 downto 0) := "00";
@ -632,6 +632,7 @@ begin
variable mulexp : signed(EXP_BITS-1 downto 0);
variable mulexp : signed(EXP_BITS-1 downto 0);
variable maddend : std_ulogic_vector(127 downto 0);
variable maddend : std_ulogic_vector(127 downto 0);
variable sum : std_ulogic_vector(63 downto 0);
variable sum : std_ulogic_vector(63 downto 0);
variable round_inc : std_ulogic_vector(63 downto 0);
begin
begin
v := r;
v := r;
illegal := '0';
illegal := '0';
@ -1117,7 +1118,6 @@ begin
elsif r.b.exponent > to_signed(127, EXP_BITS) then
elsif r.b.exponent > to_signed(127, EXP_BITS) then
v.state := ROUND_OFLOW;
v.state := ROUND_OFLOW;
else
else
v.shift := to_signed(-2, EXP_BITS);
v.state := ROUNDING;
v.state := ROUNDING;
end if;
end if;
else
else
@ -1619,7 +1619,6 @@ begin
-- sum overflowed, shift right
-- sum overflowed, shift right
opsel_r <= RES_SHIFT;
opsel_r <= RES_SHIFT;
set_x := '1';
set_x := '1';
v.shift := to_signed(-2, EXP_BITS);
if exp_huge = '1' then
if exp_huge = '1' then
v.state := ROUND_OFLOW;
v.state := ROUND_OFLOW;
else
else
@ -1627,7 +1626,6 @@ begin
end if;
end if;
elsif r.r(54) = '1' then
elsif r.r(54) = '1' then
set_x := '1';
set_x := '1';
v.shift := to_signed(-2, EXP_BITS);
v.state := ROUNDING;
v.state := ROUNDING;
elsif (r_hi_nz or r_lo_nz or r.r(1) or r.r(0)) = '0' then
elsif (r_hi_nz or r_lo_nz or r.r(1) or r.r(0)) = '0' then
-- r.x must be zero at this point
-- r.x must be zero at this point
@ -2085,7 +2083,6 @@ begin
-- r.shift = b.exponent - 52
-- r.shift = b.exponent - 52
opsel_r <= RES_SHIFT;
opsel_r <= RES_SHIFT;
set_x := '1';
set_x := '1';
v.shift := to_signed(-2, EXP_BITS);
v.state := ROUNDING;
v.state := ROUNDING;
when FINISH =>
when FINISH =>
@ -2103,7 +2100,6 @@ begin
elsif exp_huge = '1' then
elsif exp_huge = '1' then
v.state := ROUND_OFLOW;
v.state := ROUND_OFLOW;
else
else
v.shift := to_signed(-2, EXP_BITS);
v.state := ROUNDING;
v.state := ROUNDING;
end if;
end if;
end if;
end if;
@ -2119,7 +2115,6 @@ begin
elsif exp_huge = '1' then
elsif exp_huge = '1' then
v.state := ROUND_OFLOW;
v.state := ROUND_OFLOW;
else
else
v.shift := to_signed(-2, EXP_BITS);
v.state := ROUNDING;
v.state := ROUNDING;
end if;
end if;
@ -2131,7 +2126,6 @@ begin
-- have to denormalize before rounding
-- have to denormalize before rounding
opsel_r <= RES_SHIFT;
opsel_r <= RES_SHIFT;
set_x := '1';
set_x := '1';
v.shift := to_signed(-2, EXP_BITS);
v.state := ROUNDING;
v.state := ROUNDING;
else
else
-- enabled underflow exception case
-- enabled underflow exception case
@ -2142,7 +2136,6 @@ begin
renormalize := '1';
renormalize := '1';
v.state := NORMALIZE;
v.state := NORMALIZE;
else
else
v.shift := to_signed(-2, EXP_BITS);
v.state := ROUNDING;
v.state := ROUNDING;
end if;
end if;
end if;
end if;
@ -2169,7 +2162,6 @@ begin
else
else
-- enabled overflow exception
-- enabled overflow exception
v.result_exp := r.result_exp - bias_exp;
v.result_exp := r.result_exp - bias_exp;
v.shift := to_signed(-2, EXP_BITS);
v.state := ROUNDING;
v.state := ROUNDING;
end if;
end if;
@ -2178,9 +2170,8 @@ begin
round := fp_rounding(r.r, r.x, r.single_prec, r.round_mode, r.result_sign);
round := fp_rounding(r.r, r.x, r.single_prec, r.round_mode, r.result_sign);
v.fpscr(FPSCR_FR downto FPSCR_FI) := round;
v.fpscr(FPSCR_FR downto FPSCR_FI) := round;
if round(1) = '1' then
if round(1) = '1' then
-- set mask to increment the LSB for the precision
-- increment the LSB for the precision
opsel_b <= BIN_MASK;
opsel_b <= BIN_RND;
carry_in <= '1';
v.shift := to_signed(-1, EXP_BITS);
v.shift := to_signed(-1, EXP_BITS);
v.state := ROUNDING_2;
v.state := ROUNDING_2;
else
else
@ -2402,8 +2393,9 @@ begin
in_b0 := (others => '0');
in_b0 := (others => '0');
when BIN_R =>
when BIN_R =>
in_b0 := r.r;
in_b0 := r.r;
when BIN_MASK =>
when BIN_RND =>
in_b0 := mask;
round_inc := (31 => r.single_prec, 2 => not r.single_prec, others => '0');
in_b0 := round_inc;
when others =>
when others =>
-- BIN_PS6, 6 LSBs of P/4 sign-extended to 64
-- BIN_PS6, 6 LSBs of P/4 sign-extended to 64
in_b0 := std_ulogic_vector(resize(signed(r.p(7 downto 2)), 64));
in_b0 := std_ulogic_vector(resize(signed(r.p(7 downto 2)), 64));
@ -2420,7 +2412,10 @@ begin
end if;
end if;
sum := std_ulogic_vector(unsigned(in_a) + unsigned(in_b) + carry_in);
sum := std_ulogic_vector(unsigned(in_a) + unsigned(in_b) + carry_in);
if opsel_mask = '1' then
if opsel_mask = '1' then
sum := sum and not mask;
sum(1 downto 0) := "00";
if r.single_prec = '1' then
sum(30 downto 2) := (others => '0');
end if;
end if;
end if;
case opsel_r is
case opsel_r is
when RES_SUM =>
when RES_SUM =>