Skip to content

Commit

Permalink
cmo: fix flush operation that shall clear the dirty bit in directory
Browse files Browse the repository at this point in the history
  • Loading branch information
cfuguet committed Jan 5, 2025
1 parent d300e52 commit 04de808
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 50 deletions.
39 changes: 30 additions & 9 deletions rtl/src/hpdcache.sv
Original file line number Diff line number Diff line change
Expand Up @@ -286,16 +286,23 @@ import hpdcache_pkg::*;
hpdcache_set_t cmo_dir_check_nline_set;
hpdcache_tag_t cmo_dir_check_nline_tag;
hpdcache_way_vector_t cmo_dir_check_nline_hit_way;
logic cmo_dir_check_nline_wback;
logic cmo_dir_check_nline_dirty;
logic cmo_dir_check_entry;
hpdcache_set_t cmo_dir_check_entry_set;
hpdcache_way_vector_t cmo_dir_check_entry_way;
logic cmo_dir_check_entry_valid;
logic cmo_dir_check_entry_wback;
logic cmo_dir_check_entry_dirty;
hpdcache_tag_t cmo_dir_check_entry_tag;
logic cmo_dir_inval;
hpdcache_set_t cmo_dir_inval_set;
hpdcache_way_vector_t cmo_dir_inval_way;
logic cmo_dir_updt;
hpdcache_set_t cmo_dir_updt_set;
hpdcache_way_vector_t cmo_dir_updt_way;
logic cmo_dir_updt_valid;
logic cmo_dir_updt_wback;
logic cmo_dir_updt_dirty;
logic cmo_dir_updt_fetch;
hpdcache_tag_t cmo_dir_updt_tag;
logic cmo_wait;
logic cmo_flush_alloc;
hpdcache_nline_t cmo_flush_alloc_nline;
Expand Down Expand Up @@ -599,16 +606,23 @@ import hpdcache_pkg::*;
.cmo_dir_check_nline_set_i (cmo_dir_check_nline_set),
.cmo_dir_check_nline_tag_i (cmo_dir_check_nline_tag),
.cmo_dir_check_nline_hit_way_o (cmo_dir_check_nline_hit_way),
.cmo_dir_check_nline_wback_o (cmo_dir_check_nline_wback),
.cmo_dir_check_nline_dirty_o (cmo_dir_check_nline_dirty),
.cmo_dir_check_entry_i (cmo_dir_check_entry),
.cmo_dir_check_entry_set_i (cmo_dir_check_entry_set),
.cmo_dir_check_entry_way_i (cmo_dir_check_entry_way),
.cmo_dir_check_entry_valid_o (cmo_dir_check_entry_valid),
.cmo_dir_check_entry_wback_o (cmo_dir_check_entry_wback),
.cmo_dir_check_entry_dirty_o (cmo_dir_check_entry_dirty),
.cmo_dir_check_entry_tag_o (cmo_dir_check_entry_tag),
.cmo_dir_inval_i (cmo_dir_inval),
.cmo_dir_inval_set_i (cmo_dir_inval_set),
.cmo_dir_inval_way_i (cmo_dir_inval_way),
.cmo_dir_updt_i (cmo_dir_updt),
.cmo_dir_updt_set_i (cmo_dir_updt_set),
.cmo_dir_updt_way_i (cmo_dir_updt_way),
.cmo_dir_updt_valid_i (cmo_dir_updt_valid),
.cmo_dir_updt_wback_i (cmo_dir_updt_wback),
.cmo_dir_updt_dirty_i (cmo_dir_updt_dirty),
.cmo_dir_updt_fetch_i (cmo_dir_updt_fetch),
.cmo_dir_updt_tag_i (cmo_dir_updt_tag),
.cmo_core_rsp_ready_o (cmo_core_rsp_ready),
.cmo_core_rsp_valid_i (cmo_core_rsp_valid),
.cmo_core_rsp_i (cmo_core_rsp),
Expand Down Expand Up @@ -933,18 +947,25 @@ import hpdcache_pkg::*;
.dir_check_nline_set_o (cmo_dir_check_nline_set),
.dir_check_nline_tag_o (cmo_dir_check_nline_tag),
.dir_check_nline_hit_way_i (cmo_dir_check_nline_hit_way),
.dir_check_nline_wback_i (cmo_dir_check_nline_wback),
.dir_check_nline_dirty_i (cmo_dir_check_nline_dirty),

