@ -42,7 +42,6 @@ architecture behaviour of writeback is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal sign_extend : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal negative : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal second_word : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal zero : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    writeback_0: process(clk)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -62,6 +61,8 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable k : unsigned(3 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					variable cf: std_ulogic_vector(3 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					variable xe: xer_common_t;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable zero : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable sign : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        x := "" & e_in.valid;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        y := "" & l_in.valid;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -85,10 +86,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        rc <= '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        brev_lenm1 <= "000";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        byte_offset <= "000";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        data_len <= x"8";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        partial_write <= '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        sign_extend <= '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        second_word <= '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					xe := e_in.xerc;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					data_in <= (others => '0');
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -96,9 +94,6 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if e_in.write_enable = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            w_out.write_reg <= e_in.write_reg;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            w_out.write_enable <= '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    data_in <= e_in.write_data;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            data_len <= unsigned(e_in.write_len);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            sign_extend <= e_in.sign_extend;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            rc <= e_in.rc;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -113,12 +108,11 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            c_out.write_xerc_data <= e_in.xerc;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        sign_extend <= l_in.sign_extend;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        data_len <= unsigned(l_in.write_len);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        byte_offset <= unsigned(l_in.write_shift);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if l_in.write_enable = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            w_out.write_reg <= gpr_to_gspr(l_in.write_reg);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            data_in <= l_in.write_data;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            data_len <= unsigned(l_in.write_len);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            byte_offset <= unsigned(l_in.write_shift);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            sign_extend <= l_in.sign_extend;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if l_in.byte_reverse = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                brev_lenm1 <= unsigned(l_in.write_len(2 downto 0)) - 1;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -138,7 +132,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end loop;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        for i in 0 to 7 loop
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            j := to_integer(perm(i)) * 8;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            data_permuted(i * 8 + 7 downto i * 8) <= data_in(j + 7 downto j);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            data_permuted(i * 8 + 7 downto i * 8) <= l_in.write_data(j + 7 downto j);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end loop;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- If the data can arrive split over two cycles, this will be correct
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -160,16 +154,12 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                trim_ctl(i) <= '0' & (negative and sign_extend);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end loop;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					zero <= not negative;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        for i in 0 to 7 loop
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            case trim_ctl(i) is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when "11" =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    data_trimmed(i * 8 + 7 downto i * 8) <= data_latched(i * 8 + 7 downto i * 8);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when "10" =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    data_trimmed(i * 8 + 7 downto i * 8) <= data_permuted(i * 8 + 7 downto i * 8);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    if or data_permuted(i * 8 + 7 downto i * 8) /= '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							zero <= '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when "01" =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    data_trimmed(i * 8 + 7 downto i * 8) <= x"FF";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when others =>
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -178,14 +168,21 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end loop;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- deliver to regfile
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        w_out.write_data <= data_trimmed;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if l_in.write_enable = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            w_out.write_data <= data_trimmed;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            w_out.write_data <= e_in.write_data;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Perform CR0 update for RC forms
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Note that loads never have a form with an RC bit, therefore this can test e_in.write_data
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if rc = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            sign := e_in.write_data(63);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            zero := not (or e_in.write_data);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            c_out.write_cr_enable <= '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            c_out.write_cr_mask <= num_to_fxm(0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    cf(3) := negative;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    cf(2) := not negative and not zero;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    cf(3) := sign;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    cf(2) := not sign and not zero;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    cf(1) := zero;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    cf(0) := xe.so;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    c_out.write_cr_data(31 downto 28) <= cf;