icache & dcache: Fix store way variable
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 17 Oct 2019 05:41:19 +0000 (16:41 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 23 Oct 2019 01:30:49 +0000 (12:30 +1100)
We used the variable "way" in the wrong state in the cache when
updating a line valid bit after the end of the wishbone transactions,
we need to use the latched "store_way".

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
dcache.vhdl
icache.vhdl

index 1e2a86cc46ad1d752e62c3bb695d305cede7d11c..087e71dbf6fb6c7ab7a1a41bd4946847f0b10b04 100644 (file)
@@ -221,6 +221,7 @@ architecture rtl of dcache is
     -- PLRU output interface
     type plru_out_t is array(index_t) of std_ulogic_vector(WAY_BITS-1 downto 0);
     signal plru_victim : plru_out_t;
+    signal replace_way : way_t;
 
     -- Wishbone read/write/cache write formatting signals
     signal bus_sel                  : wishbone_sel_type;
@@ -395,6 +396,9 @@ begin
        -- The way that matched on a hit               
        req_hit_way <= hit_way;
 
+       -- The way to replace on a miss
+       replace_way <= to_integer(unsigned(plru_victim(req_index)));
+
        -- Combine the request and cache his status to decide what
        -- operation needs to be done
        --
@@ -666,7 +670,6 @@ begin
     -- operates at stage 1.
     --
     dcache_slow : process(clk)
-       variable way : integer range 0 to NUM_WAYS-1;
        variable tagset : cache_tags_set_t;
     begin
         if rising_edge(clk) then
@@ -706,21 +709,17 @@ begin
                    when OP_LOAD_MISS =>
                        -- Normal load cache miss, start the reload machine
                        --
-                       -- First find a victim way from the PLRU
-                       --
-                       way := to_integer(unsigned(plru_victim(req_index)));
-
                        report "cache miss addr:" & to_hstring(d_in.addr) &
                            " idx:" & integer'image(req_index) &
-                           " way:" & integer'image(way) &
+                           " way:" & integer'image(replace_way) &
                            " tag:" & to_hstring(req_tag);
 
                        -- Force misses on that way while reloading that line
-                       cache_valids(req_index)(way) <= '0';
+                       cache_valids(req_index)(replace_way) <= '0';
 
                        -- Store new tag in selected way
                        for i in 0 to NUM_WAYS-1 loop
-                           if i = way then
+                           if i = replace_way then
                                tagset := cache_tags(req_index);
                                write_tag(i, tagset, req_tag);
                                cache_tags(req_index) <= tagset;
@@ -729,7 +728,7 @@ begin
 
                        -- Keep track of our index and way for subsequent stores.
                        r1.store_index <= req_index;
-                       r1.store_way <= way;
+                       r1.store_way <= replace_way;
 
                        -- Prep for first wishbone read. We calculate the address of
                        -- the start of the cache line
@@ -785,7 +784,7 @@ begin
 
                        -- That was the last word ? We are done
                        if is_last_row(r1.wb.adr) then
-                           cache_valids(r1.store_index)(way) <= '1';
+                           cache_valids(r1.store_index)(r1.store_way) <= '1';
                            r1.wb.cyc <= '0';
                            r1.wb.stb <= '0';
 
index 75695e1c3e5bf06ce3910cec784e1abb4edb9c4b..95e37af3a7bb0667c24c26726a27de732122f827 100644 (file)
@@ -178,6 +178,7 @@ architecture rtl of icache is
     -- PLRU output interface
     type plru_out_t is array(index_t) of std_ulogic_vector(WAY_BITS-1 downto 0);
     signal plru_victim : plru_out_t;
+    signal replace_way : way_t;
 
     -- Return the cache line index (tag index) for an address
     function get_index(addr: std_ulogic_vector(63 downto 0)) return index_t is
@@ -371,6 +372,9 @@ begin
        req_is_miss <= i_in.req and not is_hit and not flush_in;
        req_hit_way <= hit_way;
 
+       -- The way to replace on a miss
+       replace_way <= to_integer(unsigned(plru_victim(req_index)));
+
        -- Output instruction from current cache row
        --
        -- Note: This is a mild violation of our design principle of having pipeline
@@ -420,7 +424,6 @@ begin
 
     -- Cache miss/reload synchronous machine
     icache_miss : process(clk)
-       variable way : integer range 0 to NUM_WAYS-1;
        variable tagset : cache_tags_set_t;
     begin
         if rising_edge(clk) then
@@ -446,20 +449,18 @@ begin
                when IDLE =>
                    -- We need to read a cache line
                    if req_is_miss = '1' then
-                       way := to_integer(unsigned(plru_victim(req_index)));
-
                        report "cache miss nia:" & to_hstring(i_in.nia) &
                            " SM:" & std_ulogic'image(i_in.stop_mark) &
                            " idx:" & integer'image(req_index) &
-                           " way:" & integer'image(way) &
+                           " way:" & integer'image(replace_way) &
                            " tag:" & to_hstring(req_tag);
 
                        -- Force misses on that way while reloading that line
-                       cache_valids(req_index)(way) <= '0';
+                       cache_valids(req_index)(replace_way) <= '0';
 
                        -- Store new tag in selected way
                        for i in 0 to NUM_WAYS-1 loop
-                           if i = way then
+                           if i = replace_way then
                                tagset := cache_tags(req_index);
                                write_tag(i, tagset, req_tag);
                                cache_tags(req_index) <= tagset;
@@ -468,7 +469,7 @@ begin
 
                        -- Keep track of our index and way for subsequent stores
                        r.store_index <= req_index;
-                       r.store_way <= way;
+                       r.store_way <= replace_way;
 
                        -- Prep for first wishbone read. We calculate the address of
                        -- the start of the cache line
@@ -484,7 +485,7 @@ begin
                    if wishbone_in.ack = '1' then
                        -- That was the last word ? We are done
                        if is_last_row(r.wb.adr) then
-                           cache_valids(r.store_index)(way) <= '1';
+                           cache_valids(r.store_index)(r.store_way) <= '1';
                            r.wb.cyc <= '0';
                            r.wb.stb <= '0';
                            r.state <= IDLE;