icache & dcache: Fix store way variable

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>
pull/114/head
Benjamin Herrenschmidt 5 years ago
parent 587a5e3c45
commit 6e0ee0b0db

@ -221,6 +221,7 @@ architecture rtl of dcache is
-- PLRU output interface -- PLRU output interface
type plru_out_t is array(index_t) of std_ulogic_vector(WAY_BITS-1 downto 0); type plru_out_t is array(index_t) of std_ulogic_vector(WAY_BITS-1 downto 0);
signal plru_victim : plru_out_t; signal plru_victim : plru_out_t;
signal replace_way : way_t;


-- Wishbone read/write/cache write formatting signals -- Wishbone read/write/cache write formatting signals
signal bus_sel : wishbone_sel_type; signal bus_sel : wishbone_sel_type;
@ -395,6 +396,9 @@ begin
-- The way that matched on a hit -- The way that matched on a hit
req_hit_way <= hit_way; 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 -- Combine the request and cache his status to decide what
-- operation needs to be done -- operation needs to be done
-- --
@ -666,7 +670,6 @@ begin
-- operates at stage 1. -- operates at stage 1.
-- --
dcache_slow : process(clk) dcache_slow : process(clk)
variable way : integer range 0 to NUM_WAYS-1;
variable tagset : cache_tags_set_t; variable tagset : cache_tags_set_t;
begin begin
if rising_edge(clk) then if rising_edge(clk) then
@ -706,21 +709,17 @@ begin
when OP_LOAD_MISS => when OP_LOAD_MISS =>
-- Normal load cache miss, start the reload machine -- 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) & report "cache miss addr:" & to_hstring(d_in.addr) &
" idx:" & integer'image(req_index) & " idx:" & integer'image(req_index) &
" way:" & integer'image(way) & " way:" & integer'image(replace_way) &
" tag:" & to_hstring(req_tag); " tag:" & to_hstring(req_tag);


-- Force misses on that way while reloading that line -- 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 -- Store new tag in selected way
for i in 0 to NUM_WAYS-1 loop for i in 0 to NUM_WAYS-1 loop
if i = way then if i = replace_way then
tagset := cache_tags(req_index); tagset := cache_tags(req_index);
write_tag(i, tagset, req_tag); write_tag(i, tagset, req_tag);
cache_tags(req_index) <= tagset; cache_tags(req_index) <= tagset;
@ -729,7 +728,7 @@ begin


-- Keep track of our index and way for subsequent stores. -- Keep track of our index and way for subsequent stores.
r1.store_index <= req_index; r1.store_index <= req_index;
r1.store_way <= way; r1.store_way <= replace_way;


-- Prep for first wishbone read. We calculate the address of -- Prep for first wishbone read. We calculate the address of
-- the start of the cache line -- the start of the cache line
@ -785,7 +784,7 @@ begin


-- That was the last word ? We are done -- That was the last word ? We are done
if is_last_row(r1.wb.adr) then 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.cyc <= '0';
r1.wb.stb <= '0'; r1.wb.stb <= '0';



@ -178,6 +178,7 @@ architecture rtl of icache is
-- PLRU output interface -- PLRU output interface
type plru_out_t is array(index_t) of std_ulogic_vector(WAY_BITS-1 downto 0); type plru_out_t is array(index_t) of std_ulogic_vector(WAY_BITS-1 downto 0);
signal plru_victim : plru_out_t; signal plru_victim : plru_out_t;
signal replace_way : way_t;


-- Return the cache line index (tag index) for an address -- Return the cache line index (tag index) for an address
function get_index(addr: std_ulogic_vector(63 downto 0)) return index_t is 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_is_miss <= i_in.req and not is_hit and not flush_in;
req_hit_way <= hit_way; 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 -- Output instruction from current cache row
-- --
-- Note: This is a mild violation of our design principle of having pipeline -- Note: This is a mild violation of our design principle of having pipeline
@ -420,7 +424,6 @@ begin


-- Cache miss/reload synchronous machine -- Cache miss/reload synchronous machine
icache_miss : process(clk) icache_miss : process(clk)
variable way : integer range 0 to NUM_WAYS-1;
variable tagset : cache_tags_set_t; variable tagset : cache_tags_set_t;
begin begin
if rising_edge(clk) then if rising_edge(clk) then
@ -446,20 +449,18 @@ begin
when IDLE => when IDLE =>
-- We need to read a cache line -- We need to read a cache line
if req_is_miss = '1' then if req_is_miss = '1' then
way := to_integer(unsigned(plru_victim(req_index)));

report "cache miss nia:" & to_hstring(i_in.nia) & report "cache miss nia:" & to_hstring(i_in.nia) &
" SM:" & std_ulogic'image(i_in.stop_mark) & " SM:" & std_ulogic'image(i_in.stop_mark) &
" idx:" & integer'image(req_index) & " idx:" & integer'image(req_index) &
" way:" & integer'image(way) & " way:" & integer'image(replace_way) &
" tag:" & to_hstring(req_tag); " tag:" & to_hstring(req_tag);


-- Force misses on that way while reloading that line -- 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 -- Store new tag in selected way
for i in 0 to NUM_WAYS-1 loop for i in 0 to NUM_WAYS-1 loop
if i = way then if i = replace_way then
tagset := cache_tags(req_index); tagset := cache_tags(req_index);
write_tag(i, tagset, req_tag); write_tag(i, tagset, req_tag);
cache_tags(req_index) <= tagset; cache_tags(req_index) <= tagset;
@ -468,7 +469,7 @@ begin


-- Keep track of our index and way for subsequent stores -- Keep track of our index and way for subsequent stores
r.store_index <= req_index; r.store_index <= req_index;
r.store_way <= way; r.store_way <= replace_way;


-- Prep for first wishbone read. We calculate the address of -- Prep for first wishbone read. We calculate the address of
-- the start of the cache line -- the start of the cache line
@ -484,7 +485,7 @@ begin
if wishbone_in.ack = '1' then if wishbone_in.ack = '1' then
-- That was the last word ? We are done -- That was the last word ? We are done
if is_last_row(r.wb.adr) then 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.cyc <= '0';
r.wb.stb <= '0'; r.wb.stb <= '0';
r.state <= IDLE; r.state <= IDLE;

Loading…
Cancel
Save