From 53e674aeb30beb1aad231770ee8c63f26112de06 Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Sat, 26 Aug 2017 08:59:24 +0200 Subject: [PATCH 1/6] WIP: Disable CSR side-effects on exception --- Makefile | 3 +++ src/csr_regfile.sv | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ba69ae084..738cf1808 100644 --- a/Makefile +++ b/Makefile @@ -175,6 +175,9 @@ lint: verilator $(ariane_pkg) $(src) --lint-only \ $(list_incdir) --top-module ariane +verify: + qverify vlog -sv src/csr_regfile.sv + clean: rm -rf work/ *.ucdb diff --git a/src/csr_regfile.sv b/src/csr_regfile.sv index 8fe8caeaa..d64248667 100644 --- a/src/csr_regfile.sv +++ b/src/csr_regfile.sv @@ -467,6 +467,13 @@ module csr_regfile #( csr_read = 1'b0; end endcase + // if we are retiring an exception do not modify anything + if (ex_i.valid) begin + mret = 1'b0; + sret = 1'b0; + csr_we = 1'b0; + csr_read = 1'b0; + end // ------------------------------ // Debug Multiplexer (Priority) // ------------------------------ @@ -671,7 +678,7 @@ module csr_regfile #( `ifndef VERILATOR // check that eret and ex are never valid together assert property ( - @(posedge clk_i) !(eret_i && ex_valid_i)) + @(posedge clk_i) !(eret_o && ex_i.valid)) else $warning("eret and exception should never be valid at the same time"); `endif `endif From e2424c1cc2004167d653f8eabaf48abd4c845e1e Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Sat, 26 Aug 2017 09:12:26 +0200 Subject: [PATCH 2/6] WIP: Remove timing loop --- src/csr_regfile.sv | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/csr_regfile.sv b/src/csr_regfile.sv index d64248667..29e2867ff 100644 --- a/src/csr_regfile.sv +++ b/src/csr_regfile.sv @@ -467,12 +467,10 @@ module csr_regfile #( csr_read = 1'b0; end endcase - // if we are retiring an exception do not modify anything + // if we are retiring an exception do not return from exception if (ex_i.valid) begin - mret = 1'b0; - sret = 1'b0; - csr_we = 1'b0; - csr_read = 1'b0; + mret = 1'b0; + sret = 1'b0; end // ------------------------------ // Debug Multiplexer (Priority) @@ -679,7 +677,7 @@ module csr_regfile #( // check that eret and ex are never valid together assert property ( @(posedge clk_i) !(eret_o && ex_i.valid)) - else $warning("eret and exception should never be valid at the same time"); + else begin $error("eret and exception should never be valid at the same time"); $stop(); end `endif `endif endmodule From a569aede23cba8d78e08b53167496a3b404a5ae1 Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Sat, 26 Aug 2017 10:20:10 +0200 Subject: [PATCH 3/6] Flag excepting instruction as valid --- src/decoder.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/decoder.sv b/src/decoder.sv index 164b36e6e..8b7f54489 100644 --- a/src/decoder.sv +++ b/src/decoder.sv @@ -507,7 +507,7 @@ module decoder ( // --------------------- always_comb begin : exception_handling instruction_o.ex = ex_i; - instruction_o.valid = 1'b0; + instruction_o.valid = ex_i.valid; // look if we didn't already get an exception in any previous // stage - we should not overwrite it as we retain order regarding the exception if (~ex_i.valid) begin From b3abf7491cae5f9565ce8e18f1b1cb4ca17ab4a5 Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Sat, 26 Aug 2017 11:48:57 +0200 Subject: [PATCH 4/6] Report the last PC when debug not halted --- src/debug_unit.sv | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/debug_unit.sv b/src/debug_unit.sv index 9eb4d9115..1433b082d 100755 --- a/src/debug_unit.sv +++ b/src/debug_unit.sv @@ -153,8 +153,6 @@ module debug_unit ( if (debug_halted_o) begin if (commit_instr_i.valid) rdata_n = commit_instr_i.pc; - else - rdata_n = 64'hdeadbeefdeadbeef; if (cause_is_bp_q) // if the cause is a breakpoint we trick the debugger in assuming the next instruction @@ -163,8 +161,9 @@ module debug_unit ( rdata_n = dbg_ppc_q + 64'h2; else rdata_n = dbg_ppc_q + 64'h4; - // TODO: Breakpoint - end + // we are not in debug mode - so just report what we know: the last valid PC + end else + rdata_n = dbg_ppc_q; // if we came from reset - output the boot address if (reset_q) rdata_n = boot_addr_i; From 01f628d488cb6c64bba9ab57b48abfc868e4ede3 Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Sat, 26 Aug 2017 11:49:50 +0200 Subject: [PATCH 5/6] Also check for interrupt flag when halting debug --- src/debug_unit.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug_unit.sv b/src/debug_unit.sv index 9eb4d9115..0934f3691 100755 --- a/src/debug_unit.sv +++ b/src/debug_unit.sv @@ -251,7 +251,7 @@ module debug_unit ( // Debugger Signaling // ------------------------ // if an exception occurred and it is enabled to trigger debug mode, halt the processor and enter debug mode - if (commit_ack_i && ex_i.valid && dbg_ie_q[ex_i.cause[5:0]]) begin + if (commit_ack_i && ex_i.valid && dbg_ie_q[ex_i.cause[5:0]] && (ex_i.cause[63] == dbg_ie_q[63])) begin halt_req = 1'b1; // save the cause why we entered the exception dbg_cause_n = ex_i.cause; From 633a10d0c5ce4b5d385f4d06226259bdfbca5d91 Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Sat, 26 Aug 2017 18:07:22 +0200 Subject: [PATCH 6/6] :bug: Fix issue in store buffer flush signal The flush of the speculative store buffer wasn't performed when the store buffer was full. I actually have no idea why I've added this in the first place. --- Makefile | 2 +- src/store_buffer.sv | 12 ++++++------ src/store_unit.sv | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 738cf1808..d5d5469d5 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,7 @@ sim: build ariane_tb.dtb simc: build ariane_tb.dtb vsim${questa_version} -c -lib ${library} ${top_level}_optimized +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \ - +BASEDIR=$(riscv-test-dir) $(uvm-flags) +ASMTEST=$(riscv-test) -coverage -classdebug + +BASEDIR=$(riscv-test-dir) $(uvm-flags) +ASMTEST=$(riscv-test) -coverage -classdebug -do "do tb/wave/wave_core.do" run-asm-tests: build ariane_tb.dtb $(foreach test, $(riscv-tests), vsim$(questa_version) +BASEDIR=$(riscv-test-dir) +max-cycles=$(max_cycles) \ diff --git a/src/store_buffer.sv b/src/store_buffer.sv index 2a7e8bcc6..a6654bd60 100644 --- a/src/store_buffer.sv +++ b/src/store_buffer.sv @@ -25,8 +25,8 @@ module store_buffer ( // otherwise we will run in a deadlock with the memory arbiter output logic no_st_pending_o, // non-speculative queue is empty (e.g.: everything is committed to the memory hierarchy) - input logic [11:0] page_offset_i, - output logic page_offset_matches_o, + input logic [11:0] page_offset_i, // check for the page offset (the last 12 bit if the current load matches them) + output logic page_offset_matches_o, // the above input page offset matches -> let the store buffer drain input logic commit_i, // commit the instruction which was placed there most recently output logic commit_ready_o, // commit queue is ready to accept another commit request @@ -119,7 +119,7 @@ module store_buffer ( speculative_status_cnt_n = speculative_status_cnt; // when we flush evict the speculative stores - if (ready_o && flush_i) begin + if (flush_i) begin // reset all valid flags for (int unsigned i = 0; i < DEPTH_SPEC; i++) speculative_queue_n[i].valid = 1'b0; @@ -260,15 +260,15 @@ module store_buffer ( `ifndef verilator // assert that commit is never set when we are flushing this would be counter intuitive // as flush and commit is decided in the same stage - assert property ( + commit_and_flush: assert property ( @(posedge clk_i) rst_ni && flush_i |-> !commit_i) else $error ("[Commit Queue] You are trying to commit and flush in the same cycle"); - assert property ( + speculative_buffer_overflow: assert property ( @(posedge clk_i) rst_ni && (speculative_status_cnt_q == DEPTH_SPEC) |-> !valid_i) else $error ("[Speculative Queue] You are trying to push new data although the buffer is not ready"); - assert property ( + commit_buffer_overflow: assert property ( @(posedge clk_i) rst_ni && (commit_status_cnt_q == DEPTH_SPEC) |-> !commit_i) else $error("[Commit Queue] You are trying to commit a store although the buffer is full"); diff --git a/src/store_unit.sv b/src/store_unit.sv index 32c8a62a2..c158b75a5 100644 --- a/src/store_unit.sv +++ b/src/store_unit.sv @@ -19,9 +19,9 @@ import ariane_pkg::*; module store_unit ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - input logic flush_i, + input logic clk_i, // Clock + input logic rst_ni, // Asynchronous reset active low + input logic flush_i, output logic no_st_pending_o, // store unit input port input logic valid_i,