diff --git a/src/ariane.sv b/src/ariane.sv index 4463e622bd51126c6c98404288d18e467b951e74..9e4216eff18894d224e7192f8ae4077383a00a11 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -94,6 +94,11 @@ module ariane import ariane_pkg::*; #( // -------------- logic has_mem_access_id_verif; + // -------------- + // ISSUE -> verifier + // -------------- + logic has_mem_access_is_verif; + // -------------- // ISSUE <-> EX // -------------- @@ -362,6 +367,7 @@ module ariane import ariane_pkg::*; #( .we_fpr_i ( we_fpr_commit_id ), .commit_instr_o ( commit_instr_id_commit ), .commit_ack_i ( commit_ack ), + .has_mem_access_o ( has_mem_access_is_verif ), .* ); @@ -635,6 +641,9 @@ module ariane import ariane_pkg::*; #( // ID .id_has_mem_access_i (has_mem_access_id_verif), + // IS + .is_has_mem_access_i (has_mem_access_is_verif), + // CO .commit_instr_i (commit_instr_id_commit), .commit_ack_i (commit_ack) diff --git a/src/issue_stage.sv b/src/issue_stage.sv index 2258eb69912ba386d95d02fb7acb141f8acfbdaf..54c4122187c426f63891f2dcb6892c39d133fcd0 100644 --- a/src/issue_stage.sv +++ b/src/issue_stage.sv @@ -70,7 +70,10 @@ module issue_stage import ariane_pkg::*; #( input logic [NR_COMMIT_PORTS-1:0] we_fpr_i, output scoreboard_entry_t [NR_COMMIT_PORTS-1:0] commit_instr_o, - input logic [NR_COMMIT_PORTS-1:0] commit_ack_i + input logic [NR_COMMIT_PORTS-1:0] commit_ack_i, + + // to verifier + output has_mem_access_o ); // --------------------------------------------------- // Scoreboard (SB) <-> Issue and Read Operands (IRO) diff --git a/src/scoreboard.sv b/src/scoreboard.sv index c48d44c987f030c356b877efbd93b28d20a03e49..a20b0ef1cabe3b5ba59230f1ce2f8e3cc7fc021a 100644 --- a/src/scoreboard.sv +++ b/src/scoreboard.sv @@ -60,7 +60,10 @@ module scoreboard #( input logic [NR_WB_PORTS-1:0][ariane_pkg::TRANS_ID_BITS-1:0] trans_id_i, // transaction ID at which to write the result back input logic [NR_WB_PORTS-1:0][riscv::XLEN-1:0] wbdata_i, // write data in input ariane_pkg::exception_t [NR_WB_PORTS-1:0] ex_i, // exception from a functional unit (e.g.: ld/st exception) - input logic [NR_WB_PORTS-1:0] wt_valid_i // data in is valid + input logic [NR_WB_PORTS-1:0] wt_valid_i, // data in is valid + + // to verifier + output logic has_mem_access_o ); localparam int unsigned BITS_ENTRIES = $clog2(NR_ENTRIES); @@ -77,6 +80,8 @@ module scoreboard #( logic [NR_COMMIT_PORTS-1:0][BITS_ENTRIES-1:0] commit_pointer_n, commit_pointer_q; logic [$clog2(NR_COMMIT_PORTS):0] num_commit; + logic [NR_ENTRIES-1:0] has_mem_access_n, has_mem_access_q; + // the issue queue is full don't issue any new instructions // works since aligned to power of 2 assign issue_full = &issue_cnt_q; @@ -91,6 +96,9 @@ module scoreboard #( end end + // check instructions in the scoreboard for memory operations + assign has_mem_access_o = (|has_mem_access_q); + // an instruction is ready for issue if we have place in the issue FIFO and it the decoder says it is valid always_comb begin issue_instr_o = decoded_instr_i; @@ -106,8 +114,9 @@ module scoreboard #( // keep track of all issued instructions always_comb begin : issue_fifo // default assignment - mem_n = mem_q; - issue_en = 1'b0; + mem_n = mem_q; + issue_en = 1'b0; + has_mem_access_n = has_mem_access_q; // if we got a acknowledge from the issue stage, put this scoreboard entry in the queue if (decoded_instr_valid_i && decoded_instr_ack_o && !flush_unissued_instr_i) begin @@ -118,6 +127,7 @@ module scoreboard #( ariane_pkg::is_rd_fpr(decoded_instr_i.op), // whether rd goes to the fpr decoded_instr_i // decoded instruction record }; + has_mem_access_n[issue_pointer_q] = decoded_instr_i.fu inside {ariane_pkg::LOAD, ariane_pkg::STORE}; end // ------------ @@ -146,6 +156,9 @@ module scoreboard #( // write the fflags back from the FPU (exception valid is never set), leave tval intact else if (mem_q[trans_id_i[i]].sbe.fu inside {ariane_pkg::FPU, ariane_pkg::FPU_VEC}) mem_n[trans_id_i[i]].sbe.ex.cause = ex_i[i].cause; + + if (mem_n[trans_id_i[i]].sbe.fu != ariane_pkg::STORE) + has_mem_access_n[trans_id_i[i]] = 1'b0; end end @@ -156,8 +169,9 @@ module scoreboard #( for (logic [BITS_ENTRIES-1:0] i = 0; i < NR_COMMIT_PORTS; i++) begin if (commit_ack_i[i]) begin // this instruction is no longer in issue e.g.: it is considered finished - mem_n[commit_pointer_q[i]].issued = 1'b0; - mem_n[commit_pointer_q[i]].sbe.valid = 1'b0; + mem_n[commit_pointer_q[i]].issued = 1'b0; + mem_n[commit_pointer_q[i]].sbe.valid = 1'b0; + has_mem_access_n[commit_pointer_q[i]] = 1'b0; end end @@ -170,6 +184,7 @@ module scoreboard #( mem_n[i].issued = 1'b0; mem_n[i].sbe.valid = 1'b0; mem_n[i].sbe.ex.valid = 1'b0; + has_mem_access_n[i] = 1'b0; end end end @@ -353,15 +368,17 @@ module scoreboard #( // sequential process always_ff @(posedge clk_i or negedge rst_ni) begin : regs if(!rst_ni) begin - mem_q <= '{default: 0}; - issue_cnt_q <= '0; - commit_pointer_q <= '0; - issue_pointer_q <= '0; + mem_q <= '{default: 0}; + issue_cnt_q <= '0; + commit_pointer_q <= '0; + issue_pointer_q <= '0; + has_mem_access_q <= '0; end else begin - issue_cnt_q <= issue_cnt_n; - issue_pointer_q <= issue_pointer_n; - mem_q <= mem_n; - commit_pointer_q <= commit_pointer_n; + issue_cnt_q <= issue_cnt_n; + issue_pointer_q <= issue_pointer_n; + mem_q <= mem_n; + commit_pointer_q <= commit_pointer_n; + has_mem_access_q <= has_mem_access_n; end end diff --git a/src/verifier.sv b/src/verifier.sv index cc4278b8a3f69df17b1447f3cbb1ed8790d7d136..5ff2707de0cef740c0bc683583544ababae99c26 100644 --- a/src/verifier.sv +++ b/src/verifier.sv @@ -12,6 +12,9 @@ module verifier #( // ID input logic id_has_mem_access_i, + // IS + input logic is_has_mem_access_i, + // CO input ariane_pkg::scoreboard_entry_t [NR_COMMIT_PORTS-1:0] commit_instr_i, input logic [NR_COMMIT_PORTS-1:0] commit_ack_i