.dir_check_entry_o (cmo_dir_check_entry),
.dir_check_entry_set_o (cmo_dir_check_entry_set),
.dir_check_entry_way_o (cmo_dir_check_entry_way),
.dir_check_entry_valid_i (cmo_dir_check_entry_valid),
.dir_check_entry_wback_i (cmo_dir_check_entry_wback),
.dir_check_entry_dirty_i (cmo_dir_check_entry_dirty),
.dir_check_entry_tag_i (cmo_dir_check_entry_tag),

.dir_inval_o (cmo_dir_inval),
.dir_inval_set_o (cmo_dir_inval_set),
.dir_inval_way_o (cmo_dir_inval_way),
.dir_updt_o (cmo_dir_updt),
.dir_updt_set_o (cmo_dir_updt_set),
.dir_updt_way_o (cmo_dir_updt_way),
.dir_updt_valid_o (cmo_dir_updt_valid),
.dir_updt_wback_o (cmo_dir_updt_wback),
.dir_updt_dirty_o (cmo_dir_updt_dirty),
.dir_updt_fetch_o (cmo_dir_updt_fetch),
.dir_updt_tag_o (cmo_dir_updt_tag),

.flush_empty_i (flush_empty),
.flush_alloc_o (cmo_flush_alloc),
Expand Down
93 changes: 67 additions & 26 deletions rtl/src/hpdcache_cmo.sv
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,25 @@ import hpdcache_pkg::*;
output hpdcache_set_t dir_check_nline_set_o,
output hpdcache_tag_t dir_check_nline_tag_o,
input hpdcache_way_vector_t dir_check_nline_hit_way_i,
input logic dir_check_nline_wback_i,
input logic dir_check_nline_dirty_i,

output logic dir_check_entry_o,
output hpdcache_set_t dir_check_entry_set_o,
output hpdcache_way_vector_t dir_check_entry_way_o,
input logic dir_check_entry_valid_i,
input logic dir_check_entry_wback_i,
input logic dir_check_entry_dirty_i,
input hpdcache_tag_t dir_check_entry_tag_i,

output logic dir_inval_o,
output hpdcache_set_t dir_inval_set_o,
output hpdcache_way_vector_t dir_inval_way_o,
output logic dir_updt_o,
output hpdcache_set_t dir_updt_set_o,
output hpdcache_way_vector_t dir_updt_way_o,
output logic dir_updt_valid_o,
output logic dir_updt_wback_o,
output logic dir_updt_dirty_o,
output logic dir_updt_fetch_o,
output hpdcache_tag_t dir_updt_tag_o,
// }}}

// Flush Controller Interface
Expand Down Expand Up @@ -224,9 +231,14 @@ import hpdcache_pkg::*;
dir_check_entry_set_o = cmoh_set_q;
dir_check_entry_way_o = cmoh_way_q;

dir_inval_o = 1'b0;
dir_inval_set_o = cmoh_set_q;
dir_inval_way_o = '0;
dir_updt_o = 1'b0;
dir_updt_set_o = '0;
dir_updt_way_o = '0;
dir_updt_valid_o = 1'b0;
dir_updt_wback_o = 1'b0;
dir_updt_dirty_o = 1'b0;
dir_updt_fetch_o = 1'b0;
dir_updt_tag_o = '0;

wbuf_flush_all_o = 1'b0;

Expand Down Expand Up @@ -340,9 +352,14 @@ import hpdcache_pkg::*;
cmoh_op_q.is_flush_inval_by_nline: begin
/* FIXME this adds a DIR to DIR timing path. We should probably delay the
* invalidation of one cycle to ease the timing closure */
dir_inval_o = cmoh_dir_check_nline_hit;
dir_inval_way_o = dir_check_nline_hit_way_i;
dir_inval_set_o = cmoh_set;
dir_updt_o = cmoh_dir_check_nline_hit;
dir_updt_set_o = cmoh_set;
dir_updt_way_o = dir_check_nline_hit_way_i;
dir_updt_valid_o = 1'b0;
dir_updt_wback_o = 1'b0;
dir_updt_dirty_o = 1'b0;
dir_updt_fetch_o = 1'b0;
dir_updt_tag_o = '0;

