diff --git a/src/ariane.sv b/src/ariane.sv index a4c589cc56ffdf9d8caa997e1c1523017c9d87be..4fc9e1a5b98ad206b36a8ae2da7038e0b86f59fa 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -76,6 +76,11 @@ module ariane import ariane_pkg::*; #( logic fetch_valid_if_id; logic fetch_ready_id_if; + // -------------- + // IF -> verifier + // -------------- + logic has_mem_access_if_verif; + // -------------- // ID <-> ISSUE // -------------- @@ -261,6 +266,7 @@ module ariane import ariane_pkg::*; #( .fetch_entry_o ( fetch_entry_if_id ), .fetch_entry_valid_o ( fetch_valid_if_id ), .fetch_entry_ready_i ( fetch_ready_id_if ), + .has_mem_access_o ( has_mem_access_if_verif ), .* ); @@ -617,6 +623,9 @@ module ariane import ariane_pkg::*; #( .rst_ni, .flush_i (flush_ctrl_id), + // IF + .if_has_mem_access_i (has_mem_access_if_verif), + // CO .commit_instr_i (commit_instr_id_commit), .commit_ack_i (commit_ack) diff --git a/src/frontend/frontend.sv b/src/frontend/frontend.sv index a9c5c2206a831fadc7adf756cdb99ce5ca0478bb..7b37a788b189cbf3b84a2c52a998473afab4a39a 100644 --- a/src/frontend/frontend.sv +++ b/src/frontend/frontend.sv @@ -43,7 +43,9 @@ module frontend import ariane_pkg::*; #( // instruction output port -> to processor back-end output fetch_entry_t fetch_entry_o, // fetch entry containing all relevant data for the ID stage output logic fetch_entry_valid_o, // instruction in IF is valid - input logic fetch_entry_ready_i // ID acknowledged this instruction + input logic fetch_entry_ready_i, // ID acknowledged this instruction + + output logic has_mem_access_o ); // Instruction Cache Registers, from I$ logic [FETCH_WIDTH-1:0] icache_data_q; @@ -428,7 +430,8 @@ module frontend import ariane_pkg::*; #( .replay_addr_o ( replay_addr ), .fetch_entry_o ( fetch_entry_o ), // to back-end .fetch_entry_valid_o ( fetch_entry_valid_o ), // to back-end - .fetch_entry_ready_i ( fetch_entry_ready_i ) // to back-end + .fetch_entry_ready_i ( fetch_entry_ready_i ), // to back-end + .has_mem_access_o ( has_mem_access_o ) // to verifier ); // pragma translate_off diff --git a/src/frontend/instr_queue.sv b/src/frontend/instr_queue.sv index 37c81a9e011ce8759193f21a8a46d3dbb51c900c..6e125aacccbd185b4248f2dc30fc5698ae163b07 100644 --- a/src/frontend/instr_queue.sv +++ b/src/frontend/instr_queue.sv @@ -64,7 +64,9 @@ module instr_queue ( // to processor backend output ariane_pkg::fetch_entry_t fetch_entry_o, output logic fetch_entry_valid_o, - input logic fetch_entry_ready_i + input logic fetch_entry_ready_i, + + output logic has_mem_access_o ); typedef struct packed { @@ -117,6 +119,12 @@ module instr_queue ( // replay interface logic [ariane_pkg::INSTR_PER_FETCH-1:0] instr_overflow_fifo; + // memory access count + logic [ariane_pkg::INSTR_PER_FETCH-1:0] input_is_mem; + logic output_is_mem; + + logic [$clog2(ariane_pkg::FETCH_FIFO_DEPTH)*2-1:0] nr_mem_n, nr_mem_q; + assign ready_o = ~(|instr_queue_full) & ~full_address; for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin : gen_unpack_taken @@ -211,6 +219,41 @@ module instr_queue ( // as long as there is at least one queue which can take the value we have a valid instruction assign fetch_entry_valid_o = ~(&instr_queue_empty); + // ---------------------- + // Memory access detector + // ---------------------- + for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin + assign input_is_mem[i] = valid_i[i] & + ((instr_i[i][6:0] == riscv::OpcodeLoad) | + (instr_i[i][6:0] == riscv::OpcodeLoadFp) | + (instr_i[i][6:0] == riscv::OpcodeStore) | + (instr_i[i][6:0] == riscv::OpcodeStoreFp) | + (instr_i[i][6:0] == riscv::OpcodeAmo)); + end + + assign output_is_mem = fetch_entry_valid_o & + ((fetch_entry_o.instruction[6:0] == riscv::OpcodeLoad) | + (fetch_entry_o.instruction[6:0] == riscv::OpcodeLoadFp) | + (fetch_entry_o.instruction[6:0] == riscv::OpcodeStore) | + (fetch_entry_o.instruction[6:0] == riscv::OpcodeStoreFp) | + (fetch_entry_o.instruction[6:0] == riscv::OpcodeAmo)); + + assign has_mem_access_o = (|nr_mem_n) | (|input_is_mem) | output_is_mem; + + always_comb begin + nr_mem_n = nr_mem_q; + + for (int unsigned i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin + if (push_instr_fifo[i]) begin + nr_mem_n = nr_mem_n + 1'b1; + end + end + + if (fetch_entry_ready_i) begin + nr_mem_n = nr_mem_n - 1'b1; + end + end + always_comb begin idx_ds_d = idx_ds_q; @@ -331,6 +374,7 @@ module instr_queue ( idx_is_q <= '0; pc_q <= '0; reset_address_q <= 1'b1; + nr_mem_q <= '0; end else begin pc_q <= pc_d; reset_address_q <= reset_address_d; @@ -340,9 +384,11 @@ module instr_queue ( // binary encoded idx_is_q <= '0; reset_address_q <= 1'b1; + nr_mem_q <= '0; end else begin - idx_ds_q <= idx_ds_d; - idx_is_q <= idx_is_d; + idx_ds_q <= idx_ds_d; + idx_is_q <= idx_is_d; + nr_mem_q <= nr_mem_n; end end end diff --git a/src/verifier.sv b/src/verifier.sv index f41a5584a54efe4aeec3a351c0d2d277dad2ba2e..24fdfdb51143c87cb64e096782ff82e8328e1de9 100644 --- a/src/verifier.sv +++ b/src/verifier.sv @@ -2,12 +2,15 @@ module verifier #( parameter int unsigned NR_ENTRIES = 8, parameter int unsigned NR_COMMIT_PORTS = 2 ) ( - input logic clk_i, - input logic rst_ni, - input logic flush_i, + input logic clk_i, + input logic rst_ni, + input logic flush_i, + + // Frontend + input logic if_has_mem_access_i, // CO - input ariane_pkg::scoreboard_entry_t [NR_COMMIT_PORTS-1:0] commit_instr_i, + input ariane_pkg::scoreboard_entry_t [NR_COMMIT_PORTS-1:0] commit_instr_i, input logic [NR_COMMIT_PORTS-1:0] commit_ack_i );