fix obi issue when req is granted with delay

This commit is contained in:
Yannick Casamatta 2024-07-22 18:45:33 +02:00 committed by JeanRochCoulon
parent 37f1c45613
commit 04c6232da9
2 changed files with 26 additions and 19 deletions

View file

@ -82,7 +82,8 @@ module cva6_icache
logic cache_en_d, cache_en_q; // cache is enabled
logic [CVA6Cfg.VLEN-1:0] vaddr_d, vaddr_q;
logic paddr_is_nc_q, paddr_is_nc_d; // asserted if physical address is non-cacheable
logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] cl_hit; // hit from tag compare
logic [CVA6Cfg.ICACHE_SET_ASSOC-1:0] cl_hit, cl_hit2; // hit from tag compare
logic cache_rden; // triggers cache lookup
logic cache_wren; // triggers write to cacheline
logic
@ -233,8 +234,12 @@ module cva6_icache
unique case (obi_r_state_q)
OBI_R_IDLE: begin
if (fetch_obi_req_i.req) begin
obi_r_state_d = OBI_R_WAIT;
if (fetch_obi_req_i.req && obi_grant) begin
if (!(dreq_i.kill_req || flush_d)) begin
obi_r_state_d = OBI_R_WAIT;
end else begin
obi_r_state_d = OBI_R_KILLED;
end
end
end
@ -250,7 +255,7 @@ module cva6_icache
obi_ruser = userdata_d;
end
obi_ruser = userdata_d;
if (!(fetch_obi_req_i.req)) begin
if (!(fetch_obi_req_i.req && obi_grant)) begin
obi_r_state_d = OBI_R_IDLE;
end
end
@ -259,8 +264,10 @@ module cva6_icache
OBI_R_KILLED: begin
obi_valid = '1;
dreq_o.invalid_data = '1;
if (fetch_obi_req_i.req) begin
obi_r_state_d = OBI_R_WAIT;
if (fetch_obi_req_i.req && obi_grant) begin
if (!(dreq_i.kill_req || flush_d)) begin
obi_r_state_d = OBI_R_WAIT;
end
end else begin
obi_r_state_d = OBI_R_IDLE;
end
@ -333,14 +340,13 @@ module cva6_icache
if (!mem_rtrn_vld_i) begin
dreq_o.ready = 1'b1;
// we have a new request not killed
if (dreq_i.req && !dreq_i.kill_req) begin
if (fetch_obi_req_i.req && !dreq_i.kill_req) begin
cache_rden = 1'b1;
if (fetch_obi_req_i.req) begin
state_d = READ_BIS;
obi_grant = 1'b1;
end else begin
state_d = READ;
end
state_d = READ_BIS;
obi_grant = 1'b1;
end else if (dreq_i.req && !dreq_i.kill_req) begin
cache_rden = 1'b1;
state_d = READ;
end
end
end
@ -438,7 +444,7 @@ module cva6_icache
end
// we have a hit
end else if ((|cl_hit && cache_en_q && !inv_q)) begin
end else if ((|cl_hit2 && cache_en_q && !inv_q)) begin
state_d = IDLE;
data_valid_obi = 1'b1;
// we can accept another request
@ -571,6 +577,7 @@ module cva6_icache
for (genvar i = 0; i < CVA6Cfg.ICACHE_SET_ASSOC; i++) begin : gen_tag_cmpsel
assign cl_hit[i] = (cl_tag_rdata[i] == cl_tag_d) & vld_rdata[i];
assign cl_hit2[i] = (cl_tag_rdata[i] == cl_tag_q) & vld_rdata[i];
assign cl_sel[i] = cl_rdata[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_WIDTH];
assign cl_user[i] = cl_ruser[i][{cl_offset_q, 3'b0}+:CVA6Cfg.FETCH_USER_WIDTH];
end

View file

@ -337,7 +337,7 @@ module frontend
logic paddr_nonidempotent;
assign paddr_nonidempotent = config_pkg::is_inside_nonidempotent_regions(
CVA6Cfg, {{64 - CVA6Cfg.PLEN{1'b0}}, fetch_obi_req_o.a.addr} //TO DO CHECK GRANULARITY
);
);
// Caches optimisation signals
@ -437,7 +437,7 @@ module frontend
unique case (custom_state_q)
WAIT_NEW_REQ: begin
vaddr_d = npc_fetch_address;
if (instr_queue_ready && atrans_ready && !kill_s2) begin
if ((obi_a_state_q == TRANSPARENT || obi_r_req == '1) && instr_queue_ready && atrans_ready && !kill_s2) begin
fetch_dreq_o.req = '1;
if (fetch_dreq_i.ready) begin
if_ready = '1;
@ -470,7 +470,7 @@ module frontend
obi_a_req = '1;
obi_vaddr_d = vaddr_d;
vaddr_d = npc_fetch_address;
if (instr_queue_ready && atrans_ready && !kill_s1) begin
if (obi_r_req && instr_queue_ready && atrans_ready && !kill_s1) begin
fetch_dreq_o.req = '1;
if (fetch_dreq_i.ready) begin
if_ready = '1;
@ -505,7 +505,7 @@ module frontend
WAIT_OBI: begin
if (kill_s2) begin
vaddr_d = npc_fetch_address;
if (instr_queue_ready && atrans_ready && !kill_s1) begin
if ((obi_a_state_q == TRANSPARENT || obi_r_req == '1) && instr_queue_ready && atrans_ready && !kill_s1) begin
fetch_dreq_o.req = '1;
if (fetch_dreq_i.ready) begin
if_ready = '1;
@ -521,7 +521,7 @@ module frontend
obi_a_req = '1;
obi_vaddr_d = vaddr_d;
vaddr_d = npc_fetch_address;
if (instr_queue_ready && atrans_ready && !kill_s1) begin
if (obi_r_req && instr_queue_ready && atrans_ready && !kill_s1) begin
fetch_dreq_o.req = '1;
if (fetch_dreq_i.ready) begin
if_ready = '1;