Co-authored-by: cxy004 <cxy004@qq.com>
Co-authored-by: Paul <1323564116@qq.com>
This commit is contained in:
hoo 2021-07-20 22:01:23 +08:00
parent b771d3d6eb
commit 2c273bbd75
3 changed files with 214 additions and 24 deletions

View File

@ -65,30 +65,28 @@ module AXI (
AXIRead.AXIReadAddr.arid = 4'b0; // ICache(0) DCache(1) AXIRead.AXIReadAddr.arid = 4'b0; // ICache(0) DCache(1)
AXIRead.AXIReadAddr.arport = 3'b101; // ICache(101) DCache(001) AXIRead.AXIReadAddr.arport = 3'b101; // ICache(101) DCache(001)
AXIRead.AXIReadAddr.araddr = 32'b0; AXIRead.AXIReadAddr.araddr = 32'b0;
AXIRead.AXIReadAddr.arvalid = 1'b0;
AXIRead.AXIReadAddr.rready = 1'b1; AXIRead.AXIReadAddr.rready = 1'b1;
rdata.addr_ok = 0; AXIRead.AXIReadAddr.arvalid = rdata.req | inst.req;
if (AXIRead.AXIReadData.arready) begin if (AXIRead.AXIReadData.arready) begin
if (rdata.req) begin if (rdata.req) begin
AXIRead.AXIReadAddr.arid = 4'b0001; AXIRead.AXIReadAddr.arid = 4'b0001;
AXIRead.AXIReadAddr.arport = 3'b001; AXIRead.AXIReadAddr.arport = 3'b001;
AXIRead.AXIReadAddr.araddr = rdata.addr; AXIRead.AXIReadAddr.araddr = rdata.addr;
AXIRead.AXIReadAddr.arlen = {2'b0, rdata.size}; AXIRead.AXIReadAddr.arlen = {2'b0, rdata.size};
AXIRead.AXIReadAddr.arvalid = 1'b1;
AXIRead.AXIReadAddr.rready = 1'b1;
rdata.addr_ok = 1'b1; rdata.addr_ok = 1'b1;
inst.addr_ok = 0; inst.addr_ok = 1'b0;
end else if (inst.req) begin end else if (inst.req) begin
AXIRead.AXIReadAddr.arid = 4'b0000; AXIRead.AXIReadAddr.arid = 4'b0000;
AXIRead.AXIReadAddr.arport = 3'b101; AXIRead.AXIReadAddr.arport = 3'b101;
AXIRead.AXIReadAddr.araddr = inst.addr; AXIRead.AXIReadAddr.araddr = inst.addr;
AXIRead.AXIReadAddr.arlen = {2'b0, inst.size}; AXIRead.AXIReadAddr.arlen = {2'b0, inst.size};
AXIRead.AXIReadAddr.arvalid = 1'b1;
AXIRead.AXIReadAddr.rready = 1'b1;
inst.addr_ok = 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
end end

View File

@ -27,6 +27,23 @@ module ffenr #(
endmodule 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 #( module mux2 #(
parameter WIDTH = 8 parameter WIDTH = 8
) ( ) (

View File

@ -10,12 +10,14 @@ module MMU (
input logic [1:0] K0, input logic [1:0] K0,
ICache_i.mmu ic, ICache_i.mmu ic,
// DCache_i.mmu dc, DCache_i.mmu dc,
sramro_i.slave inst, sramro_i.slave inst,
sram_i.slave data, 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_WD1,
I_WD2, I_WD2,
I_WD3, I_WD3,
I_WD4 I_WD4,
} state_t; I_REFILL
state_t iState; } istate_t;
state_t iNextState; istate_t iState;
istate_t iNextState;
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (rst) iState <= I_IDLE; if (rst) iState <= I_IDLE;
@ -68,8 +71,7 @@ module MMU (
end else begin end else begin
inst_axi.req = 1; inst_axi.req = 1;
if (~inst_axi.addr_ok) iNextState = I_WA; if (~inst_axi.addr_ok) iNextState = I_WA;
else if (~inst_axi.rvalid) iNextState = I_WD1; else iNextState = I_WD1;
else iNextState = I_WD2;
end end
end end
I_WA: begin I_WA: begin
@ -97,11 +99,14 @@ module MMU (
end end
I_WD4: begin I_WD4: begin
if (inst_axi.rvalid) begin if (inst_axi.rvalid) begin
iEn = 1;
ic.wvalid = 1; ic.wvalid = 1;
iNextState = I_IDLE; iNextState = I_REFILL;
end end
end end
I_REFILL: begin
iEn = 1;
iNextState = I_IDLE;
end
endcase endcase
end end
@ -173,20 +178,190 @@ module MMU (
word_t dPA; word_t dPA;
logic dCached; logic dCached;
// ================================ logic dEn, drEn, dwEn;
// ======== dState Machine ======== logic dValid1, dwr1;
// ================================ logic dCached1;
word_t dPA1;
logic [3:0] dWstrb1;
word_t dWdata1;
word_t drD1, drD2, drD3;
// ============================ // ============================
// ======== dFlip-Flop ======== // ======== 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 ========== // ========== 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 ========== // ========== VA -> PA ==========