mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 05:07:21 -04:00
🐛 Fix exception not taken problem
This commit is contained in:
parent
fc7969b385
commit
773efe42a8
10 changed files with 43 additions and 39 deletions
5
Makefile
5
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
24
src/lsu.sv
24
src/lsu.sv
|
@ -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: ;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
// --------------
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue