bugfix MMU

This commit is contained in:
Hooo1941 2021-07-16 16:12:57 +08:00
parent dbd82fe117
commit 461cf15334
3 changed files with 93 additions and 51 deletions

View File

@ -69,7 +69,6 @@ module AXI (
AXIRead.AXIReadAddr.rready = 1'b1;
rdata.addr_ok = 0;
inst.addr_ok = 0;
if (AXIRead.AXIReadData.arready) begin
if (rdata.req) begin
@ -80,6 +79,7 @@ module AXI (
AXIRead.AXIReadAddr.arvalid = 1'b1;
AXIRead.AXIReadAddr.rready = 1'b1;
rdata.addr_ok = 1'b1;
inst.addr_ok = 0;
end else if (inst.req) begin
AXIRead.AXIReadAddr.arid = 4'b0000;
AXIRead.AXIReadAddr.arport = 3'b101;
@ -88,7 +88,7 @@ module AXI (
AXIRead.AXIReadAddr.arvalid = 1'b1;
AXIRead.AXIReadAddr.rready = 1'b1;
inst.addr_ok = 1'b1;
end
end else inst.addr_ok = 0;
end
end
@ -106,7 +106,7 @@ module AXI (
AXIWrite.AXIWriteAddr.wlast = 0;
AXIWrite.AXIWriteAddr.wvalid = 0;
if(AXIWrite.AXIWriteData.wready & wdata.wvalid) begin
if (AXIWrite.AXIWriteData.wready & wdata.wvalid) begin
AXIWrite.AXIWriteAddr.wid = 4'b1;
AXIWrite.AXIWriteAddr.wdata = wdata.wdata;
AXIWrite.AXIWriteAddr.wstrb = wdata.wstrb;

View File

@ -4,7 +4,8 @@
`include "AXI.svh"
module MMU (
input clk, rst,
input clk,
rst,
input logic [1:0] K0,
@ -25,23 +26,30 @@ module MMU (
word_t iPA;
logic iCached;
logic iEn;
logic iEn;
logic iValid1;
logic iCached1;
word_t iPA1;
word_t iD1, iD2, iD3;
// ================================
// ======== iState Machine ========
// ================================
typedef enum bit [2:0] { I_IDLE, I_WA, I_WD1, I_WD2, I_WD3, I_WD4 } state_t;
typedef enum bit [2:0] {
I_IDLE,
I_WA,
I_WD1,
I_WD2,
I_WD3,
I_WD4
} state_t;
state_t iState;
state_t iNextState;
always_ff @(posedge clk) begin
if(rst) iState <= I_IDLE;
if (rst) iState <= I_IDLE;
else iState <= iNextState;
end
@ -51,46 +59,49 @@ module MMU (
inst.data_ok = 0;
ic.wvalid = 0;
inst_axi.req = 0;
case(iState)
case (iState)
I_IDLE: begin
if(~iValid1) iEn = 1;
else
if(iCached1 & ic.hit) begin
iEn = 1;
inst.data_ok = 1;
end else begin
inst_axi.req = 1;
if (~inst_axi.addr_ok) iNextState = I_WA;
else if (~inst_axi.rvalid) iNextState = I_WD1;
else iNextState = I_WD2;
end
end
I_WA: begin
if (~iValid1) iEn = 1;
else if (iCached1 & ic.hit) begin
iEn = 1;
inst.data_ok = 1;
end else begin
inst_axi.req = 1;
if (~inst_axi.addr_ok) iNextState = I_WA;
else if (~inst_axi.rvalid) iNextState = I_WD1;
else iNextState = I_WD2;
end
end
I_WA: begin
inst_axi.req = 1;
if (inst_axi.addr_ok) begin
if (~inst_axi.rvalid) iNextState = I_WD1;
else iNextState = I_WD2;
else iNextState = I_WD2;
end
end
I_WD1: begin
end
I_WD1: begin
if (inst_axi.rvalid) iNextState = I_WD2;
end
I_WD2: begin
end
I_WD2: begin
if (inst_axi.rvalid) begin
inst.data_ok = 1;
if (iCached1) iNextState = I_IDLE;
else iNextState = I_WD3;
if (iCached1) iNextState = I_WD3;
else begin
iEn = 1;
iNextState = I_IDLE;
end
end
end
I_WD3: begin
end
I_WD3: begin
if (inst_axi.rvalid) iNextState = I_WD4;
end
I_WD4: begin
end
I_WD4: begin
if (inst_axi.rvalid) begin
iEn = 1;
ic.wvalid = 1;
iNextState = I_IDLE;
end
end
end
endcase
end
@ -98,13 +109,44 @@ module MMU (
// ======== iFlip-Flop ========
// ============================
ffenr#(1) ivalid_ff(clk, rst, inst.req, iEn, iValid1);
ffen#(1) icached_ff(clk, iCached, iEn, iCached1);
ffen#(32) ipa_ff(clk, iPA, iEn, iPA1);
ffenr #(1) ivalid_ff (
clk,
rst,
inst.req,
iEn,
iValid1
);
ffen #(1) icached_ff (
clk,
iCached,
iEn,
iCached1
);
ffen #(32) ipa_ff (
clk,
iPA,
iEn,
iPA1
);
ffen#(32) id1_ff(clk, inst_axi.rdata, iNextState == I_WD2, iD1);
ffen#(32) id2_ff(clk, inst_axi.rdata, iNextState == I_WD3, iD2);
ffen#(32) id3_ff(clk, inst_axi.rdata, iNextState == I_WD4, iD3);
ffen #(32) id1_ff (
clk,
inst_axi.rdata,
iNextState == I_WD2,
iD1
);
ffen #(32) id2_ff (
clk,
inst_axi.rdata,
iNextState == I_WD3,
iD2
);
ffen #(32) id3_ff (
clk,
inst_axi.rdata,
iNextState == I_WD4,
iD3
);
// ===============================
// ========== iFunction ==========
@ -112,12 +154,12 @@ module MMU (
assign iVA = inst.addr;
assign inst.addr_ok = iEn;
assign {inst.rdata1, inst.rdata0} = (iState == I_IDLE) ? {inst_axi.rdata, iD1}
: iPA1[3] ? ic.row[127:64]
: ic.row[ 63: 0];
assign {inst.rdata1, inst.rdata0} = (iState == I_WD2) ? {
inst_axi.rdata, iD1
} : iPA1[3] ? ic.row[127:64] : ic.row[63:0];
assign ic.valid = inst.req & iEn & iCached;
assign ic.addr = iPA;
assign ic.addr = iPA;
assign ic.wdata = iPA1[3] ? {iD2, iD1, inst_axi.rdata, iD3} : {inst_axi.rdata, iD3, iD2, iD1};
assign inst_axi.addr = iPA1;
@ -167,10 +209,10 @@ module MMU (
endmodule
module mapping (
input logic [1:0] K0,
input word_t addr_in,
input logic [1:0] K0,
input word_t addr_in,
output word_t addr_out,
output logic cached
output logic cached
);
always_comb begin
if (addr_in > 32'hBFFF_FFFF || addr_in <= 32'h7FFF_FFFF) begin // kseg2 + kseg3 + kuseg? -> tlb

View File

@ -132,12 +132,12 @@ module test_MMU ();
reg [29:0] addr, queue[$];
reg cached;
reg [29:0] cacheAddrOffset = 'h2800_0000;
reg [29:0] cacheAddrOffset = 'h2000_0000;
assign inst.req = 1;
assign inst.addr = {addr, 2'b0};
assign inst.addr = {addr[29:1], 3'b0};
always @(posedge clk) begin
cached = ~cached; // one cached and one uncached kuseg <-> kesg1
cached = ~cached; // one cached and one uncached kuseg <-> kseg0
// next addr
if (inst.addr_ok) begin