From 0abbabad86cd499c52aa0f31682ffc428a9781b4 Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Thu, 8 Jun 2017 15:35:44 +0200 Subject: [PATCH] :bug: Fix bug in misaligned ld/st exception --- Makefile | 2 +- README.md | 2 +- src/load_unit.sv | 12 +++++++++--- src/lsu.sv | 30 +++++++++++++----------------- src/store_unit.sv | 2 +- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index a94c365d1..a6f3faa60 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ riscv-tests = rv64ui-p-add rv64ui-p-addi rv64ui-p-slli rv64ui-p-addiw rv64ui-p-a rv64ui-p-sraiw rv64ui-p-sraw rv64ui-p-srl rv64ui-p-srli rv64ui-p-srliw rv64ui-p-srlw \ rv64ui-p-lb rv64ui-p-lbu rv64ui-p-ld rv64ui-p-lh rv64ui-p-lhu rv64ui-p-lui \ rv64ui-p-lw rv64ui-p-lwu \ - rv64mi-p-csr rv64mi-p-mcsr rv64mi-p-illegal + rv64mi-p-csr rv64mi-p-mcsr rv64mi-p-illegal rv64mi-p-ma_addr riscv-test = rv64ui-p-add # Search here for include files (e.g.: non-standalone components) diff --git a/README.md b/README.md index ddd125678..7ffcaaddb 100644 --- a/README.md +++ b/README.md @@ -69,5 +69,5 @@ Check out the [contribution guide](CONTRIBUTING.md) | **Test Name** | **P/F/U** | **Test Name** | **P/F/U** | **Test Name** | **P/F/U** | |---------------|----------------------|---------------|----------------------|---------------|----------------------| | csr | :white_check_mark: | illegal | :white_check_mark: | mcsr | :white_check_mark: | -| breakpoint | :white_large_square: | ma_addr | :white_large_square: | ma_fetch | :white_large_square: | +| breakpoint | :white_large_square: | ma_addr | :white_check_mark: | ma_fetch | :white_large_square: | | sbreak | :white_large_square: | scall | :white_large_square: | | | diff --git a/src/load_unit.sv b/src/load_unit.sv index 7288cbb4c..cd49b22ce 100644 --- a/src/load_unit.sv +++ b/src/load_unit.sv @@ -296,6 +296,8 @@ module load_unit ( ready_o = 1'b1; // do not push this request push = 1'b0; + // reset state machine + NS = IDLE; end // if we just flushed and the queue is not empty or we are getting an rvalid this cycle wait in a extra stage if (flush_i && (!empty || data_rvalid_i)) begin @@ -309,6 +311,9 @@ module load_unit ( always_comb begin : rvalid_output pop = 1'b0; valid_o = 1'b0; + // output the queue data directly, the valid signal is set corresponding to the process above + trans_id_o = out_data.trans_id; + // we got an rvalid and are currently not flushing if (data_rvalid_i && CS != WAIT_FLUSH) begin pop = 1'b1; @@ -316,12 +321,13 @@ module load_unit ( end // pass through an exception if (valid_i && ex_i.valid) begin - valid_o = 1'b1; + valid_o = 1'b1; + // in case of an exception we can use the current trans_id since we either stalled + // or we are taking the exception in the first cycle + trans_id_o = trans_id_i; end end - // output the queue data directly, the valid signal is set corresponding to the process above - assign trans_id_o = out_data.trans_id; // latch physical address always_ff @(posedge clk_i or negedge rst_ni) begin diff --git a/src/lsu.sv b/src/lsu.sv index 323dc2a0e..f9f66de81 100644 --- a/src/lsu.sv +++ b/src/lsu.sv @@ -335,19 +335,15 @@ module lsu #( ld_valid_i = 1'b0; st_valid_i = 1'b0; - // only activate one of the units if we didn't got an misaligned exception - // we can directly output a misaligned exception and do not need to process it any further - if (!data_misaligned) begin - // check the operator to activate the right functional unit accordingly - unique case (fu) - // all loads go here - LOAD: ld_valid_i = lsu_valid_i; - // all stores go here - STORE: st_valid_i = lsu_valid_i; - // not relevant for the LSU - default: ; - endcase - end + // check the operator to activate the right functional unit accordingly + unique case (fu) + // all loads go here + LOAD: ld_valid_i = lsu_valid_i; + // all stores go here + STORE: st_valid_i = lsu_valid_i; + // not relevant for the LSU + default: ; + endcase end @@ -424,13 +420,13 @@ module lsu #( end // word LW, LWU, SW: begin - if (vaddr_i[2] == 1'b1 && vaddr_i[2:0] != 3'b100) + if (vaddr_i[1:0] != 1'b00) data_misaligned = 1'b1; end // half word LH, LHU, SH: begin - if (vaddr_i[2:0] == 3'b111) + if (vaddr_i[0] != 1'b0) data_misaligned = 1'b1; end // byte -> is always aligned @@ -442,15 +438,15 @@ module lsu #( if (fu == LOAD) begin misaligned_exception = { - 64'b0, LD_ADDR_MISALIGNED, + vaddr, 1'b1 }; end else if (fu == STORE) begin misaligned_exception = { - 64'b0, ST_ADDR_MISALIGNED, + vaddr, 1'b1 }; end diff --git a/src/store_unit.sv b/src/store_unit.sv index 554b3c3b6..b9897aa35 100644 --- a/src/store_unit.sv +++ b/src/store_unit.sv @@ -102,7 +102,7 @@ module store_unit ( if (ex_i.valid) begin // result is valid valid_o = 1'b1; - // do not store this + // do not store this st_valid = 1'b0; // we are ready if we got this exception ready_o = 1'b1;