DO_FRE, DO_FRSQRTE,
DO_FSEL,
FRI_1,
- ADD_SHIFT, ADD_2, ADD_3,
+ ADD_1, ADD_SHIFT, ADD_2, ADD_3,
CMP_1, CMP_2,
MULT_1,
FMADD_1, FMADD_2, FMADD_3,
DENORM,
RENORM_A, RENORM_A2,
RENORM_B, RENORM_B2,
- RENORM_C, RENORM_C2);
+ RENORM_C, RENORM_C2,
+ NAN_RESULT, EXC_RESULT);
type reg_type is record
state : state_t;
first : std_ulogic;
count : unsigned(1 downto 0);
doing_ftdiv : std_ulogic_vector(1 downto 0);
+ opsel_a : std_ulogic_vector(1 downto 0);
+ use_a : std_ulogic;
+ use_b : std_ulogic;
+ use_c : std_ulogic;
+ invalid : std_ulogic;
+ negate : std_ulogic;
end record;
type lookup_table is array(0 to 1023) of std_ulogic_vector(17 downto 0);
signal r, rin : reg_type;
signal fp_result : std_ulogic_vector(63 downto 0);
- signal opsel_a : std_ulogic_vector(1 downto 0);
signal opsel_b : std_ulogic_vector(1 downto 0);
signal opsel_r : std_ulogic_vector(1 downto 0);
signal opsel_s : std_ulogic_vector(1 downto 0);
v.update_fprf := '0';
v.shift := to_signed(0, EXP_BITS);
v.first := '0';
- opsel_a <= AIN_R;
+ v.opsel_a := AIN_R;
opsel_ainv <= '0';
opsel_amask <= '0';
opsel_b <= BIN_ZERO;
shiftin := '0';
case r.state is
when IDLE =>
+ v.use_a := '0';
+ v.use_b := '0';
+ v.use_c := '0';
+ v.invalid := '0';
+ v.negate := '0';
if e_in.valid = '1' then
case e_in.insn(5 downto 1) is
when "00000" =>
elsif e_in.insn(7) = '1' then
v.state := DO_MCRFS;
else
+ v.opsel_a := AIN_B;
v.state := DO_FCMP;
end if;
when "00110" =>
v.state := DO_MTFSF;
end if;
when "01000" =>
+ v.opsel_a := AIN_B;
if e_in.insn(9 downto 8) /= "11" then
v.state := DO_FMR;
else
v.state := DO_FRI;
end if;
when "01100" =>
+ v.opsel_a := AIN_B;
v.state := DO_FRSP;
when "01110" =>
+ v.opsel_a := AIN_B;
if int_input = '1' then
-- fcfid[u][s]
v.state := DO_FCFID;
end if;
when "01111" =>
v.round_mode := "001";
+ v.opsel_a := AIN_B;
v.state := DO_FCTI;
when "10010" =>
+ v.opsel_a := AIN_A;
+ if v.b.mantissa(54) = '0' and v.a.mantissa(54) = '1' then
+ v.opsel_a := AIN_B;
+ end if;
v.state := DO_FDIV;
when "10100" | "10101" =>
+ v.opsel_a := AIN_A;
v.state := DO_FADD;
when "10110" =>
v.is_sqrt := '1';
+ v.opsel_a := AIN_B;
v.state := DO_FSQRT;
when "10111" =>
v.state := DO_FSEL;
when "11000" =>
+ v.opsel_a := AIN_B;
v.state := DO_FRE;
when "11001" =>
v.is_multiply := '1';
+ v.opsel_a := AIN_A;
+ if v.c.mantissa(54) = '0' and v.a.mantissa(54) = '1' then
+ v.opsel_a := AIN_C;
+ end if;
v.state := DO_FMUL;
when "11010" =>
v.is_sqrt := '1';
+ v.opsel_a := AIN_B;
v.state := DO_FRSQRTE;
when "11100" | "11101" | "11110" | "11111" =>
+ if v.a.mantissa(54) = '0' then
+ v.opsel_a := AIN_A;
+ elsif v.c.mantissa(54) = '0' then
+ v.opsel_a := AIN_C;
+ else
+ v.opsel_a := AIN_B;
+ end if;
v.state := DO_FMADD;
when others =>
illegal := '1';
when DO_FCMP =>
-- fcmp[uo]
+ -- r.opsel_a = AIN_B
v.instr_done := '1';
v.state := IDLE;
update_fx := '1';
- opsel_a <= AIN_B;
- opsel_r <= RES_SUM;
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
-- Prepare to subtract mantissas, put B in R
v.cr_result := "0000";
v.instr_done := '0';
+ v.opsel_a := AIN_A;
v.state := CMP_1;
end if;
v.fpscr(FPSCR_FL downto FPSCR_FU) := v.cr_result;
v.state := IDLE;
when DO_FMR =>
- opsel_a <= AIN_B;
+ -- r.opsel_a = AIN_B
v.result_class := r.b.class;
v.result_exp := r.b.exponent;
v.quieten_nan := '0';
v.state := IDLE;
when DO_FRI => -- fri[nzpm]
- opsel_a <= AIN_B;
+ -- r.opsel_a = AIN_B
v.result_class := r.b.class;
v.result_sign := r.b.negative;
v.result_exp := r.b.exponent;
end if;
when DO_FRSP =>
- opsel_a <= AIN_B;
+ -- r.opsel_a = AIN_B, r.shift = 0
v.result_class := r.b.class;
v.result_sign := r.b.negative;
v.result_exp := r.b.exponent;
-- instr bit 9: 1=dword 0=word
-- instr bit 8: 1=unsigned 0=signed
-- instr bit 1: 1=round to zero 0=use fpscr[RN]
- opsel_a <= AIN_B;
+ -- r.opsel_a = AIN_B
v.result_class := r.b.class;
v.result_sign := r.b.negative;
v.result_exp := r.b.exponent;
end case;
when DO_FCFID =>
+ -- r.opsel_a = AIN_B
v.result_sign := '0';
- opsel_a <= AIN_B;
if r.insn(8) = '0' and r.b.negative = '1' then
-- fcfid[s] with negative operand, set R = -B
opsel_ainv <= '1';
when DO_FADD =>
-- fadd[s] and fsub[s]
- opsel_a <= AIN_A;
+ -- r.opsel_a = AIN_A
v.result_sign := r.a.negative;
v.result_class := r.a.class;
v.result_exp := r.a.exponent;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
+ v.use_a := '1';
+ v.use_b := '1';
is_add := r.a.negative xor r.b.negative xor r.insn(1);
if r.a.class = FINITE and r.b.class = FINITE then
v.is_subtract := not is_add;
v.add_bsmall := r.exp_cmp;
+ v.opsel_a := AIN_B;
if r.exp_cmp = '0' then
v.shift := r.a.exponent - r.b.exponent;
v.result_sign := r.b.negative xnor r.insn(1);
v.state := ADD_SHIFT;
end if;
else
- opsel_a <= AIN_B;
- v.shift := r.b.exponent - r.a.exponent;
- v.result_exp := r.b.exponent;
- v.state := ADD_SHIFT;
+ v.state := ADD_1;
end if;
else
- if (r.a.class = NAN and r.a.mantissa(53) = '0') or
- (r.b.class = NAN and r.b.mantissa(53) = '0') then
- -- Signalling NAN
- v.fpscr(FPSCR_VXSNAN) := '1';
- invalid := '1';
- end if;
- if r.a.class = NAN then
- -- nothing to do, result is A
- elsif r.b.class = NAN then
- v.result_class := NAN;
- v.result_sign := r.b.negative;
- opsel_a <= AIN_B;
+ if r.a.class = NAN or r.b.class = NAN then
+ v.state := NAN_RESULT;
elsif r.a.class = INFINITY and r.b.class = INFINITY and is_add = '0' then
-- invalid operation, construct QNaN
v.fpscr(FPSCR_VXISI) := '1';
qnan_result := '1';
+ arith_done := '1';
elsif r.a.class = ZERO and r.b.class = ZERO and is_add = '0' then
-- return -0 for rounding to -infinity
v.result_sign := r.round_mode(1) and r.round_mode(0);
+ arith_done := '1';
elsif r.a.class = INFINITY or r.b.class = ZERO then
- -- nothing to do, result is A
+ -- result is A
+ v.opsel_a := AIN_A;
+ v.state := EXC_RESULT;
else
-- result is +/- B
- v.result_sign := r.b.negative xnor r.insn(1);
- v.result_class := r.b.class;
- v.result_exp := r.b.exponent;
- opsel_a <= AIN_B;
+ v.opsel_a := AIN_B;
+ v.negate := not r.insn(1);
+ v.state := EXC_RESULT;
end if;
- arith_done := '1';
end if;
when DO_FMUL =>
-- fmul[s]
- opsel_a <= AIN_A;
- v.result_sign := r.a.negative;
+ -- r.opsel_a = AIN_A unless C is denorm and A isn't
+ v.result_sign := r.a.negative xor r.c.negative;
v.result_class := r.a.class;
- v.result_exp := r.a.exponent;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
+ v.use_a := '1';
+ v.use_c := '1';
if r.a.class = FINITE and r.c.class = FINITE then
- v.result_sign := r.a.negative xor r.c.negative;
v.result_exp := r.a.exponent + r.c.exponent;
-- Renormalize denorm operands
if r.a.mantissa(54) = '0' then
v.state := RENORM_A;
elsif r.c.mantissa(54) = '0' then
- opsel_a <= AIN_C;
v.state := RENORM_C;
else
f_to_multiply.valid <= '1';
v.state := MULT_1;
end if;
else
- if (r.a.class = NAN and r.a.mantissa(53) = '0') or
- (r.c.class = NAN and r.c.mantissa(53) = '0') then
- -- Signalling NAN
- v.fpscr(FPSCR_VXSNAN) := '1';
- invalid := '1';
- end if;
- if r.a.class = NAN then
- -- result is A
- elsif r.c.class = NAN then
- v.result_class := NAN;
- v.result_sign := r.c.negative;
- opsel_a <= AIN_C;
+ if r.a.class = NAN or r.c.class = NAN then
+ v.state := NAN_RESULT;
elsif (r.a.class = INFINITY and r.c.class = ZERO) or
(r.a.class = ZERO and r.c.class = INFINITY) then
-- invalid operation, construct QNaN
qnan_result := '1';
elsif r.a.class = ZERO or r.a.class = INFINITY then
-- result is +/- A
- v.result_sign := r.a.negative xor r.c.negative;
+ arith_done := '1';
else
-- r.c.class is ZERO or INFINITY
- v.result_class := r.c.class;
- v.result_sign := r.a.negative xor r.c.negative;
+ v.opsel_a := AIN_C;
+ v.negate := r.a.negative;
+ v.state := EXC_RESULT;
end if;
- arith_done := '1';
end if;
when DO_FDIV =>
- opsel_a <= AIN_A;
- v.result_sign := r.a.negative;
+ -- r.opsel_a = AIN_A unless B is denorm and A isn't
v.result_class := r.a.class;
- v.result_exp := r.a.exponent;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
+ v.use_a := '1';
+ v.use_b := '1';
v.result_sign := r.a.negative xor r.b.negative;
v.result_exp := r.a.exponent - r.b.exponent;
v.count := "00";
if r.a.mantissa(54) = '0' then
v.state := RENORM_A;
elsif r.b.mantissa(54) = '0' then
- opsel_a <= AIN_B;
v.state := RENORM_B;
else
v.first := '1';
v.state := DIV_2;
end if;
else
- if (r.a.class = NAN and r.a.mantissa(53) = '0') or
- (r.b.class = NAN and r.b.mantissa(53) = '0') then
- -- Signalling NAN
- v.fpscr(FPSCR_VXSNAN) := '1';
- invalid := '1';
- end if;
- if r.a.class = NAN then
- -- result is A
- v.result_sign := r.a.negative;
- elsif r.b.class = NAN then
- v.result_class := NAN;
- v.result_sign := r.b.negative;
- opsel_a <= AIN_B;
+ if r.a.class = NAN or r.b.class = NAN then
+ v.state := NAN_RESULT;
elsif r.b.class = INFINITY then
if r.a.class = INFINITY then
v.fpscr(FPSCR_VXIDI) := '1';
else
v.result_class := ZERO;
end if;
+ arith_done := '1';
elsif r.b.class = ZERO then
if r.a.class = ZERO then
v.fpscr(FPSCR_VXZDZ) := '1';
end if;
v.result_class := INFINITY;
end if;
- -- else r.b.class = FINITE, result_class = r.a.class
+ arith_done := '1';
+ else -- r.b.class = FINITE, result_class = r.a.class
+ arith_done := '1';
end if;
- arith_done := '1';
end if;
when DO_FSEL =>
- opsel_a <= AIN_A;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
if r.a.class = ZERO or (r.a.negative = '0' and r.a.class /= NAN) then
- v.result_sign := r.c.negative;
- v.result_exp := r.c.exponent;
- v.result_class := r.c.class;
- opsel_a <= AIN_C;
+ v.opsel_a := AIN_C;
else
- v.result_sign := r.b.negative;
- v.result_exp := r.b.exponent;
- v.result_class := r.b.class;
- opsel_a <= AIN_B;
+ v.opsel_a := AIN_B;
end if;
v.quieten_nan := '0';
- arith_done := '1';
+ v.state := EXC_RESULT;
when DO_FSQRT =>
- opsel_a <= AIN_B;
+ -- r.opsel_a = AIN_B
v.result_class := r.b.class;
v.result_sign := r.b.negative;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
- if r.b.class = NAN and r.b.mantissa(53) = '0' then
- v.fpscr(FPSCR_VXSNAN) := '1';
- invalid := '1';
- end if;
+ v.use_b := '1';
case r.b.class is
when FINITE =>
v.result_exp := r.b.exponent;
if r.b.negative = '1' then
v.fpscr(FPSCR_VXSQRT) := '1';
qnan_result := '1';
- arith_done := '1';
elsif r.b.mantissa(54) = '0' then
v.state := RENORM_B;
elsif r.b.exponent(0) = '0' then
v.shift := to_signed(1, EXP_BITS);
v.state := RENORM_B2;
end if;
- when NAN | ZERO =>
+ when NAN =>
+ v.state := NAN_RESULT;
+ when ZERO =>
-- result is B
arith_done := '1';
when INFINITY =>
end case;
when DO_FRE =>
- opsel_a <= AIN_B;
+ -- r.opsel_a = AIN_B
v.result_class := r.b.class;
v.result_sign := r.b.negative;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
- if r.b.class = NAN and r.b.mantissa(53) = '0' then
- v.fpscr(FPSCR_VXSNAN) := '1';
- invalid := '1';
- end if;
+ v.use_b := '1';
case r.b.class is
when FINITE =>
v.result_exp := - r.b.exponent;
v.state := FRE_1;
end if;
when NAN =>
- -- result is B
- arith_done := '1';
+ v.state := NAN_RESULT;
when INFINITY =>
v.result_class := ZERO;
arith_done := '1';
end case;
when DO_FRSQRTE =>
- opsel_a <= AIN_B;
+ -- r.opsel_a = AIN_B
v.result_class := r.b.class;
v.result_sign := r.b.negative;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
- if r.b.class = NAN and r.b.mantissa(53) = '0' then
- v.fpscr(FPSCR_VXSNAN) := '1';
- invalid := '1';
- end if;
+ v.use_b := '1';
v.shift := to_signed(1, EXP_BITS);
case r.b.class is
when FINITE =>
if r.b.negative = '1' then
v.fpscr(FPSCR_VXSQRT) := '1';
qnan_result := '1';
- arith_done := '1';
elsif r.b.mantissa(54) = '0' then
v.state := RENORM_B;
elsif r.b.exponent(0) = '0' then
v.state := RENORM_B2;
end if;
when NAN =>
- -- result is B
- arith_done := '1';
+ v.state := NAN_RESULT;
when INFINITY =>
if r.b.negative = '1' then
v.fpscr(FPSCR_VXSQRT) := '1';
when DO_FMADD =>
-- fmadd, fmsub, fnmadd, fnmsub
- opsel_a <= AIN_A;
+ -- r.opsel_a = AIN_A if A is denorm, else AIN_C if C is denorm,
+ -- else AIN_B
v.result_sign := r.a.negative;
v.result_class := r.a.class;
v.result_exp := r.a.exponent;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
+ v.use_a := '1';
+ v.use_b := '1';
+ v.use_c := '1';
is_add := r.a.negative xor r.c.negative xor r.b.negative xor r.insn(1);
if r.a.class = FINITE and r.c.class = FINITE and
(r.b.class = FINITE or r.b.class = ZERO) then
v.is_subtract := not is_add;
mulexp := r.a.exponent + r.c.exponent;
v.result_exp := mulexp;
- opsel_a <= AIN_B;
-- Make sure A and C are normalized
if r.a.mantissa(54) = '0' then
- opsel_a <= AIN_A;
v.state := RENORM_A;
elsif r.c.mantissa(54) = '0' then
- opsel_a <= AIN_C;
v.state := RENORM_C;
elsif r.b.class = ZERO then
-- no addend, degenerates to multiply
v.state := FMADD_2;
end if;
else
- if (r.a.class = NAN and r.a.mantissa(53) = '0') or
- (r.b.class = NAN and r.b.mantissa(53) = '0') or
- (r.c.class = NAN and r.c.mantissa(53) = '0') then
- -- Signalling NAN
- v.fpscr(FPSCR_VXSNAN) := '1';
- invalid := '1';
- end if;
- if r.a.class = NAN then
- -- nothing to do, result is A
- elsif r.b.class = NAN then
- -- result is B
- v.result_class := NAN;
- v.result_sign := r.b.negative;
- opsel_a <= AIN_B;
- elsif r.c.class = NAN then
- -- result is C
- v.result_class := NAN;
- v.result_sign := r.c.negative;
- opsel_a <= AIN_C;
+ if r.a.class = NAN or r.b.class = NAN or r.c.class = NAN then
+ v.state := NAN_RESULT;
elsif (r.a.class = ZERO and r.c.class = INFINITY) or
(r.a.class = INFINITY and r.c.class = ZERO) then
-- invalid operation, construct QNaN
-- result is infinity
v.result_class := INFINITY;
v.result_sign := r.a.negative xor r.c.negative xor r.insn(2);
+ arith_done := '1';
end if;
else
-- Here A is zero, C is zero, or B is infinity
-- Result is +/-B in all of those cases
- v.result_class := r.b.class;
- v.result_exp := r.b.exponent;
- if v.result_class /= ZERO or is_add = '1' then
- v.result_sign := not (r.b.negative xor r.insn(1) xor r.insn(2));
+ v.opsel_a := AIN_B;
+ if r.b.class /= ZERO or is_add = '1' then
+ v.negate := not (r.insn(1) xor r.insn(2));
else
-- have to be careful about rule for 0 - 0 result sign
- v.result_sign := (r.round_mode(1) and r.round_mode(0)) xor r.insn(2);
+ v.negate := r.b.negative xor (r.round_mode(1) and r.round_mode(0)) xor r.insn(2);
end if;
- opsel_a <= AIN_B;
+ v.state := EXC_RESULT;
end if;
- arith_done := '1';
end if;
when RENORM_A =>
renormalize := '1';
v.state := RENORM_A2;
+ if r.insn(4) = '1' then
+ v.opsel_a := AIN_C;
+ else
+ v.opsel_a := AIN_B;
+ end if;
when RENORM_A2 =>
+ -- r.opsel_a = AIN_C for fmul/fmadd, AIN_B for fdiv
set_a := '1';
v.result_exp := new_exp;
if r.insn(4) = '1' then
- opsel_a <= AIN_C;
if r.c.mantissa(54) = '1' then
if r.insn(3) = '0' or r.b.class = ZERO then
v.first := '1';
if new_exp + 1 >= r.b.exponent then
v.madd_cmp := '1';
end if;
+ v.opsel_a := AIN_B;
v.state := DO_FMADD;
end if;
else
v.state := RENORM_C;
end if;
else
- opsel_a <= AIN_B;
- if r.b.mantissa(54) = '1' then
- v.first := '1';
- v.state := DIV_2;
- else
- v.state := RENORM_B;
+ if r.b.mantissa(54) = '1' then
+ v.first := '1';
+ v.state := DIV_2;
+ else
+ v.state := RENORM_B;
end if;
end if;
else
v.result_exp := new_exp;
end if;
+ v.opsel_a := AIN_B;
v.state := LOOKUP;
when RENORM_C =>
if new_exp + 1 >= r.b.exponent then
v.madd_cmp := '1';
end if;
+ v.opsel_a := AIN_B;
v.state := DO_FMADD;
end if;
+ when ADD_1 =>
+ -- transferring B to R
+ v.shift := r.b.exponent - r.a.exponent;
+ v.result_exp := r.b.exponent;
+ v.state := ADD_SHIFT;
+
when ADD_SHIFT =>
-- r.shift = - exponent difference
opsel_r <= RES_SHIFT;
v.x := s_nz;
set_x := '1';
longmask := '0';
- v.state := ADD_2;
-
- when ADD_2 =>
if r.add_bsmall = '1' then
- opsel_a <= AIN_A;
+ v.opsel_a := AIN_A;
else
- opsel_a <= AIN_B;
+ v.opsel_a := AIN_B;
end if;
+ v.state := ADD_2;
+
+ when ADD_2 =>
+ -- r.opsel_a = AIN_A if r.add_bsmall = 1 else AIN_B
opsel_b <= BIN_R;
opsel_binv <= r.is_subtract;
carry_in <= r.is_subtract and not r.x;
end if;
when CMP_1 =>
- opsel_a <= AIN_A;
+ -- r.opsel_a = AIN_A
opsel_b <= BIN_R;
opsel_binv <= '1';
carry_in <= '1';
when FMADD_2 =>
-- Product is potentially bigger here
- -- r.shift = addend exp - product exp + 64
+ -- r.shift = addend exp - product exp + 64, r.r = r.b.mantissa
set_s := '1';
opsel_s <= S_SHIFT;
v.shift := r.shift - to_signed(64, EXP_BITS);
end if;
when LOOKUP =>
- opsel_a <= AIN_B;
+ -- r.opsel_a = AIN_B
-- wait one cycle for inverse_table[B] lookup
v.first := '1';
if r.insn(4) = '0' then
opsel_r <= RES_SHIFT;
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
+ -- Signalling NAN
+ v.fpscr(FPSCR_VXSNAN) := '1';
+ invalid := '1';
+ end if;
+ if r.use_a = '1' and r.a.class = NAN then
+ v.opsel_a := AIN_A;
+ elsif r.use_b = '1' and r.b.class = NAN then
+ v.opsel_a := AIN_B;
+ elsif r.use_c = '1' and r.c.class = NAN then
+ v.opsel_a := AIN_C;
+ end if;
+ v.state := EXC_RESULT;
+
+ when EXC_RESULT =>
+ -- r.opsel_a = AIN_A, AIN_B or AIN_C according to which input is the result
+ case r.opsel_a is
+ when AIN_B =>
+ v.result_sign := r.b.negative xor r.negate;
+ v.result_exp := r.b.exponent;
+ v.result_class := r.b.class;
+ when AIN_C =>
+ v.result_sign := r.c.negative xor r.negate;
+ v.result_exp := r.c.exponent;
+ v.result_class := r.c.class;
+ when others =>
+ v.result_sign := r.a.negative xor r.negate;
+ v.result_exp := r.a.exponent;
+ v.result_class := r.a.class;
+ end case;
+ arith_done := '1';
+
end case;
if zero_divide = '1' then
v.result_sign := '0';
misc_sel <= "0001";
opsel_r <= RES_MISC;
+ arith_done := '1';
+ end if;
+ if invalid = '1' then
+ v.invalid := '1';
end if;
if arith_done = '1' then
-- Enabled invalid exception doesn't write result or FPRF
-- Neither does enabled zero-divide exception
- if (invalid and r.fpscr(FPSCR_VE)) = '0' and
+ if (v.invalid and r.fpscr(FPSCR_VE)) = '0' and
(zero_divide and r.fpscr(FPSCR_ZE)) = '0' then
v.writing_back := '1';
v.update_fprf := '1';
else
mask := right_mask(unsigned(mshift(5 downto 0)));
end if;
- case opsel_a is
+ case r.opsel_a is
when AIN_R =>
in_a0 := r.r;
when AIN_A =>