🐛 Fix exception not taken problem

This commit is contained in:
Florian Zaruba 2017-06-22 15:32:01 +02:00
parent fc7969b385
commit 773efe42a8
10 changed files with 43 additions and 39 deletions

View file

@ -40,9 +40,10 @@ 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-ma_addr rv64mi-p-ma_fetch rv64mi-p-sbreak rv64mi-p-scall \
rv64mi-p-csr rv64mi-p-mcsr rv64mi-p-illegal \
rv64mi-p-ma_addr rv64mi-p-ma_fetch rv64mi-p-sbreak rv64mi-p-scall \
rv64si-p-csr rv64si-p-ma_fetch rv64si-p-scall rv64si-p-wfi rv64si-p-sbreak \
rv64uc-p-rvc rv64si-p-dirty
rv64si-p-dirty
riscv-test = rv64ui-p-add

View file

@ -524,11 +524,11 @@ module ariane
assign tracer_if.commit_instr = commit_instr_id_commit;
assign tracer_if.commit_ack = commit_ack;
// address translation
// assign tracer_if.vaddress_valid = ex_stage_i.lsu_i.mmu_i.lsu_valid_o
assign tracer_if.lsu_valid = ex_stage_i.lsu_i.lsu_valid_i;
assign tracer_if.translation_valid = ex_stage_i.lsu_i.mmu_i.lsu_valid_o;
assign tracer_if.vaddr = ex_stage_i.lsu_i.mmu_i.lsu_vaddr_i;
assign tracer_if.vaddr = ex_stage_i.lsu_i.vaddr_i;
assign tracer_if.paddr = ex_stage_i.lsu_i.mmu_i.lsu_paddr_o;
assign tracer_if.is_store = ex_stage_i.lsu_i.mmu_i.lsu_is_store_i;
assign tracer_if.is_store = ex_stage_i.lsu_i.mmu_i.lsu_is_store_i; // was this translation a store
assign tracer_if.st_ready = ex_stage_i.lsu_i.store_unit_i.ready_o;
assign tracer_if.ld_ready = ex_stage_i.lsu_i.load_unit_i.ready_o;
// exceptions

View file

