bugfix MMU
This commit is contained in:
parent
dbd82fe117
commit
461cf15334
@ -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;
|
||||
|
132
src/MMU/MMU.sv
132
src/MMU/MMU.sv
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user