103 lines
3.2 KiB
Systemverilog
103 lines
3.2 KiB
Systemverilog
// Generated by CIRCT firtool-1.139.0
|
|
module PageTableWalker(
|
|
input clock,
|
|
reset,
|
|
io_reqValid,
|
|
input [26:0] io_reqVpn,
|
|
input io_isStore,
|
|
input [63:0] io_satp,
|
|
output io_memReq_valid,
|
|
output [63:0] io_memReq_addr,
|
|
input io_memResp_valid,
|
|
input [63:0] io_memResp_data,
|
|
output io_respValid,
|
|
io_refill_valid,
|
|
output [26:0] io_refill_vpn,
|
|
output [43:0] io_refill_ppn,
|
|
output [7:0] io_refill_flags,
|
|
output io_pageFault
|
|
);
|
|
|
|
reg [2:0] state;
|
|
reg [26:0] vpnReg;
|
|
reg isStoreReg;
|
|
reg walkFault;
|
|
reg [43:0] nextPpn;
|
|
wire _io_memReq_addr_T = state == 3'h1;
|
|
wire _io_memReq_addr_T_1 = state == 3'h2;
|
|
reg [43:0] curPpn;
|
|
wire _io_memReq_valid_T_3 = state == 3'h3;
|
|
wire io_respValid_0 = state == 3'h4;
|
|
always @(posedge clock) begin
|
|
automatic logic pteIsLeaf;
|
|
automatic logic invalidPte;
|
|
automatic logic _GEN;
|
|
automatic logic _GEN_0;
|
|
automatic logic _GEN_1;
|
|
automatic logic _GEN_2;
|
|
pteIsLeaf = io_memResp_data[1] | io_memResp_data[3];
|
|
invalidPte = ~(io_memResp_data[0]) | ~(io_memResp_data[1]) & io_memResp_data[2];
|
|
_GEN = state == 3'h0;
|
|
_GEN_0 = _io_memReq_addr_T | _io_memReq_addr_T_1;
|
|
_GEN_1 = (_GEN_0 | _io_memReq_valid_T_3) & io_memResp_valid;
|
|
_GEN_2 = invalidPte | pteIsLeaf;
|
|
if (reset) begin
|
|
state <= 3'h0;
|
|
walkFault <= 1'h0;
|
|
end
|
|
else begin
|
|
if (_GEN) begin
|
|
if (io_reqValid)
|
|
state <= 3'h1;
|
|
end
|
|
else if (_GEN_1)
|
|
state <=
|
|
_GEN_2 ? 3'h4 : _io_memReq_addr_T ? 3'h2 : _io_memReq_addr_T_1 ? 3'h3 : 3'h4;
|
|
else if (io_respValid_0)
|
|
state <= 3'h0;
|
|
walkFault <=
|
|
~_GEN
|
|
& (_GEN_1
|
|
? invalidPte
|
|
| (pteIsLeaf
|
|
? (isStoreReg
|
|
? ~(io_memResp_data[2]) | ~(io_memResp_data[7])
|
|
: ~(io_memResp_data[1])) | ~(io_memResp_data[6]) | walkFault
|
|
: ~_GEN_0 | walkFault)
|
|
: walkFault);
|
|
end
|
|
if (_GEN & io_reqValid) begin
|
|
vpnReg <= io_reqVpn;
|
|
isStoreReg <= io_isStore;
|
|
end
|
|
if (_GEN | ~_GEN_1 | invalidPte | ~pteIsLeaf) begin
|
|
end
|
|
else begin
|
|
automatic logic [1:0] level =
|
|
_io_memReq_addr_T ? 2'h2 : {1'h0, _io_memReq_addr_T_1};
|
|
nextPpn <=
|
|
{io_memResp_data[53:28],
|
|
level[1] ? vpnReg[17:9] : io_memResp_data[27:19],
|
|
level == 2'h0 ? io_memResp_data[18:10] : vpnReg[8:0]};
|
|
end
|
|
if (_GEN | ~_GEN_1 | _GEN_2) begin
|
|
end
|
|
else
|
|
curPpn <= io_memResp_data[53:10];
|
|
end // always @(posedge)
|
|
assign io_memReq_valid = _io_memReq_addr_T | _io_memReq_addr_T_1 | _io_memReq_valid_T_3;
|
|
assign io_memReq_addr =
|
|
{8'h0,
|
|
_io_memReq_addr_T
|
|
? {io_satp[43:0], vpnReg[26:18]}
|
|
: {curPpn, _io_memReq_addr_T_1 ? vpnReg[17:9] : vpnReg[8:0]},
|
|
3'h0};
|
|
assign io_respValid = io_respValid_0;
|
|
assign io_refill_valid = io_respValid_0 & ~walkFault;
|
|
assign io_refill_vpn = vpnReg;
|
|
assign io_refill_ppn = nextPpn;
|
|
assign io_refill_flags = io_memResp_data[7:0];
|
|
assign io_pageFault = walkFault;
|
|
endmodule
|
|
|