mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-24 22:27:10 -04:00
Also flush dcache on fence.i
This commit is contained in:
parent
5f9d7a5ea0
commit
97b8b12a42
5 changed files with 36 additions and 14 deletions
|
@ -241,7 +241,7 @@ module ariane
|
||||||
logic fence_i_commit_controller;
|
logic fence_i_commit_controller;
|
||||||
logic fence_commit_controller;
|
logic fence_commit_controller;
|
||||||
logic sfence_vma_commit_controller;
|
logic sfence_vma_commit_controller;
|
||||||
logic halt_ctrl_commit;
|
logic halt_ctrl;
|
||||||
logic halt_debug_ctrl;
|
logic halt_debug_ctrl;
|
||||||
logic halt_csr_ctrl;
|
logic halt_csr_ctrl;
|
||||||
// --------------
|
// --------------
|
||||||
|
@ -290,6 +290,7 @@ module ariane
|
||||||
// ---------
|
// ---------
|
||||||
if_stage if_stage_i (
|
if_stage if_stage_i (
|
||||||
.flush_i ( flush_ctrl_if ),
|
.flush_i ( flush_ctrl_if ),
|
||||||
|
.halt_i ( halt_ctrl ),
|
||||||
.if_busy_o ( if_ready_if_pcgen ),
|
.if_busy_o ( if_ready_if_pcgen ),
|
||||||
.fetch_address_i ( fetch_address_pcgen_if ),
|
.fetch_address_i ( fetch_address_pcgen_if ),
|
||||||
.fetch_valid_i ( fetch_valid_pcgen_if ),
|
.fetch_valid_i ( fetch_valid_pcgen_if ),
|
||||||
|
@ -475,7 +476,7 @@ module ariane
|
||||||
// Commit
|
// Commit
|
||||||
// ---------
|
// ---------
|
||||||
commit_stage commit_stage_i (
|
commit_stage commit_stage_i (
|
||||||
.halt_i ( halt_ctrl_commit ),
|
.halt_i ( halt_ctrl ),
|
||||||
.exception_o ( ex_commit ),
|
.exception_o ( ex_commit ),
|
||||||
.commit_instr_i ( commit_instr_id_commit ),
|
.commit_instr_i ( commit_instr_id_commit ),
|
||||||
.commit_ack_o ( commit_ack ),
|
.commit_ack_o ( commit_ack ),
|
||||||
|
@ -552,7 +553,7 @@ module ariane
|
||||||
.halt_csr_i ( halt_csr_ctrl ),
|
.halt_csr_i ( halt_csr_ctrl ),
|
||||||
.halt_debug_i ( halt_debug_ctrl ),
|
.halt_debug_i ( halt_debug_ctrl ),
|
||||||
.debug_set_pc_i ( set_pc_debug ),
|
.debug_set_pc_i ( set_pc_debug ),
|
||||||
.halt_o ( halt_ctrl_commit ),
|
.halt_o ( halt_ctrl ),
|
||||||
// control ports
|
// control ports
|
||||||
.eret_i ( eret ),
|
.eret_i ( eret ),
|
||||||
.ex_valid_i ( ex_commit.valid ),
|
.ex_valid_i ( ex_commit.valid ),
|
||||||
|
|
|
@ -123,6 +123,8 @@ module commit_stage (
|
||||||
// ------------------
|
// ------------------
|
||||||
// FENCE.I Logic
|
// FENCE.I Logic
|
||||||
// ------------------
|
// ------------------
|
||||||
|
// Fence synchronizes data and instruction streams. That means that we need to flush the private icache
|
||||||
|
// and the private dcache. This is the most expensive instruction.
|
||||||
if (commit_instr_i.op == FENCE_I) begin
|
if (commit_instr_i.op == FENCE_I) begin
|
||||||
commit_ack_o = 1'b1;
|
commit_ack_o = 1'b1;
|
||||||
// tell the controller to flush the I$
|
// tell the controller to flush the I$
|
||||||
|
|
|
@ -78,22 +78,15 @@ module controller (
|
||||||
// FENCE
|
// FENCE
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
if (fence_i) begin
|
if (fence_i) begin
|
||||||
fence_active_n = 1'b1;
|
|
||||||
flush_dcache = 1'b1;
|
|
||||||
// this can be seen as a CSR instruction with side-effect
|
// this can be seen as a CSR instruction with side-effect
|
||||||
flush_pcgen_o = 1'b1;
|
flush_pcgen_o = 1'b1;
|
||||||
flush_if_o = 1'b1;
|
flush_if_o = 1'b1;
|
||||||
flush_unissued_instr_o = 1'b1;
|
flush_unissued_instr_o = 1'b1;
|
||||||
flush_id_o = 1'b1;
|
flush_id_o = 1'b1;
|
||||||
flush_ex_o = 1'b1;
|
flush_ex_o = 1'b1;
|
||||||
end
|
|
||||||
|
|
||||||
// wait for the acknowledge here
|
flush_dcache = 1'b1;
|
||||||
if (flush_dcache_ack_i && fence_active_q) begin
|
fence_active_n = 1'b1;
|
||||||
fence_active_n = 1'b0;
|
|
||||||
// keep the flush dcache signal high as long as we didn't get the acknowledge from the cache
|
|
||||||
end else if (fence_active_q) begin
|
|
||||||
flush_dcache = 1'b1;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
@ -106,6 +99,17 @@ module controller (
|
||||||
flush_id_o = 1'b1;
|
flush_id_o = 1'b1;
|
||||||
flush_ex_o = 1'b1;
|
flush_ex_o = 1'b1;
|
||||||
flush_icache_o = 1'b1;
|
flush_icache_o = 1'b1;
|
||||||
|
|
||||||
|
flush_dcache = 1'b1;
|
||||||
|
fence_active_n = 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// wait for the acknowledge here
|
||||||
|
if (flush_dcache_ack_i && fence_active_q) begin
|
||||||
|
fence_active_n = 1'b0;
|
||||||
|
// keep the flush dcache signal high as long as we didn't get the acknowledge from the cache
|
||||||
|
end else if (fence_active_q) begin
|
||||||
|
flush_dcache = 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
@ -137,8 +141,8 @@ module controller (
|
||||||
// 3. Debug
|
// 3. Debug
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
if (ex_valid_i || eret_i || debug_set_pc_i) begin
|
if (ex_valid_i || eret_i || debug_set_pc_i) begin
|
||||||
// don't flush pcgen as we want to take the exception, flush pcgen is not a flush signal
|
// don't flush pcgen as we want to take the exception: Flush PCGen is not a flush signal
|
||||||
// for the PC GEN stage but instead tells it to take the PC we gave it
|
// for the PC Gen stage but instead tells it to take the PC we gave it
|
||||||
flush_pcgen_o = 1'b0;
|
flush_pcgen_o = 1'b0;
|
||||||
flush_if_o = 1'b1;
|
flush_if_o = 1'b1;
|
||||||
flush_unissued_instr_o = 1'b1;
|
flush_unissued_instr_o = 1'b1;
|
||||||
|
|
|
@ -24,6 +24,7 @@ module if_stage (
|
||||||
// control signals
|
// control signals
|
||||||
input logic flush_i,
|
input logic flush_i,
|
||||||
output logic if_busy_o, // is the IF stage busy fetching instructions?
|
output logic if_busy_o, // is the IF stage busy fetching instructions?
|
||||||
|
input logic halt_i,
|
||||||
// fetch direction from PC Gen
|
// fetch direction from PC Gen
|
||||||
input logic [63:0] fetch_address_i, // address to fetch from
|
input logic [63:0] fetch_address_i, // address to fetch from
|
||||||
input logic fetch_valid_i, // the fetch address is valid
|
input logic fetch_valid_i, // the fetch address is valid
|
||||||
|
@ -189,6 +190,17 @@ module if_stage (
|
||||||
else
|
else
|
||||||
NS = WAIT_ABORTED;
|
NS = WAIT_ABORTED;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// -------------
|
||||||
|
// Halt
|
||||||
|
// -------------
|
||||||
|
// halt the instruction interface if we halt the core:
|
||||||
|
// the idea behind this is mainly in the case of an fence.i. For that instruction we need to flush both private caches
|
||||||
|
// now it could be the case that the icache flush finishes earlier than the dcache flush (most likely even). In that case
|
||||||
|
// a fetch can return stale data so we need to wait for the dcache flush to finish before making any new request.
|
||||||
|
// The solution is to check if the core is halted and in that case do not make any new request.
|
||||||
|
if (halt_i)
|
||||||
|
instr_req_o = 1'b0;
|
||||||
end
|
end
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
|
|
@ -118,6 +118,7 @@ module pcgen_stage (
|
||||||
if (if_ready_i && branch_predict_btb.valid && branch_predict_btb.predict_taken && !fetch_address[1]) begin
|
if (if_ready_i && branch_predict_btb.valid && branch_predict_btb.predict_taken && !fetch_address[1]) begin
|
||||||
npc_n = branch_predict_btb.predict_address;
|
npc_n = branch_predict_btb.predict_address;
|
||||||
end
|
end
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// 2. Debug
|
// 2. Debug
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
@ -125,6 +126,7 @@ module pcgen_stage (
|
||||||
npc_n = debug_pc_i;
|
npc_n = debug_pc_i;
|
||||||
set_pc_n = 1'b1;
|
set_pc_n = 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// 4. Exception
|
// 4. Exception
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
@ -164,6 +166,7 @@ module pcgen_stage (
|
||||||
fetch_address_o = fetch_address;
|
fetch_address_o = fetch_address;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// -------------------
|
// -------------------
|
||||||
// Sequential Process
|
// Sequential Process
|
||||||
// -------------------
|
// -------------------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue