Plumb loadstore1 input from execute1 not decode2
[microwatt.git] / execute1.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.decode_types.all;
7 use work.common.all;
8 use work.helpers.all;
9 use work.crhelpers.all;
10 use work.insn_helpers.all;
11 use work.ppc_fx_insns.all;
12
13 entity execute1 is
14 generic (
15 EX1_BYPASS : boolean := true
16 );
17 port (
18 clk : in std_ulogic;
19 rst : in std_ulogic;
20
21 -- asynchronous
22 flush_out : out std_ulogic;
23 stall_out : out std_ulogic;
24
25 e_in : in Decode2ToExecute1Type;
26
27 -- asynchronous
28 l_out : out Execute1ToLoadstore1Type;
29 f_out : out Execute1ToFetch1Type;
30
31 e_out : out Execute1ToWritebackType;
32
33 icache_inval : out std_ulogic;
34 terminate_out : out std_ulogic
35 );
36 end entity execute1;
37
38 architecture behaviour of execute1 is
39 type reg_type is record
40 e : Execute1ToWritebackType;
41 lr_update : std_ulogic;
42 next_lr : std_ulogic_vector(63 downto 0);
43 mul_in_progress : std_ulogic;
44 div_in_progress : std_ulogic;
45 slow_op_dest : gpr_index_t;
46 slow_op_rc : std_ulogic;
47 slow_op_oe : std_ulogic;
48 slow_op_xerc : xer_common_t;
49 end record;
50
51 signal r, rin : reg_type;
52
53 signal a_in, b_in, c_in : std_ulogic_vector(63 downto 0);
54
55 signal ctrl: ctrl_t := (others => (others => '0'));
56 signal ctrl_tmp: ctrl_t := (others => (others => '0'));
57
58 signal right_shift, rot_clear_left, rot_clear_right: std_ulogic;
59 signal rotator_result: std_ulogic_vector(63 downto 0);
60 signal rotator_carry: std_ulogic;
61 signal logical_result: std_ulogic_vector(63 downto 0);
62 signal countzero_result: std_ulogic_vector(63 downto 0);
63 signal popcnt_result: std_ulogic_vector(63 downto 0);
64 signal parity_result: std_ulogic_vector(63 downto 0);
65
66 -- multiply signals
67 signal x_to_multiply: Execute1ToMultiplyType;
68 signal multiply_to_x: MultiplyToExecute1Type;
69
70 -- divider signals
71 signal x_to_divider: Execute1ToDividerType;
72 signal divider_to_x: DividerToExecute1Type;
73
74 procedure set_carry(e: inout Execute1ToWritebackType;
75 carry32 : in std_ulogic;
76 carry : in std_ulogic) is
77 begin
78 e.xerc.ca32 := carry32;
79 e.xerc.ca := carry;
80 e.write_xerc_enable := '1';
81 end;
82
83 procedure set_ov(e: inout Execute1ToWritebackType;
84 ov : in std_ulogic;
85 ov32 : in std_ulogic) is
86 begin
87 e.xerc.ov32 := ov32;
88 e.xerc.ov := ov;
89 if ov = '1' then
90 e.xerc.so := '1';
91 end if;
92 e.write_xerc_enable := '1';
93 end;
94
95 function calc_ov(msb_a : std_ulogic; msb_b: std_ulogic;
96 ca: std_ulogic; msb_r: std_ulogic) return std_ulogic is
97 begin
98 return (ca xor msb_r) and not (msb_a xor msb_b);
99 end;
100
101 function decode_input_carry(ic : carry_in_t;
102 xerc : xer_common_t) return std_ulogic is
103 begin
104 case ic is
105 when ZERO =>
106 return '0';
107 when CA =>
108 return xerc.ca;
109 when ONE =>
110 return '1';
111 end case;
112 end;
113
114 begin
115
116 rotator_0: entity work.rotator
117 port map (
118 rs => c_in,
119 ra => a_in,
120 shift => b_in(6 downto 0),
121 insn => e_in.insn,
122 is_32bit => e_in.is_32bit,
123 right_shift => right_shift,
124 arith => e_in.is_signed,
125 clear_left => rot_clear_left,
126 clear_right => rot_clear_right,
127 result => rotator_result,
128 carry_out => rotator_carry
129 );
130
131 logical_0: entity work.logical
132 port map (
133 rs => c_in,
134 rb => b_in,
135 op => e_in.insn_type,
136 invert_in => e_in.invert_a,
137 invert_out => e_in.invert_out,
138 result => logical_result,
139 datalen => e_in.data_len,
140 popcnt => popcnt_result,
141 parity => parity_result
142 );
143
144 countzero_0: entity work.zero_counter
145 port map (
146 rs => c_in,
147 count_right => e_in.insn(10),
148 is_32bit => e_in.is_32bit,
149 result => countzero_result
150 );
151
152 multiply_0: entity work.multiply
153 port map (
154 clk => clk,
155 m_in => x_to_multiply,
156 m_out => multiply_to_x
157 );
158
159 divider_0: entity work.divider
160 port map (
161 clk => clk,
162 rst => rst,
163 d_in => x_to_divider,
164 d_out => divider_to_x
165 );
166
167 a_in <= r.e.write_data when EX1_BYPASS and e_in.bypass_data1 = '1' else e_in.read_data1;
168 b_in <= r.e.write_data when EX1_BYPASS and e_in.bypass_data2 = '1' else e_in.read_data2;
169 c_in <= r.e.write_data when EX1_BYPASS and e_in.bypass_data3 = '1' else e_in.read_data3;
170
171 execute1_0: process(clk)
172 begin
173 if rising_edge(clk) then
174 r <= rin;
175 ctrl <= ctrl_tmp;
176 assert not (r.lr_update = '1' and e_in.valid = '1')
177 report "LR update collision with valid in EX1"
178 severity failure;
179 if r.lr_update = '1' then
180 report "LR update to " & to_hstring(r.next_lr);
181 end if;
182 end if;
183 end process;
184
185 execute1_1: process(all)
186 variable v : reg_type;
187 variable a_inv : std_ulogic_vector(63 downto 0);
188 variable result : std_ulogic_vector(63 downto 0);
189 variable newcrf : std_ulogic_vector(3 downto 0);
190 variable result_with_carry : std_ulogic_vector(64 downto 0);
191 variable result_en : std_ulogic;
192 variable crnum : crnum_t;
193 variable crbit : integer range 0 to 31;
194 variable scrnum : crnum_t;
195 variable lo, hi : integer;
196 variable sh, mb, me : std_ulogic_vector(5 downto 0);
197 variable sh32, mb32, me32 : std_ulogic_vector(4 downto 0);
198 variable bo, bi : std_ulogic_vector(4 downto 0);
199 variable bf, bfa : std_ulogic_vector(2 downto 0);
200 variable cr_op : std_ulogic_vector(9 downto 0);
201 variable bt, ba, bb : std_ulogic_vector(4 downto 0);
202 variable btnum, banum, bbnum : integer range 0 to 31;
203 variable crresult : std_ulogic;
204 variable l : std_ulogic;
205 variable next_nia : std_ulogic_vector(63 downto 0);
206 variable carry_32, carry_64 : std_ulogic;
207 variable sign1, sign2 : std_ulogic;
208 variable abs1, abs2 : signed(63 downto 0);
209 variable overflow : std_ulogic;
210 variable negative : std_ulogic;
211 variable zerohi, zerolo : std_ulogic;
212 variable msb_a, msb_b : std_ulogic;
213 variable a_lt : std_ulogic;
214 variable lv : Execute1ToLoadstore1Type;
215 begin
216 result := (others => '0');
217 result_with_carry := (others => '0');
218 result_en := '0';
219 newcrf := (others => '0');
220
221 v := r;
222 v.e := Execute1ToWritebackInit;
223
224 -- XER forwarding. To avoid having to track XER hazards, we
225 -- use the previously latched value.
226 --
227 -- If the XER was modified by a multiply or a divide, those are
228 -- single issue, we'll get the up to date value from decode2 from
229 -- the register file.
230 --
231 -- If it was modified by an instruction older than the previous
232 -- one in EX1, it will have also hit writeback and will be up
233 -- to date in decode2.
234 --
235 -- That leaves us with the case where it was updated by the previous
236 -- instruction in EX1. In that case, we can forward it back here.
237 --
238 -- This will break if we allow pipelining of multiply and divide,
239 -- but ideally, those should go via EX1 anyway and run as a state
240 -- machine from here.
241 --
242 -- One additional hazard to beware of is an XER:SO modifying instruction
243 -- in EX1 followed immediately by a store conditional. Due to our
244 -- writeback latency, the store will go down the LSU with the previous
245 -- XER value, thus the stcx. will set CR0:SO using an obsolete SO value.
246 --
247 -- We will need to handle that if we ever make stcx. not single issue
248 --
249 -- We always pass a valid XER value downto writeback even when
250 -- we aren't updating it, in order for XER:SO -> CR0:SO transfer
251 -- to work for RC instructions.
252 --
253 if r.e.write_xerc_enable = '1' then
254 v.e.xerc := r.e.xerc;
255 else
256 v.e.xerc := e_in.xerc;
257 end if;
258
259 v.lr_update := '0';
260 v.mul_in_progress := '0';
261 v.div_in_progress := '0';
262
263 -- signals to multiply unit
264 x_to_multiply <= Execute1ToMultiplyInit;
265 x_to_multiply.insn_type <= e_in.insn_type;
266 x_to_multiply.is_32bit <= e_in.is_32bit;
267
268 if e_in.is_32bit = '1' then
269 if e_in.is_signed = '1' then
270 x_to_multiply.data1 <= (others => a_in(31));
271 x_to_multiply.data1(31 downto 0) <= a_in(31 downto 0);
272 x_to_multiply.data2 <= (others => b_in(31));
273 x_to_multiply.data2(31 downto 0) <= b_in(31 downto 0);
274 else
275 x_to_multiply.data1 <= '0' & x"00000000" & a_in(31 downto 0);
276 x_to_multiply.data2 <= '0' & x"00000000" & b_in(31 downto 0);
277 end if;
278 else
279 if e_in.is_signed = '1' then
280 x_to_multiply.data1 <= a_in(63) & a_in;
281 x_to_multiply.data2 <= b_in(63) & b_in;
282 else
283 x_to_multiply.data1 <= '0' & a_in;
284 x_to_multiply.data2 <= '0' & b_in;
285 end if;
286 end if;
287
288 -- signals to divide unit
289 sign1 := '0';
290 sign2 := '0';
291 if e_in.is_signed = '1' then
292 if e_in.is_32bit = '1' then
293 sign1 := a_in(31);
294 sign2 := b_in(31);
295 else
296 sign1 := a_in(63);
297 sign2 := b_in(63);
298 end if;
299 end if;
300 -- take absolute values
301 if sign1 = '0' then
302 abs1 := signed(a_in);
303 else
304 abs1 := - signed(a_in);
305 end if;
306 if sign2 = '0' then
307 abs2 := signed(b_in);
308 else
309 abs2 := - signed(b_in);
310 end if;
311
312 x_to_divider <= Execute1ToDividerInit;
313 x_to_divider.is_signed <= e_in.is_signed;
314 x_to_divider.is_32bit <= e_in.is_32bit;
315 if e_in.insn_type = OP_MOD then
316 x_to_divider.is_modulus <= '1';
317 end if;
318 x_to_divider.neg_result <= sign1 xor (sign2 and not x_to_divider.is_modulus);
319 if e_in.is_32bit = '0' then
320 -- 64-bit forms
321 if e_in.insn_type = OP_DIVE then
322 x_to_divider.is_extended <= '1';
323 end if;
324 x_to_divider.dividend <= std_ulogic_vector(abs1);
325 x_to_divider.divisor <= std_ulogic_vector(abs2);
326 else
327 -- 32-bit forms
328 x_to_divider.is_extended <= '0';
329 if e_in.insn_type = OP_DIVE then -- extended forms
330 x_to_divider.dividend <= std_ulogic_vector(abs1(31 downto 0)) & x"00000000";
331 else
332 x_to_divider.dividend <= x"00000000" & std_ulogic_vector(abs1(31 downto 0));
333 end if;
334 x_to_divider.divisor <= x"00000000" & std_ulogic_vector(abs2(31 downto 0));
335 end if;
336
337 ctrl_tmp <= ctrl;
338 -- FIXME: run at 512MHz not core freq
339 ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1);
340
341 terminate_out <= '0';
342 icache_inval <= '0';
343 stall_out <= '0';
344 f_out <= Execute1ToFetch1TypeInit;
345
346 -- Next insn adder used in a couple of places
347 next_nia := std_ulogic_vector(unsigned(e_in.nia) + 4);
348
349 -- rotator control signals
350 right_shift <= '1' when e_in.insn_type = OP_SHR else '0';
351 rot_clear_left <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCL else '0';
352 rot_clear_right <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCR else '0';
353
354 if e_in.valid = '1' then
355
356 v.e.valid := '1';
357 v.e.write_reg := e_in.write_reg;
358 v.slow_op_dest := gspr_to_gpr(e_in.write_reg);
359 v.slow_op_rc := e_in.rc;
360 v.slow_op_oe := e_in.oe;
361 v.slow_op_xerc := v.e.xerc;
362
363 case_0: case e_in.insn_type is
364
365 when OP_ILLEGAL =>
366 terminate_out <= '1';
367 report "illegal";
368 when OP_NOP =>
369 -- Do nothing
370 when OP_ADD | OP_CMP =>
371 if e_in.invert_a = '0' then
372 a_inv := a_in;
373 else
374 a_inv := not a_in;
375 end if;
376 result_with_carry := ppc_adde(a_inv, b_in,
377 decode_input_carry(e_in.input_carry, v.e.xerc));
378 result := result_with_carry(63 downto 0);
379 carry_32 := result(32) xor a_inv(32) xor b_in(32);
380 carry_64 := result_with_carry(64);
381 if e_in.insn_type = OP_ADD then
382 if e_in.output_carry = '1' then
383 set_carry(v.e, carry_32, carry_64);
384 end if;
385 if e_in.oe = '1' then
386 set_ov(v.e,
387 calc_ov(a_inv(63), b_in(63), carry_64, result_with_carry(63)),
388 calc_ov(a_inv(31), b_in(31), carry_32, result_with_carry(31)));
389 end if;
390 result_en := '1';
391 else
392 -- CMP and CMPL instructions
393 -- Note, we have done RB - RA, not RA - RB
394 bf := insn_bf(e_in.insn);
395 l := insn_l(e_in.insn);
396 v.e.write_cr_enable := '1';
397 crnum := to_integer(unsigned(bf));
398 v.e.write_cr_mask := num_to_fxm(crnum);
399 zerolo := not (or (a_in(31 downto 0) xor b_in(31 downto 0)));
400 zerohi := not (or (a_in(63 downto 32) xor b_in(63 downto 32)));
401 if zerolo = '1' and (l = '0' or zerohi = '1') then
402 -- values are equal
403 newcrf := "001" & v.e.xerc.so;
404 else
405 if l = '1' then
406 -- 64-bit comparison
407 msb_a := a_in(63);
408 msb_b := b_in(63);
409 else
410 -- 32-bit comparison
411 msb_a := a_in(31);
412 msb_b := b_in(31);
413 end if;
414 if msb_a /= msb_b then
415 -- Subtraction might overflow, but
416 -- comparison is clear from MSB difference.
417 -- for signed, 0 is greater; for unsigned, 1 is greater
418 a_lt := msb_a xnor e_in.is_signed;
419 else
420 -- Subtraction cannot overflow since MSBs are equal.
421 -- carry = 1 indicates RA is smaller (signed or unsigned)
422 a_lt := (not l and carry_32) or (l and carry_64);
423 end if;
424 newcrf := a_lt & not a_lt & '0' & v.e.xerc.so;
425 end if;
426 for i in 0 to 7 loop
427 lo := i*4;
428 hi := lo + 3;
429 v.e.write_cr_data(hi downto lo) := newcrf;
430 end loop;
431 end if;
432 when OP_AND | OP_OR | OP_XOR =>
433 result := logical_result;
434 result_en := '1';
435 when OP_B =>
436 f_out.redirect <= '1';
437 if (insn_aa(e_in.insn)) then
438 f_out.redirect_nia <= std_ulogic_vector(signed(b_in));
439 else
440 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(b_in));
441 end if;
442 when OP_BC =>
443 -- read_data1 is CTR
444 bo := insn_bo(e_in.insn);
445 bi := insn_bi(e_in.insn);
446 if bo(4-2) = '0' then
447 result := std_ulogic_vector(unsigned(a_in) - 1);
448 result_en := '1';
449 v.e.write_reg := fast_spr_num(SPR_CTR);
450 end if;
451 if ppc_bc_taken(bo, bi, e_in.cr, a_in) = 1 then
452 f_out.redirect <= '1';
453 if (insn_aa(e_in.insn)) then
454 f_out.redirect_nia <= std_ulogic_vector(signed(b_in));
455 else
456 f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(b_in));
457 end if;
458 end if;
459 when OP_BCREG =>
460 -- read_data1 is CTR
461 -- read_data2 is target register (CTR, LR or TAR)
462 bo := insn_bo(e_in.insn);
463 bi := insn_bi(e_in.insn);
464 if bo(4-2) = '0' and e_in.insn(10) = '0' then
465 result := std_ulogic_vector(unsigned(a_in) - 1);
466 result_en := '1';
467 v.e.write_reg := fast_spr_num(SPR_CTR);
468 end if;
469 if ppc_bc_taken(bo, bi, e_in.cr, a_in) = 1 then
470 f_out.redirect <= '1';
471 f_out.redirect_nia <= b_in(63 downto 2) & "00";
472 end if;
473 when OP_CMPB =>
474 result := ppc_cmpb(c_in, b_in);
475 result_en := '1';
476 when OP_CNTZ =>
477 result := countzero_result;
478 result_en := '1';
479 when OP_EXTS =>
480 -- note data_len is a 1-hot encoding
481 negative := (e_in.data_len(0) and c_in(7)) or
482 (e_in.data_len(1) and c_in(15)) or
483 (e_in.data_len(2) and c_in(31));
484 result := (others => negative);
485 if e_in.data_len(2) = '1' then
486 result(31 downto 16) := c_in(31 downto 16);
487 end if;
488 if e_in.data_len(2) = '1' or e_in.data_len(1) = '1' then
489 result(15 downto 8) := c_in(15 downto 8);
490 end if;
491 result(7 downto 0) := c_in(7 downto 0);
492 result_en := '1';
493 when OP_ISEL =>
494 crbit := to_integer(unsigned(insn_bc(e_in.insn)));
495 if e_in.cr(31-crbit) = '1' then
496 result := a_in;
497 else
498 result := b_in;
499 end if;
500 result_en := '1';
501 when OP_MCRF =>
502 cr_op := insn_cr(e_in.insn);
503 report "CR OP " & to_hstring(cr_op);
504 if cr_op(0) = '0' then -- MCRF
505 bf := insn_bf(e_in.insn);
506 bfa := insn_bfa(e_in.insn);
507 v.e.write_cr_enable := '1';
508 crnum := to_integer(unsigned(bf));
509 scrnum := to_integer(unsigned(bfa));
510 v.e.write_cr_mask := num_to_fxm(crnum);
511 for i in 0 to 7 loop
512 lo := (7-i)*4;
513 hi := lo + 3;
514 if i = scrnum then
515 newcrf := e_in.cr(hi downto lo);
516 end if;
517 end loop;
518 for i in 0 to 7 loop
519 lo := i*4;
520 hi := lo + 3;
521 v.e.write_cr_data(hi downto lo) := newcrf;
522 end loop;
523 else
524 v.e.write_cr_enable := '1';
525 bt := insn_bt(e_in.insn);
526 ba := insn_ba(e_in.insn);
527 bb := insn_bb(e_in.insn);
528 btnum := 31 - to_integer(unsigned(bt));
529 banum := 31 - to_integer(unsigned(ba));
530 bbnum := 31 - to_integer(unsigned(bb));
531 case cr_op(8 downto 5) is
532 when "1001" => -- CREQV
533 crresult := not(e_in.cr(banum) xor e_in.cr(bbnum));
534 when "0111" => -- CRNAND
535 crresult := not(e_in.cr(banum) and e_in.cr(bbnum));
536 when "0100" => -- CRANDC
537 crresult := (e_in.cr(banum) and not e_in.cr(bbnum));
538 when "1000" => -- CRAND
539 crresult := (e_in.cr(banum) and e_in.cr(bbnum));
540 when "0001" => -- CRNOR
541 crresult := not(e_in.cr(banum) or e_in.cr(bbnum));
542 when "1101" => -- CRORC
543 crresult := (e_in.cr(banum) or not e_in.cr(bbnum));
544 when "0110" => -- CRXOR
545 crresult := (e_in.cr(banum) xor e_in.cr(bbnum));
546 when "1110" => -- CROR
547 crresult := (e_in.cr(banum) or e_in.cr(bbnum));
548 when others =>
549 crresult := '0';
550 report "BAD CR?";
551 end case;
552 v.e.write_cr_mask := num_to_fxm((31-btnum) / 4);
553 for i in 0 to 31 loop
554 if i = btnum then
555 v.e.write_cr_data(i) := crresult;
556 else
557 v.e.write_cr_data(i) := e_in.cr(i);
558 end if;
559 end loop;
560 end if;
561 when OP_MFSPR =>
562 if is_fast_spr(e_in.read_reg1) then
563 result := a_in;
564 if decode_spr_num(e_in.insn) = SPR_XER then
565 -- bits 0:31 and 35:43 are treated as reserved and return 0s when read using mfxer
566 result(63 downto 32) := (others => '0');
567 result(63-32) := v.e.xerc.so;
568 result(63-33) := v.e.xerc.ov;
569 result(63-34) := v.e.xerc.ca;
570 result(63-35 downto 63-43) := "000000000";
571 result(63-44) := v.e.xerc.ov32;
572 result(63-45) := v.e.xerc.ca32;
573 end if;
574 else
575 case decode_spr_num(e_in.insn) is
576 when SPR_TB =>
577 result := ctrl.tb;
578 when others =>
579 result := (others => '0');
580 end case;
581 end if;
582 result_en := '1';
583 when OP_MFCR =>
584 if e_in.insn(20) = '0' then
585 -- mfcr
586 result := x"00000000" & e_in.cr;
587 else
588 -- mfocrf
589 crnum := fxm_to_num(insn_fxm(e_in.insn));
590 result := (others => '0');
591 for i in 0 to 7 loop
592 lo := (7-i)*4;
593 hi := lo + 3;
594 if crnum = i then
595 result(hi downto lo) := e_in.cr(hi downto lo);
596 end if;
597 end loop;
598 end if;
599 result_en := '1';
600 when OP_MTCRF =>
601 v.e.write_cr_enable := '1';
602 if e_in.insn(20) = '0' then
603 -- mtcrf
604 v.e.write_cr_mask := insn_fxm(e_in.insn);
605 else
606 -- mtocrf: We require one hot priority encoding here
607 crnum := fxm_to_num(insn_fxm(e_in.insn));
608 v.e.write_cr_mask := num_to_fxm(crnum);
609 end if;
610 v.e.write_cr_data := c_in(31 downto 0);
611 when OP_MTSPR =>
612 report "MTSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
613 "=" & to_hstring(c_in);
614 if is_fast_spr(e_in.write_reg) then
615 result := c_in;
616 result_en := '1';
617 if decode_spr_num(e_in.insn) = SPR_XER then
618 v.e.xerc.so := c_in(63-32);
619 v.e.xerc.ov := c_in(63-33);
620 v.e.xerc.ca := c_in(63-34);
621 v.e.xerc.ov32 := c_in(63-44);
622 v.e.xerc.ca32 := c_in(63-45);
623 v.e.write_xerc_enable := '1';
624 end if;
625 else
626 -- TODO: Implement slow SPRs
627 -- case decode_spr_num(e_in.insn) is
628 -- when others =>
629 -- end case;
630 end if;
631 when OP_POPCNT =>
632 result := popcnt_result;
633 result_en := '1';
634 when OP_PRTY =>
635 result := parity_result;
636 result_en := '1';
637 when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR =>
638 result := rotator_result;
639 if e_in.output_carry = '1' then
640 set_carry(v.e, rotator_carry, rotator_carry);
641 end if;
642 result_en := '1';
643 when OP_SIM_CONFIG =>
644 -- bit 0 was used to select the microwatt console, which
645 -- we no longer support.
646 result := x"0000000000000000";
647 result_en := '1';
648
649 when OP_TDI =>
650 -- Keep our test cases happy for now, ignore trap instructions
651 report "OP_TDI FIXME";
652
653 when OP_ISYNC =>
654 f_out.redirect <= '1';
655 f_out.redirect_nia <= next_nia;
656
657 when OP_ICBI =>
658 icache_inval <= '1';
659
660 when OP_MUL_L64 | OP_MUL_H64 | OP_MUL_H32 =>
661 v.e.valid := '0';
662 v.mul_in_progress := '1';
663 stall_out <= '1';
664 x_to_multiply.valid <= '1';
665
666 when OP_DIV | OP_DIVE | OP_MOD =>
667 v.e.valid := '0';
668 v.div_in_progress := '1';
669 stall_out <= '1';
670 x_to_divider.valid <= '1';
671
672 when OP_LOAD | OP_STORE =>
673 -- loadstore/dcache has its own port to writeback
674 v.e.valid := '0';
675
676 when others =>
677 terminate_out <= '1';
678 report "illegal";
679 end case;
680
681 v.e.rc := e_in.rc and e_in.valid;
682
683 -- Update LR on the next cycle after a branch link
684 --
685 -- WARNING: The LR update isn't tracked by our hazard tracker. This
686 -- will work (well I hope) because it only happens on branches
687 -- which will flush all decoded instructions. By the time
688 -- fetch catches up, we'll have the new LR. This will
689 -- *not* work properly however if we have a branch predictor,
690 -- in which case the solution would probably be to keep a
691 -- local cache of the updated LR in execute1 (flushed on
692 -- exceptions) that is used instead of the value from
693 -- decode when its content is valid.
694 if e_in.lr = '1' then
695 v.lr_update := '1';
696 v.next_lr := next_nia;
697 v.e.valid := '0';
698 report "Delayed LR update to " & to_hstring(next_nia);
699 stall_out <= '1';
700 end if;
701 elsif r.lr_update = '1' then
702 result_en := '1';
703 result := r.next_lr;
704 v.e.write_reg := fast_spr_num(SPR_LR);
705 v.e.valid := '1';
706 elsif r.mul_in_progress = '1' or r.div_in_progress = '1' then
707 if (r.mul_in_progress = '1' and multiply_to_x.valid = '1') or
708 (r.div_in_progress = '1' and divider_to_x.valid = '1') then
709 if r.mul_in_progress = '1' then
710 result := multiply_to_x.write_reg_data;
711 overflow := multiply_to_x.overflow;
712 else
713 result := divider_to_x.write_reg_data;
714 overflow := divider_to_x.overflow;
715 end if;
716 result_en := '1';
717 v.e.write_reg := gpr_to_gspr(v.slow_op_dest);
718 v.e.rc := v.slow_op_rc;
719 v.e.xerc := v.slow_op_xerc;
720 v.e.write_xerc_enable := v.slow_op_oe;
721 -- We must test oe because the RC update code in writeback
722 -- will use the xerc value to set CR0:SO so we must not clobber
723 -- xerc if OE wasn't set.
724 if v.slow_op_oe = '1' then
725 v.e.xerc.ov := overflow;
726 v.e.xerc.ov32 := overflow;
727 v.e.xerc.so := v.slow_op_xerc.so or overflow;
728 end if;
729 v.e.valid := '1';
730 else
731 stall_out <= '1';
732 v.mul_in_progress := r.mul_in_progress;
733 v.div_in_progress := r.div_in_progress;
734 end if;
735 end if;
736
737 v.e.write_data := result;
738 v.e.write_enable := result_en;
739
740 -- Outputs to loadstore1 (async)
741 lv := Execute1ToLoadstore1Init;
742 if e_in.valid = '1' and (e_in.insn_type = OP_LOAD or e_in.insn_type = OP_STORE) then
743 lv.valid := '1';
744 end if;
745 if e_in.insn_type = OP_LOAD then
746 lv.load := '1';
747 end if;
748 lv.addr1 := a_in;
749 lv.addr2 := b_in;
750 lv.data := c_in;
751 lv.write_reg := gspr_to_gpr(e_in.write_reg);
752 lv.length := e_in.data_len;
753 lv.byte_reverse := e_in.byte_reverse;
754 lv.sign_extend := e_in.sign_extend;
755 lv.update := e_in.update;
756 lv.update_reg := gspr_to_gpr(e_in.read_reg1);
757 lv.xerc := v.e.xerc;
758
759 -- Update registers
760 rin <= v;
761
762 -- update outputs
763 --f_out <= r.f;
764 l_out <= lv;
765 e_out <= r.e;
766 flush_out <= f_out.redirect;
767 end process;
768 end architecture behaviour;