168 lines
6.4 KiB
Systemverilog
168 lines
6.4 KiB
Systemverilog
// Generated by CIRCT firtool-1.139.0
|
|
module Frontend(
|
|
input clock,
|
|
reset,
|
|
io_redirectValid,
|
|
input [63:0] io_redirectPc,
|
|
input io_invalidateICache,
|
|
io_sfenceVma,
|
|
input [63:0] io_satp,
|
|
input [1:0] io_currentPriv,
|
|
output io_imemReqValid,
|
|
output [63:0] io_imemReqAddr,
|
|
input io_imemRespValid,
|
|
input [31:0] io_imemRespBits_0,
|
|
io_imemRespBits_1,
|
|
output io_ptwMemReqValid,
|
|
output [63:0] io_ptwMemReqAddr,
|
|
input io_ptwMemRespValid,
|
|
input [63:0] io_ptwMemRespData,
|
|
input io_outReady,
|
|
output io_outValid,
|
|
output [63:0] io_out_pc,
|
|
output [31:0] io_out_inst_0,
|
|
io_out_inst_1,
|
|
output io_out_laneValid_0,
|
|
io_out_laneValid_1,
|
|
io_out_exception,
|
|
output [63:0] io_out_exceptionCause,
|
|
io_out_exceptionTval
|
|
);
|
|
|
|
wire _icache_io_respValid;
|
|
wire [63:0] _icache_io_resp_pc;
|
|
wire [31:0] _icache_io_resp_inst_0;
|
|
wire [31:0] _icache_io_resp_inst_1;
|
|
wire _icache_io_resp_laneValid_0;
|
|
wire _icache_io_resp_laneValid_1;
|
|
wire _icache_io_resp_exception;
|
|
wire [63:0] _icache_io_resp_exceptionCause;
|
|
wire [63:0] _icache_io_resp_exceptionTval;
|
|
wire _immu_io_resp_pageFault;
|
|
wire _immu_io_refill_valid;
|
|
wire [26:0] _immu_io_refill_vpn;
|
|
wire [43:0] _immu_io_refill_ppn;
|
|
wire [1:0] _immu_io_refill_level;
|
|
wire [7:0] _immu_io_refill_flags;
|
|
wire _itlb_io_resp_hit;
|
|
wire _itlb_io_resp_miss;
|
|
wire [63:0] _itlb_io_resp_paddr;
|
|
wire _itlb_io_resp_pageFault;
|
|
reg [63:0] pc;
|
|
reg faultPending;
|
|
reg [63:0] faultPc;
|
|
reg [63:0] faultCause;
|
|
wire fetchTranslate = (|(io_satp[63:60])) & io_currentPriv != 2'h3;
|
|
wire itlbMiss = fetchTranslate & _itlb_io_resp_miss;
|
|
wire instPageFault =
|
|
fetchTranslate & (_itlb_io_resp_pageFault | _immu_io_resp_pageFault);
|
|
wire fetchFault = (|(pc[1:0])) | instPageFault;
|
|
wire translationReady = ~fetchTranslate | _itlb_io_resp_hit | instPageFault;
|
|
wire [63:0] translatedFetchAddr = fetchTranslate ? _itlb_io_resp_paddr : pc;
|
|
always @(posedge clock) begin
|
|
automatic logic _GEN;
|
|
_GEN = fetchFault & ~faultPending;
|
|
if (reset) begin
|
|
pc <= 64'h80000000;
|
|
faultPending <= 1'h0;
|
|
end
|
|
else begin
|
|
automatic logic _GEN_0;
|
|
_GEN_0 = faultPending & io_outReady;
|
|
if (io_redirectValid)
|
|
pc <= io_redirectPc;
|
|
else if (~_GEN) begin
|
|
if (_GEN_0)
|
|
pc <= pc + 64'h4;
|
|
else if (_icache_io_respValid & io_outReady)
|
|
pc <=
|
|
_icache_io_resp_pc
|
|
+ {60'h0,
|
|
{1'h0, _icache_io_resp_laneValid_0} + {1'h0, _icache_io_resp_laneValid_1},
|
|
2'h0};
|
|
end
|
|
faultPending <= ~io_redirectValid & (_GEN | ~_GEN_0 & faultPending);
|
|
end
|
|
if (io_redirectValid | ~_GEN) begin
|
|
end
|
|
else begin
|
|
faultPc <= pc;
|
|
faultCause <= {56'h0, (|(pc[1:0])) ? 8'h0 : 8'hC};
|
|
end
|
|
end // always @(posedge)
|
|
ITLB itlb (
|
|
.clock (clock),
|
|
.reset (reset),
|
|
.io_req_valid (fetchTranslate & ~faultPending),
|
|
.io_req_vaddr (pc),
|
|
.io_req_priv (io_currentPriv),
|
|
.io_resp_hit (_itlb_io_resp_hit),
|
|
.io_resp_miss (_itlb_io_resp_miss),
|
|
.io_resp_paddr (_itlb_io_resp_paddr),
|
|
.io_resp_pageFault (_itlb_io_resp_pageFault),
|
|
.io_refill_valid (_immu_io_refill_valid),
|
|
.io_refill_vpn (_immu_io_refill_vpn),
|
|
.io_refill_ppn (_immu_io_refill_ppn),
|
|
.io_refill_level (_immu_io_refill_level),
|
|
.io_refill_flags (_immu_io_refill_flags),
|
|
.io_flush (io_redirectValid | io_invalidateICache | io_sfenceVma)
|
|
);
|
|
MMU immu (
|
|
.clock (clock),
|
|
.reset (reset),
|
|
.io_satp (io_satp),
|
|
.io_req_valid (itlbMiss),
|
|
.io_req_vaddr (pc),
|
|
.io_req_isStore (1'h0),
|
|
.io_req_isFetch (1'h1),
|
|
.io_req_priv (io_currentPriv),
|
|
.io_req_sum (1'h0),
|
|
.io_req_mxr (1'h0),
|
|
.io_resp_pageFault (_immu_io_resp_pageFault),
|
|
.io_ptwMemReq_valid (io_ptwMemReqValid),
|
|
.io_ptwMemReq_addr (io_ptwMemReqAddr),
|
|
.io_ptwMemResp_valid (io_ptwMemRespValid),
|
|
.io_ptwMemResp_data (io_ptwMemRespData),
|
|
.io_refill_valid (_immu_io_refill_valid),
|
|
.io_refill_vpn (_immu_io_refill_vpn),
|
|
.io_refill_ppn (_immu_io_refill_ppn),
|
|
.io_refill_level (_immu_io_refill_level),
|
|
.io_refill_flags (_immu_io_refill_flags)
|
|
);
|
|
ICache icache (
|
|
.clock (clock),
|
|
.reset (reset),
|
|
.io_reqValid (~fetchFault & ~faultPending & translationReady),
|
|
.io_reqAddr (translatedFetchAddr),
|
|
.io_reqPc (pc),
|
|
.io_flush (io_redirectValid),
|
|
.io_invalidate (io_invalidateICache),
|
|
.io_respReady (io_outReady),
|
|
.io_memReqValid (io_imemReqValid),
|
|
.io_memReqAddr (io_imemReqAddr),
|
|
.io_memRespValid (io_imemRespValid),
|
|
.io_memRespBits_0 (io_imemRespBits_0),
|
|
.io_memRespBits_1 (io_imemRespBits_1),
|
|
.io_respValid (_icache_io_respValid),
|
|
.io_resp_pc (_icache_io_resp_pc),
|
|
.io_resp_inst_0 (_icache_io_resp_inst_0),
|
|
.io_resp_inst_1 (_icache_io_resp_inst_1),
|
|
.io_resp_laneValid_0 (_icache_io_resp_laneValid_0),
|
|
.io_resp_laneValid_1 (_icache_io_resp_laneValid_1),
|
|
.io_resp_exception (_icache_io_resp_exception),
|
|
.io_resp_exceptionCause (_icache_io_resp_exceptionCause),
|
|
.io_resp_exceptionTval (_icache_io_resp_exceptionTval)
|
|
);
|
|
assign io_outValid = faultPending | _icache_io_respValid;
|
|
assign io_out_pc = faultPending ? faultPc : _icache_io_resp_pc;
|
|
assign io_out_inst_0 = faultPending ? 32'h0 : _icache_io_resp_inst_0;
|
|
assign io_out_inst_1 = faultPending ? 32'h0 : _icache_io_resp_inst_1;
|
|
assign io_out_laneValid_0 = faultPending | _icache_io_resp_laneValid_0;
|
|
assign io_out_laneValid_1 = ~faultPending & _icache_io_resp_laneValid_1;
|
|
assign io_out_exception = faultPending | _icache_io_resp_exception;
|
|
assign io_out_exceptionCause =
|
|
faultPending ? faultCause : _icache_io_resp_exceptionCause;
|
|
assign io_out_exceptionTval = faultPending ? faultPc : _icache_io_resp_exceptionTval;
|
|
endmodule
|
|
|