core_rsp_send_d = core_rsp_rok;
cmoh_fsm_d = CMOH_IDLE;
Expand All @@ -353,9 +370,14 @@ import hpdcache_pkg::*;
cmoh_op_q.is_inval_all,
cmoh_op_q.is_flush_inval_all:
begin
dir_inval_o = 1'b1;
dir_inval_way_o = {HPDcacheCfg.u.ways{1'b1}};
dir_inval_set_o = cmoh_set_q;
dir_updt_o = 1'b1;
dir_updt_set_o = cmoh_set_q;
dir_updt_way_o = {HPDcacheCfg.u.ways{1'b1}};
dir_updt_valid_o = 1'b0;
dir_updt_wback_o = 1'b0;
dir_updt_dirty_o = 1'b0;
dir_updt_fetch_o = 1'b0;
dir_updt_tag_o = '0;
cmoh_set_incr = 1'b1;
if (cmoh_set_last) begin
core_rsp_send_d = core_rsp_rok;
Expand Down Expand Up @@ -384,21 +406,28 @@ import hpdcache_pkg::*;
end
CMOH_FLUSH_ALL_NEXT: begin
if (cmoh_flush_req_valid_q) begin
dir_inval_o = cmoh_flush_req_inval_q;
dir_inval_set_o = cmoh_flush_req_set_q;
dir_inval_way_o = cmoh_flush_req_way_q;
dir_updt_o = dir_check_entry_valid_i &
(dir_check_entry_dirty_i | cmoh_flush_req_inval_q);

dir_updt_set_o = cmoh_flush_req_set_q;
dir_updt_way_o = cmoh_flush_req_way_q;
dir_updt_valid_o = ~cmoh_flush_req_inval_q;
dir_updt_wback_o = ~cmoh_flush_req_inval_q & dir_check_entry_wback_i;
dir_updt_dirty_o = 1'b0;
dir_updt_fetch_o = 1'b0;
dir_updt_tag_o = dir_check_entry_tag_i;

cmoh_flush_req_set = cmoh_flush_req_set_q;
cmoh_flush_req_way = cmoh_flush_req_way_q;
cmoh_flush_req_tag = dir_check_entry_tag_i;

// In case of invalidation, the CMO handler needs to dedicate one cycle to
// check the directory and one cycle to invalidate that entry.
// The CMO handler needs to dedicate one cycle to
// check the directory and one cycle to update that entry.
// This means that the CMO handler takes 2 cycles per flush request
cmoh_flush_req_valid_d = ~cmoh_flush_req_inval_q;
cmoh_flush_req_valid_d = 1'b0;
end

if ((!cmoh_flush_req_valid_q || !cmoh_flush_req_inval_q) && cmoh_flush_req_wok)
begin
if (!cmoh_flush_req_valid_q && cmoh_flush_req_wok) begin
dir_check_entry_o = 1'b1;
cmoh_set_incr = cmoh_way_last;
cmoh_way_incr = 1'b1;
Expand All @@ -414,9 +443,16 @@ import hpdcache_pkg::*;
CMOH_FLUSH_ALL_LAST: begin
cmoh_flush_req_valid_d = 1'b0;
if (cmoh_flush_req_valid_q) begin
dir_inval_o = cmoh_flush_req_inval_q;
dir_inval_set_o = cmoh_flush_req_set_q;
dir_inval_way_o = cmoh_flush_req_way_q;
dir_updt_o = dir_check_entry_valid_i &
(dir_check_entry_dirty_i | cmoh_flush_req_inval_q);

dir_updt_set_o = cmoh_flush_req_set_q;
dir_updt_way_o = cmoh_flush_req_way_q;
dir_updt_valid_o = ~cmoh_flush_req_inval_q;
dir_updt_wback_o = ~cmoh_flush_req_inval_q & dir_check_entry_wback_i;
dir_updt_dirty_o = 1'b0;
dir_updt_fetch_o = 1'b0;
dir_updt_tag_o = dir_check_entry_tag_i;
cmoh_flush_req_set = cmoh_flush_req_set_q;
cmoh_flush_req_way = cmoh_flush_req_way_q;
cmoh_flush_req_tag = dir_check_entry_tag_i;
Expand Down Expand Up @@ -447,9 +483,14 @@ import hpdcache_pkg::*;
if (cmoh_flush_req_valid_q) begin
/* FIXME this adds a DIR to DIR timing path. We should probably delay the
* invalidation of one cycle to ease the timing closure */
dir_inval_o = cmoh_flush_req_inval_q & cmoh_dir_check_nline_hit;
dir_inval_set_o = cmoh_set;
dir_inval_way_o = dir_check_nline_hit_way_i;
dir_updt_o = cmoh_dir_check_nline_hit;
dir_updt_set_o = cmoh_set;
dir_updt_way_o = dir_check_nline_hit_way_i;
dir_updt_valid_o = ~cmoh_flush_req_inval_q;
dir_updt_wback_o = ~cmoh_flush_req_inval_q & dir_check_nline_wback_i;
dir_updt_dirty_o = 1'b0;
dir_updt_fetch_o = 1'b0;
dir_updt_tag_o = cmoh_tag;
cmoh_flush_req_set = cmoh_set;
cmoh_flush_req_tag = cmoh_tag;
cmoh_flush_req_way = dir_check_nline_hit_way_i;
Expand Down
26 changes: 20 additions & 6 deletions rtl/src/hpdcache_ctrl.sv
Original file line number Diff line number Diff line change
Expand Up @@ -210,16 +210,23 @@ import hpdcache_pkg::*;
input hpdcache_set_t cmo_dir_check_nline_set_i,
input hpdcache_tag_t cmo_dir_check_nline_tag_i,
output hpdcache_way_vector_t cmo_dir_check_nline_hit_way_o,
output logic cmo_dir_check_nline_wback_o,
output logic cmo_dir_check_nline_dirty_o,
input logic cmo_dir_check_entry_i,
input hpdcache_set_t cmo_dir_check_entry_set_i,
input hpdcache_way_vector_t cmo_dir_check_entry_way_i,
output logic cmo_dir_check_entry_valid_o,
output logic cmo_dir_check_entry_wback_o,
output logic cmo_dir_check_entry_dirty_o,
output hpdcache_tag_t cmo_dir_check_entry_tag_o,
input logic cmo_dir_inval_i,
input hpdcache_set_t cmo_dir_inval_set_i,
input hpdcache_way_vector_t cmo_dir_inval_way_i,
input logic cmo_dir_updt_i,
input hpdcache_set_t cmo_dir_updt_set_i,
input hpdcache_way_vector_t cmo_dir_updt_way_i,
input logic cmo_dir_updt_valid_i,
input logic cmo_dir_updt_wback_i,
input logic cmo_dir_updt_dirty_i,
input logic cmo_dir_updt_fetch_i,
input hpdcache_tag_t cmo_dir_updt_tag_i,
output logic cmo_core_rsp_ready_o,
input logic cmo_core_rsp_valid_i,
input hpdcache_rsp_t cmo_core_rsp_i,
Expand Down Expand Up @@ -888,18 +895,25 @@ import hpdcache_pkg::*;
.dir_cmo_check_nline_set_i (cmo_dir_check_nline_set_i),
.dir_cmo_check_nline_tag_i (cmo_dir_check_nline_tag_i),
.dir_cmo_check_nline_hit_way_o (cmo_dir_check_nline_hit_way_o),
.dir_cmo_check_nline_wback_o (cmo_dir_check_nline_wback_o),
.dir_cmo_check_nline_dirty_o (cmo_dir_check_nline_dirty_o),

.dir_cmo_check_entry_i (cmo_dir_check_entry_i),
.dir_cmo_check_entry_set_i (cmo_dir_check_entry_set_i),
.dir_cmo_check_entry_way_i (cmo_dir_check_entry_way_i),
.dir_cmo_check_entry_valid_o (cmo_dir_check_entry_valid_o),
.dir_cmo_check_entry_wback_o (cmo_dir_check_entry_wback_o),
.dir_cmo_check_entry_dirty_o (cmo_dir_check_entry_dirty_o),
.dir_cmo_check_entry_tag_o (cmo_dir_check_entry_tag_o),

.dir_cmo_inval_i (cmo_dir_inval_i),
.dir_cmo_inval_set_i (cmo_dir_inval_set_i),
.dir_cmo_inval_way_i (cmo_dir_inval_way_i),
.dir_cmo_updt_i (cmo_dir_updt_i),
.dir_cmo_updt_set_i (cmo_dir_updt_set_i),
.dir_cmo_updt_way_i (cmo_dir_updt_way_i),
.dir_cmo_updt_tag_i (cmo_dir_updt_tag_i),
.dir_cmo_updt_valid_i (cmo_dir_updt_valid_i),
.dir_cmo_updt_wback_i (cmo_dir_updt_wback_i),
.dir_cmo_updt_dirty_i (cmo_dir_updt_dirty_i),
.dir_cmo_updt_fetch_i (cmo_dir_updt_fetch_i),

.data_req_read_i (st0_req_cachedata_read),
.data_req_read_set_i (st0_req_set),
Expand Down
36 changes: 27 additions & 9 deletions rtl/src/hpdcache_memctrl.sv
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,25 @@ import hpdcache_pkg::*;
input hpdcache_set_t dir_cmo_check_nline_set_i,
input hpdcache_tag_t dir_cmo_check_nline_tag_i,
output hpdcache_way_vector_t dir_cmo_check_nline_hit_way_o,
output logic dir_cmo_check_nline_wback_o,
output logic dir_cmo_check_nline_dirty_o,

input logic dir_cmo_check_entry_i,
input hpdcache_set_t dir_cmo_check_entry_set_i,
input hpdcache_way_vector_t dir_cmo_check_entry_way_i,
output logic dir_cmo_check_entry_valid_o,
output logic dir_cmo_check_entry_wback_o,
output logic dir_cmo_check_entry_dirty_o,
output hpdcache_tag_t dir_cmo_check_entry_tag_o,

input logic dir_cmo_inval_i,
input hpdcache_set_t dir_cmo_inval_set_i,
input hpdcache_way_vector_t dir_cmo_inval_way_i,
input logic dir_cmo_updt_i,
input hpdcache_set_t dir_cmo_updt_set_i,
input hpdcache_way_vector_t dir_cmo_updt_way_i,
input hpdcache_tag_t dir_cmo_updt_tag_i,
input logic dir_cmo_updt_valid_i,
input logic dir_cmo_updt_wback_i,
input logic dir_cmo_updt_dirty_i,
input logic dir_cmo_updt_fetch_i,
// }}}

// DATA array access interface
Expand Down Expand Up @@ -504,11 +511,20 @@ import hpdcache_pkg::*;
end

// Cache directory CMO inval tag
dir_cmo_inval_i: begin
dir_addr = dir_cmo_inval_set_i;
dir_cs = dir_cmo_inval_way_i;
dir_we = dir_cmo_inval_way_i;
dir_wentry = '0;
dir_cmo_updt_i: begin
dir_addr = dir_cmo_updt_set_i;
dir_cs = dir_cmo_updt_way_i;
dir_we = dir_cmo_updt_way_i;

for (hpdcache_uint i = 0; i < HPDcacheCfg.u.ways; i++) begin
dir_wentry[i] = '{
valid: dir_cmo_updt_valid_i,
wback: dir_cmo_updt_wback_i,
dirty: dir_cmo_updt_dirty_i,
fetch: dir_cmo_updt_fetch_i,
tag : dir_cmo_updt_tag_i
};
end
end

// Cache directory match tag -> hit
Expand Down Expand Up @@ -577,8 +593,10 @@ import hpdcache_pkg::*;
assign dir_hit_dirty_o = |(dir_hit_way_o & dir_dirty);
assign dir_hit_fetch_o = |(dir_hit_way_o & dir_fetch);

assign dir_cmo_check_nline_wback_o = |(dir_cmo_check_nline_hit_way_o & dir_wback);
assign dir_cmo_check_nline_dirty_o = |(dir_cmo_check_nline_hit_way_o & dir_dirty);
assign dir_cmo_check_entry_valid_o = |(dir_req_way_q & dir_valid);
assign dir_cmo_check_entry_wback_o = |(dir_req_way_q & dir_wback);
assign dir_cmo_check_entry_dirty_o = |(dir_req_way_q & dir_dirty);
hpdcache_mux #(
.NINPUT (HPDcacheCfg.u.ways),
Expand Down Expand Up @@ -962,7 +980,7 @@ import hpdcache_pkg::*;
dir_inval_write_i,
dir_cmo_check_nline_i,
dir_cmo_check_entry_i,
dir_cmo_inval_i,
dir_cmo_updt_i,
dir_updt_i})) else
$error("hpdcache_memctrl: more than one process is accessing the cache directory");

Expand Down

0 comments on commit 04de808

Please sign in to comment.