From: Luke Kenneth Casson Leighton Date: Sun, 21 Apr 2019 06:34:43 +0000 (+0100) Subject: begin experimental ariane mmu.sv conversion X-Git-Tag: div_pipeline~2211 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e373287c5acedff52f3f3ca0b9449fd4407f8a38;p=soc.git begin experimental ariane mmu.sv conversion --- diff --git a/TLB/src/ariane/mmu.py b/TLB/src/ariane/mmu.py index d85abc9f..5a530154 100644 --- a/TLB/src/ariane/mmu.py +++ b/TLB/src/ariane/mmu.py @@ -19,7 +19,9 @@ import ariane_pkg::*; """ from nmigen import Const, Signal, Cat, Module -from ptw import DCacheReqI, DCacheReqO +from ptw import DCacheReqI, DCacheReqO, TLBUpdate, PTE +from tlb import TLB + PRIV_LVL_M = Const(0b11, 2) PRIV_LVL_S = Const(0b01, 2) @@ -114,295 +116,281 @@ class MMU: # PTW memory interface self.req_port_i = DCacheReqO() self.req_port_o = DCacheReqI() -); - - logic iaccess_err; # insufficient priv to access instr page - logic daccess_err; # insufficient priv to access data page - logic ptw_active; # PTW is currently walking a page table - logic walking_instr; # PTW is walking because of an ITLB miss - logic ptw_error; # PTW threw an exception - - logic [38:0] update_vaddr; - tlb_update_t update_ptw_itlb, update_ptw_dtlb; - - logic itlb_lu_access; - riscv::pte_t itlb_content; - logic itlb_is_2M; - logic itlb_is_1G; - logic itlb_lu_hit; - - logic dtlb_lu_access; - riscv::pte_t dtlb_content; - logic dtlb_is_2M; - logic dtlb_is_1G; - logic dtlb_lu_hit; - - - # Assignments - assign itlb_lu_access = icache_areq_i.fetch_req; - assign dtlb_lu_access = lsu_req_i; - - - tlb #( - .TLB_ENTRIES ( INSTR_TLB_ENTRIES ), - .ASID_WIDTH ( ASID_WIDTH ) - ) i_itlb ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .flush_i ( flush_tlb_i ), - - .update_i ( update_ptw_itlb ), - - .lu_access_i ( itlb_lu_access ), - .lu_asid_i ( asid_i ), - .lu_vaddr_i ( icache_areq_i.fetch_vaddr ), - .lu_content_o ( itlb_content ), - - .lu_is_2M_o ( itlb_is_2M ), - .lu_is_1G_o ( itlb_is_1G ), - .lu_hit_o ( itlb_lu_hit ) - ); - - tlb #( - .TLB_ENTRIES ( DATA_TLB_ENTRIES ), - .ASID_WIDTH ( ASID_WIDTH ) - ) i_dtlb ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .flush_i ( flush_tlb_i ), - - .update_i ( update_ptw_dtlb ), - - .lu_access_i ( dtlb_lu_access ), - .lu_asid_i ( asid_i ), - .lu_vaddr_i ( lsu_vaddr_i ), - .lu_content_o ( dtlb_content ), - - .lu_is_2M_o ( dtlb_is_2M ), - .lu_is_1G_o ( dtlb_is_1G ), - .lu_hit_o ( dtlb_lu_hit ) - ); - - - ptw #( - .ASID_WIDTH ( ASID_WIDTH ) - ) i_ptw ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .ptw_active_o ( ptw_active ), - .walking_instr_o ( walking_instr ), - .ptw_error_o ( ptw_error ), - .enable_translation_i ( enable_translation_i ), - - .update_vaddr_o ( update_vaddr ), - .itlb_update_o ( update_ptw_itlb ), - .dtlb_update_o ( update_ptw_dtlb ), - - .itlb_access_i ( itlb_lu_access ), - .itlb_hit_i ( itlb_lu_hit ), - .itlb_vaddr_i ( icache_areq_i.fetch_vaddr ), - - .dtlb_access_i ( dtlb_lu_access ), - .dtlb_hit_i ( dtlb_lu_hit ), - .dtlb_vaddr_i ( lsu_vaddr_i ), - - .req_port_i ( req_port_i ), - .req_port_o ( req_port_o ), - - .* - ); - - # ila_1 i_ila_1 ( - # .clk(clk_i), # input wire clk - # .probe0({req_port_o.address_tag, req_port_o.address_index}), - # .probe1(req_port_o.data_req), # input wire [63:0] probe1 - # .probe2(req_port_i.data_gnt), # input wire [0:0] probe2 - # .probe3(req_port_i.data_rdata), # input wire [0:0] probe3 - # .probe4(req_port_i.data_rvalid), # input wire [0:0] probe4 - # .probe5(ptw_error), # input wire [1:0] probe5 - # .probe6(update_vaddr), # input wire [0:0] probe6 - # .probe7(update_ptw_itlb.valid), # input wire [0:0] probe7 - # .probe8(update_ptw_dtlb.valid), # input wire [0:0] probe8 - # .probe9(dtlb_lu_access), # input wire [0:0] probe9 - # .probe10(lsu_vaddr_i), # input wire [0:0] probe10 - # .probe11(dtlb_lu_hit), # input wire [0:0] probe11 - # .probe12(itlb_lu_access), # input wire [0:0] probe12 - # .probe13(icache_areq_i.fetch_vaddr), # input wire [0:0] probe13 - # .probe14(itlb_lu_hit) # input wire [0:0] probe13 - # ); - - #----------------------- - # Instruction Interface - #----------------------- - # The instruction interface is a simple request response interface - always_comb begin : instr_interface - # MMU disabled: just pass through - icache_areq_o.fetch_valid = icache_areq_i.fetch_req; - icache_areq_o.fetch_paddr = icache_areq_i.fetch_vaddr; # play through in case we disabled address translation - # two potential exception sources: - # 1. HPTW threw an exception -> signal with a page fault exception - # 2. We got an access error because of insufficient permissions -> throw an access exception - icache_areq_o.fetch_exception = '0; - # Check whether we are allowed to access this memory region from a fetch perspective - iaccess_err = icache_areq_i.fetch_req && (((priv_lvl_i == riscv::PRIV_LVL_U) && ~itlb_content.u) - || ((priv_lvl_i == riscv::PRIV_LVL_S) && itlb_content.u)); - - # MMU enabled: address from TLB, request delayed until hit. Error when TLB - # hit and no access right or TLB hit and translated address not valid (e.g. - # AXI decode error), or when PTW performs walk due to ITLB miss and raises - # an error. - if (enable_translation_i) begin - # we work with SV39, so if VM is enabled, check that all bits [63:38] are equal - if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[63:38]) == 1'b1 || (|icache_areq_i.fetch_vaddr[63:38]) == 1'b0)) begin - icache_areq_o.fetch_exception = {riscv::INSTR_ACCESS_FAULT, icache_areq_i.fetch_vaddr, 1'b1}; - end - icache_areq_o.fetch_valid = 1'b0; + def elaborate(self, platform): + iaccess_err = Signal() # insufficient priv to access instr page + daccess_err = Signal() # insufficient priv to access data page + ptw_active = Signal() # PTW is currently walking a page table + walking_instr = Signal() # PTW is walking because of an ITLB miss + ptw_error = Signal() # PTW threw an exception + + update_vaddr = Signal(39) + update_ptw_itlb = TLBUpdate() + update_ptw_dtlb = TLBUpdate() + + itlb_lu_access = Signal() + itlb_content = PTE() + itlb_is_2M = Signal() + itlb_is_1G = Signal() + itlb_lu_hit = Signal() + + dtlb_lu_access = Signal() + dtlb_content = PTE() + dtlb_is_2M = Signal() + dtlb_is_1G = Signal() + dtlb_lu_hit = Signal() + + # Assignments + m.d.comb += [itlb_lu_access.eq(icache_areq_i.fetch_req), + dtlb_lu_access.eq(lsu_req_i) + ] + + + # ITLB + m.submodules.i_tlb = i_tlb = TLB(INSTR_TLB_ENTRIES, ASID_WIDTH) + m.d.comb += [i_tlb.flush_i.eq(flush_tlb_i), + i_tlb.update_i.eq(update_ptw_itlb), + i_tlb.lu_access_i.eq(itlb_lu_access), + i_tlb.lu_asid_i.eq(asid_i), + i_tlb.lu_vaddr_i.eq(icache_areq_i.fetch_vaddr), + itlb_content.eq(i_tlb.lu_content_o), + itlb_is_2M.eq(i_tlb.lu_is_2M_o), + itlb_is_1G.eq(i_tlb.lu_is_1G_o), + itlb_lu_hit.eq(i_tlb.lu_hit_o), + ] + + # DTLB + m.submodules.d_tlb = d_tlb = TLB(DATA_TLB_ENTRIES, ASID_WIDTH) + m.d.comb += [d_tlb.flush_i.eq(flush_tlb_i), + d_tlb.update_i.eq(update_ptw_dtlb), + d_tlb.lu_access_i.eq(dtlb_lu_access), + d_tlb.lu_asid_i.eq(asid_i), + d_tlb.lu_vaddr_i.eq(lsu_vaddr_i), + dtlb_content.eq(d_tlb.lu_content_o), + dtlb_is_2M.eq(d_tlb.lu_is_2M_o), + dtlb_is_1G.eq(d_tlb.lu_is_1G_o), + dtlb_lu_hit.eq(d_tlb.lu_hit_o), + ] + + ptw #( + .ASID_WIDTH ( ASID_WIDTH ) + ) i_ptw ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .ptw_active_o ( ptw_active ), + .walking_instr_o ( walking_instr ), + .ptw_error_o ( ptw_error ), + .enable_translation_i ( enable_translation_i ), + + .update_vaddr_o ( update_vaddr ), + .itlb_update_o ( update_ptw_itlb ), + .dtlb_update_o ( update_ptw_dtlb ), + + .itlb_access_i ( itlb_lu_access ), + .itlb_hit_i ( itlb_lu_hit ), + .itlb_vaddr_i ( icache_areq_i.fetch_vaddr ), + + .dtlb_access_i ( dtlb_lu_access ), + .dtlb_hit_i ( dtlb_lu_hit ), + .dtlb_vaddr_i ( lsu_vaddr_i ), + + .req_port_i ( req_port_i ), + .req_port_o ( req_port_o ), + + .* + ); + + # ila_1 i_ila_1 ( + # .clk(clk_i), # input wire clk + # .probe0({req_port_o.address_tag, req_port_o.address_index}), + # .probe1(req_port_o.data_req), # input wire [63:0] probe1 + # .probe2(req_port_i.data_gnt), # input wire [0:0] probe2 + # .probe3(req_port_i.data_rdata), # input wire [0:0] probe3 + # .probe4(req_port_i.data_rvalid), # input wire [0:0] probe4 + # .probe5(ptw_error), # input wire [1:0] probe5 + # .probe6(update_vaddr), # input wire [0:0] probe6 + # .probe7(update_ptw_itlb.valid), # input wire [0:0] probe7 + # .probe8(update_ptw_dtlb.valid), # input wire [0:0] probe8 + # .probe9(dtlb_lu_access), # input wire [0:0] probe9 + # .probe10(lsu_vaddr_i), # input wire [0:0] probe10 + # .probe11(dtlb_lu_hit), # input wire [0:0] probe11 + # .probe12(itlb_lu_access), # input wire [0:0] probe12 + # .probe13(icache_areq_i.fetch_vaddr), # input wire [0:0] probe13 + # .probe14(itlb_lu_hit) # input wire [0:0] probe13 + # ); + + #----------------------- + # Instruction Interface + #----------------------- + # The instruction interface is a simple request response interface + always_comb begin : instr_interface + # MMU disabled: just pass through + icache_areq_o.fetch_valid = icache_areq_i.fetch_req; + icache_areq_o.fetch_paddr = icache_areq_i.fetch_vaddr; # play through in case we disabled address translation + # two potential exception sources: + # 1. HPTW threw an exception -> signal with a page fault exception + # 2. We got an access error because of insufficient permissions -> throw an access exception + icache_areq_o.fetch_exception = '0; + # Check whether we are allowed to access this memory region from a fetch perspective + iaccess_err = icache_areq_i.fetch_req && (((priv_lvl_i == riscv::PRIV_LVL_U) && ~itlb_content.u) + || ((priv_lvl_i == riscv::PRIV_LVL_S) && itlb_content.u)); + + # MMU enabled: address from TLB, request delayed until hit. Error when TLB + # hit and no access right or TLB hit and translated address not valid (e.g. + # AXI decode error), or when PTW performs walk due to ITLB miss and raises + # an error. + if (enable_translation_i) begin + # we work with SV39, so if VM is enabled, check that all bits [63:38] are equal + if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[63:38]) == 1'b1 || (|icache_areq_i.fetch_vaddr[63:38]) == 1'b0)) begin + icache_areq_o.fetch_exception = {riscv::INSTR_ACCESS_FAULT, icache_areq_i.fetch_vaddr, 1'b1}; + end - # 4K page - icache_areq_o.fetch_paddr = {itlb_content.ppn, icache_areq_i.fetch_vaddr[11:0]}; - # Mega page - if (itlb_is_2M) begin - icache_areq_o.fetch_paddr[20:12] = icache_areq_i.fetch_vaddr[20:12]; - end - # Giga page - if (itlb_is_1G) begin - icache_areq_o.fetch_paddr[29:12] = icache_areq_i.fetch_vaddr[29:12]; - end + icache_areq_o.fetch_valid = 1'b0; - # --------- - # ITLB Hit - # -------- - # if we hit the ITLB output the request signal immediately - if (itlb_lu_hit) begin - icache_areq_o.fetch_valid = icache_areq_i.fetch_req; - # we got an access error - if (iaccess_err) begin - # throw a page fault - icache_areq_o.fetch_exception = {riscv::INSTR_PAGE_FAULT, icache_areq_i.fetch_vaddr, 1'b1}; + # 4K page + icache_areq_o.fetch_paddr = {itlb_content.ppn, icache_areq_i.fetch_vaddr[11:0]}; + # Mega page + if (itlb_is_2M) begin + icache_areq_o.fetch_paddr[20:12] = icache_areq_i.fetch_vaddr[20:12]; + end + # Giga page + if (itlb_is_1G) begin + icache_areq_o.fetch_paddr[29:12] = icache_areq_i.fetch_vaddr[29:12]; + end + + # --------- + # ITLB Hit + # -------- + # if we hit the ITLB output the request signal immediately + if (itlb_lu_hit) begin + icache_areq_o.fetch_valid = icache_areq_i.fetch_req; + # we got an access error + if (iaccess_err) begin + # throw a page fault + icache_areq_o.fetch_exception = {riscv::INSTR_PAGE_FAULT, icache_areq_i.fetch_vaddr, 1'b1}; + end + end else + # --------- + # ITLB Miss + # --------- + # watch out for exceptions happening during walking the page table + if (ptw_active && walking_instr) begin + icache_areq_o.fetch_valid = ptw_error; + icache_areq_o.fetch_exception = {riscv::INSTR_PAGE_FAULT, {25'b0, update_vaddr}, 1'b1}; end - end else - # --------- - # ITLB Miss - # --------- - # watch out for exceptions happening during walking the page table - if (ptw_active && walking_instr) begin - icache_areq_o.fetch_valid = ptw_error; - icache_areq_o.fetch_exception = {riscv::INSTR_PAGE_FAULT, {25'b0, update_vaddr}, 1'b1}; end end - end - - #----------------------- - # Data Interface - #----------------------- - logic [63:0] lsu_vaddr_n, lsu_vaddr_q; - riscv::pte_t dtlb_pte_n, dtlb_pte_q; - exception_t misaligned_ex_n, misaligned_ex_q; - logic lsu_req_n, lsu_req_q; - logic lsu_is_store_n, lsu_is_store_q; - logic dtlb_hit_n, dtlb_hit_q; - logic dtlb_is_2M_n, dtlb_is_2M_q; - logic dtlb_is_1G_n, dtlb_is_1G_q; - - # check if we need to do translation or if we are always ready (e.g.: we are not translating anything) - assign lsu_dtlb_hit_o = (en_ld_st_translation_i) ? dtlb_lu_hit : 1'b1; - - # The data interface is simpler and only consists of a request/response interface - always_comb begin : data_interface - # save request and DTLB response - lsu_vaddr_n = lsu_vaddr_i; - lsu_req_n = lsu_req_i; - misaligned_ex_n = misaligned_ex_i; - dtlb_pte_n = dtlb_content; - dtlb_hit_n = dtlb_lu_hit; - lsu_is_store_n = lsu_is_store_i; - dtlb_is_2M_n = dtlb_is_2M; - dtlb_is_1G_n = dtlb_is_1G; - - lsu_paddr_o = lsu_vaddr_q; - lsu_valid_o = lsu_req_q; - lsu_exception_o = misaligned_ex_q; - # mute misaligned exceptions if there is no request otherwise they will throw accidental exceptions - misaligned_ex_n.valid = misaligned_ex_i.valid & lsu_req_i; - - # Check if the User flag is set, then we may only access it in supervisor mode - # if SUM is enabled - daccess_err = (ld_st_priv_lvl_i == riscv::PRIV_LVL_S && !sum_i && dtlb_pte_q.u) || # SUM is not set and we are trying to access a user page in supervisor mode - (ld_st_priv_lvl_i == riscv::PRIV_LVL_U && !dtlb_pte_q.u); # this is not a user page but we are in user mode and trying to access it - # translation is enabled and no misaligned exception occurred - if (en_ld_st_translation_i && !misaligned_ex_q.valid) begin - lsu_valid_o = 1'b0; - # 4K page - lsu_paddr_o = {dtlb_pte_q.ppn, lsu_vaddr_q[11:0]}; - # Mega page - if (dtlb_is_2M_q) begin - lsu_paddr_o[20:12] = lsu_vaddr_q[20:12]; - end - # Giga page - if (dtlb_is_1G_q) begin - lsu_paddr_o[29:12] = lsu_vaddr_q[29:12]; - end - # --------- - # DTLB Hit - # -------- - if (dtlb_hit_q && lsu_req_q) begin - lsu_valid_o = 1'b1; - # this is a store - if (lsu_is_store_q) begin - # check if the page is write-able and we are not violating privileges - # also check if the dirty flag is set - if (!dtlb_pte_q.w || daccess_err || !dtlb_pte_q.d) begin - lsu_exception_o = {riscv::STORE_PAGE_FAULT, lsu_vaddr_q, 1'b1}; - end - # this is a load, check for sufficient access privileges - throw a page fault if necessary - end else if (daccess_err) begin - lsu_exception_o = {riscv::LOAD_PAGE_FAULT, lsu_vaddr_q, 1'b1}; + #----------------------- + # Data Interface + #----------------------- + logic [63:0] lsu_vaddr_n, lsu_vaddr_q; + riscv::pte_t dtlb_pte_n, dtlb_pte_q; + exception_t misaligned_ex_n, misaligned_ex_q; + logic lsu_req_n, lsu_req_q; + logic lsu_is_store_n, lsu_is_store_q; + logic dtlb_hit_n, dtlb_hit_q; + logic dtlb_is_2M_n, dtlb_is_2M_q; + logic dtlb_is_1G_n, dtlb_is_1G_q; + + # check if we need to do translation or if we are always ready (e.g.: we are not translating anything) + assign lsu_dtlb_hit_o = (en_ld_st_translation_i) ? dtlb_lu_hit : 1'b1; + + # The data interface is simpler and only consists of a request/response interface + always_comb begin : data_interface + # save request and DTLB response + lsu_vaddr_n = lsu_vaddr_i; + lsu_req_n = lsu_req_i; + misaligned_ex_n = misaligned_ex_i; + dtlb_pte_n = dtlb_content; + dtlb_hit_n = dtlb_lu_hit; + lsu_is_store_n = lsu_is_store_i; + dtlb_is_2M_n = dtlb_is_2M; + dtlb_is_1G_n = dtlb_is_1G; + + lsu_paddr_o = lsu_vaddr_q; + lsu_valid_o = lsu_req_q; + lsu_exception_o = misaligned_ex_q; + # mute misaligned exceptions if there is no request otherwise they will throw accidental exceptions + misaligned_ex_n.valid = misaligned_ex_i.valid & lsu_req_i; + + # Check if the User flag is set, then we may only access it in supervisor mode + # if SUM is enabled + daccess_err = (ld_st_priv_lvl_i == riscv::PRIV_LVL_S && !sum_i && dtlb_pte_q.u) || # SUM is not set and we are trying to access a user page in supervisor mode + (ld_st_priv_lvl_i == riscv::PRIV_LVL_U && !dtlb_pte_q.u); # this is not a user page but we are in user mode and trying to access it + # translation is enabled and no misaligned exception occurred + if (en_ld_st_translation_i && !misaligned_ex_q.valid) begin + lsu_valid_o = 1'b0; + # 4K page + lsu_paddr_o = {dtlb_pte_q.ppn, lsu_vaddr_q[11:0]}; + # Mega page + if (dtlb_is_2M_q) begin + lsu_paddr_o[20:12] = lsu_vaddr_q[20:12]; end - end else - - # --------- - # DTLB Miss - # --------- - # watch out for exceptions - if (ptw_active && !walking_instr) begin - # page table walker threw an exception - if (ptw_error) begin - # an error makes the translation valid + # Giga page + if (dtlb_is_1G_q) begin + lsu_paddr_o[29:12] = lsu_vaddr_q[29:12]; + end + # --------- + # DTLB Hit + # -------- + if (dtlb_hit_q && lsu_req_q) begin lsu_valid_o = 1'b1; - # the page table walker can only throw page faults + # this is a store if (lsu_is_store_q) begin - lsu_exception_o = {riscv::STORE_PAGE_FAULT, {25'b0, update_vaddr}, 1'b1}; - end else begin - lsu_exception_o = {riscv::LOAD_PAGE_FAULT, {25'b0, update_vaddr}, 1'b1}; + # check if the page is write-able and we are not violating privileges + # also check if the dirty flag is set + if (!dtlb_pte_q.w || daccess_err || !dtlb_pte_q.d) begin + lsu_exception_o = {riscv::STORE_PAGE_FAULT, lsu_vaddr_q, 1'b1}; + end + + # this is a load, check for sufficient access privileges - throw a page fault if necessary + end else if (daccess_err) begin + lsu_exception_o = {riscv::LOAD_PAGE_FAULT, lsu_vaddr_q, 1'b1}; + end + end else + + # --------- + # DTLB Miss + # --------- + # watch out for exceptions + if (ptw_active && !walking_instr) begin + # page table walker threw an exception + if (ptw_error) begin + # an error makes the translation valid + lsu_valid_o = 1'b1; + # the page table walker can only throw page faults + if (lsu_is_store_q) begin + lsu_exception_o = {riscv::STORE_PAGE_FAULT, {25'b0, update_vaddr}, 1'b1}; + end else begin + lsu_exception_o = {riscv::LOAD_PAGE_FAULT, {25'b0, update_vaddr}, 1'b1}; + end end end end end - end - # ---------- - # Registers - # ---------- - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) begin - lsu_vaddr_q <= '0; - lsu_req_q <= '0; - misaligned_ex_q <= '0; - dtlb_pte_q <= '0; - dtlb_hit_q <= '0; - lsu_is_store_q <= '0; - dtlb_is_2M_q <= '0; - dtlb_is_1G_q <= '0; - end else begin - lsu_vaddr_q <= lsu_vaddr_n; - lsu_req_q <= lsu_req_n; - misaligned_ex_q <= misaligned_ex_n; - dtlb_pte_q <= dtlb_pte_n; - dtlb_hit_q <= dtlb_hit_n; - lsu_is_store_q <= lsu_is_store_n; - dtlb_is_2M_q <= dtlb_is_2M_n; - dtlb_is_1G_q <= dtlb_is_1G_n; + # ---------- + # Registers + # ---------- + always_ff @(posedge clk_i or negedge rst_ni) begin + if (~rst_ni) begin + lsu_vaddr_q <= '0; + lsu_req_q <= '0; + misaligned_ex_q <= '0; + dtlb_pte_q <= '0; + dtlb_hit_q <= '0; + lsu_is_store_q <= '0; + dtlb_is_2M_q <= '0; + dtlb_is_1G_q <= '0; + end else begin + lsu_vaddr_q <= lsu_vaddr_n; + lsu_req_q <= lsu_req_n; + misaligned_ex_q <= misaligned_ex_n; + dtlb_pte_q <= dtlb_pte_n; + dtlb_hit_q <= dtlb_hit_n; + lsu_is_store_q <= lsu_is_store_n; + dtlb_is_2M_q <= dtlb_is_2M_n; + dtlb_is_1G_q <= dtlb_is_1G_n; + end end - end -endmodule + endmodule