From 60ec4a7333734e8ee0669431194217c155306186 Mon Sep 17 00:00:00 2001 From: Michael Platzer Date: Wed, 8 Jun 2022 11:37:40 +0200 Subject: [PATCH] Ignore memory results if instr ID does not match Ignore memory result transactions on the XIF interface for which the instruction ID does not match the expected ID. --- rtl/vproc_lsu.sv | 10 ++++++++-- rtl/vproc_top.sv | 10 +++++++++- sva/vproc_lsu_sva.svh | 12 ++++++------ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/rtl/vproc_lsu.sv b/rtl/vproc_lsu.sv index 0db4c3f..4d4e080 100644 --- a/rtl/vproc_lsu.sv +++ b/rtl/vproc_lsu.sv @@ -344,7 +344,13 @@ module vproc_lsu import vproc_pkg::*; #( .flags_any_o ( ), .flags_all_o ( ) ); - assign deq_ready = xif_memres_if.mem_result_valid | deq_state.suppressed | mem_err_d; + + // XIF mem_result_valid is asserted and the memory result's instruction ID matches + logic xif_mem_result_id_valid; + assign xif_mem_result_id_valid = xif_memres_if.mem_result_valid & + (xif_memres_if.mem_result.id == deq_state.id); + + assign deq_ready = xif_mem_result_id_valid | deq_state.suppressed | mem_err_d; assign state_rdata_valid_d = deq_valid & deq_ready; // monitor the memory result for bus errors and the queue for exceptions @@ -354,7 +360,7 @@ module vproc_lsu import vproc_pkg::*; #( if (deq_valid & (deq_state.first_cycle | ~mem_err_q)) begin // reset the error flag in the first cycle, unless there is a bus // error or an exception occured during the request - mem_err_d = deq_state.exc | (xif_memres_if.mem_result_valid & xif_memres_if.mem_result.err); + mem_err_d = deq_state.exc | (xif_mem_result_id_valid & xif_memres_if.mem_result.err); mem_exccode_d = deq_state.exc ? deq_state.exccode : ( // bus error translates to a load/store access fault exception deq_state.mode.store ? 6'h07 : 6'h05 diff --git a/rtl/vproc_top.sv b/rtl/vproc_top.sv index d7698e6..5972795 100644 --- a/rtl/vproc_top.sv +++ b/rtl/vproc_top.sv @@ -395,6 +395,8 @@ module vproc_top #( logic vdata_we; logic [VMEM_W/8-1:0] vdata_be; logic [VMEM_W-1:0] vdata_wdata; + logic [X_ID_WIDTH-1:0] vdata_req_id; + logic [X_ID_WIDTH-1:0] vdata_res_id; localparam bit [vproc_pkg::VLSU_FLAGS_W-1:0] VLSU_FLAGS = USE_XIF_MEM ? '0 : (vproc_pkg::VLSU_FLAGS_W'(1) << vproc_pkg::VLSU_ADDR_ALIGNED); @@ -447,6 +449,7 @@ module vproc_top #( assign vdata_we = '0; assign vdata_be = '0; assign vdata_wdata = '0; + assign vdata_req_id = '0; end else begin assign vdata_req = vcore_xif.mem_valid; assign vcore_xif.mem_ready = vdata_gnt; @@ -454,11 +457,12 @@ module vproc_top #( assign vdata_we = vcore_xif.mem_req.we; assign vdata_be = vcore_xif.mem_req.be; assign vdata_wdata = vcore_xif.mem_req.wdata; + assign vdata_req_id = vcore_xif.mem_req.id; assign vcore_xif.mem_resp.exc = '0; assign vcore_xif.mem_resp.exccode = '0; assign vcore_xif.mem_resp.dbg = '0; assign vcore_xif.mem_result_valid = vdata_rvalid; - assign vcore_xif.mem_result.id = '0; // TODO supply instruction ID + assign vcore_xif.mem_result.id = vdata_res_id; assign vcore_xif.mem_result.rdata = vdata_rdata; assign vcore_xif.mem_result.err = vdata_err; assign vcore_xif.mem_result.dbg = '0; @@ -477,6 +481,7 @@ module vproc_top #( logic [VMEM_W -1:0] data_rdata; logic sdata_waiting, vdata_waiting; logic [31:0] sdata_wait_addr; + logic [X_ID_WIDTH-1:0] vdata_wait_id; assign sdata_hold = ~USE_XIF_MEM & (vdata_req | vect_pending_store | (vect_pending_load & sdata_we)); always_comb begin data_req = vdata_req | (sdata_req & ~sdata_hold); @@ -501,6 +506,7 @@ module vproc_top #( sdata_waiting <= 1'b0; vdata_waiting <= 1'b0; sdata_wait_addr <= '0; + vdata_wait_id <= '0; end else begin if (sdata_gnt) begin sdata_waiting <= 1'b1; @@ -511,6 +517,7 @@ module vproc_top #( end if (vdata_gnt) begin vdata_waiting <= 1'b1; + vdata_wait_id <= vdata_req_id; end else if (vdata_rvalid) begin vdata_waiting <= 1'b0; @@ -523,6 +530,7 @@ module vproc_top #( assign vdata_err = data_err; assign sdata_rdata = data_rdata[(sdata_wait_addr[$clog2(VMEM_W)-1:0] & {3'b000, {($clog2(VMEM_W/8)-2){1'b1}}, 2'b00})*8 +: 32]; assign vdata_rdata = data_rdata; + assign vdata_res_id = vdata_wait_id; /////////////////////////////////////////////////////////////////////////// diff --git a/sva/vproc_lsu_sva.svh b/sva/vproc_lsu_sva.svh index d440a4a..47f77c1 100644 --- a/sva/vproc_lsu_sva.svh +++ b/sva/vproc_lsu_sva.svh @@ -10,20 +10,20 @@ $error("attempt to stall LSU output"); end - // Assert that there is no memory response transaction while dequeueing a suppressed request + // Assert that there is no memory result transaction while dequeueing a suppressed request assert property ( @(posedge clk_i) - (deq_valid & xif_memres_if.mem_result_valid) |-> ~deq_state.suppressed + (deq_valid & xif_mem_result_id_valid) |-> ~deq_state.suppressed ) else begin - $error("incoming memory response transaction while dequeueing a suppressed request"); + $error("incoming memory result transaction while dequeueing a suppressed request"); end - // Assert that there is no memory response transaction while dequeueing a failed request + // Assert that there is no memory result transaction while dequeueing a failed request assert property ( @(posedge clk_i) - (deq_valid & xif_memres_if.mem_result_valid) |-> ~deq_state.exc + (deq_valid & xif_mem_result_id_valid) |-> ~deq_state.exc ) else begin - $error("incoming memory response transaction while dequeueing a failed request"); + $error("incoming memory result transaction while dequeueing a failed request"); end // Assert that the transaction complete queue is always ready