@ -163,7 +163,6 @@ architecture behaviour of litedram_wrapper is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Select a WB word inside DRAM port width
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    constant WB_WORD_COUNT              : positive := DRAM_DBITS/WBL;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    constant WB_WSEL_BITS               : positive := log2(WB_WORD_COUNT);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    constant WB_WSEL_RIGHT              : positive := log2(WBL/8);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- BRAM organisation: We never access more than wishbone_data_bits at
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- a time so to save resources we make the array only that wide, and
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -312,10 +311,20 @@ architecture behaviour of litedram_wrapper is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Helper functions to decode incoming requests
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    --
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Return the DRAM real address from a wishbone address
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    function get_real_addr(addr: wishbone_addr_type) return std_ulogic_vector is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable ra: std_ulogic_vector(REAL_ADDR_BITS - 1 downto 0) := (others => '0');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        ra(REAL_ADDR_BITS - 1 downto wishbone_log2_width) :=
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            addr(REAL_ADDR_BITS - wishbone_log2_width - 1 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        return ra;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    end;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Return the cache line index (tag index) for an address
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    function get_index(addr: wishbone_addr_type) return index_t is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        return to_integer(unsigned(addr(SET_SIZE_BITS - 1 downto LINE_OFF_BITS)));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        return to_integer(unsigned(addr(SET_SIZE_BITS - wishbone_log2_width - 1 downto
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                        LINE_OFF_BITS - wishbone_log2_width)));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    end;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Return the cache row index (data memory) for an address
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -378,7 +387,8 @@ architecture behaviour of litedram_wrapper is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Get the tag value from the address
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    function get_tag(addr: wishbone_addr_type) return cache_tag_t is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        return addr(REAL_ADDR_BITS - 1 downto SET_SIZE_BITS);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        return addr(REAL_ADDR_BITS - wishbone_log2_width - 1 downto
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    SET_SIZE_BITS - wishbone_log2_width);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    end;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Read a tag from a tag memory row
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -447,7 +457,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                wb_ctrl_stb <= '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                -- XXX Maybe only update addr when cyc = '1' to save power ?
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                wb_ctrl_adr   <= x"0000" & wb_ctrl_in.adr(15 downto 2);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                wb_ctrl_adr   <= x"0000" & wb_ctrl_in.adr(13 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                wb_ctrl_dat_w <= wb_ctrl_in.dat;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                wb_ctrl_sel   <= wb_ctrl_in.sel;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                wb_ctrl_we    <= wb_ctrl_in.we;
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -608,7 +618,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if stall = '1' and wb_out.stall = '0' and wb_in.cyc = '1' and wb_in.stb = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                 wb_stash <= wb_in;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                 if TRACE then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                     report "stashed wb req ! addr:" & to_hstring(wb_in.adr) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                     report "stashed wb req ! addr:" & to_hstring(wb_in.adr & "000") &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                         " we:" & std_ulogic'image(wb_in.we) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                         " sel:" & to_hstring(wb_in.sel);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                 end if;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -621,7 +631,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    wb_req <= wb_stash;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    wb_stash.cyc <= '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    if TRACE then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        report "unstashed wb req ! addr:" & to_hstring(wb_stash.adr) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        report "unstashed wb req ! addr:" & to_hstring(wb_stash.adr & "000") &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            " we:" & std_ulogic'image(wb_stash.we) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            " sel:" & to_hstring(wb_stash.sel);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    end if;
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -636,7 +646,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    if TRACE then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        if wb_in.cyc = '1' and wb_in.stb = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            report "latch new wb req ! addr:" & to_hstring(wb_in.adr) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            report "latch new wb req ! addr:" & to_hstring(wb_in.adr & "000") &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                " we:" & std_ulogic'image(wb_in.we) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                " sel:" & to_hstring(wb_in.sel);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        end if;
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -665,12 +675,12 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if TRACE then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if req_op = OP_LOAD_HIT then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    report "Load hit addr:" & to_hstring(wb_req.adr) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    report "Load hit addr:" & to_hstring(wb_req.adr & "000") &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        " idx:" & integer'image(req_index) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        " tag:" & to_hstring(req_tag) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        " way:" & integer'image(req_hit_way);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                elsif req_op = OP_LOAD_MISS then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    report "Load miss addr:" & to_hstring(wb_req.adr);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    report "Load miss addr:" & to_hstring(wb_req.adr & "000");
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if read_ack_0 = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    report "read data:" & to_hstring(cache_out(read_way_0));
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -771,20 +781,19 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Extract line, row and tag from request
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        req_index <= get_index(wb_req.adr);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        req_row <= get_row(wb_req.adr(REAL_ADDR_BITS-1 downto 0));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        req_row <= get_row(get_real_addr(wb_req.adr));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        req_tag <= get_tag(wb_req.adr);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Calculate address of beginning of cache row, will be
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- used for cache miss processing if needed
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        req_laddr <= wb_req.adr(REAL_ADDR_BITS - 1 downto ROW_OFF_BITS) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                     (ROW_OFF_BITS-1 downto 0 => '0');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        req_laddr <= get_real_addr(wb_req.adr);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Do we have a valid request in the WB latch ?
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        valid := wb_req.cyc = '1' and wb_req.stb = '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Store signals (hard wired for 64-bit wishbone at the moment)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        req_wsl <= wb_req.adr(WB_WSEL_RIGHT+WB_WSEL_BITS-1 downto WB_WSEL_RIGHT);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        req_wsl <= wb_req.adr(WB_WSEL_BITS-1 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        for i in 0 to WB_WORD_COUNT-1 loop
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if to_integer(unsigned(req_wsl)) = i then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                req_we(WBSL*(i+1)-1 downto WBSL*i) <= wb_req.sel;
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -892,7 +901,7 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable stq_wsl  : std_ulogic_vector(WB_WSEL_BITS-1 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        storeq_wr_data <= wb_req.dat & wb_req.sel &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                          wb_req.adr(WB_WSEL_RIGHT+WB_WSEL_BITS-1 downto WB_WSEL_RIGHT);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                          wb_req.adr(WB_WSEL_BITS-1 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        -- Only queue stores if we can also send a command
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if req_op = OP_STORE_HIT or req_op = OP_STORE_MISS then
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -927,13 +936,13 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if rising_edge(system_clk) then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if req_op = OP_STORE_HIT then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    report "Store hit to:" &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        to_hstring(wb_req.adr(DRAM_ABITS+3 downto 0)) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        to_hstring(wb_req.adr(DRAM_ABITS downto 0) & "000") &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        " data:" & to_hstring(req_wdata) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        " we:" & to_hstring(req_we) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        " V:" & std_ulogic'image(user_port0_cmd_ready);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    report "Store miss to:" &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        to_hstring(wb_req.adr(DRAM_ABITS+3 downto 0)) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        to_hstring(wb_req.adr(DRAM_ABITS downto 0) & "000") &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        " data:" & to_hstring(req_wdata) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        " we:" & to_hstring(req_we) &
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        " V:" & std_ulogic'image(user_port0_cmd_ready);
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -954,7 +963,8 @@ begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if req_op = OP_STORE_HIT or req_op = OP_STORE_MISS then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            -- For stores, forward signals directly. Only send command if
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            -- the FIFO can accept a store.
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            user_port0_cmd_addr  <= wb_req.adr(DRAM_ABITS+ROW_OFF_BITS-1 downto ROW_OFF_BITS);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            user_port0_cmd_addr  <= wb_req.adr(DRAM_ABITS + ROW_OFF_BITS - wishbone_log2_width - 1 downto
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                               ROW_OFF_BITS - wishbone_log2_width);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            user_port0_cmd_we    <= '1';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            user_port0_cmd_valid <= storeq_wr_ready;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        else