diff --git a/openpiton/ariane_verilog_wrap.sv b/openpiton/ariane_verilog_wrap.sv index c01af03336eba2e1154b28609e0c2f4ea0f10158..c1e5833d0b66e0339aad54bb16556d3f183c1e59 100644 --- a/openpiton/ariane_verilog_wrap.sv +++ b/openpiton/ariane_verilog_wrap.sv @@ -23,9 +23,9 @@ module ariane_verilog_wrap #( parameter bit SwapEndianess = 1, // PMA configuration // idempotent region - parameter int unsigned NrNonIdempotentRules = 0, - parameter logic [NrMaxRules*64-1:0] NonIdempotentAddrBase = '0, - parameter logic [NrMaxRules*64-1:0] NonIdempotentLength = '0, + parameter int unsigned NrNonIdempotentRules = 1, + parameter logic [NrMaxRules*64-1:0] NonIdempotentAddrBase = 64'h00C0000000, + parameter logic [NrMaxRules*64-1:0] NonIdempotentLength = 64'hFFFFFFFFFF, // executable regions parameter int unsigned NrExecuteRegionRules = 0, parameter logic [NrMaxRules*64-1:0] ExecuteRegionAddrBase = '0, diff --git a/src/ariane.sv b/src/ariane.sv index 7a4fb395509e2016c079ad300410f5d365e1b117..17e8a4330c9377a673656ed022d0d8677a9a4b66 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -231,6 +231,7 @@ module ariane import ariane_pkg::*; #( dcache_req_i_t [2:0] dcache_req_ports_ex_cache; dcache_req_o_t [2:0] dcache_req_ports_cache_ex; logic dcache_commit_wbuffer_empty; + logic dcache_commit_wbuffer_not_ni; // -------------- // Frontend @@ -428,6 +429,7 @@ module ariane import ariane_pkg::*; #( .dcache_req_ports_i ( dcache_req_ports_cache_ex ), .dcache_req_ports_o ( dcache_req_ports_ex_cache ), .dcache_wbuffer_empty_i ( dcache_commit_wbuffer_empty ), + .dcache_wbuffer_not_ni_i ( dcache_commit_wbuffer_not_ni ), // PMP .pmpcfg_i ( pmpcfg ), .pmpaddr_i ( pmpaddr ) @@ -626,6 +628,7 @@ module ariane import ariane_pkg::*; #( .dcache_req_ports_o ( dcache_req_ports_cache_ex ), // write buffer status .wbuffer_empty_o ( dcache_commit_wbuffer_empty ), + .wbuffer_not_ni_o ( dcache_commit_wbuffer_not_ni ), `ifdef PITON_ARIANE .l15_req_o ( l15_req_o ), .l15_rtrn_i ( l15_rtrn_i ) @@ -672,6 +675,7 @@ module ariane import ariane_pkg::*; #( .axi_req_o ( axi_req_o ), .axi_resp_i ( axi_resp_i ) ); + assign dcache_commit_wbuffer_not_ni = 1'b1; `endif // ------------------- diff --git a/src/cache_subsystem/wt_cache_subsystem.sv b/src/cache_subsystem/wt_cache_subsystem.sv index 199a2c81ba37a71babccf7c3e68f26f0beee21c6..5a0662dc4c2efa9bcc4fc34ebc15c0b6b2cc000c 100644 --- a/src/cache_subsystem/wt_cache_subsystem.sv +++ b/src/cache_subsystem/wt_cache_subsystem.sv @@ -48,6 +48,7 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #( output dcache_req_o_t [2:0] dcache_req_ports_o, // to/from LSU // writebuffer status output logic wbuffer_empty_o, + output logic wbuffer_not_ni_o, `ifdef PITON_ARIANE // L15 (memory side) output l15_req_t l15_req_o, @@ -108,6 +109,7 @@ module wt_cache_subsystem import ariane_pkg::*; import wt_cache_pkg::*; #( .flush_ack_o ( dcache_flush_ack_o ), .miss_o ( dcache_miss_o ), .wbuffer_empty_o ( wbuffer_empty_o ), + .wbuffer_not_ni_o ( wbuffer_not_ni_o ), .amo_req_i ( dcache_amo_req_i ), .amo_resp_o ( dcache_amo_resp_o ), .req_ports_i ( dcache_req_ports_i ), diff --git a/src/cache_subsystem/wt_dcache.sv b/src/cache_subsystem/wt_dcache.sv index ed160292447a4445ccf23e54b9ce1345bbee25a0..28e1d4a194a6e053f586a8081af6c269c2a0d0f8 100644 --- a/src/cache_subsystem/wt_dcache.sv +++ b/src/cache_subsystem/wt_dcache.sv @@ -29,6 +29,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #( output logic flush_ack_o, // send a single cycle acknowledge signal when the cache is flushed output logic miss_o, // we missed on a ld/st output logic wbuffer_empty_o, + output logic wbuffer_not_ni_o, // AMO interface input amo_req_t amo_req_i, @@ -214,6 +215,7 @@ module wt_dcache import ariane_pkg::*; import wt_cache_pkg::*; #( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .empty_o ( wbuffer_empty_o ), + .not_ni_o ( wbuffer_not_ni_o ), // TODO: fix this .cache_en_i ( cache_en ), // .cache_en_i ( '0 ), diff --git a/src/cache_subsystem/wt_dcache_ctrl.sv b/src/cache_subsystem/wt_dcache_ctrl.sv index 55945942be9ab323f3b321d28fb00b30218bdd75..225487039b11d7a54fe4113b460a6580303efb6b 100644 --- a/src/cache_subsystem/wt_dcache_ctrl.sv +++ b/src/cache_subsystem/wt_dcache_ctrl.sv @@ -112,6 +112,7 @@ module wt_dcache_ctrl import ariane_pkg::*; import wt_cache_pkg::*; #( IDLE: begin if (req_port_i.data_req) begin rd_req_o = 1'b1; + // if read ack then ack the `req_port_o`, and goto `READ` state if (rd_ack_i) begin state_d = READ; req_port_o.data_gnt = 1'b1; diff --git a/src/cache_subsystem/wt_dcache_missunit.sv b/src/cache_subsystem/wt_dcache_missunit.sv index 10dca1231c6d86eb557fe6a2852789d3a69c23e3..ae1f7a1e9b8389749ba878878a18826cda210106 100644 --- a/src/cache_subsystem/wt_dcache_missunit.sv +++ b/src/cache_subsystem/wt_dcache_missunit.sv @@ -184,7 +184,7 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #( end // read/write collision, stalls the corresponding request - // write collides with MSHR + // write port[NumPorts-1] collides with MSHR_Q assign mshr_rdwr_collision = (mshr_q.paddr[riscv::PLEN-1:DCACHE_OFFSET_WIDTH] == miss_paddr_i[NumPorts-1][riscv::PLEN-1:DCACHE_OFFSET_WIDTH]) && mshr_vld_q; // read collides with inflight TX @@ -341,7 +341,7 @@ module wt_dcache_missunit import ariane_pkg::*; import wt_cache_pkg::*; #( assign wr_cl_data_o = mem_rtrn_i.data; assign wr_cl_data_be_o = (cl_write_en) ? '1 : '0;// we only write complete cachelines into the memory - // only NC responses write to the cache + // only non-NC responses write to the cache assign cl_write_en = load_ack & ~mshr_q.nc; /////////////////////////////////////////////////////// diff --git a/src/cache_subsystem/wt_dcache_wbuffer.sv b/src/cache_subsystem/wt_dcache_wbuffer.sv index c5a82bf014d49049373bce9c8a82115c14d74fdd..e87d8d85d227110f5874b7737591a6e7b1ef1351 100644 --- a/src/cache_subsystem/wt_dcache_wbuffer.sv +++ b/src/cache_subsystem/wt_dcache_wbuffer.sv @@ -57,6 +57,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( input logic cache_en_i, // writes are treated as NC if disabled output logic empty_o, // asserted if no data is present in write buffer + output logic not_ni_o, // asserted if no ni data is present in write buffer // core request ports input dcache_req_i_t req_port_i, output dcache_req_o_t req_port_o, @@ -118,7 +119,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( logic check_en_d, check_en_q, check_en_q1; logic full, dirty_rd_en, rdy; logic rtrn_empty, evict; - logic nc_pending_d, nc_pending_q, addr_is_nc; + logic [DCACHE_WBUF_DEPTH-1:0] ni_pending_d, ni_pending_q; logic wbuffer_wren; logic free_tx_slots; @@ -132,11 +133,14 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( /////////////////////////////////////////////////////// // misc /////////////////////////////////////////////////////// - - assign miss_nc_o = nc_pending_q; - - // noncacheable if request goes to I/O space, or if cache is disabled - assign addr_is_nc = (~cache_en_i) | (~ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH{1'b0}}, req_port_i.address_tag, {DCACHE_INDEX_WIDTH{1'b0}}})); + logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] miss_tag; + logic is_nc_miss; + logic is_ni; + assign miss_tag = miss_paddr_o[ariane_pkg::DCACHE_INDEX_WIDTH+:ariane_pkg::DCACHE_TAG_WIDTH]; + assign is_nc_miss = !ariane_pkg::is_inside_cacheable_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH{1'b0}}, miss_tag, {DCACHE_INDEX_WIDTH{1'b0}}}); + assign miss_nc_o = !cache_en_i || is_nc_miss; + // Non-idempotent if request goes to NI region + assign is_ni = ariane_pkg::is_inside_nonidempotent_regions(ArianeCfg, {{64-DCACHE_TAG_WIDTH{1'b0}}, req_port_i.address_tag, {DCACHE_INDEX_WIDTH{1'b0}}}); assign miss_we_o = 1'b1; assign miss_vld_bits_o = '0; @@ -322,7 +326,6 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( end assign wr_ptr = (|wbuffer_hit_oh) ? hit_ptr : next_ptr; - assign empty_o = ~(|valid); assign rdy = (|wbuffer_hit_oh) | (~full); // next free entry in the buffer @@ -388,11 +391,17 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( assign req_port_o.data_rdata = '0; assign rd_hit_oh_d = rd_hit_oh_i; + + logic ni_inside,ni_conflict; + assign ni_inside = |ni_pending_q; + assign ni_conflict = is_ni && ni_inside; + assign not_ni_o = !ni_inside; + assign empty_o = !(|valid); // TODO: rewrite and separate into MUXES and write strobe logic always_comb begin : p_buffer wbuffer_d = wbuffer_q; - nc_pending_d = nc_pending_q; + ni_pending_d = ni_pending_q; dirty_rd_en = 1'b0; req_port_o.data_gnt = 1'b0; wbuffer_wren = 1'b0; @@ -431,6 +440,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( // if all bytes are evicted, clear the cache status flag if (wbuffer_d[rtrn_ptr].valid == 0) begin wbuffer_d[rtrn_ptr].checked = 1'b0; + ni_pending_d[rtrn_ptr] = 1'b0; end end @@ -447,13 +457,13 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( // write new word into the buffer if (req_port_i.data_req && rdy) begin - // in case we have an NC address, need to drain the buffer first - // in case we are serving an NC address, we block until it is written to memory - if (empty_o || !(addr_is_nc || nc_pending_q)) begin + // in case we have an NI address, need to drain the buffer first + // in case we are serving an NI address, we block until it is written to memory + if (!ni_conflict) begin //empty of NI operations wbuffer_wren = 1'b1; req_port_o.data_gnt = 1'b1; - nc_pending_d = addr_is_nc; + ni_pending_d[wr_ptr] = is_ni; wbuffer_d[wr_ptr].checked = 1'b0; wbuffer_d[wr_ptr].wtag = {req_port_i.address_tag, req_port_i.address_index[DCACHE_INDEX_WIDTH-1:3]}; @@ -479,7 +489,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( if (!rst_ni) begin wbuffer_q <= '{default: '0}; tx_stat_q <= '{default: '0}; - nc_pending_q <= '0; + ni_pending_q <= '0; check_ptr_q <= '0; check_ptr_q1 <= '0; check_en_q <= '0; @@ -491,7 +501,7 @@ module wt_dcache_wbuffer import ariane_pkg::*; import wt_cache_pkg::*; #( end else begin wbuffer_q <= wbuffer_d; tx_stat_q <= tx_stat_d; - nc_pending_q <= nc_pending_d; + ni_pending_q <= ni_pending_d; check_ptr_q <= check_ptr_d; check_ptr_q1 <= check_ptr_q; check_en_q <= check_en_d; diff --git a/src/ex_stage.sv b/src/ex_stage.sv index f3a401c4017158d8031ca18fd1ab7f2521a70fb0..4806002f33c2351f04c8dd25598033f8d67006de 100644 --- a/src/ex_stage.sv +++ b/src/ex_stage.sv @@ -94,6 +94,7 @@ module ex_stage import ariane_pkg::*; #( input dcache_req_o_t [2:0] dcache_req_ports_i, output dcache_req_i_t [2:0] dcache_req_ports_o, input logic dcache_wbuffer_empty_i, + input logic dcache_wbuffer_not_ni_i, output amo_req_t amo_req_o, // request to cache subsytem input amo_resp_t amo_resp_i, // response from cache subsystem // Performance counters @@ -297,6 +298,7 @@ module ex_stage import ariane_pkg::*; #( .dcache_req_ports_i, .dcache_req_ports_o, .dcache_wbuffer_empty_i, + .dcache_wbuffer_not_ni_i, .amo_valid_commit_i, .amo_req_o, .amo_resp_i, diff --git a/src/load_store_unit.sv b/src/load_store_unit.sv index d9edec96e8627f7509c368c793da2e485f31bb19..fe4e3003ac18556201080d92475870515227ac3f 100644 --- a/src/load_store_unit.sv +++ b/src/load_store_unit.sv @@ -63,6 +63,7 @@ module load_store_unit import ariane_pkg::*; #( input dcache_req_o_t [2:0] dcache_req_ports_i, output dcache_req_i_t [2:0] dcache_req_ports_o, input logic dcache_wbuffer_empty_i, + input logic dcache_wbuffer_not_ni_i, // AMO interface output amo_req_t amo_req_o, input amo_resp_t amo_resp_i, @@ -108,6 +109,7 @@ module load_store_unit import ariane_pkg::*; #( logic [riscv::PLEN-1:0] mmu_paddr; exception_t mmu_exception; logic dtlb_hit; + logic [riscv::PLEN-13:0] dtlb_ppn; logic ld_valid; logic [TRANS_ID_BITS-1:0] ld_trans_id; @@ -141,6 +143,7 @@ module load_store_unit import ariane_pkg::*; #( .lsu_paddr_o ( mmu_paddr ), .lsu_exception_o ( mmu_exception ), .lsu_dtlb_hit_o ( dtlb_hit ), // send in the same cycle as the request + .lsu_dtlb_ppn_o ( dtlb_ppn ), // send in the same cycle as the request // connecting PTW to D$ IF .req_port_i ( dcache_req_ports_i [0] ), .req_port_o ( dcache_req_ports_o [0] ), @@ -210,6 +213,7 @@ module load_store_unit import ariane_pkg::*; #( .paddr_i ( mmu_paddr ), .ex_i ( mmu_exception ), .dtlb_hit_i ( dtlb_hit ), + .dtlb_ppn_i ( dtlb_ppn ), // to store unit .page_offset_o ( page_offset ), .page_offset_matches_i ( page_offset_matches ), @@ -217,7 +221,7 @@ module load_store_unit import ariane_pkg::*; #( // to memory arbiter .req_port_i ( dcache_req_ports_i [1] ), .req_port_o ( dcache_req_ports_o [1] ), - .dcache_wbuffer_empty_i, + .dcache_wbuffer_not_ni_i, .commit_tran_id_i, .* ); diff --git a/src/load_unit.sv b/src/load_unit.sv index ee1493d3745e1d0c9f83a0a2e7de89160c3426db..84e9b10cfdd4b5c7ca4c21b71eb4b4f3657e4d4c 100644 --- a/src/load_unit.sv +++ b/src/load_unit.sv @@ -34,6 +34,7 @@ module load_unit import ariane_pkg::*; #( input logic [riscv::PLEN-1:0] paddr_i, // physical address in input exception_t 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 + input logic [riscv::PLEN-13:0] dtlb_ppn_i, // ppn on the dtlb, send in the same cycle as the request // address checker output logic [11:0] page_offset_o, input logic page_offset_matches_i, @@ -42,10 +43,10 @@ module load_unit import ariane_pkg::*; #( // D$ interface input dcache_req_o_t req_port_i, output dcache_req_i_t req_port_o, - input logic dcache_wbuffer_empty_i + input logic dcache_wbuffer_not_ni_i ); enum logic [3:0] { IDLE, WAIT_GNT, SEND_TAG, WAIT_PAGE_OFFSET, - ABORT_TRANSACTION, ABORT_TRANSACTION_NC, WAIT_TRANSLATION, WAIT_FLUSH, + ABORT_TRANSACTION, ABORT_TRANSACTION_NI, WAIT_TRANSLATION, WAIT_FLUSH, WAIT_WB_EMPTY } state_d, state_q; // in order to decouple the response interface from the request interface we need a @@ -75,13 +76,15 @@ module load_unit import ariane_pkg::*; #( // directly output an exception assign ex_o = ex_i; - logic stall_nc; // stall because of non-empty WB and address within non-cacheable region. - // should we stall the request e.g.: is it withing a non-cacheable region - // and the write buffer (in the cache and in the core) is not empty so that we don't forward anything - // from the write buffer (e.g. it would essentially be cached). - assign stall_nc = (~(dcache_wbuffer_empty_i | store_buffer_empty_i) & is_inside_cacheable_regions(ArianeCfg, paddr_i)) - // this guards the load to be executed non-speculatively (we wait until our transaction id is on port 0 - | (commit_tran_id_i != lsu_ctrl_i.trans_id & is_inside_nonidempotent_regions(ArianeCfg, paddr_i)); + // Check that NI operations follow the necessary conditions + logic paddr_ni; + logic not_commit_time; + logic inflight_stores; + logic stall_ni; + assign paddr_ni = is_inside_nonidempotent_regions(ArianeCfg, {dtlb_ppn_i,12'd0}); + assign not_commit_time = commit_tran_id_i != lsu_ctrl_i.trans_id; + assign inflight_stores = (!dcache_wbuffer_not_ni_i || !store_buffer_empty_i); + assign stall_ni = (inflight_stores || not_commit_time) && paddr_ni; // --------------- // Load Control @@ -114,14 +117,14 @@ module load_unit import ariane_pkg::*; #( if (!req_port_i.data_gnt) begin state_d = WAIT_GNT; end else begin - if (dtlb_hit_i && !stall_nc) begin + if (dtlb_hit_i && !stall_ni) begin // we got a grant and a hit on the DTLB so we can send the tag in the next cycle state_d = SEND_TAG; pop_ld_o = 1'b1; // translation valid but this is to NC and the WB is not yet empty. - end else if (dtlb_hit_i && stall_nc) begin - state_d = ABORT_TRANSACTION_NC; - end else begin + end else if (dtlb_hit_i && stall_ni) begin + state_d = ABORT_TRANSACTION_NI; + end else begin // TLB miss state_d = ABORT_TRANSACTION; end end @@ -143,17 +146,17 @@ module load_unit import ariane_pkg::*; #( // abort the previous request - free the D$ arbiter // we are here because of a TLB miss, we need to abort the current request and give way for the // PTW walker to satisfy the TLB miss - ABORT_TRANSACTION, ABORT_TRANSACTION_NC: begin + ABORT_TRANSACTION, ABORT_TRANSACTION_NI: begin req_port_o.kill_req = 1'b1; req_port_o.tag_valid = 1'b1; // either re-do the request or wait until the WB is empty (depending on where we came from). - state_d = (state_q == ABORT_TRANSACTION_NC) ? WAIT_WB_EMPTY : WAIT_TRANSLATION; + state_d = (state_q == ABORT_TRANSACTION_NI) ? WAIT_WB_EMPTY : WAIT_TRANSLATION; end // Wait until the write-back buffer is empty in the data cache. WAIT_WB_EMPTY: begin // the write buffer is empty, so lets go and re-do the translation. - if (dcache_wbuffer_empty_i) state_d = WAIT_TRANSLATION; + if (dcache_wbuffer_not_ni_i) state_d = WAIT_TRANSLATION; end WAIT_TRANSLATION: begin @@ -171,12 +174,12 @@ module load_unit import ariane_pkg::*; #( // we finally got a data grant if (req_port_i.data_gnt) begin // so we send the tag in the next cycle - if (dtlb_hit_i && !stall_nc) begin + if (dtlb_hit_i && !stall_ni) begin state_d = SEND_TAG; pop_ld_o = 1'b1; // translation valid but this is to NC and the WB is not yet empty. - end else if (dtlb_hit_i && stall_nc) begin - state_d = ABORT_TRANSACTION_NC; + end else if (dtlb_hit_i && stall_ni) begin + state_d = ABORT_TRANSACTION_NI; end else begin // should we not have hit on the TLB abort this transaction an retry later state_d = ABORT_TRANSACTION; @@ -202,13 +205,13 @@ module load_unit import ariane_pkg::*; #( state_d = WAIT_GNT; end else begin // we got a grant so we can send the tag in the next cycle - if (dtlb_hit_i && !stall_nc) begin + if (dtlb_hit_i && !stall_ni) begin // we got a grant and a hit on the DTLB so we can send the tag in the next cycle state_d = SEND_TAG; pop_ld_o = 1'b1; // translation valid but this is to NC and the WB is not yet empty. - end else if (dtlb_hit_i && stall_nc) begin - state_d = ABORT_TRANSACTION_NC; + end else if (dtlb_hit_i && stall_ni) begin + state_d = ABORT_TRANSACTION_NI; end else begin state_d = ABORT_TRANSACTION;// we missed on the TLB -> wait for the translation end diff --git a/src/mmu.sv b/src/mmu.sv index 6890c9a747ec2f404f476bd66aa12053aced4e50..768425ad57317641ef288cde1b2e60c38321166c 100644 --- a/src/mmu.sv +++ b/src/mmu.sv @@ -39,6 +39,7 @@ module mmu import ariane_pkg::*; #( // if we need to walk the page table we can't grant in the same cycle // Cycle 0 output logic lsu_dtlb_hit_o, // sent in the same cycle as the request if translation hits in the DTLB + output logic [riscv::PLEN-13:0] lsu_dtlb_ppn_o, // ppn (send same cycle as hit) // Cycle 1 output logic lsu_valid_o, // translation is valid output logic [riscv::PLEN-1:0] lsu_paddr_o, // translated address @@ -308,6 +309,7 @@ module mmu import ariane_pkg::*; #( dtlb_is_1G_n = dtlb_is_1G; lsu_paddr_o = lsu_vaddr_q[riscv::PLEN-1:0]; + lsu_dtlb_ppn_o = lsu_vaddr_n[riscv::PLEN-1:12]; lsu_valid_o = lsu_req_q; lsu_exception_o = misaligned_ex_q; pmp_access_type = lsu_is_store_q ? riscv::ACCESS_WRITE : riscv::ACCESS_READ; @@ -324,13 +326,16 @@ module mmu import ariane_pkg::*; #( lsu_valid_o = 1'b0; // 4K page lsu_paddr_o = {dtlb_pte_q.ppn, lsu_vaddr_q[11:0]}; + lsu_dtlb_ppn_o = dtlb_content.ppn; // Mega page if (dtlb_is_2M_q) begin lsu_paddr_o[20:12] = lsu_vaddr_q[20:12]; + lsu_dtlb_ppn_o[20:12] = lsu_vaddr_n[20:12]; end // Giga page if (dtlb_is_1G_q) begin lsu_paddr_o[29:12] = lsu_vaddr_q[29:12]; + lsu_dtlb_ppn_o[29:12] = lsu_vaddr_n[29:12]; end // --------- // DTLB Hit