CVA6 TLB SV32

Join the Discussion Create a free account

Does anyone know why we need a flush request for two SFENCE.VMA cases and not for the cases of SFENCE.VMA in the else if statement?

always_comb begin : update_flush
tags_n = tags_q;
content_n = content_q;
for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin
vaddr_vpn0_match = (vaddr_to_be_flushed_i[21:12] == tags_q.vpn0);
vaddr_vpn1_match = (vaddr_to_be_flushed_i[31:22] == tags_q.vpn1);
if (flush_i) begin
// invalidate logic
// flush everything if ASID is 0 and vaddr is 0 ("SFENCE.VMA x0 x0" case)
if (asid_to_be_flushed_is0 && vaddr_to_be_flushed_is0 )
tags_n.valid = 1'b0;
// flush vaddr in all addressing space ("SFENCE.VMA vaddr x0" case), it should happen only for leaf pages
else if (asid_to_be_flushed_is0 && ( (vaddr_vpn0_match && vaddr_vpn1_match) || (vaddr_vpn1_match && tags_q.is_4M) ) && (~vaddr_to_be_flushed_is0))
tags_n.valid = 1'b0;
// the entry is flushed if it's not global and asid and vaddr both matches with the entry to be flushed ("SFENCE.VMA vaddr asid" case)
else if ((!content_q.g) && ((vaddr_vpn0_match && vaddr_vpn1_match) || (vaddr_vpn1_match && tags_q.is_4M)) && (asid_to_be_flushed_i == tags_q.asid[ASID_WIDTH-1:0]) && (!vaddr_to_be_flushed_is0) && (!asid_to_be_flushed_is0))
tags_n.valid = 1'b0;
// the entry is flushed if it's not global, and the asid matches and vaddr is 0. ("SFENCE.VMA 0 asid" case)
else if ((!content_q.g) && (vaddr_to_be_flushed_is0) && (asid_to_be_flushed_i == tags_q.asid[ASID_WIDTH-1:0]) && (!asid_to_be_flushed_is0))
tags_n.valid = 1'b0;
// normal replacement
end else if (update_i.valid & replace_en) begin
// update tag array
tags_n = '{
asid: update_i.asid,
vpn1: update_i.vpn [19:10],
vpn0: update_i.vpn [9:0],
is_4M: update_i.is_4M,
valid: 1'b1
};
// and content as well
content_n = update_i.content;
end
end
end
 
Upvote 0

Join the Discussion Create a free account