diff --git a/core/acc_dispatcher.sv b/core/acc_dispatcher.sv index b5472945de..8e965f4d01 100644 --- a/core/acc_dispatcher.sv +++ b/core/acc_dispatcher.sv @@ -16,7 +16,9 @@ module acc_dispatcher import ariane_pkg::*; import riscv::*; #( parameter ariane_pkg::cva6_cfg_t CVA6Cfg = ariane_pkg::cva6_cfg_empty, parameter type acc_req_t = acc_pkg::accelerator_req_t, - parameter type acc_resp_t = acc_pkg::accelerator_resp_t + parameter type acc_resp_t = acc_pkg::accelerator_resp_t, + parameter type acc_cfg_t = logic, + parameter acc_cfg_t AccCfg = '0 ) ( input logic clk_i, input logic rst_ni, @@ -43,11 +45,14 @@ module acc_dispatcher import ariane_pkg::*; import riscv::*; #( input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i, input logic commit_st_barrier_i, // A store barrier was commited // Interface with the load/store unit + output logic acc_stall_st_pending_o, input logic acc_no_st_pending_i, + input dcache_req_i_t [2:0] dcache_req_ports_i, // Interface with the controller output logic ctrl_halt_o, input logic flush_unissued_instr_i, input logic flush_ex_i, + output logic flush_pipeline_o, // Interface with cache subsystem input logic inval_ready_i, output logic inval_valid_o, @@ -401,4 +406,11 @@ module acc_dispatcher import ariane_pkg::*; import riscv::*; #( @(posedge clk_i) disable iff (~rst_ni) (acc_spec_stores_overflow == 1'b0) && (acc_disp_stores_overflow == 1'b0) ) else $error("[acc_dispatcher] Too many pending stores."); + /************************** + * Tie Off Unused Signals * + **************************/ + + assign acc_stall_st_pending_o = 1'b0; + assign flush_pipeline_o = 1'b0; + endmodule : acc_dispatcher diff --git a/core/controller.sv b/core/controller.sv index b05a3d9af5..5480286576 100644 --- a/core/controller.sv +++ b/core/controller.sv @@ -40,7 +40,8 @@ module controller import ariane_pkg::*; #( 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 - input logic flush_commit_i // Flush request from commit stage + input logic flush_commit_i, // Flush request from commit stage + input logic flush_acc_i // Flush request from accelerator ); // active fence - high if we are currently flushing the dcache @@ -132,8 +133,8 @@ module controller import ariane_pkg::*; #( flush_tlb_o = 1'b1; end - // Set PC to commit stage and flush pipleine - if (flush_csr_i || flush_commit_i) begin + // Set PC to commit stage and flush pipeline + if (flush_csr_i || flush_commit_i || flush_acc_i) begin set_pc_commit_o = 1'b1; flush_if_o = 1'b1; flush_unissued_instr_o = 1'b1; diff --git a/core/cva6.sv b/core/cva6.sv index 0f3300cd69..3b4db8cca8 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -114,6 +114,8 @@ module cva6 import ariane_pkg::*; #( }, // parameter ariane_pkg::ariane_cfg_t ArianeCfg = ariane_pkg::ArianeDefaultConfig, + parameter type acc_cfg_t = logic, + parameter acc_cfg_t AccCfg = '0, parameter type cvxif_req_t = cvxif_pkg::cvxif_req_t, parameter type cvxif_resp_t = cvxif_pkg::cvxif_resp_t ) ( @@ -252,6 +254,7 @@ module cva6 import ariane_pkg::*; #( logic lsu_commit_commit_ex; logic lsu_commit_ready_ex_commit; logic [TRANS_ID_BITS-1:0] lsu_commit_trans_id; + logic stall_st_pending_ex; logic no_st_pending_ex; logic no_st_pending_commit; logic amo_valid_commit; @@ -335,6 +338,7 @@ module cva6 import ariane_pkg::*; #( logic dcache_flush_ack_cache_ctrl; logic set_debug_pc; logic flush_commit; + logic flush_acc; icache_areq_i_t icache_areq_ex_cache; icache_areq_o_t icache_areq_cache_ex; @@ -373,6 +377,7 @@ module cva6 import ariane_pkg::*; #( ) i_frontend ( .flush_i ( flush_ctrl_if ), // not entirely correct .flush_bp_i ( 1'b0 ), + .halt_i ( halt_ctrl ), .debug_mode_i ( debug_mode ), .boot_addr_i ( boot_addr_i[riscv::VLEN-1:0] ), .icache_dreq_i ( icache_dreq_cache_if ), @@ -578,6 +583,7 @@ module cva6 import ariane_pkg::*; #( .lsu_commit_i ( lsu_commit_commit_ex ), // from commit .lsu_commit_ready_o ( lsu_commit_ready_ex_commit ), // to commit .commit_tran_id_i ( lsu_commit_trans_id ), // from commit + .stall_st_pending_i ( stall_st_pending_ex ), .no_st_pending_o ( no_st_pending_ex ), // FPU .fpu_ready_o ( fpu_ready_ex_id ), @@ -816,6 +822,7 @@ module cva6 import ariane_pkg::*; #( .fence_i ( fence_commit_controller ), .sfence_vma_i ( sfence_vma_commit_controller ), .flush_commit_i ( flush_commit ), + .flush_acc_i ( flush_acc ), .flush_icache_o ( icache_flush_ctrl_cache ), .* @@ -920,6 +927,9 @@ module cva6 import ariane_pkg::*; #( if (ENABLE_ACCELERATOR) begin: gen_accelerator acc_dispatcher #( + .CVA6Cfg ( CVA6Cfg ), + .acc_cfg_t ( acc_cfg_t ), + .AccCfg ( AccCfg ), .acc_req_t ( cvxif_req_t ), .acc_resp_t ( cvxif_resp_t ) ) i_acc_dispatcher ( @@ -927,6 +937,7 @@ module cva6 import ariane_pkg::*; #( .rst_ni ( rst_ni ), .flush_unissued_instr_i ( flush_unissued_instr_ctrl_id ), .flush_ex_i ( flush_ctrl_ex ), + .flush_pipeline_o ( flush_acc ), .acc_cons_en_i ( acc_cons_en_csr ), .acc_fflags_valid_o ( acc_resp_fflags_valid ), .acc_fflags_o ( acc_resp_fflags ), @@ -944,7 +955,9 @@ module cva6 import ariane_pkg::*; #( .acc_exception_o ( acc_exception_ex_id ), .acc_valid_ex_o ( acc_valid_acc_ex ), .commit_ack_i ( commit_ack ), + .acc_stall_st_pending_o ( stall_st_pending_ex ), .acc_no_st_pending_i ( no_st_pending_commit ), + .dcache_req_ports_i ( dcache_req_ports_ex_cache ), .ctrl_halt_o ( halt_acc_ctrl ), .inval_ready_i ( inval_ready ), .inval_valid_o ( inval_valid ), @@ -963,6 +976,8 @@ module cva6 import ariane_pkg::*; #( assign dirty_v_state = '0; assign acc_valid_acc_ex = '0; assign halt_acc_ctrl = '0; + assign stall_st_pending_ex = '0; + assign flush_acc = '0; // No invalidation interface assign inval_valid = '0; diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 078121cf34..518c403923 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -66,6 +66,7 @@ module ex_stage import ariane_pkg::*; #( input logic lsu_commit_i, output logic lsu_commit_ready_o, // commit queue is ready to accept another commit request input logic [TRANS_ID_BITS-1:0] commit_tran_id_i, + input logic stall_st_pending_i, output logic no_st_pending_o, input logic amo_valid_commit_i, // FPU @@ -307,6 +308,7 @@ module ex_stage import ariane_pkg::*; #( .clk_i, .rst_ni, .flush_i, + .stall_st_pending_i, .no_st_pending_o, .fu_data_i ( lsu_data ), .lsu_ready_o, diff --git a/core/frontend/frontend.sv b/core/frontend/frontend.sv index d359598954..031040217a 100644 --- a/core/frontend/frontend.sv +++ b/core/frontend/frontend.sv @@ -23,6 +23,7 @@ module frontend import ariane_pkg::*; #( input logic rst_ni, // Asynchronous reset active low input logic flush_i, // flush request for PCGEN input logic flush_bp_i, // flush branch prediction + input logic halt_i, // halt commit stage input logic debug_mode_i, // global input input logic [riscv::VLEN-1:0] boot_addr_i, @@ -338,12 +339,14 @@ module frontend import ariane_pkg::*; #( // 6. Pipeline Flush because of CSR side effects // On a pipeline flush start fetching from the next address // of the instruction in the commit stage - // we came here from a flush request of a CSR instruction or AMO, - // as CSR or AMO instructions do not exist in a compressed form + // we either came here from a flush request of a CSR instruction or AMO, + // so as CSR or AMO instructions do not exist in a compressed form // we can unconditionally do PC + 4 here + // or if the commit stage is halted, just take the current pc of the + // instruction in the commit stage // TODO(zarubaf) This adder can at least be merged with the one in the csr_regfile stage if (set_pc_commit_i) begin - npc_d = pc_commit_i + {{riscv::VLEN-3{1'b0}}, 3'b100}; + npc_d = pc_commit_i + (halt_i ? '0 : {{riscv::VLEN-3{1'b0}}, 3'b100}); end // 7. Debug // enter debug on a hard-coded base-address diff --git a/core/load_store_unit.sv b/core/load_store_unit.sv index 4e5d0d0d87..39b6cc406c 100644 --- a/core/load_store_unit.sv +++ b/core/load_store_unit.sv @@ -21,6 +21,7 @@ module load_store_unit import ariane_pkg::*; #( input logic clk_i, input logic rst_ni, input logic flush_i, + input logic stall_st_pending_i, output logic no_st_pending_o, input logic amo_valid_commit_i, @@ -251,6 +252,7 @@ module load_store_unit import ariane_pkg::*; #( .clk_i, .rst_ni, .flush_i, + .stall_st_pending_i, .no_st_pending_o, .store_buffer_empty_o ( store_buffer_empty ), diff --git a/core/store_buffer.sv b/core/store_buffer.sv index f563bc6e55..6a1163286a 100644 --- a/core/store_buffer.sv +++ b/core/store_buffer.sv @@ -21,6 +21,7 @@ module store_buffer import ariane_pkg::*; #( input logic rst_ni, // Asynchronous reset active low input logic flush_i, // if we flush we need to pause the transactions on the memory // otherwise we will run in a deadlock with the memory arbiter + input logic stall_st_pending_i, // Stall issuing non-speculative request output logic no_st_pending_o, // non-speculative queue is empty (e.g.: everything is committed to the memory hierarchy) output logic store_buffer_empty_o, // there is no store pending in neither the speculative unit or the non-speculative queue @@ -161,7 +162,7 @@ module store_buffer import ariane_pkg::*; #( // there should be no commit when we are flushing // if the entry in the commit queue is valid and not speculative anymore we can issue this instruction - if (commit_queue_q[commit_read_pointer_q].valid) begin + if (commit_queue_q[commit_read_pointer_q].valid && !stall_st_pending_i) begin req_port_o.data_req = 1'b1; if (req_port_i.data_gnt) begin // we can evict it from the commit buffer diff --git a/core/store_unit.sv b/core/store_unit.sv index 98d03c4e41..27eb11aaa8 100644 --- a/core/store_unit.sv +++ b/core/store_unit.sv @@ -19,6 +19,7 @@ module store_unit import ariane_pkg::*; #( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low input logic flush_i, + input logic stall_st_pending_i, output logic no_st_pending_o, output logic store_buffer_empty_o, // store unit input port @@ -221,6 +222,7 @@ module store_unit import ariane_pkg::*; #( .clk_i, .rst_ni, .flush_i, + .stall_st_pending_i, .no_st_pending_o, .store_buffer_empty_o, .page_offset_i,