diff --git a/Makefile b/Makefile index d7958d51f..cbab5c45b 100644 --- a/Makefile +++ b/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 diff --git a/src/ariane.sv b/src/ariane.sv index 2ae720df3..14ed7e66d 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -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 diff --git a/src/decoder.sv b/src/decoder.sv index 0a807509e..4075308a8 100644 --- a/src/decoder.sv +++ b/src/decoder.sv @@ -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 diff --git a/src/load_unit.sv b/src/load_unit.sv index 3fc9cfce0..086d46284 100644 --- a/src/load_unit.sv +++ b/src/load_unit.sv @@ -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 diff --git a/src/lsu.sv b/src/lsu.sv index 21008bce9..e7497937f 100644 --- a/src/lsu.sv +++ b/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: ; diff --git a/src/lsu_arbiter.sv b/src/lsu_arbiter.sv index 76a5894a9..8e62facb4 100644 --- a/src/lsu_arbiter.sv +++ b/src/lsu_arbiter.sv @@ -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; diff --git a/src/store_unit.sv b/src/store_unit.sv index aa8ca423a..bf9330b2b 100644 --- a/src/store_unit.sv +++ b/src/store_unit.sv @@ -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; diff --git a/src/util/instruction_tracer.svh b/src/util/instruction_tracer.svh index a1fff4037..d2455efe3 100755 --- a/src/util/instruction_tracer.svh +++ b/src/util/instruction_tracer.svh @@ -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 // -------------- diff --git a/src/util/instruction_tracer_if.sv b/src/util/instruction_tracer_if.sv index c805037b0..0453f2e60 100755 --- a/src/util/instruction_tracer_if.sv +++ b/src/util/instruction_tracer_if.sv @@ -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 diff --git a/tb/wave/wave_core.do b/tb/wave/wave_core.do index 569cc0886..b2c51b2f9 100644 --- a/tb/wave/wave_core.do +++ b/tb/wave/wave_core.do @@ -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/*