diff --git a/src/lsu.sv b/src/lsu.sv index cb70d5f93..f46a8fab9 100644 --- a/src/lsu.sv +++ b/src/lsu.sv @@ -120,6 +120,8 @@ 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; @@ -234,7 +236,7 @@ module lsu #( .translation_req_o ( st_translation_req ), .vaddr_o ( st_vaddr ), .paddr_i ( mmu_paddr ), - .translation_valid_i ( translation_valid ), + .translation_valid_i ( translation_valid_st ), .ex_i ( mmu_exception ), // Load Unit .page_offset_i ( page_offset ), @@ -271,7 +273,7 @@ module lsu #( .translation_req_o ( ld_translation_req ), .vaddr_o ( ld_vaddr ), .paddr_i ( mmu_paddr ), - .translation_valid_i ( translation_valid ), + .translation_valid_i ( translation_valid_ld ), .ex_i ( mmu_exception ), // to store unit .page_offset_o ( page_offset ), @@ -321,16 +323,21 @@ 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, there is only one request possible - translation_req = 1'b0; - mmu_vaddr = 64'b0; + // "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 (st_translation_req) begin - translation_req = 1'b1; - mmu_vaddr = st_vaddr; + translation_req = 1'b1; + mmu_vaddr = st_vaddr; + translation_valid_st = translation_valid; end else if (ld_translation_req) begin - translation_req = 1'b1; - mmu_vaddr = ld_vaddr; + translation_req = 1'b1; + mmu_vaddr = ld_vaddr; + translation_valid_ld = translation_valid; end end diff --git a/src/store_unit.sv b/src/store_unit.sv index 825bbcc80..8b02f0bdb 100644 --- a/src/store_unit.sv +++ b/src/store_unit.sv @@ -69,7 +69,13 @@ module store_unit ( logic st_ready; logic st_valid; - assign vaddr_o = vaddr_i; + // vaddr and valid signal one cycle later + logic [63:0] vaddr_n, vaddr_q; + logic valid_n, valid_q; + logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q; + + assign vaddr_o = vaddr_q; + assign trans_id_o = trans_id_q; // --------------- // Store Control // --------------- @@ -77,11 +83,10 @@ module store_unit ( translation_req_o = 1'b0; valid_o = 1'b0; ready_o = 1'b1; - trans_id_o = trans_id_i; ex_o = ex_i; st_valid = 1'b0; // we got a valid store - if (valid_i) begin + if (valid_q) begin // first do address translation, we need to do it in the first cycle since we want to share the MMU // between the load and the store unit. But we only know that when a new request arrives that we are not using // it at the same time. @@ -92,19 +97,43 @@ module store_unit ( valid_o = 1'b1; // post this store to the store buffer st_valid = 1'b1; + // ----------------- + // Access Exception + // ----------------- + // we got an address translation exception (access rights) + // this will also assert the translation valid + if (ex_i.valid) begin + // the only difference is that we do not want to store this request + st_valid = 1'b0; + end // translation was not successful - stall here end else begin ready_o = 1'b0; end - // ----------------- - // Access Exception - // ----------------- - // we got an address translation exception (access rights) - // this will also assert the translation valid - if (ex_i.valid) begin - // the only difference is that we do not want to store this request - st_valid = 1'b0; - end + end + end + // Store 2nd register stage + always_comb begin + vaddr_n = vaddr_q; + valid_n = valid_q; + trans_id_n = trans_id_n; + + if (ready_o) begin + vaddr_n = vaddr_i; + valid_n = valid_i; + trans_id_n = trans_id_i; + end + end + // Sequential Process for 2nd register stage + always_ff @(posedge clk_i or negedge rst_ni) begin + if(~rst_ni) begin + vaddr_q <= '0; + valid_q <= 1'b0; + trans_id_q <= '0; + end else begin + vaddr_q <= vaddr_n; + valid_q <= valid_n; + trans_id_q <= trans_id_n; end end // -----------