1 -- Floating-point unit for Microwatt
4 use ieee.std_logic_1164.all;
5 use ieee.numeric_std.all;
8 use work.insn_helpers.all;
9 use work.decode_types.all;
10 use work.crhelpers.all;
19 e_in : in Execute1toFPUType;
20 e_out : out FPUToExecute1Type;
22 w_out : out FPUToWritebackType
26 architecture behaviour of fpu is
27 type fp_number_class is (ZERO, FINITE, INFINITY, NAN);
29 constant EXP_BITS : natural := 13;
31 type fpu_reg_type is record
32 class : fp_number_class;
33 negative : std_ulogic;
34 exponent : signed(EXP_BITS-1 downto 0); -- unbiased
35 mantissa : std_ulogic_vector(63 downto 0); -- 10.54 format
38 type state_t is (IDLE,
39 DO_MCRFS, DO_MTFSB, DO_MTFSFI, DO_MFFS, DO_MTFSF,
43 DO_FADD, DO_FMUL, DO_FDIV,
45 ADD_SHIFT, ADD_2, ADD_3,
48 DIV_2, DIV_3, DIV_4, DIV_5, DIV_6,
49 INT_SHIFT, INT_ROUND, INT_ISHIFT,
50 INT_FINAL, INT_CHECK, INT_OFLOW,
52 ROUND_UFLOW, ROUND_OFLOW,
53 ROUNDING, ROUNDING_2, ROUNDING_3,
59 type reg_type is record
62 instr_done : std_ulogic;
65 insn : std_ulogic_vector(31 downto 0);
66 dest_fpr : gspr_index_t;
70 single_prec : std_ulogic;
71 fpscr : std_ulogic_vector(31 downto 0);
75 r : std_ulogic_vector(63 downto 0); -- 10.54 format
77 p : std_ulogic_vector(63 downto 0); -- 8.56 format
78 y : std_ulogic_vector(63 downto 0); -- 8.56 format
79 result_sign : std_ulogic;
80 result_class : fp_number_class;
81 result_exp : signed(EXP_BITS-1 downto 0);
82 shift : signed(EXP_BITS-1 downto 0);
83 writing_back : std_ulogic;
84 int_result : std_ulogic;
85 cr_result : std_ulogic_vector(3 downto 0);
86 cr_mask : std_ulogic_vector(7 downto 0);
87 old_exc : std_ulogic_vector(4 downto 0);
88 update_fprf : std_ulogic;
89 quieten_nan : std_ulogic;
92 round_mode : std_ulogic_vector(2 downto 0);
93 is_subtract : std_ulogic;
95 add_bsmall : std_ulogic;
96 is_multiply : std_ulogic;
98 count : unsigned(1 downto 0);
101 type lookup_table is array(0 to 255) of std_ulogic_vector(17 downto 0);
103 signal r, rin : reg_type;
105 signal fp_result : std_ulogic_vector(63 downto 0);
106 signal opsel_a : std_ulogic_vector(1 downto 0);
107 signal opsel_b : std_ulogic_vector(1 downto 0);
108 signal opsel_r : std_ulogic_vector(1 downto 0);
109 signal opsel_ainv : std_ulogic;
110 signal opsel_amask : std_ulogic;
111 signal opsel_binv : std_ulogic;
112 signal in_a : std_ulogic_vector(63 downto 0);
113 signal in_b : std_ulogic_vector(63 downto 0);
114 signal result : std_ulogic_vector(63 downto 0);
115 signal carry_in : std_ulogic;
116 signal lost_bits : std_ulogic;
117 signal r_hi_nz : std_ulogic;
118 signal r_lo_nz : std_ulogic;
119 signal misc_sel : std_ulogic_vector(3 downto 0);
120 signal f_to_multiply : MultiplyInputType;
121 signal multiply_to_f : MultiplyOutputType;
122 signal msel_1 : std_ulogic_vector(1 downto 0);
123 signal msel_2 : std_ulogic_vector(1 downto 0);
124 signal msel_add : std_ulogic_vector(1 downto 0);
125 signal msel_inv : std_ulogic;
126 signal inverse_est : std_ulogic_vector(18 downto 0);
129 constant AIN_R : std_ulogic_vector(1 downto 0) := "00";
130 constant AIN_A : std_ulogic_vector(1 downto 0) := "01";
131 constant AIN_B : std_ulogic_vector(1 downto 0) := "10";
132 constant AIN_C : std_ulogic_vector(1 downto 0) := "11";
134 constant BIN_ZERO : std_ulogic_vector(1 downto 0) := "00";
135 constant BIN_R : std_ulogic_vector(1 downto 0) := "01";
136 constant BIN_MASK : std_ulogic_vector(1 downto 0) := "10";
138 constant RES_SUM : std_ulogic_vector(1 downto 0) := "00";
139 constant RES_SHIFT : std_ulogic_vector(1 downto 0) := "01";
140 constant RES_MULT : std_ulogic_vector(1 downto 0) := "10";
141 constant RES_MISC : std_ulogic_vector(1 downto 0) := "11";
144 constant MUL1_A : std_ulogic_vector(1 downto 0) := "00";
145 constant MUL1_B : std_ulogic_vector(1 downto 0) := "01";
146 constant MUL1_Y : std_ulogic_vector(1 downto 0) := "10";
147 constant MUL1_R : std_ulogic_vector(1 downto 0) := "11";
149 constant MUL2_C : std_ulogic_vector(1 downto 0) := "00";
150 constant MUL2_LUT : std_ulogic_vector(1 downto 0) := "01";
151 constant MUL2_P : std_ulogic_vector(1 downto 0) := "10";
152 constant MUL2_R : std_ulogic_vector(1 downto 0) := "11";
154 constant MULADD_ZERO : std_ulogic_vector(1 downto 0) := "00";
155 constant MULADD_CONST : std_ulogic_vector(1 downto 0) := "01";
156 constant MULADD_A : std_ulogic_vector(1 downto 0) := "10";
158 -- Inverse lookup table, indexed by the top 8 fraction bits
159 -- Output range is [0.5, 1) in 0.19 format, though the top
160 -- bit isn't stored since it is always 1.
161 -- Each output value is the inverse of the center of the input
162 -- range for the value, i.e. entry 0 is 1 / (1 + 1/512),
163 -- entry 1 is 1 / (1 + 3/512), etc.
164 signal inverse_table : lookup_table := (
166 -- Unit bit is assumed to be 1, so input range is [1, 2)
167 18x"3fc01", 18x"3f411", 18x"3ec31", 18x"3e460", 18x"3dc9f", 18x"3d4ec", 18x"3cd49", 18x"3c5b5",
168 18x"3be2f", 18x"3b6b8", 18x"3af4f", 18x"3a7f4", 18x"3a0a7", 18x"39968", 18x"39237", 18x"38b14",
169 18x"383fe", 18x"37cf5", 18x"375f9", 18x"36f0a", 18x"36828", 18x"36153", 18x"35a8a", 18x"353ce",
170 18x"34d1e", 18x"3467a", 18x"33fe3", 18x"33957", 18x"332d7", 18x"32c62", 18x"325f9", 18x"31f9c",
171 18x"3194a", 18x"31303", 18x"30cc7", 18x"30696", 18x"30070", 18x"2fa54", 18x"2f443", 18x"2ee3d",
172 18x"2e841", 18x"2e250", 18x"2dc68", 18x"2d68b", 18x"2d0b8", 18x"2caee", 18x"2c52e", 18x"2bf79",
173 18x"2b9cc", 18x"2b429", 18x"2ae90", 18x"2a900", 18x"2a379", 18x"29dfb", 18x"29887", 18x"2931b",
174 18x"28db8", 18x"2885e", 18x"2830d", 18x"27dc4", 18x"27884", 18x"2734d", 18x"26e1d", 18x"268f6",
175 18x"263d8", 18x"25ec1", 18x"259b3", 18x"254ac", 18x"24fad", 18x"24ab7", 18x"245c8", 18x"240e1",
176 18x"23c01", 18x"23729", 18x"23259", 18x"22d90", 18x"228ce", 18x"22413", 18x"21f60", 18x"21ab4",
177 18x"2160f", 18x"21172", 18x"20cdb", 18x"2084b", 18x"203c2", 18x"1ff40", 18x"1fac4", 18x"1f64f",
178 18x"1f1e1", 18x"1ed79", 18x"1e918", 18x"1e4be", 18x"1e069", 18x"1dc1b", 18x"1d7d4", 18x"1d392",
179 18x"1cf57", 18x"1cb22", 18x"1c6f3", 18x"1c2ca", 18x"1bea7", 18x"1ba8a", 18x"1b672", 18x"1b261",
180 18x"1ae55", 18x"1aa50", 18x"1a64f", 18x"1a255", 18x"19e60", 18x"19a70", 18x"19686", 18x"192a2",
181 18x"18ec3", 18x"18ae9", 18x"18715", 18x"18345", 18x"17f7c", 18x"17bb7", 18x"177f7", 18x"1743d",
182 18x"17087", 18x"16cd7", 18x"1692c", 18x"16585", 18x"161e4", 18x"15e47", 18x"15ab0", 18x"1571d",
183 18x"1538e", 18x"15005", 18x"14c80", 18x"14900", 18x"14584", 18x"1420d", 18x"13e9b", 18x"13b2d",
184 18x"137c3", 18x"1345e", 18x"130fe", 18x"12da2", 18x"12a4a", 18x"126f6", 18x"123a7", 18x"1205c",
185 18x"11d15", 18x"119d2", 18x"11694", 18x"11359", 18x"11023", 18x"10cf1", 18x"109c2", 18x"10698",
186 18x"10372", 18x"10050", 18x"0fd31", 18x"0fa17", 18x"0f700", 18x"0f3ed", 18x"0f0de", 18x"0edd3",
187 18x"0eacb", 18x"0e7c7", 18x"0e4c7", 18x"0e1ca", 18x"0ded2", 18x"0dbdc", 18x"0d8eb", 18x"0d5fc",
188 18x"0d312", 18x"0d02b", 18x"0cd47", 18x"0ca67", 18x"0c78a", 18x"0c4b1", 18x"0c1db", 18x"0bf09",
189 18x"0bc3a", 18x"0b96e", 18x"0b6a5", 18x"0b3e0", 18x"0b11e", 18x"0ae5f", 18x"0aba3", 18x"0a8eb",
190 18x"0a636", 18x"0a383", 18x"0a0d4", 18x"09e28", 18x"09b80", 18x"098da", 18x"09637", 18x"09397",
191 18x"090fb", 18x"08e61", 18x"08bca", 18x"08936", 18x"086a5", 18x"08417", 18x"0818c", 18x"07f04",
192 18x"07c7e", 18x"079fc", 18x"0777c", 18x"074ff", 18x"07284", 18x"0700d", 18x"06d98", 18x"06b26",
193 18x"068b6", 18x"0664a", 18x"063e0", 18x"06178", 18x"05f13", 18x"05cb1", 18x"05a52", 18x"057f5",
194 18x"0559a", 18x"05342", 18x"050ed", 18x"04e9a", 18x"04c4a", 18x"049fc", 18x"047b0", 18x"04567",
195 18x"04321", 18x"040dd", 18x"03e9b", 18x"03c5c", 18x"03a1f", 18x"037e4", 18x"035ac", 18x"03376",
196 18x"03142", 18x"02f11", 18x"02ce2", 18x"02ab5", 18x"0288b", 18x"02663", 18x"0243d", 18x"02219",
197 18x"01ff7", 18x"01dd8", 18x"01bbb", 18x"019a0", 18x"01787", 18x"01570", 18x"0135b", 18x"01149",
198 18x"00f39", 18x"00d2a", 18x"00b1e", 18x"00914", 18x"0070c", 18x"00506", 18x"00302", 18x"00100"
201 -- Left and right shifter with 120 bit input and 64 bit output.
202 -- Shifts inp left by shift bits and returns the upper 64 bits of
203 -- the result. The shift parameter is interpreted as a signed
204 -- number in the range -64..63, with negative values indicating
206 function shifter_64(inp: std_ulogic_vector(119 downto 0);
207 shift: std_ulogic_vector(6 downto 0))
208 return std_ulogic_vector is
209 variable s1 : std_ulogic_vector(94 downto 0);
210 variable s2 : std_ulogic_vector(70 downto 0);
211 variable result : std_ulogic_vector(63 downto 0);
213 case shift(6 downto 5) is
215 s1 := inp(119 downto 25);
217 s1 := inp(87 downto 0) & "0000000";
219 s1 := x"0000000000000000" & inp(119 downto 89);
221 s1 := x"00000000" & inp(119 downto 57);
223 case shift(4 downto 3) is
225 s2 := s1(94 downto 24);
227 s2 := s1(86 downto 16);
229 s2 := s1(78 downto 8);
231 s2 := s1(70 downto 0);
233 case shift(2 downto 0) is
235 result := s2(70 downto 7);
237 result := s2(69 downto 6);
239 result := s2(68 downto 5);
241 result := s2(67 downto 4);
243 result := s2(66 downto 3);
245 result := s2(65 downto 2);
247 result := s2(64 downto 1);
249 result := s2(63 downto 0);
254 -- Generate a mask with 0-bits on the left and 1-bits on the right which
255 -- selects the bits will be lost in doing a right shift. The shift
256 -- parameter is the bottom 6 bits of a negative shift count,
257 -- indicating a right shift.
258 function right_mask(shift: unsigned(5 downto 0)) return std_ulogic_vector is
259 variable result: std_ulogic_vector(63 downto 0);
261 result := (others => '0');
262 for i in 0 to 63 loop
264 result(63 - i) := '1';
270 -- Split a DP floating-point number into components and work out its class.
271 -- If is_int = 1, the input is considered an integer
272 function decode_dp(fpr: std_ulogic_vector(63 downto 0); is_int: std_ulogic) return fpu_reg_type is
273 variable r : fpu_reg_type;
274 variable exp_nz : std_ulogic;
275 variable exp_ao : std_ulogic;
276 variable frac_nz : std_ulogic;
277 variable cls : std_ulogic_vector(2 downto 0);
279 r.negative := fpr(63);
280 exp_nz := or (fpr(62 downto 52));
281 exp_ao := and (fpr(62 downto 52));
282 frac_nz := or (fpr(51 downto 0));
284 r.exponent := signed(resize(unsigned(fpr(62 downto 52)), EXP_BITS)) - to_signed(1023, EXP_BITS);
286 r.exponent := to_signed(-1022, EXP_BITS);
288 r.mantissa := "000000000" & exp_nz & fpr(51 downto 0) & "00";
289 cls := exp_ao & exp_nz & frac_nz;
291 when "000" => r.class := ZERO;
292 when "001" => r.class := FINITE; -- denormalized
293 when "010" => r.class := FINITE;
294 when "011" => r.class := FINITE;
295 when "110" => r.class := INFINITY;
296 when others => r.class := NAN;
300 r.exponent := (others => '0');
301 if (fpr(63) or exp_nz or frac_nz) = '1' then
310 -- Construct a DP floating-point result from components
311 function pack_dp(sign: std_ulogic; class: fp_number_class; exp: signed(EXP_BITS-1 downto 0);
312 mantissa: std_ulogic_vector; single_prec: std_ulogic; quieten_nan: std_ulogic)
313 return std_ulogic_vector is
314 variable result : std_ulogic_vector(63 downto 0);
316 result := (others => '0');
321 if mantissa(54) = '1' then
323 result(62 downto 52) := std_ulogic_vector(resize(exp, 11) + 1023);
325 result(51 downto 29) := mantissa(53 downto 31);
326 if single_prec = '0' then
327 result(28 downto 0) := mantissa(30 downto 2);
330 result(62 downto 52) := "11111111111";
332 result(62 downto 52) := "11111111111";
333 result(51) := quieten_nan or mantissa(53);
334 result(50 downto 29) := mantissa(52 downto 31);
335 if single_prec = '0' then
336 result(28 downto 0) := mantissa(30 downto 2);
342 -- Determine whether to increment when rounding
343 -- Returns rounding_inc & inexact
344 -- Assumes x includes the bottom 29 bits of the mantissa already
345 -- if single_prec = 1 (usually arranged by setting set_x = 1 earlier).
346 function fp_rounding(mantissa: std_ulogic_vector(63 downto 0); x: std_ulogic;
347 single_prec: std_ulogic; rn: std_ulogic_vector(2 downto 0);
349 return std_ulogic_vector is
350 variable grx : std_ulogic_vector(2 downto 0);
351 variable ret : std_ulogic_vector(1 downto 0);
352 variable lsb : std_ulogic;
354 if single_prec = '0' then
355 grx := mantissa(1 downto 0) & x;
358 grx := mantissa(30 downto 29) & x;
363 case rn(1 downto 0) is
364 when "00" => -- round to nearest
365 if grx = "100" and rn(2) = '0' then
366 ret(1) := lsb; -- tie, round to even
370 when "01" => -- round towards zero
371 when others => -- round towards +/- inf
373 -- round towards greater magnitude
380 -- Determine result flags to write into the FPSCR
381 function result_flags(sign: std_ulogic; class: fp_number_class; unitbit: std_ulogic)
382 return std_ulogic_vector is
386 return sign & "0010";
388 return (not unitbit) & sign & (not sign) & "00";
390 return '0' & sign & (not sign) & "01";
397 fpu_multiply_0: entity work.multiply
400 m_in => f_to_multiply,
401 m_out => multiply_to_f
406 if rising_edge(clk) then
412 r.fpscr <= (others => '0');
413 r.writing_back <= '0';
415 assert not (r.state /= IDLE and e_in.valid = '1') severity failure;
421 -- synchronous reads from lookup table
422 lut_access: process(clk)
424 if rising_edge(clk) then
425 inverse_est <= '1' & inverse_table(to_integer(unsigned(r.b.mantissa(53 downto 46))));
429 e_out.busy <= r.busy;
430 e_out.exception <= r.fpscr(FPSCR_FEX);
431 e_out.interrupt <= r.do_intr;
433 w_out.valid <= r.instr_done and not r.do_intr;
434 w_out.write_enable <= r.writing_back;
435 w_out.write_reg <= r.dest_fpr;
436 w_out.write_data <= fp_result;
437 w_out.write_cr_enable <= r.instr_done and (r.rc or r.is_cmp);
438 w_out.write_cr_mask <= r.cr_mask;
439 w_out.write_cr_data <= r.cr_result & r.cr_result & r.cr_result & r.cr_result &
440 r.cr_result & r.cr_result & r.cr_result & r.cr_result;
443 variable v : reg_type;
444 variable adec : fpu_reg_type;
445 variable bdec : fpu_reg_type;
446 variable cdec : fpu_reg_type;
447 variable fpscr_mask : std_ulogic_vector(31 downto 0);
448 variable illegal : std_ulogic;
449 variable j, k : integer;
450 variable flm : std_ulogic_vector(7 downto 0);
451 variable int_input : std_ulogic;
452 variable mask : std_ulogic_vector(63 downto 0);
453 variable in_a0 : std_ulogic_vector(63 downto 0);
454 variable in_b0 : std_ulogic_vector(63 downto 0);
455 variable misc : std_ulogic_vector(63 downto 0);
456 variable shift_res : std_ulogic_vector(63 downto 0);
457 variable round : std_ulogic_vector(1 downto 0);
458 variable update_fx : std_ulogic;
459 variable arith_done : std_ulogic;
460 variable invalid : std_ulogic;
461 variable zero_divide : std_ulogic;
462 variable mant_nz : std_ulogic;
463 variable min_exp : signed(EXP_BITS-1 downto 0);
464 variable max_exp : signed(EXP_BITS-1 downto 0);
465 variable bias_exp : signed(EXP_BITS-1 downto 0);
466 variable new_exp : signed(EXP_BITS-1 downto 0);
467 variable exp_tiny : std_ulogic;
468 variable exp_huge : std_ulogic;
469 variable renormalize : std_ulogic;
470 variable clz : std_ulogic_vector(5 downto 0);
471 variable set_x : std_ulogic;
472 variable mshift : signed(EXP_BITS-1 downto 0);
473 variable need_check : std_ulogic;
474 variable msb : std_ulogic;
475 variable is_add : std_ulogic;
476 variable qnan_result : std_ulogic;
477 variable longmask : std_ulogic;
478 variable set_a : std_ulogic;
479 variable set_b : std_ulogic;
480 variable set_c : std_ulogic;
481 variable px_nz : std_ulogic;
482 variable maddend : std_ulogic_vector(127 downto 0);
483 variable set_y : std_ulogic;
484 variable pcmpb_eq : std_ulogic;
485 variable pcmpb_lt : std_ulogic;
486 variable pshift : std_ulogic;
493 -- capture incoming instruction
494 if e_in.valid = '1' then
497 v.fe_mode := or (e_in.fe_mode);
498 v.dest_fpr := e_in.frt;
499 v.single_prec := e_in.single;
502 v.is_cmp := e_in.out_cr;
503 if e_in.out_cr = '0' then
504 v.cr_mask := num_to_fxm(1);
506 v.cr_mask := num_to_fxm(to_integer(unsigned(insn_bf(e_in.insn))));
509 if e_in.op = OP_FPOP_I then
512 v.quieten_nan := '1';
515 v.round_mode := '0' & r.fpscr(FPSCR_RN+1 downto FPSCR_RN);
516 v.is_subtract := '0';
517 v.is_multiply := '0';
519 adec := decode_dp(e_in.fra, int_input);
520 bdec := decode_dp(e_in.frb, int_input);
521 cdec := decode_dp(e_in.frc, int_input);
527 if adec.exponent > bdec.exponent then
532 r_hi_nz <= or (r.r(55 downto 31));
533 r_lo_nz <= or (r.r(30 downto 2));
535 if r.single_prec = '0' then
536 max_exp := to_signed(1023, EXP_BITS);
537 min_exp := to_signed(-1022, EXP_BITS);
538 bias_exp := to_signed(1536, EXP_BITS);
540 max_exp := to_signed(127, EXP_BITS);
541 min_exp := to_signed(-126, EXP_BITS);
542 bias_exp := to_signed(192, EXP_BITS);
544 new_exp := r.result_exp - r.shift;
547 if new_exp < min_exp then
550 if new_exp > max_exp then
554 -- Compare P with zero and with B
555 px_nz := or (r.p(57 downto 4));
557 if r.p(59 downto 4) = r.b.mantissa(55 downto 0) then
561 if unsigned(r.p(59 downto 4)) < unsigned(r.b.mantissa(55 downto 0)) then
565 v.writing_back := '0';
567 v.update_fprf := '0';
568 v.shift := to_signed(0, EXP_BITS);
578 fpscr_mask := (others => '1');
586 longmask := r.single_prec;
590 f_to_multiply.is_32bit <= '0';
591 f_to_multiply.valid <= '0';
594 msel_add <= MULADD_ZERO;
600 if e_in.valid = '1' then
601 case e_in.insn(5 downto 1) is
605 if e_in.insn(10) = '0' then
606 if e_in.insn(8) = '0' then
609 v.state := DO_MTFSFI;
615 if e_in.insn(8) = '0' then
621 if e_in.insn(9 downto 8) /= "11" then
629 if int_input = '1' then
636 v.round_mode := "001";
640 when "10100" | "10101" =>
643 v.is_multiply := '1';
650 v.old_exc := r.fpscr(FPSCR_VX downto FPSCR_XX);
653 j := to_integer(unsigned(insn_bfa(r.insn)));
657 v.cr_result := r.fpscr(k + 3 downto k);
658 fpscr_mask(k + 3 downto k) := "0000";
661 v.fpscr := r.fpscr and (fpscr_mask or x"6007F8FF");
667 j := to_integer(unsigned(insn_bt(r.insn)));
668 for i in 0 to 31 loop
670 v.fpscr(31 - i) := r.insn(6);
678 j := to_integer(unsigned(insn_bf(r.insn)));
679 if r.insn(16) = '0' then
683 v.fpscr(k + 3 downto k) := insn_u(r.insn);
693 misc_sel <= "01" & r.insn(8) & '0';
695 v.writing_back := '1';
701 v.writing_back := '1';
703 case r.insn(20 downto 16) is
708 v.fpscr(FPSCR_VE downto FPSCR_XE) := "00000";
709 when "10100" | "10101" =>
710 -- mffscdrn[i] (but we don't implement DRN)
711 fpscr_mask := x"000000FF";
714 fpscr_mask := x"000000FF";
715 v.fpscr(FPSCR_RN+1 downto FPSCR_RN) :=
716 r.b.mantissa(FPSCR_RN+1 downto FPSCR_RN);
719 fpscr_mask := x"000000FF";
720 v.fpscr(FPSCR_RN+1 downto FPSCR_RN) := r.insn(12 downto 11);
723 fpscr_mask := x"0007F0FF";
731 if r.insn(25) = '1' then
733 elsif r.insn(16) = '1' then
736 flm := r.insn(24 downto 17);
741 v.fpscr(k + 3 downto k) := r.b.mantissa(k + 3 downto k);
749 v.result_class := r.b.class;
750 v.result_exp := r.b.exponent;
751 v.quieten_nan := '0';
752 if r.insn(9) = '1' then
753 v.result_sign := '0'; -- fabs
754 elsif r.insn(8) = '1' then
755 v.result_sign := '1'; -- fnabs
756 elsif r.insn(7) = '1' then
757 v.result_sign := r.b.negative; -- fmr
758 elsif r.insn(6) = '1' then
759 v.result_sign := not r.b.negative; -- fneg
761 v.result_sign := r.a.negative; -- fcpsgn
763 v.writing_back := '1';
767 when DO_FRI => -- fri[nzpm]
769 v.result_class := r.b.class;
770 v.result_sign := r.b.negative;
771 v.result_exp := r.b.exponent;
772 v.fpscr(FPSCR_FR) := '0';
773 v.fpscr(FPSCR_FI) := '0';
774 if r.b.class = NAN and r.b.mantissa(53) = '0' then
776 v.fpscr(FPSCR_VXSNAN) := '1';
779 if r.b.class = FINITE then
780 if r.b.exponent >= to_signed(52, EXP_BITS) then
781 -- integer already, no rounding required
784 v.shift := r.b.exponent - to_signed(52, EXP_BITS);
786 v.round_mode := '1' & r.insn(7 downto 6);
794 v.result_class := r.b.class;
795 v.result_sign := r.b.negative;
796 v.result_exp := r.b.exponent;
797 v.fpscr(FPSCR_FR) := '0';
798 v.fpscr(FPSCR_FI) := '0';
799 if r.b.class = NAN and r.b.mantissa(53) = '0' then
801 v.fpscr(FPSCR_VXSNAN) := '1';
805 if r.b.class = FINITE then
806 if r.b.exponent < to_signed(-126, EXP_BITS) then
807 v.shift := r.b.exponent - to_signed(-126, EXP_BITS);
808 v.state := ROUND_UFLOW;
809 elsif r.b.exponent > to_signed(127, EXP_BITS) then
810 v.state := ROUND_OFLOW;
812 v.shift := to_signed(-2, EXP_BITS);
820 -- instr bit 9: 1=dword 0=word
821 -- instr bit 8: 1=unsigned 0=signed
822 -- instr bit 1: 1=round to zero 0=use fpscr[RN]
824 v.result_class := r.b.class;
825 v.result_sign := r.b.negative;
826 v.result_exp := r.b.exponent;
827 v.fpscr(FPSCR_FR) := '0';
828 v.fpscr(FPSCR_FI) := '0';
829 if r.b.class = NAN and r.b.mantissa(53) = '0' then
831 v.fpscr(FPSCR_VXSNAN) := '1';
840 if r.b.exponent >= to_signed(64, EXP_BITS) or
841 (r.insn(9) = '0' and r.b.exponent >= to_signed(32, EXP_BITS)) then
842 v.state := INT_OFLOW;
843 elsif r.b.exponent >= to_signed(52, EXP_BITS) then
844 -- integer already, no rounding required,
845 -- shift into final position
846 v.shift := r.b.exponent - to_signed(54, EXP_BITS);
847 if r.insn(8) = '1' and r.b.negative = '1' then
848 v.state := INT_OFLOW;
850 v.state := INT_ISHIFT;
853 v.shift := r.b.exponent - to_signed(52, EXP_BITS);
854 v.state := INT_SHIFT;
856 when INFINITY | NAN =>
857 v.state := INT_OFLOW;
861 v.result_sign := '0';
863 if r.insn(8) = '0' and r.b.negative = '1' then
864 -- fcfid[s] with negative operand, set R = -B
867 v.result_sign := '1';
869 v.result_class := r.b.class;
870 v.result_exp := to_signed(54, EXP_BITS);
871 v.fpscr(FPSCR_FR) := '0';
872 v.fpscr(FPSCR_FI) := '0';
873 if r.b.class = ZERO then
880 -- fadd[s] and fsub[s]
882 v.result_sign := r.a.negative;
883 v.result_class := r.a.class;
884 v.result_exp := r.a.exponent;
885 v.fpscr(FPSCR_FR) := '0';
886 v.fpscr(FPSCR_FI) := '0';
887 is_add := r.a.negative xor r.b.negative xor r.insn(1);
888 if r.a.class = FINITE and r.b.class = FINITE then
889 v.is_subtract := not is_add;
890 v.add_bsmall := r.exp_cmp;
891 if r.exp_cmp = '0' then
892 v.shift := r.a.exponent - r.b.exponent;
893 v.result_sign := r.b.negative xnor r.insn(1);
894 if r.a.exponent = r.b.exponent then
897 v.state := ADD_SHIFT;
901 v.shift := r.b.exponent - r.a.exponent;
902 v.result_exp := r.b.exponent;
903 v.state := ADD_SHIFT;
906 if (r.a.class = NAN and r.a.mantissa(53) = '0') or
907 (r.b.class = NAN and r.b.mantissa(53) = '0') then
909 v.fpscr(FPSCR_VXSNAN) := '1';
912 if r.a.class = NAN then
913 -- nothing to do, result is A
914 elsif r.b.class = NAN then
915 v.result_class := NAN;
916 v.result_sign := r.b.negative;
918 elsif r.a.class = INFINITY and r.b.class = INFINITY and is_add = '0' then
919 -- invalid operation, construct QNaN
920 v.fpscr(FPSCR_VXISI) := '1';
922 elsif r.a.class = ZERO and r.b.class = ZERO and is_add = '0' then
923 -- return -0 for rounding to -infinity
924 v.result_sign := r.round_mode(1) and r.round_mode(0);
925 elsif r.a.class = INFINITY or r.b.class = ZERO then
926 -- nothing to do, result is A
929 v.result_sign := r.b.negative xnor r.insn(1);
930 v.result_class := r.b.class;
931 v.result_exp := r.b.exponent;
940 v.result_sign := r.a.negative;
941 v.result_class := r.a.class;
942 v.result_exp := r.a.exponent;
943 v.fpscr(FPSCR_FR) := '0';
944 v.fpscr(FPSCR_FI) := '0';
945 if r.a.class = FINITE and r.c.class = FINITE then
946 v.result_sign := r.a.negative xor r.c.negative;
947 v.result_exp := r.a.exponent + r.c.exponent;
948 -- Renormalize denorm operands
949 if r.a.mantissa(54) = '0' then
951 elsif r.c.mantissa(54) = '0' then
955 f_to_multiply.valid <= '1';
959 if (r.a.class = NAN and r.a.mantissa(53) = '0') or
960 (r.c.class = NAN and r.c.mantissa(53) = '0') then
962 v.fpscr(FPSCR_VXSNAN) := '1';
965 if r.a.class = NAN then
967 elsif r.c.class = NAN then
968 v.result_class := NAN;
969 v.result_sign := r.c.negative;
971 elsif (r.a.class = INFINITY and r.c.class = ZERO) or
972 (r.a.class = ZERO and r.c.class = INFINITY) then
973 -- invalid operation, construct QNaN
974 v.fpscr(FPSCR_VXIMZ) := '1';
976 elsif r.a.class = ZERO or r.a.class = INFINITY then
978 v.result_sign := r.a.negative xor r.c.negative;
980 -- r.c.class is ZERO or INFINITY
981 v.result_class := r.c.class;
982 v.result_sign := r.a.negative xor r.c.negative;
989 v.result_sign := r.a.negative;
990 v.result_class := r.a.class;
991 v.result_exp := r.a.exponent;
992 v.fpscr(FPSCR_FR) := '0';
993 v.fpscr(FPSCR_FI) := '0';
994 v.result_sign := r.a.negative xor r.b.negative;
995 v.result_exp := r.a.exponent - r.b.exponent;
997 if r.a.class = FINITE and r.b.class = FINITE then
998 -- Renormalize denorm operands
999 if r.a.mantissa(54) = '0' then
1000 v.state := RENORM_A;
1001 elsif r.b.mantissa(54) = '0' then
1003 v.state := RENORM_B;
1009 if (r.a.class = NAN and r.a.mantissa(53) = '0') or
1010 (r.b.class = NAN and r.b.mantissa(53) = '0') then
1012 v.fpscr(FPSCR_VXSNAN) := '1';
1015 if r.a.class = NAN then
1017 v.result_sign := r.a.negative;
1018 elsif r.b.class = NAN then
1019 v.result_class := NAN;
1020 v.result_sign := r.b.negative;
1022 elsif r.b.class = INFINITY then
1023 if r.a.class = INFINITY then
1024 v.fpscr(FPSCR_VXIDI) := '1';
1027 v.result_class := ZERO;
1029 elsif r.b.class = ZERO then
1030 if r.a.class = ZERO then
1031 v.fpscr(FPSCR_VXZDZ) := '1';
1034 if r.a.class = FINITE then
1037 v.result_class := INFINITY;
1039 -- else r.b.class = FINITE, result_class = r.a.class
1046 v.state := RENORM_A2;
1050 v.result_exp := new_exp;
1051 if r.insn(4) = '1' then
1053 if r.c.mantissa(54) = '1' then
1057 v.state := RENORM_C;
1061 if r.b.mantissa(54) = '1' then
1065 v.state := RENORM_B;
1071 v.state := RENORM_B2;
1075 v.result_exp := r.result_exp + r.shift;
1080 v.state := RENORM_C2;
1084 v.result_exp := new_exp;
1089 opsel_r <= RES_SHIFT;
1095 if r.add_bsmall = '1' then
1101 opsel_binv <= r.is_subtract;
1102 carry_in <= r.is_subtract and not r.x;
1103 v.shift := to_signed(-1, EXP_BITS);
1107 -- check for overflow or negative result (can't get both)
1108 if r.r(63) = '1' then
1109 -- result is opposite sign to expected
1110 v.result_sign := not r.result_sign;
1114 elsif r.r(55) = '1' then
1115 -- sum overflowed, shift right
1116 opsel_r <= RES_SHIFT;
1118 v.shift := to_signed(-2, EXP_BITS);
1119 if exp_huge = '1' then
1120 v.state := ROUND_OFLOW;
1122 v.state := ROUNDING;
1124 elsif r.r(54) = '1' then
1126 v.shift := to_signed(-2, EXP_BITS);
1127 v.state := ROUNDING;
1128 elsif (r_hi_nz or r_lo_nz or r.r(1) or r.r(0)) = '0' then
1129 -- r.x must be zero at this point
1130 v.result_class := ZERO;
1131 if r.is_subtract = '1' then
1132 -- set result sign depending on rounding mode
1133 v.result_sign := r.round_mode(1) and r.round_mode(0);
1138 v.state := NORMALIZE;
1142 f_to_multiply.valid <= r.first;
1143 opsel_r <= RES_MULT;
1144 if multiply_to_f.valid = '1' then
1150 -- wait one cycle for inverse_table[B] lookup
1155 -- compute Y = inverse_table[B] (when count=0); P = 2 - B * Y
1157 msel_add <= MULADD_CONST;
1166 f_to_multiply.valid <= r.first;
1167 if multiply_to_f.valid = '1' then
1169 v.count := r.count + 1;
1174 -- compute Y = P = P * Y
1177 f_to_multiply.valid <= r.first;
1179 if multiply_to_f.valid = '1' then
1189 -- compute R = P = A * Y (quotient)
1193 f_to_multiply.valid <= r.first;
1195 if multiply_to_f.valid = '1' then
1196 opsel_r <= RES_MULT;
1202 -- compute P = A - B * R (remainder)
1205 msel_add <= MULADD_A;
1207 f_to_multiply.valid <= r.first;
1208 if multiply_to_f.valid = '1' then
1213 -- test if remainder is 0 or >= B
1214 if pcmpb_lt = '1' then
1215 -- quotient is correct, set X if remainder non-zero
1216 v.x := r.p(58) or px_nz;
1218 -- quotient needs to be incremented by 1
1220 v.x := not pcmpb_eq;
1225 opsel_r <= RES_SHIFT;
1227 v.state := INT_ROUND;
1228 v.shift := to_signed(-2, EXP_BITS);
1231 opsel_r <= RES_SHIFT;
1232 round := fp_rounding(r.r, r.x, '0', r.round_mode, r.result_sign);
1233 v.fpscr(FPSCR_FR downto FPSCR_FI) := round;
1234 -- Check for negative values that don't round to 0 for fcti*u*
1235 if r.insn(8) = '1' and r.result_sign = '1' and
1236 (r_hi_nz or r_lo_nz or v.fpscr(FPSCR_FR)) = '1' then
1237 v.state := INT_OFLOW;
1239 v.state := INT_FINAL;
1243 opsel_r <= RES_SHIFT;
1244 v.state := INT_FINAL;
1247 -- Negate if necessary, and increment for rounding if needed
1248 opsel_ainv <= r.result_sign;
1249 carry_in <= r.fpscr(FPSCR_FR) xor r.result_sign;
1250 -- Check for possible overflows
1251 case r.insn(9 downto 8) is
1252 when "00" => -- fctiw[z]
1253 need_check := r.r(31) or (r.r(30) and not r.result_sign);
1254 when "01" => -- fctiwu[z]
1255 need_check := r.r(31);
1256 when "10" => -- fctid[z]
1257 need_check := r.r(63) or (r.r(62) and not r.result_sign);
1258 when others => -- fctidu[z]
1259 need_check := r.r(63);
1261 if need_check = '1' then
1262 v.state := INT_CHECK;
1264 if r.fpscr(FPSCR_FI) = '1' then
1265 v.fpscr(FPSCR_XX) := '1';
1271 if r.insn(9) = '0' then
1276 misc_sel <= '1' & r.insn(9 downto 8) & r.result_sign;
1277 if (r.insn(8) = '0' and msb /= r.result_sign) or
1278 (r.insn(8) = '1' and msb /= '1') then
1279 opsel_r <= RES_MISC;
1280 v.fpscr(FPSCR_VXCVI) := '1';
1283 if r.fpscr(FPSCR_FI) = '1' then
1284 v.fpscr(FPSCR_XX) := '1';
1290 opsel_r <= RES_MISC;
1291 misc_sel <= '1' & r.insn(9 downto 8) & r.result_sign;
1292 if r.b.class = NAN then
1295 v.fpscr(FPSCR_VXCVI) := '1';
1300 opsel_r <= RES_SHIFT;
1302 v.shift := to_signed(-2, EXP_BITS);
1303 v.state := ROUNDING;
1306 if r.is_multiply = '1' and px_nz = '1' then
1309 if r.r(63 downto 54) /= "0000000001" then
1311 v.state := NORMALIZE;
1314 if exp_tiny = '1' then
1315 v.shift := new_exp - min_exp;
1316 v.state := ROUND_UFLOW;
1317 elsif exp_huge = '1' then
1318 v.state := ROUND_OFLOW;
1320 v.shift := to_signed(-2, EXP_BITS);
1321 v.state := ROUNDING;
1326 -- Shift so we have 9 leading zeroes (we know R is non-zero)
1327 opsel_r <= RES_SHIFT;
1329 if exp_tiny = '1' then
1330 v.shift := new_exp - min_exp;
1331 v.state := ROUND_UFLOW;
1332 elsif exp_huge = '1' then
1333 v.state := ROUND_OFLOW;
1335 v.shift := to_signed(-2, EXP_BITS);
1336 v.state := ROUNDING;
1341 if r.fpscr(FPSCR_UE) = '0' then
1342 -- disabled underflow exception case
1343 -- have to denormalize before rounding
1344 opsel_r <= RES_SHIFT;
1346 v.shift := to_signed(-2, EXP_BITS);
1347 v.state := ROUNDING;
1349 -- enabled underflow exception case
1350 -- if denormalized, have to normalize before rounding
1351 v.fpscr(FPSCR_UX) := '1';
1352 v.result_exp := r.result_exp + bias_exp;
1353 if r.r(54) = '0' then
1355 v.state := NORMALIZE;
1357 v.shift := to_signed(-2, EXP_BITS);
1358 v.state := ROUNDING;
1363 v.fpscr(FPSCR_OX) := '1';
1364 if r.fpscr(FPSCR_OE) = '0' then
1365 -- disabled overflow exception
1366 -- result depends on rounding mode
1367 v.fpscr(FPSCR_XX) := '1';
1368 v.fpscr(FPSCR_FI) := '1';
1369 if r.round_mode(1 downto 0) = "00" or
1370 (r.round_mode(1) = '1' and r.round_mode(0) = r.result_sign) then
1371 v.result_class := INFINITY;
1372 v.fpscr(FPSCR_FR) := '1';
1374 v.fpscr(FPSCR_FR) := '0';
1376 -- construct largest representable number
1377 v.result_exp := max_exp;
1378 opsel_r <= RES_MISC;
1379 misc_sel <= "001" & r.single_prec;
1382 -- enabled overflow exception
1383 v.result_exp := r.result_exp - bias_exp;
1384 v.shift := to_signed(-2, EXP_BITS);
1385 v.state := ROUNDING;
1390 round := fp_rounding(r.r, r.x, r.single_prec, r.round_mode, r.result_sign);
1391 v.fpscr(FPSCR_FR downto FPSCR_FI) := round;
1392 if round(1) = '1' then
1393 -- set mask to increment the LSB for the precision
1394 opsel_b <= BIN_MASK;
1396 v.shift := to_signed(-1, EXP_BITS);
1397 v.state := ROUNDING_2;
1399 if r.r(54) = '0' then
1400 -- result after masking could be zero, or could be a
1401 -- denormalized result that needs to be renormalized
1403 v.state := ROUNDING_3;
1408 if round(0) = '1' then
1409 v.fpscr(FPSCR_XX) := '1';
1410 if r.tiny = '1' then
1411 v.fpscr(FPSCR_UX) := '1';
1416 -- Check for overflow during rounding
1418 if r.r(55) = '1' then
1419 opsel_r <= RES_SHIFT;
1420 if exp_huge = '1' then
1421 v.state := ROUND_OFLOW;
1425 elsif r.r(54) = '0' then
1426 -- Do CLZ so we can renormalize the result
1428 v.state := ROUNDING_3;
1434 mant_nz := r_hi_nz or (r_lo_nz and not r.single_prec);
1435 if mant_nz = '0' then
1436 v.result_class := ZERO;
1437 if r.is_subtract = '1' then
1438 -- set result sign depending on rounding mode
1439 v.result_sign := r.round_mode(1) and r.round_mode(0);
1443 -- Renormalize result after rounding
1444 opsel_r <= RES_SHIFT;
1445 v.denorm := exp_tiny;
1446 v.shift := new_exp - to_signed(-1022, EXP_BITS);
1447 if new_exp < to_signed(-1022, EXP_BITS) then
1455 opsel_r <= RES_SHIFT;
1460 if zero_divide = '1' then
1461 v.fpscr(FPSCR_ZX) := '1';
1463 if qnan_result = '1' then
1465 v.result_class := NAN;
1466 v.result_sign := '0';
1468 opsel_r <= RES_MISC;
1470 if arith_done = '1' then
1471 -- Enabled invalid exception doesn't write result or FPRF
1472 -- Neither does enabled zero-divide exception
1473 if (invalid and r.fpscr(FPSCR_VE)) = '0' and
1474 (zero_divide and r.fpscr(FPSCR_ZE)) = '0' then
1475 v.writing_back := '1';
1476 v.update_fprf := '1';
1478 v.instr_done := '1';
1483 -- Multiplier and divide/square root data path
1486 f_to_multiply.data1 <= r.a.mantissa(61 downto 0) & "00";
1488 f_to_multiply.data1 <= r.b.mantissa(61 downto 0) & "00";
1490 f_to_multiply.data1 <= r.y;
1492 f_to_multiply.data1 <= r.r(61 downto 0) & "00";
1496 f_to_multiply.data2 <= r.c.mantissa(61 downto 0) & "00";
1498 f_to_multiply.data2 <= x"00" & inverse_est & '0' & x"000000000";
1500 f_to_multiply.data2 <= r.p;
1502 f_to_multiply.data2 <= r.r(61 downto 0) & "00";
1504 maddend := (others => '0');
1506 when MULADD_CONST =>
1507 -- addend is 2.0 in 16.112 format
1508 maddend(113) := '1'; -- 2.0
1510 -- addend is A in 16.112 format
1511 maddend(121 downto 58) := r.a.mantissa;
1514 if msel_inv = '1' then
1515 f_to_multiply.addend <= not maddend;
1517 f_to_multiply.addend <= maddend;
1519 f_to_multiply.not_result <= msel_inv;
1521 v.y := f_to_multiply.data2;
1523 if multiply_to_f.valid = '1' then
1524 if pshift = '0' then
1525 v.p := multiply_to_f.result(63 downto 0);
1527 v.p := multiply_to_f.result(119 downto 56);
1532 -- This has A and B input multiplexers, an adder, a shifter,
1533 -- count-leading-zeroes logic, and a result mux.
1534 if longmask = '1' then
1535 mshift := r.shift + to_signed(-29, EXP_BITS);
1539 if mshift < to_signed(-64, EXP_BITS) then
1540 mask := (others => '1');
1541 elsif mshift >= to_signed(0, EXP_BITS) then
1542 mask := (others => '0');
1544 mask := right_mask(unsigned(mshift(5 downto 0)));
1550 in_a0 := r.a.mantissa;
1552 in_a0 := r.b.mantissa;
1554 in_a0 := r.c.mantissa;
1556 if (or (mask and in_a0)) = '1' and set_x = '1' then
1559 if opsel_ainv = '1' then
1562 if opsel_amask = '1' then
1563 in_a0 := in_a0 and not mask;
1568 in_b0 := (others => '0');
1574 in_b0 := (others => '0');
1576 if opsel_binv = '1' then
1580 if r.shift >= to_signed(-64, EXP_BITS) and r.shift <= to_signed(63, EXP_BITS) then
1581 shift_res := shifter_64(r.r & x"00000000000000",
1582 std_ulogic_vector(r.shift(6 downto 0)));
1584 shift_res := (others => '0');
1588 result <= std_ulogic_vector(unsigned(in_a) + unsigned(in_b) + carry_in);
1590 result <= shift_res;
1592 result <= multiply_to_f.result(121 downto 58);
1596 misc := x"00000000" & (r.fpscr and fpscr_mask);
1598 -- generated QNaN mantissa
1599 misc := x"0020000000000000";
1601 -- mantissa of max representable DP number
1602 misc := x"007ffffffffffffc";
1604 -- mantissa of max representable SP number
1605 misc := x"007fffff80000000";
1608 misc := r.a.mantissa(31 downto 0) & r.b.mantissa(31 downto 0);
1611 misc := r.a.mantissa(63 downto 32) & r.b.mantissa(63 downto 32);
1613 -- max positive result for fctiw[z]
1614 misc := x"000000007fffffff";
1616 -- max negative result for fctiw[z]
1617 misc := x"ffffffff80000000";
1619 -- max positive result for fctiwu[z]
1620 misc := x"00000000ffffffff";
1622 -- max negative result for fctiwu[z]
1623 misc := x"0000000000000000";
1625 -- max positive result for fctid[z]
1626 misc := x"7fffffffffffffff";
1628 -- max negative result for fctid[z]
1629 misc := x"8000000000000000";
1631 -- max positive result for fctidu[z]
1632 misc := x"ffffffffffffffff";
1634 -- max negative result for fctidu[z]
1635 misc := x"0000000000000000";
1637 misc := x"0000000000000000";
1644 v.a.exponent := new_exp;
1645 v.a.mantissa := shift_res;
1648 v.b.exponent := new_exp;
1649 v.b.mantissa := shift_res;
1652 v.c.exponent := new_exp;
1653 v.c.mantissa := shift_res;
1656 if opsel_r = RES_SHIFT then
1657 v.result_exp := new_exp;
1660 if renormalize = '1' then
1661 clz := count_left_zeroes(r.r);
1662 v.shift := resize(signed('0' & clz) - 9, EXP_BITS);
1665 if r.int_result = '1' then
1668 fp_result <= pack_dp(r.result_sign, r.result_class, r.result_exp, r.r,
1669 r.single_prec, r.quieten_nan);
1671 if r.update_fprf = '1' then
1672 v.fpscr(FPSCR_C downto FPSCR_FU) := result_flags(r.result_sign, r.result_class,
1673 r.r(54) and not r.denorm);
1676 v.fpscr(FPSCR_VX) := (or (v.fpscr(FPSCR_VXSNAN downto FPSCR_VXVC))) or
1677 (or (v.fpscr(FPSCR_VXSOFT downto FPSCR_VXCVI)));
1678 v.fpscr(FPSCR_FEX) := or (v.fpscr(FPSCR_VX downto FPSCR_XX) and
1679 v.fpscr(FPSCR_VE downto FPSCR_XE));
1680 if update_fx = '1' and
1681 (v.fpscr(FPSCR_VX downto FPSCR_XX) and not r.old_exc) /= "00000" then
1682 v.fpscr(FPSCR_FX) := '1';
1685 v.cr_result := v.fpscr(FPSCR_FX downto FPSCR_OX);
1688 if illegal = '1' then
1689 v.instr_done := '0';
1691 v.writing_back := '0';
1695 v.do_intr := v.instr_done and v.fpscr(FPSCR_FEX) and r.fe_mode;
1696 if v.state /= IDLE or v.do_intr = '1' then
1702 e_out.illegal <= illegal;
1705 end architecture behaviour;