@ -47,7 +47,6 @@ architecture behave of loadstore1 is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                     );
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    type reg_stage_t is record
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        busy         : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- latch most of the input request
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        load         : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        tlbie        : std_ulogic;
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -126,7 +125,6 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if rising_edge(clk) then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if rst = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                r.state <= IDLE;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                r.busy <= '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                r <= rin;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -143,7 +141,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable long_sel : std_ulogic_vector(15 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable byte_sel : std_ulogic_vector(7 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable req : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable stall : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable busy : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable addr : std_ulogic_vector(63 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable wdata : std_ulogic_vector(63 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable write_enable : std_ulogic;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -165,15 +163,12 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        v := r;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        req := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        stall := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        done := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        byte_sel := (others => '0');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        addr := lsu_sum;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        v.mfspr := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        mmu_mtspr := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        itlb_fault := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        sprn := std_ulogic_vector(to_unsigned(decode_spr_num(l_in.insn), 10));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        exception := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        dsisr := (others => '0');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        mmureq := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -232,130 +227,18 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- compute (addr + 8) & ~7 for the second doubleword when unaligned
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        next_addr := std_ulogic_vector(unsigned(r.addr(63 downto 3)) + 1) & "000";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        done := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        exception := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        case r.state is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        when IDLE =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if l_in.valid = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.addr := lsu_sum;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.load := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.dcbz := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.tlbie := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.instr_fault := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.dwords_done := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                case l_in.op is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_STORE =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    req := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_LOAD =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    req := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.load := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_DCBZ =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    req := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.dcbz := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_TLBIE =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    mmureq := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    stall := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.tlbie := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.state := TLBIE_WAIT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_MFSPR =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.mfspr := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    -- partial decode on SPR number should be adequate given
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    -- the restricted set that get sent down this path
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    if sprn(9) = '0' and sprn(5) = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        if sprn(0) = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            v.sprval := x"00000000" & r.dsisr;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            v.sprval := r.dar;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        -- reading one of the SPRs in the MMU
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        v.sprval := m_in.sprval;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.state := SPR_CMPLT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_MTSPR =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    if sprn(9) = '0' and sprn(5) = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        if sprn(0) = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            v.dsisr := l_in.data(31 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            v.dar := l_in.data;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        v.state := SPR_CMPLT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        -- writing one of the SPRs in the MMU
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        mmu_mtspr := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        stall := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        v.state := TLBIE_WAIT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_FETCH_FAILED =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    -- send it to the MMU to do the radix walk
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    addr := l_in.nia;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.addr := l_in.nia;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.instr_fault := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    mmureq := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    stall := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.state := MMU_LOOKUP;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when others =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    assert false report "unknown op sent to loadstore1";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                end case;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.write_reg := l_in.write_reg;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.length := l_in.length;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.byte_reverse := l_in.byte_reverse;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.sign_extend := l_in.sign_extend;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.update := l_in.update;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.update_reg := l_in.update_reg;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.xerc := l_in.xerc;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.reserve := l_in.reserve;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.rc := l_in.rc;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.nc := l_in.ci;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.virt_mode := l_in.virt_mode;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.priv_mode := l_in.priv_mode;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                -- XXX Temporary hack. Mark the op as non-cachable if the address
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                -- is the form 0xc------- for a real-mode access.
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                --
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                -- This will have to be replaced by a combination of implementing the
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                -- proper HV CI load/store instructions and having an MMU to get the I
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                -- bit otherwise.
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if lsu_sum(31 downto 28) = "1100" and l_in.virt_mode = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.nc := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                -- Do length_to_sel and work out if we are doing 2 dwords
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                long_sel := xfer_data_sel(l_in.length, v.addr(2 downto 0));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                byte_sel := long_sel(7 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.first_bytes := byte_sel;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.second_bytes := long_sel(15 downto 8);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                -- Do byte reversing and rotating for stores in the first cycle
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                byte_offset := unsigned(lsu_sum(2 downto 0));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                brev_lenm1 := "000";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if l_in.byte_reverse = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    brev_lenm1 := unsigned(l_in.length(2 downto 0)) - 1;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                for i in 0 to 7 loop
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    k := (to_unsigned(i, 3) xor brev_lenm1) + byte_offset;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    j := to_integer(k) * 8;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.store_data(j + 7 downto j) := l_in.data(i * 8 + 7 downto i * 8);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                end loop;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if req = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    stall := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    if long_sel(15 downto 8) = "00000000" then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        v.state := ACK_WAIT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        v.state := SECOND_REQ;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        when SECOND_REQ =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            addr := next_addr;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            byte_sel := r.second_bytes;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            req := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            stall := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.state := ACK_WAIT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        when ACK_WAIT =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            stall := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if d_in.valid = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if d_in.error = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    -- dcache will discard the second request if it
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -393,7 +276,6 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            -- stores write back rA update in this cycle
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            do_update := r.update;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            stall := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            done := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            v.state := IDLE;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        end if;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -402,7 +284,6 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        when MMU_LOOKUP =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            stall := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if r.dwords_done = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                addr := next_addr;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                byte_sel := r.second_bytes;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -423,7 +304,6 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        -- nothing to do, the icache retries automatically
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        stall := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        done := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        v.state := IDLE;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    end if;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -439,10 +319,8 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        when TLBIE_WAIT =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            stall := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if m_in.done = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                -- tlbie is finished
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                stall := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                done := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.state := IDLE;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -458,6 +336,117 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end case;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        busy := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if r.state = IDLE or done = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            busy := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Note that l_in.valid is gated with busy inside execute1
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if l_in.valid = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.addr := lsu_sum;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.load := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.dcbz := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.tlbie := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.instr_fault := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.dwords_done := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.write_reg := l_in.write_reg;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.length := l_in.length;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.byte_reverse := l_in.byte_reverse;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.sign_extend := l_in.sign_extend;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.update := l_in.update;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.update_reg := l_in.update_reg;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.xerc := l_in.xerc;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.reserve := l_in.reserve;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.rc := l_in.rc;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.nc := l_in.ci;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.virt_mode := l_in.virt_mode;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.priv_mode := l_in.priv_mode;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            -- XXX Temporary hack. Mark the op as non-cachable if the address
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            -- is the form 0xc------- for a real-mode access.
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if lsu_sum(31 downto 28) = "1100" and l_in.virt_mode = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.nc := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            -- Do length_to_sel and work out if we are doing 2 dwords
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            long_sel := xfer_data_sel(l_in.length, v.addr(2 downto 0));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            byte_sel := long_sel(7 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.first_bytes := byte_sel;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            v.second_bytes := long_sel(15 downto 8);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            -- Do byte reversing and rotating for stores in the first cycle
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            byte_offset := unsigned(lsu_sum(2 downto 0));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            brev_lenm1 := "000";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if l_in.byte_reverse = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                brev_lenm1 := unsigned(l_in.length(2 downto 0)) - 1;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            for i in 0 to 7 loop
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                k := (to_unsigned(i, 3) xor brev_lenm1) + byte_offset;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                j := to_integer(k) * 8;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                v.store_data(j + 7 downto j) := l_in.data(i * 8 + 7 downto i * 8);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end loop;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            case l_in.op is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_STORE =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    req := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_LOAD =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    req := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.load := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_DCBZ =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    req := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.dcbz := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_TLBIE =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    mmureq := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.tlbie := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.state := TLBIE_WAIT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_MFSPR =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.mfspr := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    -- partial decode on SPR number should be adequate given
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    -- the restricted set that get sent down this path
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    if sprn(9) = '0' and sprn(5) = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        if sprn(0) = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            v.sprval := x"00000000" & r.dsisr;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            v.sprval := r.dar;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        -- reading one of the SPRs in the MMU
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        v.sprval := m_in.sprval;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.state := SPR_CMPLT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_MTSPR =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    if sprn(9) = '0' and sprn(5) = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        if sprn(0) = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            v.dsisr := l_in.data(31 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            v.dar := l_in.data;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        v.state := SPR_CMPLT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        -- writing one of the SPRs in the MMU
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        mmu_mtspr := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        v.state := TLBIE_WAIT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when OP_FETCH_FAILED =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    -- send it to the MMU to do the radix walk
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    addr := l_in.nia;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.addr := l_in.nia;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.instr_fault := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    mmureq := '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.state := MMU_LOOKUP;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                when others =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    assert false report "unknown op sent to loadstore1";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end case;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if req = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if long_sel(15 downto 8) = "00000000" then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.state := ACK_WAIT;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    v.state := SECOND_REQ;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Update outputs to dcache
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        d_out.valid <= req;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        d_out.load <= v.load;
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -504,7 +493,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        l_out.store_done <= d_in.store_done;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- update exception info back to execute1
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        e_out.busy <= r.busy;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        e_out.busy <= busy;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        e_out.exception <= exception;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        e_out.instr_fault <= r.instr_fault;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        e_out.invalid <= m_in.invalid;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -519,8 +508,6 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        v.busy := stall;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Update registers
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        rin <= v;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -529,7 +516,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    ls1_log: process(clk)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if rising_edge(clk) then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            log_data <= r.busy &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            log_data <= e_out.busy &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        e_out.exception &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        l_out.valid &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        m_out.valid &