@ -96,11 +96,17 @@ module decoder (
instruction_o.op = SRET;
// check privilege level, SRET can only be executed in S and M mode
// we'll just decode an illegal instruction if we are in the wrong privilege level
if (priv_lvl_i == PRIV_LVL_U)
if (priv_lvl_i == PRIV_LVL_U) begin
illegal_instr = 1'b1;
// do not change privilege level if this is an illegal instruction
instruction_o.op = ADD;
end
// if we are in S-Mode and Trap SRET (tsr) is set -> trap on illegal instruction
if (priv_lvl_i == PRIV_LVL_S && tsr_i)
if (priv_lvl_i == PRIV_LVL_S && tsr_i) begin
illegal_instr = 1'b1;
// do not change privilege level if this is an illegal instruction
instruction_o.op = ADD;
end
end
// MRET
12'b1100000010: begin

View file

@ -38,7 +38,6 @@ module load_unit (
output logic translation_req_o, // request address translation
output logic [63:0] vaddr_o, // virtual address out
input logic [63:0] paddr_i, // physical address in
input logic translation_valid_i,
input exception ex_i, // exception which may has happened earlier. for example: mis-aligned exception
input logic dtlb_hit_i, // hit on the dtlb, send in the same cycle as the request
// address checker
@ -240,8 +239,14 @@ module load_unit (
trans_id_o = load_data_q.trans_id;
// we got an rvalid and are currently not flushing and not aborting the request
if (data_rvalid_i && CS != WAIT_FLUSH) begin
valid_o = 1'b1;
// we killed the request
if(!kill_req_o)
valid_o = 1'b1;
// the output is also valid if we got an exception
if (ex_i.valid)
valid_o = 1'b1;
end
end

View file

@ -119,8 +119,6 @@ module lsu #(
logic [63:0] st_vaddr;
logic translation_req;
logic translation_valid;
logic translation_valid_st;
logic translation_valid_ld;
logic [63:0] mmu_vaddr;
logic [63:0] mmu_paddr;
exception mmu_exception;
@ -237,7 +235,6 @@ module lsu #(
.translation_req_o ( st_translation_req ),
.vaddr_o ( st_vaddr ),
.paddr_i ( mmu_paddr ),
.translation_valid_i ( translation_valid_st ),
.ex_i ( mmu_exception ),
.dtlb_hit_i ( dtlb_hit ),
// Load Unit
@ -275,7 +272,6 @@ module lsu #(
.translation_req_o ( ld_translation_req ),
.vaddr_o ( ld_vaddr ),
.paddr_i ( mmu_paddr ),
.translation_valid_i ( translation_valid_ld ),
.ex_i ( mmu_exception ),
.dtlb_hit_i ( dtlb_hit ),
// to store unit
@ -326,22 +322,6 @@ module lsu #(
// the LSU is ready if both, stores and loads are ready because we do not know
// which of the two we are getting
lsu_ready_o = ld_ready_o && st_ready_o;
// "arbitrate" MMU access
// translation_req = 1'b0;
// mmu_vaddr = 64'b0;
// translation_valid_st = 1'b0;
// translation_valid_ld = 1'b0;
// // this arbitrates access to the MMU
// if (ld_translation_req) begin
// translation_req = ld_translation_req;
// mmu_vaddr = ld_vaddr;
// translation_valid_ld = translation_valid;
// end else begin
// translation_req = st_translation_req;
// mmu_vaddr = st_vaddr;
// translation_valid_st = translation_valid;
// end
end
// determine whether this is a load or store
@ -352,8 +332,6 @@ module lsu #(
translation_req = 1'b0;
mmu_vaddr = 64'b0;
translation_valid_st = 1'b0;
translation_valid_ld = 1'b0;
// check the operator to activate the right functional unit accordingly
unique case (fu)
@ -362,14 +340,12 @@ module lsu #(
ld_valid_i = valid;
translation_req = ld_translation_req;
mmu_vaddr = ld_vaddr;
translation_valid_ld = translation_valid;
end
// all stores go here
STORE: begin
st_valid_i = valid;
translation_req = st_translation_req;
mmu_vaddr = st_vaddr;
translation_valid_st = translation_valid;
end
// not relevant for the LSU
default: ;

View file

@ -43,7 +43,7 @@ module lsu_arbiter (
// it unconditionally posts the result on its output ports and expects it to be consumed.
// 4 entries is enough to unconditionally post loads and stores since we can only have two outstanding loads
localparam int WIDTH = 4;
localparam int WIDTH = 2;
// queue pointer
logic [$clog2(WIDTH)-1:0] read_pointer_n, read_pointer_q;

View file

@ -41,7 +41,6 @@ module store_unit (
output logic translation_req_o, // request address translation
output logic [63:0] vaddr_o, // virtual address out
input logic [63:0] paddr_i, // physical address in
input logic translation_valid_i,
input exception ex_i,
input logic dtlb_hit_i, // will be one in the same cycle translation_req was asserted if it hits
// address checker
@ -160,7 +159,7 @@ module store_unit (
// Access Exception
// -----------------
// we got an address translation exception (access rights, misaligned or page fault)
if (ex_i.valid) begin
if (ex_i.valid && (CS != IDLE)) begin
// the only difference is that we do not want to store this request
st_valid = 1'b0;
NS = IDLE;

View file

@ -82,7 +82,8 @@ class instruction_tracer;
// --------------------
// Address Translation
// --------------------
if (tracer_if.pck.translation_valid) begin
// we've got a LSU request
if (tracer_if.pck.lsu_valid) begin
// put it in the store mapping queue if it is a store
if (tracer_if.pck.is_store && tracer_if.pck.st_ready) begin
store_mapping.push_back('{
@ -98,6 +99,22 @@ class instruction_tracer;
end
end
if (tracer_if.pck.translation_valid) begin
// put it in the store mapping queue if it is a store
// if (tracer_if.pck.is_store && tracer_if.pck.st_ready) begin
// store_mapping.push_back('{
// vaddr: tracer_if.pck.vaddr,
// paddr: tracer_if.pck.paddr
// });
// // or else put it in the load mapping
// end else if (!tracer_if.pck.is_store && tracer_if.pck.ld_ready) begin
// load_mapping.push_back('{
// vaddr: tracer_if.pck.vaddr,
// paddr: tracer_if.pck.paddr
// });
// end
end
// --------------
// Commit
// --------------

View file

@ -40,6 +40,7 @@ interface instruction_tracer_if (
scoreboard_entry commit_instr; // commit instruction
logic commit_ack;
// address translation
logic lsu_valid;
logic translation_valid;
logic [63:0] vaddr;
logic [63:0] paddr;
@ -50,7 +51,7 @@ interface instruction_tracer_if (
exception exception;
// the tracer just has a passive interface we do not drive anything with it
clocking pck @(posedge clk);
input rstn, flush_unissued, flush, fetch, fetch_valid, fetch_ack, issue_ack, issue_sbe, waddr,
input rstn, flush_unissued, flush, fetch, fetch_valid, fetch_ack, issue_ack, issue_sbe, waddr, lsu_valid,
wdata, we, commit_instr, commit_ack, translation_valid, vaddr, paddr, is_store, st_ready, ld_ready, exception;
endclocking

View file

@ -24,7 +24,6 @@ add wave -noupdate -group ex_stage -group lsu -group mem_arbiter -group arbiter_
add wave -noupdate -group ex_stage -group lsu -group store_unit /core_tb/dut/ex_stage_i/lsu_i/store_unit_i/*
add wave -noupdate -group ex_stage -group lsu -group store_unit -group store_queue /core_tb/dut/ex_stage_i/lsu_i/store_unit_i/store_queue_i/*
add wave -noupdate -group ex_stage -group lsu -group load_unit /core_tb/dut/ex_stage_i/lsu_i/load_unit_i/*
add wave -noupdate -group ex_stage -group lsu -group load_unit -group fifo /core_tb/dut/ex_stage_i/lsu_i/load_unit_i/fifo_i/*
add wave -noupdate -group ex_stage -group lsu -group lsu_arbiter /core_tb/dut/ex_stage_i/lsu_i/lsu_arbiter_i/*
add wave -noupdate -group ex_stage -group branch_unit /core_tb/dut/ex_stage_i/branch_unit_i/*
add wave -noupdate -group ex_stage -group csr_buffer /core_tb/dut/ex_stage_i/csr_buffer_i/*