| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -119,10 +119,11 @@ architecture behaviour of execute1 is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal overflow_32 : std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal overflow_64 : std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal cmprb_result : std_ulogic_vector(3 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal cmpeqb_result : std_ulogic_vector(3 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal trapval : std_ulogic_vector(4 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal write_cr_mask : std_ulogic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal write_cr_data : std_ulogic_vector(31 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    -- multiply signals
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal x_to_multiply: MultiplyInputType;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal multiply_to_x: MultiplyOutputType;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -169,7 +170,6 @@ architecture behaviour of execute1 is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					e.xerc.ca32 := carry32;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					e.xerc.ca := carry;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					e.write_xerc_enable := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    procedure set_ov(e: inout Execute1ToWritebackType;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -181,7 +181,6 @@ architecture behaviour of execute1 is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if ov = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    e.xerc.so := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					e.write_xerc_enable := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    function calc_ov(msb_a : std_ulogic; msb_b: std_ulogic;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -360,7 +359,6 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable darn : std_ulogic_vector(63 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable setb_result : std_ulogic_vector(63 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable mfcr_result : std_ulogic_vector(63 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable crnum : crnum_t;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable lo, hi : integer;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable l : std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable zerohi, zerolo : std_ulogic;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -368,7 +366,16 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable a_lt : std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable a_lt_lo : std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable a_lt_hi : std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable bfa : std_ulogic_vector(2 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable newcrf : std_ulogic_vector(3 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable bf, bfa : std_ulogic_vector(2 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable crnum : crnum_t;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable scrnum : crnum_t;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable cr_operands : std_ulogic_vector(1 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable crresult : std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable bt, ba, bb : std_ulogic_vector(4 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable btnum : integer range 0 to 3;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable banum, bbnum : integer range 0 to 31;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable j : integer;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        -- Main adder
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if e_in.invert_a = '0' then
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -591,24 +598,77 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        cmprb_result <= ppc_cmprb(a_in, b_in, insn_l(e_in.insn));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        cmpeqb_result <= ppc_cmpeqb(a_in, b_in);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        -- CR result mux
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        bf := insn_bf(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        crnum := to_integer(unsigned(bf));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        newcrf := (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        case current.sub_select is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when "000" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                -- CMP and CMPL instructions
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if e_in.is_signed = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    newcrf := trapval(4 downto 2) & xerc_in.so;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    newcrf := trapval(1 downto 0) & trapval(2) & xerc_in.so;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when "001" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                newcrf := ppc_cmprb(a_in, b_in, insn_l(e_in.insn));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when "010" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                newcrf := ppc_cmpeqb(a_in, b_in);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when "011" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if current.insn(1) = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- CR logical instructions
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    j := (7 - crnum) * 4;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    newcrf := cr_in(j + 3 downto j);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    bt := insn_bt(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    ba := insn_ba(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    bb := insn_bb(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    btnum := 3 - to_integer(unsigned(bt(1 downto 0)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    banum := 31 - to_integer(unsigned(ba));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    bbnum := 31 - to_integer(unsigned(bb));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- Bits 6-9 of the instruction word give the truth table
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- of the requested logical operation
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    cr_operands := cr_in(banum) & cr_in(bbnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    crresult := e_in.insn(6 + to_integer(unsigned(cr_operands)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    for i in 0 to 3 loop
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        if i = btnum then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            newcrf(i) := crresult;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    end loop;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- MCRF
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    bfa := insn_bfa(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    scrnum := to_integer(unsigned(bfa));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    j := (7 - scrnum) * 4;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    newcrf := cr_in(j + 3 downto j);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when "100" =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                -- MCRXRX
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                newcrf := xerc_in.ov & xerc_in.ca & xerc_in.ov32 & xerc_in.ca32;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when others =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if current.insn_type = OP_MTCRF then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if e_in.insn(20) = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                -- mtcrf
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                write_cr_mask <= insn_fxm(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                -- mtocrf: We require one hot priority encoding here
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                crnum := fxm_to_num(insn_fxm(e_in.insn));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                write_cr_mask <= num_to_fxm(crnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            write_cr_data <= c_in(31 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            write_cr_mask <= num_to_fxm(crnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            write_cr_data <= newcrf & newcrf & newcrf & newcrf &
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                             newcrf & newcrf & newcrf & newcrf;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end process;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    execute1_1: process(all)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable v : reg_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable newcrf : std_ulogic_vector(3 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable crnum : crnum_t;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable scrnum : crnum_t;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable lo, hi : integer;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable sh, mb, me : std_ulogic_vector(5 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable bo, bi : std_ulogic_vector(4 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable bf, bfa : std_ulogic_vector(2 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable cr_op : std_ulogic_vector(9 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable cr_operands : std_ulogic_vector(1 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable bt, ba, bb : std_ulogic_vector(4 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable btnum, banum, bbnum : integer range 0 to 31;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable crresult : std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable overflow : std_ulogic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable lv : Execute1ToLoadstore1Type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					variable irq_valid : std_ulogic;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -625,7 +685,6 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable f : Execute1ToFetch1Type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        variable fv : Execute1ToFPUType;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					newcrf := (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        is_branch := '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        is_direct_branch := '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        taken_branch := '0';
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -800,27 +859,12 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        v.e.xerc.ov := carry_64;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        v.e.xerc.ov32 := carry_32;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        v.e.write_xerc_enable := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if e_in.oe = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    set_ov(v.e, overflow_64, overflow_32);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_CMP =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                -- CMP and CMPL instructions
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if e_in.is_signed = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    newcrf := trapval(4 downto 2) & xerc_in.so;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    newcrf := trapval(1 downto 0) & trapval(2) & xerc_in.so;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                bf := insn_bf(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                crnum := to_integer(unsigned(bf));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.e.write_cr_mask := num_to_fxm(crnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                for i in 0 to 7 loop
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    lo := i*4;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    hi := lo + 3;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    v.e.write_cr_data(hi downto lo) := newcrf;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                end loop;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_TRAP =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                -- trap instructions (tw, twi, td, tdi)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.vector := 16#700#;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -833,19 +877,7 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_ADDG6S =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_CMPRB =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                newcrf := cmprb_result;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                bf := insn_bf(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                crnum := to_integer(unsigned(bf));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.e.write_cr_mask := num_to_fxm(crnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.e.write_cr_data := newcrf & newcrf & newcrf & newcrf &
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                     newcrf & newcrf & newcrf & newcrf;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_CMPEQB =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                newcrf := cmpeqb_result;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                bf := insn_bf(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                crnum := to_integer(unsigned(bf));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.e.write_cr_mask := num_to_fxm(crnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.e.write_cr_data := newcrf & newcrf & newcrf & newcrf &
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                     newcrf & newcrf & newcrf & newcrf;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_AND | OP_OR | OP_XOR | OP_POPCNT | OP_PRTY | OP_CMPB | OP_EXTS |
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    OP_BPERM | OP_BCD =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -911,53 +943,8 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.cntz_in_progress := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.busy := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    when OP_ISEL =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    when OP_CROP =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						cr_op := insn_cr(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if cr_op(0) = '0' then -- MCRF
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    bf := insn_bf(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    bfa := insn_bfa(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    crnum := to_integer(unsigned(bf));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    scrnum := to_integer(unsigned(bfa));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    v.e.write_cr_mask := num_to_fxm(crnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    for i in 0 to 7 loop
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						        lo := (7-i)*4;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						        hi := lo + 3;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						        if i = scrnum then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    newcrf := cr_in(hi downto lo);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						        end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end loop;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    for i in 0 to 7 loop
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						        lo := i*4;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						        hi := lo + 3;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						        v.e.write_cr_data(hi downto lo) := newcrf;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end loop;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    bt := insn_bt(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    ba := insn_ba(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    bb := insn_bb(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    btnum := 31 - to_integer(unsigned(bt));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    banum := 31 - to_integer(unsigned(ba));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    bbnum := 31 - to_integer(unsigned(bb));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- Bits 5-8 of cr_op give the truth table of the requested
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- logical operation
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    cr_operands := cr_in(banum) & cr_in(bbnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    crresult := cr_op(5 + to_integer(unsigned(cr_operands)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    v.e.write_cr_mask := num_to_fxm((31-btnum) / 4);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    for i in 0 to 31 loop
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if i = btnum then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						            v.e.write_cr_data(i) := crresult;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						            v.e.write_cr_data(i) := cr_in(i);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end loop;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_CROP =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_MCRXRX =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                newcrf := xerc_in.ov & xerc_in.ca & xerc_in.ov32 & xerc_in.ca32;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                bf := insn_bf(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                crnum := to_integer(unsigned(bf));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.e.write_cr_mask := num_to_fxm(crnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                v.e.write_cr_data := newcrf & newcrf & newcrf & newcrf &
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                     newcrf & newcrf & newcrf & newcrf;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_DARN =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    when OP_MFMSR =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    when OP_MFSPR =>
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -1007,15 +994,6 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    when OP_MFCR =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    when OP_MTCRF =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if e_in.insn(20) = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    -- mtcrf
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    v.e.write_cr_mask := insn_fxm(e_in.insn);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    -- mtocrf: We require one hot priority encoding here
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    crnum := fxm_to_num(insn_fxm(e_in.insn));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    v.e.write_cr_mask := num_to_fxm(crnum);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						v.e.write_cr_data := c_in(31 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            when OP_MTMSRD =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if e_in.insn(16) = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- just update EE and RI
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -1050,7 +1028,6 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							v.e.xerc.ca := c_in(63-34);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							v.e.xerc.ov32 := c_in(63-44);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							v.e.xerc.ca32 := c_in(63-45);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							v.e.write_xerc_enable := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    -- slow spr
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -1170,7 +1147,6 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    v.mul_finish := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    v.busy := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    v.e.write_xerc_enable := current.oe;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- We must test oe because the RC update code in writeback
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- will use the xerc value to set CR0:SO so we must not clobber
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    -- xerc if OE wasn't set.
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1190,7 +1166,6 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        elsif r.mul_finish = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            hold_wr_data := '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            v.e.write_xerc_enable := current.oe;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            v.e.xerc.ov := multiply_to_x.overflow;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            v.e.xerc.ov32 := multiply_to_x.overflow;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if multiply_to_x.overflow = '1' then
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -1268,8 +1243,11 @@ begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        v.e.write_reg := current.write_reg;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					v.e.write_enable := current.write_reg_enable and v.e.valid and not exception;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        v.e.write_cr_enable := current.output_cr and v.e.valid and not exception;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        v.e.rc := current.rc and v.e.valid and not exception;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        v.e.write_cr_data := write_cr_data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        v.e.write_cr_mask := write_cr_mask;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        v.e.write_cr_enable := current.output_cr and v.e.valid and not exception;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        v.e.write_xerc_enable := current.output_xer and v.e.valid and not exception;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        bypass_data.tag.valid <= current.instr_tag.valid and current.write_reg_enable and v.e.valid;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        bypass_data.tag.tag <= current.instr_tag.tag;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |