MMU
Co-authored-by: cxy004 <cxy004@qq.com> Co-authored-by: Paul <1323564116@qq.com>
This commit is contained in:
parent
b771d3d6eb
commit
2c273bbd75
@ -65,30 +65,28 @@ module AXI (
|
||||
AXIRead.AXIReadAddr.arid = 4'b0; // ICache(0) DCache(1)
|
||||
AXIRead.AXIReadAddr.arport = 3'b101; // ICache(101) DCache(001)
|
||||
AXIRead.AXIReadAddr.araddr = 32'b0;
|
||||
AXIRead.AXIReadAddr.arvalid = 1'b0;
|
||||
AXIRead.AXIReadAddr.rready = 1'b1;
|
||||
|
||||
rdata.addr_ok = 0;
|
||||
|
||||
AXIRead.AXIReadAddr.arvalid = rdata.req | inst.req;
|
||||
if (AXIRead.AXIReadData.arready) begin
|
||||
if (rdata.req) begin
|
||||
AXIRead.AXIReadAddr.arid = 4'b0001;
|
||||
AXIRead.AXIReadAddr.arport = 3'b001;
|
||||
AXIRead.AXIReadAddr.araddr = rdata.addr;
|
||||
AXIRead.AXIReadAddr.arlen = {2'b0, rdata.size};
|
||||
AXIRead.AXIReadAddr.arvalid = 1'b1;
|
||||
AXIRead.AXIReadAddr.rready = 1'b1;
|
||||
rdata.addr_ok = 1'b1;
|
||||
inst.addr_ok = 0;
|
||||
inst.addr_ok = 1'b0;
|
||||
end else if (inst.req) begin
|
||||
AXIRead.AXIReadAddr.arid = 4'b0000;
|
||||
AXIRead.AXIReadAddr.arport = 3'b101;
|
||||
AXIRead.AXIReadAddr.araddr = inst.addr;
|
||||
AXIRead.AXIReadAddr.arlen = {2'b0, inst.size};
|
||||
AXIRead.AXIReadAddr.arvalid = 1'b1;
|
||||
AXIRead.AXIReadAddr.rready = 1'b1;
|
||||
inst.addr_ok = 1'b1;
|
||||
end else inst.addr_ok = 0;
|
||||
rdata.addr_ok = 1'b0;
|
||||
end else begin
|
||||
inst.addr_ok = 1'b0;
|
||||
rdata.addr_ok = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -27,6 +27,23 @@ module ffenr #(
|
||||
|
||||
endmodule
|
||||
|
||||
module ffenrc #(
|
||||
parameter WIDTH = 8
|
||||
) (
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic [WIDTH-1:0] d,
|
||||
input logic en,
|
||||
input logic c,
|
||||
output logic [WIDTH-1:0] q
|
||||
);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (rst | c) q <= {WIDTH{1'b0}};
|
||||
else if (en) q <= d;
|
||||
|
||||
endmodule
|
||||
|
||||
module mux2 #(
|
||||
parameter WIDTH = 8
|
||||
) (
|
||||
|
205
src/MMU/MMU.sv
205
src/MMU/MMU.sv
@ -10,12 +10,14 @@ module MMU (
|
||||
input logic [1:0] K0,
|
||||
|
||||
ICache_i.mmu ic,
|
||||
// DCache_i.mmu dc,
|
||||
DCache_i.mmu dc,
|
||||
|
||||
sramro_i.slave inst,
|
||||
sram_i.slave data,
|
||||
|
||||
SRAM_RO_AXI_i.master inst_axi
|
||||
SRAM_RO_AXI_i.master inst_axi,
|
||||
SRAM_RO_AXI_i.master rdata_axi,
|
||||
SRAM_W_AXI_i.slave wdata_axi
|
||||
);
|
||||
|
||||
// ======================
|
||||
@ -43,10 +45,11 @@ module MMU (
|
||||
I_WD1,
|
||||
I_WD2,
|
||||
I_WD3,
|
||||
I_WD4
|
||||
} state_t;
|
||||
state_t iState;
|
||||
state_t iNextState;
|
||||
I_WD4,
|
||||
I_REFILL
|
||||
} istate_t;
|
||||
istate_t iState;
|
||||
istate_t iNextState;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) iState <= I_IDLE;
|
||||
@ -68,8 +71,7 @@ module MMU (
|
||||
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;
|
||||
else iNextState = I_WD1;
|
||||
end
|
||||
end
|
||||
I_WA: begin
|
||||
@ -97,11 +99,14 @@ module MMU (
|
||||
end
|
||||
I_WD4: begin
|
||||
if (inst_axi.rvalid) begin
|
||||
iEn = 1;
|
||||
ic.wvalid = 1;
|
||||
iNextState = I_IDLE;
|
||||
iNextState = I_REFILL;
|
||||
end
|
||||
end
|
||||
I_REFILL: begin
|
||||
iEn = 1;
|
||||
iNextState = I_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
@ -173,20 +178,190 @@ module MMU (
|
||||
word_t dPA;
|
||||
logic dCached;
|
||||
|
||||
// ================================
|
||||
// ======== dState Machine ========
|
||||
// ================================
|
||||
logic dEn, drEn, dwEn;
|
||||
logic dValid1, dwr1;
|
||||
logic dCached1;
|
||||
word_t dPA1;
|
||||
logic [3:0] dWstrb1;
|
||||
word_t dWdata1;
|
||||
|
||||
word_t drD1, drD2, drD3;
|
||||
|
||||
// ============================
|
||||
// ======== dFlip-Flop ========
|
||||
// ============================
|
||||
|
||||
ffenr #(1) dvalid_ff (
|
||||
clk,
|
||||
rst,
|
||||
data.req,
|
||||
dEn,
|
||||
dValid1
|
||||
);
|
||||
ffen #(1) dcached_ff (
|
||||
clk,
|
||||
dCached,
|
||||
dEn,
|
||||
dCached1
|
||||
);
|
||||
ffen #(32) dpa_ff (
|
||||
clk,
|
||||
dPA,
|
||||
dEn,
|
||||
dPA1
|
||||
);
|
||||
ffenr #(1) dwr_ff (
|
||||
clk,
|
||||
rst,
|
||||
data.wr,
|
||||
dEn,
|
||||
dwr1,
|
||||
);
|
||||
ffenr #(1) dwstrb_ff (
|
||||
clk,
|
||||
rst,
|
||||
data.wstrb,
|
||||
dEn,
|
||||
dWstrb1,
|
||||
);
|
||||
ffenr #(1) dwdata_ff (
|
||||
clk,
|
||||
rst,
|
||||
data.wdata,
|
||||
dEn,
|
||||
dWdata1,
|
||||
);
|
||||
|
||||
// ===============================
|
||||
// ================================
|
||||
// ========== dFunction ==========
|
||||
// ===============================
|
||||
// ================================
|
||||
|
||||
assign dVA = data.addr;
|
||||
|
||||
// =================================
|
||||
// ======== drState Machine ========
|
||||
// =================================
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
DR_IDLE,
|
||||
DR_WA,
|
||||
DR_WD1,
|
||||
DR_WD2,
|
||||
DR_WD3,
|
||||
DR_WD4,
|
||||
DR_REFILL
|
||||
} drstate_t;
|
||||
drstate_t drState;
|
||||
drstate_t drNextState;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) drState <= DR_IDLE;
|
||||
else drState <= drNextState;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
drEn = 0;
|
||||
drNextState = drState;
|
||||
data.data_ok = 0;
|
||||
dc.rvalid = 0;
|
||||
data.req = 0;
|
||||
case (drState)
|
||||
DR_IDLE: begin
|
||||
if (~dValid1) drEn = 1;
|
||||
else if (dCached1 & dc.hit) begin
|
||||
else drNextState = DR_REFILL;
|
||||
data.data_ok = 1;
|
||||
end else begin
|
||||
rdata_axi.req = 1;
|
||||
if (~rdata_axi.addr_ok) drNextState = DR_WA;
|
||||
else drNextState = DR_WD1;
|
||||
end
|
||||
end
|
||||
DR_WA: begin
|
||||
rdata_axi.req = 1;
|
||||
if (rdata_axi.addr_ok) begin
|
||||
if (~rdata_axi.rvalid) drNextState = DR_WD1;
|
||||
else begin
|
||||
data.data_ok = 1;
|
||||
if (dCached1) drNextState = DR_WD2;
|
||||
else begin
|
||||
drEn = 1;
|
||||
drNextState = DR_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
DR_WD1: begin
|
||||
if (rdata_axi.rvalid) begin
|
||||
data.data_ok = 1;
|
||||
if (dCached1) drNextState = DR_WD2;
|
||||
else begin
|
||||
drEn = 1;
|
||||
drNextState = DR_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
DR_WD2: begin
|
||||
if (rdata_axi.rvalid) drNextState = DR_WD3;
|
||||
end
|
||||
DR_WD3: begin
|
||||
if (rdata_axi.rvalid) drNextState = DR_WD4;
|
||||
end
|
||||
DR_WD4: begin
|
||||
if (rdata_axi.rvalid) begin
|
||||
dc.rvalid = 1;
|
||||
drNextState = DR_REFILL;
|
||||
end
|
||||
DR_REFILL: begin
|
||||
drEn = 1; // todo: dEn with dw finish
|
||||
drNextState = DR_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// =============================
|
||||
// ======== drFlip-Flop ========
|
||||
// =============================
|
||||
|
||||
ffen #(32) drd1_ff (
|
||||
clk,
|
||||
rdata_axi.rdata,
|
||||
drNextState == DR_WD2,
|
||||
drD1
|
||||
);
|
||||
ffen #(32) drd2_ff (
|
||||
clk,
|
||||
rdata_axi.rdata,
|
||||
drNextState == DR_WD3,
|
||||
drD2
|
||||
);
|
||||
ffen #(32) drd3_ff (
|
||||
clk,
|
||||
rdata_axi.rdata,
|
||||
drNextState == DR_WD4,
|
||||
drD3
|
||||
);
|
||||
|
||||
// ================================
|
||||
// ========== drFunction ==========
|
||||
// ================================
|
||||
|
||||
assign data.addr_ok = dEn;
|
||||
assign data.rdata = rdata_axi.rdata;
|
||||
|
||||
assign dc.valid = data.req & dEn & dCached;
|
||||
assign dc.addr = dPA;
|
||||
assign dc.rdata =
|
||||
dPA1[3] ? dPA1[2] ? {drD1, rdata_axi.rdata, drD3, drD2} : {drD2, drD1, rdata_axi.rdata, drD3}
|
||||
: dPA1[2] ? {drD3, drD2, drD1, rdata_axi.rdata} : {rdata_axi.rdata, drD3, drD2, drD1};
|
||||
|
||||
assign dc.wvalid = dwr1;
|
||||
assign dc.wstrb = dWstrb1;
|
||||
assign dc.wdata = dWdata1;
|
||||
|
||||
assign rdata_axi.addr = dPA1;
|
||||
assign rdata_axi.size = dCached1 ? 2'b11 : 2'b00;
|
||||
|
||||
// ==============================
|
||||
// ========== VA -> PA ==========
|
||||
|
Loading…
Reference in New Issue
Block a user