Add DCache flush signal and logic

This commit is contained in:
Florian Zaruba 2017-08-03 19:23:09 +02:00
parent 97102210f7
commit f1dc5bc69b
6 changed files with 63 additions and 10 deletions

View file

@ -63,7 +63,7 @@ max_cycles = 10000000
# Test case to run
test_case = core_test
# QuestaSim Version
questa_version = -10.6
questa_version =
compile_flag = +cover=bcfst+/dut -incr -64 -nologo -quiet -suppress 13262 -permissive
# Moore binary
moore = ~fschuiki/bin/moore

View file

@ -91,7 +91,7 @@ package ariane_pkg;
// set lower than operations
SLTS, SLTU,
// CSR functions
MRET, SRET, ECALL, WFI, FENCE_I, SFENCE_VMA, CSR_WRITE, CSR_READ, CSR_SET, CSR_CLEAR,
MRET, SRET, ECALL, WFI, FENCE, FENCE_I, SFENCE_VMA, CSR_WRITE, CSR_READ, CSR_SET, CSR_CLEAR,
// LSU functions
LD, SD, LW, LWU, SW, LH, LHU, SH, LB, SB, LBU
} fu_op;

View file

@ -37,6 +37,8 @@ module ariane
input logic test_en_i, // enable all clock gates for testing
output logic flush_icache_o, // request to flush icache
output logic flush_dcache_o, // request to flush the dcache
input logic flush_dcache_ack_i, // dcache flushed successfully
// CPU Control Signals
input logic fetch_enable_i,
output logic core_busy_o,
@ -233,6 +235,7 @@ module ariane
logic flush_ctrl_ex;
logic flush_tlb_ctrl_ex;
logic fence_i_commit_controller;
logic fence_commit_controller;
logic sfence_vma_commit_controller;
logic halt_ctrl_commit;
logic halt_debug_ctrl;
@ -480,6 +483,7 @@ module ariane
.csr_rdata_i ( csr_rdata_csr_commit ),
.csr_exception_i ( csr_exception_csr_commit ),
.fence_i_o ( fence_i_commit_controller ),
.fence_o ( fence_commit_controller ),
.sfence_vma_o ( sfence_vma_commit_controller ),
.*
);
@ -546,6 +550,7 @@ module ariane
.flush_csr_i ( flush_csr_ctrl ),
.resolved_branch_i ( resolved_branch ),
.fence_i_i ( fence_i_commit_controller ),
.fence_i ( fence_commit_controller ),
.sfence_vma_i ( sfence_vma_commit_controller ),
.*

View file

@ -43,7 +43,8 @@ module commit_stage (
output logic commit_lsu_o, // commit the pending store
input logic no_st_pending_i, // there is no store pending
output logic commit_csr_o, // commit the pending CSR instruction
output logic fence_i_o, // flush icache and pipeline
output logic fence_i_o, // flush icache and pipeline
output logic fence_o, // flush dcache and pipeline
output logic sfence_vma_o // flush TLBs and pipeline
);
@ -64,6 +65,7 @@ module commit_stage (
csr_op_o = ADD; // this corresponds to a CSR NOP
csr_wdata_o = 64'b0;
fence_i_o = 1'b0;
fence_o = 1'b0;
sfence_vma_o = 1'b0;
// we will not commit the instruction if we took an exception
@ -119,6 +121,14 @@ module commit_stage (
// tell the controller to flush the I$
fence_i_o = 1'b1;
end
// ------------------
// FENCE Logic
// ------------------
if (commit_instr_i.op == FENCE) begin
commit_ack_o = 1'b1;
// tell the controller to flush the D$
fence_o = 1'b1;
end
end
end

View file

@ -20,6 +20,8 @@
import ariane_pkg::*;
module controller (
input logic clk_i,
input logic rst_ni,
output logic flush_bp_o, // Flush branch prediction data structures
output logic flush_pcgen_o, // Flush PC Generation Stage
output logic flush_if_o, // Flush the IF stage
@ -27,6 +29,8 @@ module controller (
output logic flush_id_o, // Flush ID stage
output logic flush_ex_o, // Flush EX stage
output logic flush_icache_o, // Flush ICache
output logic flush_dcache_o, // Flush DCache
input logic flush_dcache_ack_i, // Acknowledge the whole DCache Flush
output logic flush_tlb_o, // Flush TLBs
input logic halt_csr_i, // Halt request from CSR (WFI instruction)
@ -38,15 +42,19 @@ module controller (
input branchpredict resolved_branch_i, // We got a resolved branch, check if we need to flush the front-end
input logic flush_csr_i, // We got an instruction which altered the CSR, flush the pipeline
input logic fence_i_i, // fence.i in
input logic fence_i, // fence in
input logic sfence_vma_i // We got an instruction to flush the TLBs and pipeline
);
// flush branch prediction
assign flush_bp_o = 1'b0;
// active fence - high if we are currently flushing the dcache
logic fence_active_n, fence_active_q;
logic flush_dcache;
// ------------
// Flush CTRL
// ------------
always_comb begin : flush_ctrl
fence_active_n = fence_active_q;
flush_pcgen_o = 1'b0;
flush_if_o = 1'b0;
flush_unissued_instr_o = 1'b0;
@ -54,6 +62,7 @@ module controller (
flush_ex_o = 1'b0;
flush_tlb_o = 1'b0;
flush_icache_o = 1'b0;
flush_dcache = 1'b0;
// ------------
// Mis-predict
// ------------
@ -68,6 +77,21 @@ module controller (
// ---------------------------------
// FENCE
// ---------------------------------
if (fence_i) begin
fence_active_n = 1'b1;
flush_dcache = 1'b1;
// this can be seen as a CSR instruction with side-effect
flush_pcgen_o = 1'b1;
flush_if_o = 1'b1;
flush_unissued_instr_o = 1'b1;
flush_id_o = 1'b1;
flush_ex_o = 1'b1;
end
// wait for the acknowledge here
if (flush_dcache_ack_i && fence_active_q) begin
fence_active_n = 1'b0;
end
// ---------------------------------
// FENCE.I
@ -80,6 +104,7 @@ module controller (
flush_ex_o = 1'b1;
flush_icache_o = 1'b1;
end
// ---------------------------------
// SFENCE.VMA
// ---------------------------------
@ -123,6 +148,21 @@ module controller (
// Halt Logic
// ----------------------
always_comb begin
halt_o = halt_debug_i || halt_csr_i;
// halt the core if the fence is active
halt_o = halt_debug_i || halt_csr_i || fence_active_q;
end
// ----------------------
// Registers
// ----------------------
always_ff @(posedge clk_i or negedge rst_ni) begin
if(~rst_ni) begin
fence_active_q <= 1'b0;
flush_dcache_o <= 1'b0;
end else begin
fence_active_q <= fence_active_n;
// register on the flush signal, this signal might be critical
flush_dcache_o <= flush_dcache;
end
end
endmodule

View file

@ -205,13 +205,11 @@ module decoder (
instruction_o.rs1 = '0;
instruction_o.rs2 = '0;
instruction_o.rd = '0;
// FENCE
// TODO: Implement
end else begin
// Currently implemented as NOP
instruction_o.fu = ALU;
instruction_o.op = ADD;
// Currently implemented as a whole DCache flush boldly ignoring other things
instruction_o.fu = CSR;
instruction_o.op = FENCE;
instruction_o.rs1 = '0;
instruction_o.rs2 = '0;
instruction_o.rd = '0;