type fp_number_class is (ZERO, FINITE, INFINITY, NAN);
constant EXP_BITS : natural := 13;
+ constant UNIT_BIT : natural := 56;
+ constant QNAN_BIT : natural := UNIT_BIT - 1;
+ constant SP_LSB : natural := UNIT_BIT - 23;
+ constant SP_GBIT : natural := SP_LSB - 1;
+ constant SP_RBIT : natural := SP_LSB - 2;
+ constant DP_LSB : natural := UNIT_BIT - 52;
+ constant DP_GBIT : natural := DP_LSB - 1;
+ constant DP_RBIT : natural := DP_LSB - 2;
type fpu_reg_type is record
class : fp_number_class;
negative : std_ulogic;
exponent : signed(EXP_BITS-1 downto 0); -- unbiased
- mantissa : std_ulogic_vector(63 downto 0); -- 10.54 format
+ mantissa : std_ulogic_vector(63 downto 0); -- 8.56 format
end record;
type state_t is (IDLE, DO_ILLEGAL,
a : fpu_reg_type;
b : fpu_reg_type;
c : fpu_reg_type;
- r : std_ulogic_vector(63 downto 0); -- 10.54 format
+ r : std_ulogic_vector(63 downto 0); -- 8.56 format
s : std_ulogic_vector(55 downto 0); -- extended fraction
x : std_ulogic;
p : std_ulogic_vector(63 downto 0); -- 8.56 format
constant BIN_ZERO : std_ulogic_vector(1 downto 0) := "00";
constant BIN_R : std_ulogic_vector(1 downto 0) := "01";
constant BIN_RND : std_ulogic_vector(1 downto 0) := "10";
- constant BIN_PS6 : std_ulogic_vector(1 downto 0) := "11";
+ constant BIN_PS8 : std_ulogic_vector(1 downto 0) := "11";
constant RES_SUM : std_ulogic_vector(1 downto 0) := "00";
constant RES_SHIFT : std_ulogic_vector(1 downto 0) := "01";
if exp_nz = '0' then
r.exponent := to_signed(-1022, EXP_BITS);
end if;
- r.mantissa := "000000000" & exp_nz & fpr(51 downto 0) & "00";
+ r.mantissa := std_ulogic_vector(shift_left(resize(unsigned(exp_nz & fpr(51 downto 0)), 64),
+ UNIT_BIT - 52));
cls := exp_ao & exp_nz & frac_nz;
case cls is
when "000" => r.class := ZERO;
case class is
when ZERO =>
when FINITE =>
- if mantissa(54) = '1' then
+ if mantissa(UNIT_BIT) = '1' then
-- normalized number
result(62 downto 52) := std_ulogic_vector(resize(exp, 11) + 1023);
end if;
- result(51 downto 29) := mantissa(53 downto 31);
+ result(51 downto 29) := mantissa(UNIT_BIT - 1 downto SP_LSB);
if single_prec = '0' then
- result(28 downto 0) := mantissa(30 downto 2);
+ result(28 downto 0) := mantissa(SP_LSB - 1 downto DP_LSB);
end if;
when INFINITY =>
result(62 downto 52) := "11111111111";
when NAN =>
result(62 downto 52) := "11111111111";
- result(51) := quieten_nan or mantissa(53);
- result(50 downto 29) := mantissa(52 downto 31);
+ result(51) := quieten_nan or mantissa(QNAN_BIT);
+ result(50 downto 29) := mantissa(QNAN_BIT - 1 downto SP_LSB);
if single_prec = '0' then
- result(28 downto 0) := mantissa(30 downto 2);
+ result(28 downto 0) := mantissa(SP_LSB - 1 downto DP_LSB);
end if;
end case;
return result;
-- Determine whether to increment when rounding
-- Returns rounding_inc & inexact
- -- Assumes x includes the bottom 29 bits of the mantissa already
- -- if single_prec = 1 (usually arranged by setting set_x = 1 earlier).
+ -- If single_prec = 1, assumes x includes the bottom 31 (== SP_LSB - 2)
+ -- bits of the mantissa already (usually arranged by setting set_x = 1 earlier).
function fp_rounding(mantissa: std_ulogic_vector(63 downto 0); x: std_ulogic;
single_prec: std_ulogic; rn: std_ulogic_vector(2 downto 0);
sign: std_ulogic)
variable lsb : std_ulogic;
begin
if single_prec = '0' then
- grx := mantissa(1 downto 0) & x;
- lsb := mantissa(2);
+ grx := mantissa(DP_GBIT downto DP_RBIT) & (x or (or mantissa(DP_RBIT - 1 downto 0)));
+ lsb := mantissa(DP_LSB);
else
- grx := mantissa(30 downto 29) & x;
- lsb := mantissa(31);
+ grx := mantissa(SP_GBIT downto SP_RBIT) & x;
+ lsb := mantissa(SP_LSB);
end if;
ret(1) := '0';
ret(0) := or (grx);
begin
if rising_edge(clk) then
if r.is_sqrt = '1' then
- addrhi := r.b.mantissa(55 downto 54);
+ addrhi := r.b.mantissa(UNIT_BIT + 1 downto UNIT_BIT);
else
addrhi := "00";
end if;
- addr := addrhi & r.b.mantissa(53 downto 46);
+ addr := addrhi & r.b.mantissa(UNIT_BIT - 1 downto UNIT_BIT - 8);
inverse_est <= '1' & inverse_table(to_integer(unsigned(addr)));
end if;
end process;
variable maddend : std_ulogic_vector(127 downto 0);
variable sum : std_ulogic_vector(63 downto 0);
variable round_inc : std_ulogic_vector(63 downto 0);
+ variable rbit_inc : std_ulogic;
+ variable mult_mask : std_ulogic;
variable int_result : std_ulogic;
variable illegal : std_ulogic;
begin
end if;
end if;
- r_hi_nz <= or (r.r(55 downto 31));
- r_lo_nz <= or (r.r(30 downto 2));
+ r_hi_nz <= or (r.r(UNIT_BIT + 1 downto SP_LSB));
+ r_lo_nz <= or (r.r(SP_LSB - 1 downto DP_LSB));
s_nz <= or (r.s);
if r.single_prec = '0' then
end if;
-- Compare P with zero and with B
- px_nz := or (r.p(57 downto 4));
+ px_nz := or (r.p(UNIT_BIT + 1 downto 4));
pcmpb_eq := '0';
- if r.p(59 downto 4) = r.b.mantissa(55 downto 0) then
+ if r.p(59 downto 4) = r.b.mantissa(UNIT_BIT + 1 downto DP_RBIT) then
pcmpb_eq := '1';
end if;
pcmpb_lt := '0';
- if unsigned(r.p(59 downto 4)) < unsigned(r.b.mantissa(55 downto 0)) then
+ if unsigned(r.p(59 downto 4)) < unsigned(r.b.mantissa(UNIT_BIT + 1 downto DP_RBIT)) then
pcmpb_lt := '1';
end if;
pshift := '0';
renorm_sqrt := '0';
shiftin := '0';
+ rbit_inc := '0';
+ mult_mask := '0';
int_result := '0';
illegal := '0';
case r.state is
v.state := DO_FCTI;
when "10010" =>
v.opsel_a := AIN_A;
- if v.b.mantissa(54) = '0' and v.a.mantissa(54) = '1' then
+ if v.b.mantissa(UNIT_BIT) = '0' and v.a.mantissa(UNIT_BIT) = '1' then
v.opsel_a := AIN_B;
end if;
v.state := DO_FDIV;
when "11001" =>
v.is_multiply := '1';
v.opsel_a := AIN_A;
- if v.c.mantissa(54) = '0' and v.a.mantissa(54) = '1' then
+ if v.c.mantissa(UNIT_BIT) = '0' and v.a.mantissa(UNIT_BIT) = '1' then
v.opsel_a := AIN_C;
end if;
v.state := DO_FMUL;
v.opsel_a := AIN_B;
v.state := DO_FRSQRTE;
when "11100" | "11101" | "11110" | "11111" =>
- if v.a.mantissa(54) = '0' then
+ if v.a.mantissa(UNIT_BIT) = '0' then
v.opsel_a := AIN_A;
- elsif v.c.mantissa(54) = '0' then
+ elsif v.c.mantissa(UNIT_BIT) = '0' then
v.opsel_a := AIN_C;
else
v.opsel_a := AIN_B;
v.instr_done := '1';
v.cr_result := "0000";
if r.a.class = INFINITY or r.b.class = ZERO or r.b.class = INFINITY or
- (r.b.class = FINITE and r.b.mantissa(53) = '0') then
+ (r.b.class = FINITE and r.b.mantissa(UNIT_BIT) = '0') then
v.cr_result(2) := '1';
end if;
if r.a.class = NAN or r.a.class = INFINITY or
v.instr_done := '1';
v.cr_result := "0000";
if r.b.class = ZERO or r.b.class = INFINITY or
- (r.b.class = FINITE and r.b.mantissa(53) = '0') then
+ (r.b.class = FINITE and r.b.mantissa(UNIT_BIT) = '0') then
v.cr_result(2) := '1';
end if;
if r.b.class = NAN or r.b.class = INFINITY or r.b.class = ZERO
v.instr_done := '1';
update_fx := '1';
v.result_exp := r.b.exponent;
- if (r.a.class = NAN and r.a.mantissa(53) = '0') or
- (r.b.class = NAN and r.b.mantissa(53) = '0') then
+ if (r.a.class = NAN and r.a.mantissa(QNAN_BIT) = '0') or
+ (r.b.class = NAN and r.b.mantissa(QNAN_BIT) = '0') then
-- Signalling NAN
v.fpscr(FPSCR_VXSNAN) := '1';
if r.insn(6) = '1' and r.fpscr(FPSCR_VE) = '0' then
v.result_exp := r.b.exponent;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
- if r.b.class = NAN and r.b.mantissa(53) = '0' then
+ if r.b.class = NAN and r.b.mantissa(QNAN_BIT) = '0' then
-- Signalling NAN
v.fpscr(FPSCR_VXSNAN) := '1';
invalid := '1';
elsif r.b.exponent >= to_signed(52, EXP_BITS) then
-- integer already, no rounding required,
-- shift into final position
- v.shift := r.b.exponent - to_signed(54, EXP_BITS);
+ v.shift := r.b.exponent - to_signed(UNIT_BIT, EXP_BITS);
if r.insn(8) = '1' and r.b.negative = '1' then
v.state := INT_OFLOW;
else
v.result_sign := '1';
end if;
v.result_class := r.b.class;
- v.result_exp := to_signed(54, EXP_BITS);
+ v.result_exp := to_signed(UNIT_BIT, EXP_BITS);
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
if r.b.class = ZERO then
if r.a.class = FINITE and r.c.class = FINITE then
v.result_exp := r.a.exponent + r.c.exponent;
-- Renormalize denorm operands
- if r.a.mantissa(54) = '0' then
+ if r.a.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_A;
- elsif r.c.mantissa(54) = '0' then
+ elsif r.c.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_C;
else
f_to_multiply.valid <= '1';
v.count := "00";
if r.a.class = FINITE and r.b.class = FINITE then
-- Renormalize denorm operands
- if r.a.mantissa(54) = '0' then
+ if r.a.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_A;
- elsif r.b.mantissa(54) = '0' then
+ elsif r.b.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_B;
else
v.first := '1';
if r.b.negative = '1' then
v.fpscr(FPSCR_VXSQRT) := '1';
qnan_result := '1';
- elsif r.b.mantissa(54) = '0' then
+ elsif r.b.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_B;
elsif r.b.exponent(0) = '0' then
v.state := SQRT_1;
case r.b.class is
when FINITE =>
v.result_exp := - r.b.exponent;
- if r.b.mantissa(54) = '0' then
+ if r.b.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_B;
else
v.state := FRE_1;
if r.b.negative = '1' then
v.fpscr(FPSCR_VXSQRT) := '1';
qnan_result := '1';
- elsif r.b.mantissa(54) = '0' then
+ elsif r.b.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_B;
elsif r.b.exponent(0) = '0' then
v.state := RSQRT_1;
mulexp := r.a.exponent + r.c.exponent;
v.result_exp := mulexp;
-- Make sure A and C are normalized
- if r.a.mantissa(54) = '0' then
+ if r.a.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_A;
- elsif r.c.mantissa(54) = '0' then
+ elsif r.c.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_C;
elsif r.b.class = ZERO then
-- no addend, degenerates to multiply
set_a := '1';
v.result_exp := new_exp;
if r.insn(4) = '1' then
- if r.c.mantissa(54) = '1' then
+ if r.c.mantissa(UNIT_BIT) = '1' then
if r.insn(3) = '0' or r.b.class = ZERO then
v.first := '1';
v.state := MULT_1;
v.state := RENORM_C;
end if;
else
- if r.b.mantissa(54) = '1' then
+ if r.b.mantissa(UNIT_BIT) = '1' then
v.first := '1';
v.state := DIV_2;
else
opsel_ainv <= '1';
carry_in <= '1';
v.state := FINISH;
- elsif r.r(55) = '1' then
+ elsif r.r(UNIT_BIT + 1) = '1' then
-- sum overflowed, shift right
opsel_r <= RES_SHIFT;
set_x := '1';
else
v.state := ROUNDING;
end if;
- elsif r.r(54) = '1' then
+ elsif r.r(UNIT_BIT) = '1' then
set_x := '1';
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 (or (r.r(DP_LSB - 1 downto 0)))) = '0' then
-- r.x must be zero at this point
v.result_class := ZERO;
if r.is_subtract = '1' then
opsel_s <= S_NEG;
set_s := '1';
end if;
- v.shift := to_signed(56, EXP_BITS);
+ v.shift := to_signed(UNIT_BIT, EXP_BITS);
v.state := FMADD_6;
when FMADD_6 =>
- -- r.shift = 56 (or 0, but only if r is now nonzero)
- if (r.r(56) or r_hi_nz or r_lo_nz or r.r(1) or r.r(0)) = '0' then
+ -- r.shift = UNIT_BIT (or 0, but only if r is now nonzero)
+ if (r.r(UNIT_BIT + 2) or r_hi_nz or r_lo_nz or (or (r.r(DP_LSB - 1 downto 0)))) = '0' then
if s_nz = '0' then
-- must be a subtraction, and r.x must be zero
v.result_class := ZERO;
set_s := '1';
-- stay in state FMADD_6
end if;
- elsif r.r(56 downto 54) = "001" then
+ elsif r.r(UNIT_BIT + 2 downto UNIT_BIT) = "001" then
v.state := FINISH;
else
renormalize := '1';
set_y := r.first;
f_to_multiply.valid <= r.first;
pshift := '1';
+ mult_mask := '1';
if multiply_to_f.valid = '1' then
opsel_r <= RES_MULT;
v.first := '1';
end if;
when DIV_6 =>
+ -- r.opsel_a = AIN_R
-- test if remainder is 0 or >= B
if pcmpb_lt = '1' then
-- quotient is correct, set X if remainder non-zero
- v.x := r.p(58) or px_nz;
+ v.x := r.p(UNIT_BIT + 2) or px_nz;
else
- -- quotient needs to be incremented by 1
- carry_in <= '1';
+ -- quotient needs to be incremented by 1 in R-bit position
+ rbit_inc := '1';
+ opsel_b <= BIN_RND;
v.x := not pcmpb_eq;
end if;
v.state := FINISH;
msel_2 <= MUL2_R;
set_y := r.first;
pshift := '1';
+ mult_mask := '1';
if multiply_to_f.valid = '1' then
-- put result into R
opsel_r <= RES_MULT;
set_y := r.first;
-- wait for second multiply (should be here already)
pshift := '1';
+ mult_mask := '1';
if multiply_to_f.valid = '1' then
-- put result into R
opsel_r <= RES_MULT;
end if;
when SQRT_10 =>
- -- Add the bottom 8 bits of P, sign-extended,
- -- divided by 4, onto R.
- -- The division by 4 is because R is 10.54 format
- -- whereas P is 8.56 format.
- opsel_b <= BIN_PS6;
+ -- Add the bottom 8 bits of P, sign-extended, onto R.
+ opsel_b <= BIN_PS8;
sqrt_exp := r.b.exponent(EXP_BITS-1) & r.b.exponent(EXP_BITS-1 downto 1);
v.result_exp := sqrt_exp;
v.shift := to_signed(1, EXP_BITS);
-- test if remainder is 0 or >= B = 2*R + 1
if pcmpb_lt = '1' then
-- square root is correct, set X if remainder non-zero
- v.x := r.p(58) or px_nz;
+ v.x := r.p(UNIT_BIT + 2) or px_nz;
else
-- square root needs to be incremented by 1
carry_in <= '1';
opsel_r <= RES_SHIFT;
set_x := '1';
v.state := INT_ROUND;
- v.shift := to_signed(-2, EXP_BITS);
+ v.shift := to_signed(52 - UNIT_BIT, EXP_BITS);
when INT_ROUND =>
- -- r.shift = -2
+ -- r.shift = -4 (== 52 - UNIT_BIT)
opsel_r <= RES_SHIFT;
round := fp_rounding(r.r, r.x, '0', r.round_mode, r.result_sign);
v.fpscr(FPSCR_FR downto FPSCR_FI) := round;
end if;
when INT_ISHIFT =>
- -- r.shift = b.exponent - 54;
+ -- r.shift = b.exponent - UNIT_BIT;
opsel_r <= RES_SHIFT;
v.state := INT_FINAL;
if r.is_multiply = '1' and px_nz = '1' then
v.x := '1';
end if;
- if r.r(63 downto 54) /= "0000000001" then
+ if r.r(63 downto UNIT_BIT) /= std_ulogic_vector(to_unsigned(1, 64 - UNIT_BIT)) then
renormalize := '1';
v.state := NORMALIZE;
else
-- if denormalized, have to normalize before rounding
v.fpscr(FPSCR_UX) := '1';
v.result_exp := r.result_exp + bias_exp;
- if r.r(54) = '0' then
+ if r.r(UNIT_BIT) = '0' then
renormalize := '1';
v.state := NORMALIZE;
else
v.shift := to_signed(-1, EXP_BITS);
v.state := ROUNDING_2;
else
- if r.r(54) = '0' then
+ if r.r(UNIT_BIT) = '0' then
-- result after masking could be zero, or could be a
-- denormalized result that needs to be renormalized
renormalize := '1';
-- Check for overflow during rounding
-- r.shift = -1
v.x := '0';
- if r.r(55) = '1' then
+ if r.r(UNIT_BIT + 1) = '1' then
opsel_r <= RES_SHIFT;
if exp_huge = '1' then
v.state := ROUND_OFLOW;
else
arith_done := '1';
end if;
- elsif r.r(54) = '0' then
+ elsif r.r(UNIT_BIT) = '0' then
-- Do CLZ so we can renormalize the result
renormalize := '1';
v.state := ROUNDING_3;
arith_done := '1';
when NAN_RESULT =>
- if (r.use_a = '1' and r.a.class = NAN and r.a.mantissa(53) = '0') or
- (r.use_b = '1' and r.b.class = NAN and r.b.mantissa(53) = '0') or
- (r.use_c = '1' and r.c.class = NAN and r.c.mantissa(53) = '0') then
+ if (r.use_a = '1' and r.a.class = NAN and r.a.mantissa(QNAN_BIT) = '0') or
+ (r.use_b = '1' and r.b.class = NAN and r.b.mantissa(QNAN_BIT) = '0') or
+ (r.use_c = '1' and r.c.class = NAN and r.c.mantissa(QNAN_BIT) = '0') then
-- Signalling NAN
v.fpscr(FPSCR_VXSNAN) := '1';
invalid := '1';
-- Multiplier and divide/square root data path
case msel_1 is
when MUL1_A =>
- f_to_multiply.data1 <= r.a.mantissa(61 downto 0) & "00";
+ f_to_multiply.data1 <= r.a.mantissa;
when MUL1_B =>
- f_to_multiply.data1 <= r.b.mantissa(61 downto 0) & "00";
+ f_to_multiply.data1 <= r.b.mantissa;
when MUL1_Y =>
f_to_multiply.data1 <= r.y;
when others =>
- f_to_multiply.data1 <= r.r(61 downto 0) & "00";
+ f_to_multiply.data1 <= r.r;
end case;
case msel_2 is
when MUL2_C =>
- f_to_multiply.data2 <= r.c.mantissa(61 downto 0) & "00";
+ f_to_multiply.data2 <= r.c.mantissa;
when MUL2_LUT =>
- f_to_multiply.data2 <= x"00" & inverse_est & '0' & x"000000000";
+ f_to_multiply.data2 <= std_ulogic_vector(shift_left(resize(unsigned(inverse_est), 64),
+ UNIT_BIT - 19));
when MUL2_P =>
f_to_multiply.data2 <= r.p;
when others =>
- f_to_multiply.data2 <= r.r(61 downto 0) & "00";
+ f_to_multiply.data2 <= r.r;
end case;
maddend := (others => '0');
case msel_add is
when MULADD_CONST =>
-- addend is 2.0 or 1.5 in 16.112 format
if r.is_sqrt = '0' then
- maddend(113) := '1'; -- 2.0
+ maddend(2*UNIT_BIT + 1) := '1'; -- 2.0
else
- maddend(112 downto 111) := "11"; -- 1.5
+ maddend(2*UNIT_BIT downto 2*UNIT_BIT - 1) := "11"; -- 1.5
end if;
when MULADD_A =>
-- addend is A in 16.112 format
- maddend(121 downto 58) := r.a.mantissa;
+ maddend(UNIT_BIT + 63 downto UNIT_BIT) := r.a.mantissa;
when MULADD_RS =>
-- addend is concatenation of R and S in 16.112 format
- maddend := "000000" & r.r & r.s & "00";
+ maddend(UNIT_BIT + 63 downto UNIT_BIT) := r.r;
+ maddend(UNIT_BIT - 1 downto 0) := r.s;
when others =>
end case;
if msel_inv = '1' then
if pshift = '0' then
v.p := multiply_to_f.result(63 downto 0);
else
- v.p := multiply_to_f.result(119 downto 56);
+ v.p := multiply_to_f.result(UNIT_BIT + 63 downto UNIT_BIT);
end if;
end if;
when BIN_R =>
in_b0 := r.r;
when BIN_RND =>
- round_inc := (31 => r.single_prec, 2 => not r.single_prec, others => '0');
+ if rbit_inc = '0' then
+ round_inc := (SP_LSB => r.single_prec, DP_LSB => not r.single_prec, others => '0');
+ else
+ round_inc := (DP_RBIT => '1', others => '0');
+ end if;
in_b0 := round_inc;
when others =>
- -- BIN_PS6, 6 LSBs of P/4 sign-extended to 64
- in_b0 := std_ulogic_vector(resize(signed(r.p(7 downto 2)), 64));
+ -- BIN_PS8, 8 LSBs of P sign-extended to 64
+ in_b0 := std_ulogic_vector(resize(signed(r.p(7 downto 0)), 64));
end case;
if opsel_binv = '1' then
in_b0 := not in_b0;
end if;
sum := std_ulogic_vector(unsigned(in_a) + unsigned(in_b) + carry_in);
if opsel_mask = '1' then
- sum(1 downto 0) := "00";
+ sum(DP_LSB - 1 downto 0) := "0000";
if r.single_prec = '1' then
- sum(30 downto 2) := (others => '0');
+ sum(SP_LSB - 1 downto DP_LSB) := (others => '0');
end if;
end if;
case opsel_r is
when RES_SHIFT =>
result <= shift_res;
when RES_MULT =>
- result <= multiply_to_f.result(121 downto 58);
+ result <= multiply_to_f.result(UNIT_BIT + 63 downto UNIT_BIT);
+ if mult_mask = '1' then
+ -- trim to 54 fraction bits if mult_mask = 1, for quotient when dividing
+ result(UNIT_BIT - 55 downto 0) <= (others => '0');
+ end if;
when others =>
+ misc := (others => '0');
case misc_sel is
when "0000" =>
misc := x"00000000" & (r.fpscr and fpscr_mask);
when "0001" =>
-- generated QNaN mantissa
- misc := x"0020000000000000";
+ misc(QNAN_BIT) := '1';
when "0010" =>
-- mantissa of max representable DP number
- misc := x"007ffffffffffffc";
+ misc(UNIT_BIT downto DP_LSB) := (others => '1');
when "0011" =>
-- mantissa of max representable SP number
- misc := x"007fffff80000000";
+ misc(UNIT_BIT downto SP_LSB) := (others => '1');
when "0100" =>
-- fmrgow result
misc := r.a.mantissa(31 downto 0) & r.b.mantissa(31 downto 0);
-- fmrgew result
misc := r.a.mantissa(63 downto 32) & r.b.mantissa(63 downto 32);
when "0111" =>
- misc := 10x"000" & inverse_est & 35x"000000000";
+ misc := std_ulogic_vector(shift_left(resize(unsigned(inverse_est), 64),
+ UNIT_BIT - 19));
when "1000" =>
-- max positive result for fctiw[z]
misc := x"000000007fffffff";
-- max negative result for fctidu[z]
misc := x"0000000000000000";
when others =>
- misc := x"0000000000000000";
end case;
result <= misc;
end case;
when S_NEG =>
v.s := std_ulogic_vector(unsigned(not r.s) + (not r.x));
when S_MULT =>
- v.s := multiply_to_f.result(57 downto 2);
+ v.s := multiply_to_f.result(55 downto 0);
when S_SHIFT =>
v.s := shift_res(63 downto 8);
if shift_res(7 downto 0) /= x"00" then
-- make denormalized value end up with even exponent
clz(0) := '1';
end if;
- v.shift := resize(signed('0' & clz) - 9, EXP_BITS);
+ v.shift := resize(signed('0' & clz) - (63 - UNIT_BIT), EXP_BITS);
end if;
if r.update_fprf = '1' then
v.fpscr(FPSCR_C downto FPSCR_FU) := result_flags(r.result_sign, r.result_class,
- r.r(54) and not r.denorm);
+ r.r(UNIT_BIT) and not r.denorm);
end if;
v.fpscr(FPSCR_VX) := (or (v.fpscr(FPSCR_VXSNAN downto FPSCR_VXVC))) or