Skip to content

Commit

Permalink
dcache: Allow writing during write_pending
Browse files Browse the repository at this point in the history
Issue #122

This fixes case 1 from issue 122 where writes are missed after
invalidate state.

The change to invalidate_ack to to allow the invalidate_ack to
be asserted after the invalidate happens not before.

For writes we allow forwarding to WRITE state directly from invalidate
at this point pending_write will still be high and we can use that
to initialiate the write.  When we have delays the cpu_req_i may be
low when we get to the write state.
  • Loading branch information
stffrdhrn committed Jul 1, 2021
1 parent 1382b6b commit a6110ce
Showing 1 changed file with 10 additions and 20 deletions.
30 changes: 10 additions & 20 deletions rtl/verilog/mor1kx_dcache.v
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,9 @@ module mor1kx_dcache
*/
integer w1;
always @(posedge clk `OR_ASYNC_RST) begin
// The default is (of course) not to acknowledge the invalidate
invalidate_ack <= 1'b0;

if (rst) begin
state <= IDLE;
write_pending <= 0;
Expand Down Expand Up @@ -377,7 +380,7 @@ module mor1kx_dcache
// Store address in invalidate_adr that is muxed to the tag
// memory write address
invalidate_adr <= spr_bus_dat_i[WAY_WIDTH-1:OPTION_DCACHE_BLOCK_WIDTH];

invalidate_ack <= 1'b1;
// Change to invalidate state that actually accesses
// the tag memory
state <= INVALIDATE;
Expand Down Expand Up @@ -440,8 +443,10 @@ module mor1kx_dcache
// Store address in invalidate_adr that is muxed to the tag
// memory write address
invalidate_adr <= spr_bus_dat_i[WAY_WIDTH-1:OPTION_DCACHE_BLOCK_WIDTH];

invalidate_ack <= 1'b1;
state <= INVALIDATE;
end else if (cpu_we_i | write_pending) begin
state <= WRITE;
end else begin
state <= IDLE;
end
Expand Down Expand Up @@ -472,9 +477,6 @@ module mor1kx_dcache

way_wr_dat = wrdat_i;

// The default is (of course) not to acknowledge the invalidate
invalidate_ack = 1'b0;

if (snoop_hit) begin
// This is the write access
tag_we = 1'b1;
Expand All @@ -497,16 +499,6 @@ module mor1kx_dcache
wradr_i[WAY_WIDTH-1:OPTION_DCACHE_BLOCK_WIDTH];

case (state)
IDLE: begin
//
// When idle we can always acknowledge the invalidate as it
// has the highest priority in handling. When something is
// changed on the state machine handling above this needs
// to be changed.
//
invalidate_ack = 1'b1;
end

READ: begin
if (hit) begin
//
Expand All @@ -525,7 +517,7 @@ module mor1kx_dcache

WRITE: begin
way_wr_dat = cpu_dat_i;
if (hit & cpu_req_i) begin
if (hit & (cpu_req_i | write_pending)) begin
/* Mux cache output with write data */
if (!cpu_bsel_i[3])
way_wr_dat[31:24] = cpu_dat_o[31:24];
Expand All @@ -536,9 +528,9 @@ module mor1kx_dcache
if (!cpu_bsel_i[0])
way_wr_dat[7:0] = cpu_dat_o[7:0];

way_we = way_hit;
way_we = way_hit;

tag_lru_in = next_lru_history;
tag_lru_in = next_lru_history;

tag_we = 1'b1;
end
Expand Down Expand Up @@ -586,8 +578,6 @@ module mor1kx_dcache
end

INVALIDATE: begin
invalidate_ack = 1'b1;

// Lazy invalidation, invalidate everything that matches tag address
tag_lru_in = 0;
for (w2 = 0; w2 < OPTION_DCACHE_WAYS; w2 = w2 + 1) begin
Expand Down

0 comments on commit a6110ce

Please sign in to comment.