"""
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)
# 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