tlb mmu with cache
simplify AXI
This commit is contained in:
parent
a83967f9b9
commit
94e9b7bcbd
@ -2,8 +2,8 @@
|
||||
`include "sram.svh"
|
||||
|
||||
module AXI (
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
// AXI Read
|
||||
AXIRead_i.master AXIRead,
|
||||
@ -26,24 +26,19 @@ module AXI (
|
||||
// ==============================
|
||||
|
||||
always_comb begin
|
||||
inst.rdata = 0;
|
||||
inst.rvalid = 0;
|
||||
inst.data_ok = 0;
|
||||
|
||||
rdata.rdata = 0;
|
||||
rdata.rvalid = 0;
|
||||
rdata.data_ok = 0;
|
||||
|
||||
if (AXIRead.AXIReadData.rvalid) begin
|
||||
if (AXIRead.AXIReadData.rid == 0) begin
|
||||
inst.rdata = AXIRead.AXIReadData.rdata;
|
||||
inst.rvalid = 1'b1;
|
||||
inst.data_ok = AXIRead.AXIReadData.rlast;
|
||||
end else begin // not zero -> D-Cache Read(1)
|
||||
rdata.rdata = AXIRead.AXIReadData.rdata;
|
||||
rdata.rvalid = 1'b1;
|
||||
|
||||
if (AXIRead.AXIReadData.rid == 0) begin
|
||||
inst.rvalid = AXIRead.AXIReadData.rvalid;
|
||||
inst.data_ok = AXIRead.AXIReadData.rlast;
|
||||
rdata.rvalid = 1'b0;
|
||||
rdata.data_ok = 1'b0;
|
||||
end else begin
|
||||
rdata.rvalid = AXIRead.AXIReadData.rvalid;
|
||||
rdata.data_ok = AXIRead.AXIReadData.rlast;
|
||||
end
|
||||
inst.rvalid = 1'b0;
|
||||
inst.data_ok = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
@ -55,40 +50,26 @@ module AXI (
|
||||
// Constants
|
||||
AXIRead.AXIReadAddr.arcache = 4'b0;
|
||||
AXIRead.AXIReadAddr.arlock = 2'b0;
|
||||
AXIRead.AXIReadAddr.rready = 1'b1;
|
||||
|
||||
// Burst
|
||||
AXIRead.AXIReadAddr.arlen = 4'b0011;
|
||||
AXIRead.AXIReadAddr.arsize = 3'b010;
|
||||
AXIRead.AXIReadAddr.arburst = 2'b10; // Wrap
|
||||
|
||||
// 据情况修改的东西
|
||||
AXIRead.AXIReadAddr.arid = 4'b0; // ICache(0) DCache(1)
|
||||
AXIRead.AXIReadAddr.arprot = 3'b101; // ICache(101) DCache(001)
|
||||
AXIRead.AXIReadAddr.araddr = 32'b0;
|
||||
AXIRead.AXIReadAddr.rready = 1'b1;
|
||||
|
||||
AXIRead.AXIReadAddr.arvalid = rdata.req | inst.req;
|
||||
if (AXIRead.AXIReadData.arready) begin
|
||||
if (rdata.req) begin
|
||||
AXIRead.AXIReadAddr.arid = 4'b0001;
|
||||
AXIRead.AXIReadAddr.arprot = 3'b001;
|
||||
AXIRead.AXIReadAddr.araddr = rdata.addr;
|
||||
AXIRead.AXIReadAddr.arlen = {1'b0, rdata.size};
|
||||
rdata.addr_ok = 1'b1;
|
||||
rdata.addr_ok = AXIRead.AXIReadData.arready;
|
||||
inst.addr_ok = 1'b0;
|
||||
end else if (inst.req) begin
|
||||
end else begin
|
||||
AXIRead.AXIReadAddr.arid = 4'b0000;
|
||||
AXIRead.AXIReadAddr.arprot = 3'b101;
|
||||
AXIRead.AXIReadAddr.araddr = inst.addr;
|
||||
AXIRead.AXIReadAddr.arlen = {1'b0, inst.size};
|
||||
inst.addr_ok = 1'b1;
|
||||
rdata.addr_ok = 1'b0;
|
||||
end else begin
|
||||
inst.addr_ok = 1'b0;
|
||||
rdata.addr_ok = 1'b0;
|
||||
end
|
||||
end else begin
|
||||
inst.addr_ok = 1'b0;
|
||||
inst.addr_ok = AXIRead.AXIReadData.arready;
|
||||
rdata.addr_ok = 1'b0;
|
||||
end
|
||||
|
||||
@ -102,46 +83,30 @@ module AXI (
|
||||
assign wdata.wready = AXIWrite.AXIWriteData.wready;
|
||||
|
||||
always_comb begin
|
||||
AXIWrite.AXIWriteAddr.wid = 1;
|
||||
AXIWrite.AXIWriteAddr.wdata = 0;
|
||||
AXIWrite.AXIWriteAddr.wstrb = 0;
|
||||
AXIWrite.AXIWriteAddr.wlast = 0;
|
||||
AXIWrite.AXIWriteAddr.wvalid = 0;
|
||||
|
||||
if (wdata.wvalid) begin
|
||||
AXIWrite.AXIWriteAddr.wid = 4'b1;
|
||||
AXIWrite.AXIWriteAddr.wdata = wdata.wdata;
|
||||
AXIWrite.AXIWriteAddr.wstrb = wdata.wstrb;
|
||||
AXIWrite.AXIWriteAddr.wlast = wdata.wlast;
|
||||
AXIWrite.AXIWriteAddr.wvalid = 1'b1;
|
||||
AXIWrite.AXIWriteAddr.wvalid = wdata.wvalid;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always_comb begin
|
||||
// Constants
|
||||
AXIWrite.AXIWriteAddr.awcache = 4'b0;
|
||||
AXIWrite.AXIWriteAddr.awlock = 2'b0;
|
||||
AXIWrite.AXIWriteAddr.bready = 1'b1;
|
||||
|
||||
// Burst
|
||||
AXIWrite.AXIWriteAddr.awlen = 4'b0011;
|
||||
AXIWrite.AXIWriteAddr.awsize = 3'b010;
|
||||
AXIWrite.AXIWriteAddr.awburst = 2'b01; // Incr
|
||||
|
||||
AXIWrite.AXIWriteAddr.awid = 4'b1; // ICache(0) DCache(1)
|
||||
AXIWrite.AXIWriteAddr.awprot = 3'b001; // ICache(101) DCache(001)
|
||||
AXIWrite.AXIWriteAddr.awaddr = 32'b0;
|
||||
AXIWrite.AXIWriteAddr.awvalid = 1'b0;
|
||||
AXIWrite.AXIWriteAddr.bready = 1'b1;
|
||||
AXIWrite.AXIWriteAddr.awid = 4'b1;
|
||||
AXIWrite.AXIWriteAddr.awprot = 3'b001;
|
||||
|
||||
AXIWrite.AXIWriteAddr.awvalid = wdata.req;
|
||||
if (AXIWrite.AXIWriteData.awready) begin
|
||||
if (wdata.req) begin
|
||||
AXIWrite.AXIWriteAddr.awaddr = wdata.addr;
|
||||
AXIWrite.AXIWriteAddr.awlen = {2'b0, wdata.size};
|
||||
wdata.addr_ok = 1'b1;
|
||||
end else wdata.addr_ok = 0;
|
||||
end else wdata.addr_ok = 0;
|
||||
wdata.addr_ok = AXIWrite.AXIWriteData.awready;
|
||||
end
|
||||
|
||||
|
||||
|
@ -35,10 +35,7 @@ module DCache (
|
||||
DCData_t dataOut[4];
|
||||
logic [3:0] tagV;
|
||||
|
||||
logic valid;
|
||||
word_t addr;
|
||||
logic [32-`DC_TAGL-1:0] tag;
|
||||
logic [`DC_TAGL-`DC_INDEXL-1:0] index;
|
||||
DCIndexL_t index1;
|
||||
|
||||
logic hit;
|
||||
logic [3:0] hitWay;
|
||||
@ -46,11 +43,11 @@ module DCache (
|
||||
|
||||
logic [3:0] victim;
|
||||
logic [3:0] wen;
|
||||
logic [3:0] replaceWen;
|
||||
logic [3:0] wen2;
|
||||
|
||||
logic en1, en2; // en1: Lookup->Lookup, en2: Lookup->Rep
|
||||
|
||||
logic [`DC_TAGL-`DC_INDEXL-1:0] baddr;
|
||||
DCIndexL_t baddr;
|
||||
logic bwe1, bwe2; // bwe1: Lookup -> Write, bwe2: Replace -> Lookup
|
||||
|
||||
DCData_t wdata1[4], wdata2[4];
|
||||
@ -59,24 +56,17 @@ module DCache (
|
||||
// ======== Flip-Flop ========
|
||||
// ===========================
|
||||
|
||||
ffenr #(1) valid_ff (
|
||||
ffen #(`DC_TAGL-`DC_INDEXL) index_ff (
|
||||
clk,
|
||||
rst,
|
||||
port.valid,
|
||||
port.index,
|
||||
en1,
|
||||
valid
|
||||
);
|
||||
ffen #(32) addr_ff (
|
||||
clk,
|
||||
port.addr,
|
||||
en1,
|
||||
addr
|
||||
index1
|
||||
);
|
||||
ffen #(4) wen_ff (
|
||||
clk,
|
||||
wen,
|
||||
en2,
|
||||
replaceWen
|
||||
wen2
|
||||
);
|
||||
|
||||
// ===============================
|
||||
@ -98,7 +88,7 @@ module DCache (
|
||||
nextState = state;
|
||||
case (state)
|
||||
LOOKUP: begin
|
||||
if (~valid | hit) begin // hit
|
||||
if (~port.valid | hit) begin // hit
|
||||
if (port.wvalid) begin // write
|
||||
bwe1 = 1'b1;
|
||||
end else begin // read
|
||||
@ -139,13 +129,10 @@ module DCache (
|
||||
assign tagV[3] = tagOut[3].valid;
|
||||
|
||||
// Hit Check
|
||||
assign tag = addr[31:`DC_TAGL];
|
||||
assign index = addr[`DC_TAGL-1:`DC_INDEXL];
|
||||
|
||||
assign hitWay[0] = tagV[0] & tagOut[0].tag == tag;
|
||||
assign hitWay[1] = tagV[1] & tagOut[1].tag == tag;
|
||||
assign hitWay[2] = tagV[2] & tagOut[2].tag == tag;
|
||||
assign hitWay[3] = tagV[3] & tagOut[3].tag == tag;
|
||||
assign hitWay[0] = tagV[0] & tagOut[0].tag == port.tag1;
|
||||
assign hitWay[1] = tagV[1] & tagOut[1].tag == port.tag1;
|
||||
assign hitWay[2] = tagV[2] & tagOut[2].tag == port.tag1;
|
||||
assign hitWay[3] = tagV[3] & tagOut[3].tag == port.tag1;
|
||||
assign hit = |{hitWay};
|
||||
|
||||
assign cacheLine = (hitWay[0] ? dataOut[0] : `DC_DATA_LENGTH'b0)
|
||||
@ -182,7 +169,8 @@ module DCache (
|
||||
| (victim[1] ? tagOut[1].tag : {(32-`DC_TAGL){1'b0}})
|
||||
| (victim[2] ? tagOut[2].tag : {(32-`DC_TAGL){1'b0}})
|
||||
| (victim[3] ? tagOut[3].tag : {(32-`DC_TAGL){1'b0}}),
|
||||
index, 4'b0};
|
||||
index1, 4'b0
|
||||
};
|
||||
assign port.dirt_data = (victim[0] ? dataOut[0] : `DC_DATA_LENGTH'b0)
|
||||
| (victim[1] ? dataOut[1] : `DC_DATA_LENGTH'b0)
|
||||
| (victim[2] ? dataOut[2] : `DC_DATA_LENGTH'b0)
|
||||
@ -199,11 +187,13 @@ module DCache (
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
for (integer i = 0; i < 128; i++)
|
||||
LRU[i] = 4'b0;
|
||||
nowLRU = 4'b0;
|
||||
LRU[i] <= 4'b0;
|
||||
end else begin
|
||||
if (state == LOOKUP & valid) LRU[index] = nextLRU;
|
||||
nowLRU = LRU[port.addr[`DC_TAGL-1:`DC_INDEXL]];
|
||||
if (en1) begin
|
||||
nowLRU <= LRU[port.index];
|
||||
if (port.valid)
|
||||
LRU[index1] <= nextLRU;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -212,8 +202,8 @@ module DCache (
|
||||
// ==============================
|
||||
|
||||
mux2 #(`DC_TAGL-`DC_INDEXL) index_mux (
|
||||
index,
|
||||
port.addr[`DC_TAGL-1:`DC_INDEXL],
|
||||
index1,
|
||||
port.index,
|
||||
en1,
|
||||
baddr
|
||||
);
|
||||
@ -228,19 +218,19 @@ module DCache (
|
||||
assign DataRAM2.addr = baddr;
|
||||
assign DataRAM3.addr = baddr;
|
||||
// 写使能
|
||||
assign TagRAM0.wen = (bwe1 & wen[0]) | (bwe2 & replaceWen[0]);
|
||||
assign TagRAM1.wen = (bwe1 & wen[1]) | (bwe2 & replaceWen[1]);
|
||||
assign TagRAM2.wen = (bwe1 & wen[2]) | (bwe2 & replaceWen[2]);
|
||||
assign TagRAM3.wen = (bwe1 & wen[3]) | (bwe2 & replaceWen[3]);
|
||||
assign DataRAM0.wen = (bwe1 & wen[0]) | (bwe2 & replaceWen[0]);
|
||||
assign DataRAM1.wen = (bwe1 & wen[1]) | (bwe2 & replaceWen[1]);
|
||||
assign DataRAM2.wen = (bwe1 & wen[2]) | (bwe2 & replaceWen[2]);
|
||||
assign DataRAM3.wen = (bwe1 & wen[3]) | (bwe2 & replaceWen[3]);
|
||||
assign TagRAM0.wen = (bwe1 & wen[0]) | (bwe2 & wen2[0]);
|
||||
assign TagRAM1.wen = (bwe1 & wen[1]) | (bwe2 & wen2[1]);
|
||||
assign TagRAM2.wen = (bwe1 & wen[2]) | (bwe2 & wen2[2]);
|
||||
assign TagRAM3.wen = (bwe1 & wen[3]) | (bwe2 & wen2[3]);
|
||||
assign DataRAM0.wen = (bwe1 & wen[0]) | (bwe2 & wen2[0]);
|
||||
assign DataRAM1.wen = (bwe1 & wen[1]) | (bwe2 & wen2[1]);
|
||||
assign DataRAM2.wen = (bwe1 & wen[2]) | (bwe2 & wen2[2]);
|
||||
assign DataRAM3.wen = (bwe1 & wen[3]) | (bwe2 & wen2[3]);
|
||||
// 写数据
|
||||
assign TagRAM0.wdata = {tag, port.wvalid, 1'b1};
|
||||
assign TagRAM1.wdata = {tag, port.wvalid, 1'b1};
|
||||
assign TagRAM2.wdata = {tag, port.wvalid, 1'b1};
|
||||
assign TagRAM3.wdata = {tag, port.wvalid, 1'b1};
|
||||
assign TagRAM0.wdata = {port.tag1, port.wvalid, 1'b1};
|
||||
assign TagRAM1.wdata = {port.tag1, port.wvalid, 1'b1};
|
||||
assign TagRAM2.wdata = {port.tag1, port.wvalid, 1'b1};
|
||||
assign TagRAM3.wdata = {port.tag1, port.wvalid, 1'b1};
|
||||
|
||||
assign DataRAM0.wdata = state == LOOKUP ? wdata1[0] : wdata2[0];
|
||||
assign DataRAM1.wdata = state == LOOKUP ? wdata1[1] : wdata2[1];
|
||||
@ -254,7 +244,7 @@ module DCache (
|
||||
wdata2[i] = port.rdata;
|
||||
|
||||
if (port.wvalid) begin
|
||||
case (addr[3:2])
|
||||
case (port.sel1)
|
||||
2'b11: begin
|
||||
if (port.wstrb[3]) wdata1[i][127:120] = port.wdata[31:24];
|
||||
if (port.wstrb[2]) wdata1[i][119:112] = port.wdata[23:16];
|
||||
@ -280,7 +270,7 @@ module DCache (
|
||||
if (port.wstrb[0]) wdata1[i][ 7: 0] = port.wdata[ 7: 0];
|
||||
end
|
||||
endcase
|
||||
case (addr[3:2])
|
||||
case (port.sel1)
|
||||
2'b11: begin
|
||||
if (port.wstrb[3]) wdata2[i][127:120] = port.wdata[31:24];
|
||||
if (port.wstrb[2]) wdata2[i][119:112] = port.wdata[23:16];
|
||||
@ -311,7 +301,7 @@ module DCache (
|
||||
end
|
||||
endgenerate
|
||||
|
||||
logic [`DC_TAGL-`DC_INDEXL-1:0] rst_index;
|
||||
DCIndexL_t rst_index;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
rst_index <= rst_index + 1;
|
||||
|
@ -4,7 +4,8 @@
|
||||
`include "AXI.svh"
|
||||
|
||||
module ICache (
|
||||
input clk, rst,
|
||||
input clk,
|
||||
input rst,
|
||||
ICache_i.cache port
|
||||
);
|
||||
|
||||
@ -24,10 +25,7 @@ module ICache (
|
||||
ICData_t dataOut[4];
|
||||
logic [3:0] tagV;
|
||||
|
||||
logic valid;
|
||||
word_t addr;
|
||||
logic [32-`IC_TAGL-1:0] tag;
|
||||
logic [`IC_TAGL-`IC_INDEXL-1:0] index;
|
||||
ICIndexL_t index1;
|
||||
|
||||
logic hit;
|
||||
logic [3:0] hitWay;
|
||||
@ -35,37 +33,51 @@ module ICache (
|
||||
|
||||
logic [3:0] victim;
|
||||
logic [3:0] wen;
|
||||
logic [3:0] replaceWen;
|
||||
logic [3:0] wen2;
|
||||
|
||||
logic en1, en2; // en1: Lookup->Lookup, en2: Lookup->Rep
|
||||
|
||||
logic [`IC_TAGL-`IC_INDEXL-1:0] baddr;
|
||||
ICIndexL_t baddr;
|
||||
logic bwe;
|
||||
|
||||
// ===========================
|
||||
// ======== Flip-Flop ========
|
||||
// ===========================
|
||||
|
||||
ffenr#(1) valid_ff(clk, rst, port.valid, en1, valid);
|
||||
ffen#(32) addr_ff(clk, port.addr, en1, addr);
|
||||
ffen#(4) wen_ff(clk, wen, en2, replaceWen);
|
||||
ffen#(`IC_TAGL-`IC_INDEXL) index_ff(clk, port.index, en1, index1);
|
||||
ffen#(4) wen_ff(clk, wen, en2, wen2);
|
||||
|
||||
// ===============================
|
||||
// ======== State Machine ========
|
||||
// ===============================
|
||||
|
||||
enum bit { LOOKUP, REPLACE } state;
|
||||
enum bit { LOOKUP, REPLACE } state, nextState;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) state <= LOOKUP;
|
||||
else if(state == LOOKUP & valid & ~hit)
|
||||
state <= REPLACE;
|
||||
else if(state == REPLACE & port.rvalid)
|
||||
state <= LOOKUP;
|
||||
else state <= nextState;
|
||||
end
|
||||
|
||||
assign en1 = state == LOOKUP & (~valid | hit);
|
||||
assign en2 = state == LOOKUP & valid & ~hit;
|
||||
always_comb begin
|
||||
en1 = 1'b0;
|
||||
en2 = 1'b0;
|
||||
|
||||
case (state)
|
||||
LOOKUP: begin
|
||||
if (~port.valid | hit) begin
|
||||
en1 = 1'b1;
|
||||
end else begin
|
||||
en2 = 1'b1;
|
||||
nextState = REPLACE;
|
||||
end
|
||||
end
|
||||
REPLACE: begin
|
||||
if (port.rvalid) begin
|
||||
nextState = LOOKUP;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// ==============================
|
||||
// =========== Lookup ===========
|
||||
@ -88,13 +100,10 @@ module ICache (
|
||||
assign tagV[3] = tagOut[3].valid;
|
||||
|
||||
// Hit Check
|
||||
assign tag = addr[31:`IC_TAGL];
|
||||
assign index = addr[`IC_TAGL-1:`IC_INDEXL];
|
||||
|
||||
assign hitWay[0] = tagV[0] & tagOut[0].tag == tag;
|
||||
assign hitWay[1] = tagV[1] & tagOut[1].tag == tag;
|
||||
assign hitWay[2] = tagV[2] & tagOut[2].tag == tag;
|
||||
assign hitWay[3] = tagV[3] & tagOut[3].tag == tag;
|
||||
assign hitWay[0] = tagV[0] & tagOut[0].tag == port.tag1;
|
||||
assign hitWay[1] = tagV[1] & tagOut[1].tag == port.tag1;
|
||||
assign hitWay[2] = tagV[2] & tagOut[2].tag == port.tag1;
|
||||
assign hitWay[3] = tagV[3] & tagOut[3].tag == port.tag1;
|
||||
assign hit = |{hitWay};
|
||||
|
||||
assign cacheLine = (hitWay[0] ? dataOut[0] : `IC_DATA_LENGTH'b0)
|
||||
@ -128,14 +137,15 @@ module ICache (
|
||||
wen[0] | nowLRU[0] & ~|{nowLRU | wen}
|
||||
};
|
||||
|
||||
generate
|
||||
for (genvar i = 0; i < 64; i++)
|
||||
initial LRU[i] = 4'b0;
|
||||
endgenerate
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (state == LOOKUP & valid) LRU[index] = nextLRU;
|
||||
nowLRU = LRU[port.addr[`IC_TAGL-1:`IC_INDEXL]];
|
||||
if (en1) begin
|
||||
nowLRU <= LRU[port.index];
|
||||
if (port.valid)
|
||||
LRU[index1] <= nextLRU;
|
||||
end
|
||||
end
|
||||
|
||||
// ==============================
|
||||
@ -143,8 +153,8 @@ module ICache (
|
||||
// ==============================
|
||||
|
||||
mux2 #(`IC_TAGL-`IC_INDEXL) index_mux (
|
||||
index,
|
||||
port.addr[`IC_TAGL-1:`IC_INDEXL],
|
||||
index1,
|
||||
port.index,
|
||||
en1,
|
||||
baddr
|
||||
);
|
||||
@ -160,19 +170,19 @@ module ICache (
|
||||
assign DataRAM2.addr = baddr;
|
||||
assign DataRAM3.addr = baddr;
|
||||
// 写使能
|
||||
assign TagRAM0.wen = bwe & replaceWen[0];
|
||||
assign TagRAM1.wen = bwe & replaceWen[1];
|
||||
assign TagRAM2.wen = bwe & replaceWen[2];
|
||||
assign TagRAM3.wen = bwe & replaceWen[3];
|
||||
assign DataRAM0.wen = bwe & replaceWen[0];
|
||||
assign DataRAM1.wen = bwe & replaceWen[1];
|
||||
assign DataRAM2.wen = bwe & replaceWen[2];
|
||||
assign DataRAM3.wen = bwe & replaceWen[3];
|
||||
assign TagRAM0.wen = bwe & wen2[0];
|
||||
assign TagRAM1.wen = bwe & wen2[1];
|
||||
assign TagRAM2.wen = bwe & wen2[2];
|
||||
assign TagRAM3.wen = bwe & wen2[3];
|
||||
assign DataRAM0.wen = bwe & wen2[0];
|
||||
assign DataRAM1.wen = bwe & wen2[1];
|
||||
assign DataRAM2.wen = bwe & wen2[2];
|
||||
assign DataRAM3.wen = bwe & wen2[3];
|
||||
// 写数据
|
||||
assign TagRAM0.wdata = {tag, 1'b1};
|
||||
assign TagRAM1.wdata = {tag, 1'b1};
|
||||
assign TagRAM2.wdata = {tag, 1'b1};
|
||||
assign TagRAM3.wdata = {tag, 1'b1};
|
||||
assign TagRAM0.wdata = {port.tag1, 1'b1};
|
||||
assign TagRAM1.wdata = {port.tag1, 1'b1};
|
||||
assign TagRAM2.wdata = {port.tag1, 1'b1};
|
||||
assign TagRAM3.wdata = {port.tag1, 1'b1};
|
||||
assign DataRAM0.wdata = port.rdata;
|
||||
assign DataRAM1.wdata = port.rdata;
|
||||
assign DataRAM2.wdata = port.rdata;
|
||||
@ -236,6 +246,5 @@ module ICache (
|
||||
.wea (DataRAM3.wen)
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
137
src/MMU/MMU.sv
137
src/MMU/MMU.sv
@ -2,13 +2,26 @@
|
||||
`include "sram.svh"
|
||||
`include "ICache.svh"
|
||||
`include "DCache.svh"
|
||||
`include "TLB.svh"
|
||||
`include "AXI.svh"
|
||||
|
||||
module MMU (
|
||||
input clk,
|
||||
rst,
|
||||
input rst,
|
||||
|
||||
input logic [2:0] K0,
|
||||
input logic tlbwi, // TLBWI -> Write TLB
|
||||
input logic tlbp, // TLBP -> Write CP0 Index
|
||||
input Index_t c0_Index, // TLBR
|
||||
input EntryHi_t c0_EntryHi, // TLBWI + F/M(ASID)
|
||||
input PageMask_t c0_PageMask, // TLBWI
|
||||
input EntryLo_t c0_EntryLo1, // TLBWI
|
||||
input EntryLo_t c0_EntryLo0, // TLBWI
|
||||
output EntryHi_t EntryHi, // TLBR
|
||||
output PageMask_t PageMask, // TLBR
|
||||
output EntryLo_t EntryLo1, // TLBR
|
||||
output EntryLo_t EntryLo0, // TLBR
|
||||
output Index_t Index, // TLBP
|
||||
|
||||
ICache_i.mmu ic,
|
||||
DCache_i.mmu dc,
|
||||
@ -26,12 +39,13 @@ module MMU (
|
||||
// ======================
|
||||
|
||||
word_t iVA;
|
||||
word_t iPA;
|
||||
logic iCached;
|
||||
|
||||
logic iEn;
|
||||
logic iValid1;
|
||||
logic iReq1;
|
||||
logic iHit1;
|
||||
logic iCached1;
|
||||
logic iMValid1;
|
||||
logic iValid1;
|
||||
word_t iPA1;
|
||||
|
||||
word_t iD1, iD2, iD3, iD4, iD5, iD6, iD7;
|
||||
@ -132,19 +146,7 @@ module MMU (
|
||||
rst,
|
||||
inst.req,
|
||||
iEn,
|
||||
iValid1
|
||||
);
|
||||
ffen #(1) icached_ff (
|
||||
clk,
|
||||
iCached,
|
||||
iEn,
|
||||
iCached1
|
||||
);
|
||||
ffen #(32) ipa_ff (
|
||||
clk,
|
||||
iPA,
|
||||
iEn,
|
||||
iPA1
|
||||
iReq1
|
||||
);
|
||||
|
||||
ffen #(32) id1_ff (
|
||||
@ -194,6 +196,8 @@ module MMU (
|
||||
// ========== iFunction ==========
|
||||
// ===============================
|
||||
|
||||
assign iValid1 = iReq1 & iHit1 & iMValid1;
|
||||
|
||||
assign iVA = inst.addr;
|
||||
assign inst.addr_ok = iEn;
|
||||
mux5 #(64) inst_rdata_mux (
|
||||
@ -206,8 +210,9 @@ module MMU (
|
||||
{inst.rdata1, inst.rdata0}
|
||||
);
|
||||
|
||||
assign ic.valid = inst.req & iEn & iCached;
|
||||
assign ic.addr = iPA;
|
||||
assign ic.valid = iReq1 & iCached1;
|
||||
assign ic.index = iVA[`IC_TAGL-1:`IC_INDEXL];
|
||||
assign ic.tag1 = iPA1[31:`IC_TAGL];
|
||||
assign ic.rvalid = inst_axi.data_ok;
|
||||
|
||||
mux4 #(256) ic_rdata_mux (
|
||||
@ -227,12 +232,14 @@ module MMU (
|
||||
// ======================
|
||||
|
||||
word_t dVA;
|
||||
word_t dPA;
|
||||
logic dCached;
|
||||
|
||||
logic dEn;
|
||||
logic dValid1;
|
||||
logic dReq1;
|
||||
logic dHit1;
|
||||
logic dCached1;
|
||||
logic dDirty1;
|
||||
logic dMValid1;
|
||||
logic dValid1;
|
||||
word_t dPA1;
|
||||
|
||||
logic dwEn;
|
||||
@ -255,19 +262,7 @@ module MMU (
|
||||
rst,
|
||||
data.req,
|
||||
dEn,
|
||||
dValid1
|
||||
);
|
||||
ffen #(1) dcached_ff (
|
||||
clk,
|
||||
dCached,
|
||||
dEn,
|
||||
dCached1
|
||||
);
|
||||
ffen #(32) dpa_ff (
|
||||
clk,
|
||||
dPA,
|
||||
dEn,
|
||||
dPA1
|
||||
dReq1
|
||||
);
|
||||
ffen #(1) dwr_ff (
|
||||
clk,
|
||||
@ -293,6 +288,7 @@ module MMU (
|
||||
// ================================
|
||||
|
||||
assign dVA = data.addr;
|
||||
assign dValid1 = dReq1 & dHit1 & dMValid1;
|
||||
|
||||
// =================================
|
||||
// ======== drState Machine ========
|
||||
@ -323,7 +319,7 @@ module MMU (
|
||||
rdata_axi.req = 0;
|
||||
case (drState)
|
||||
DR_IDLE: begin
|
||||
if (~dValid1) dEn = 1;
|
||||
if (~dValid1 | dDirty1) dEn = 1;
|
||||
else begin
|
||||
dwEn = 1;
|
||||
if (data.wr) data.data_ok = 1;
|
||||
@ -372,7 +368,7 @@ module MMU (
|
||||
if (rdata_axi.rvalid) drNextState = DR_REFILL;
|
||||
end
|
||||
DR_REFILL: begin
|
||||
if (wdata_ok) begin // TODO
|
||||
if (wdata_ok) begin
|
||||
dEn = 1;
|
||||
drNextState = DR_IDLE;
|
||||
end
|
||||
@ -418,8 +414,10 @@ module MMU (
|
||||
data.rdata
|
||||
);
|
||||
|
||||
assign dc.valid = data.req & dEn & dCached;
|
||||
assign dc.addr = dPA;
|
||||
assign dc.valid = dValid1 & dCached1;
|
||||
assign dc.index = dVA[`DC_TAGL-1:`DC_INDEXL];
|
||||
assign dc.tag1 = dPA1[31:`DC_TAGL];
|
||||
assign dc.sel1 = dPA1[3:2];
|
||||
assign dc.rvalid = rdata_axi.data_ok;
|
||||
mux4 #(128) dc_rdata_mux (
|
||||
{rdata_axi.rdata, drD3, drD2, drD1},
|
||||
@ -620,39 +618,38 @@ module MMU (
|
||||
// ========== VA -> PA ==========
|
||||
// ==============================
|
||||
|
||||
mapping mapping_inst (
|
||||
.addr_in (iVA),
|
||||
.addr_out(iPA),
|
||||
.K0 (K0),
|
||||
.cached (iCached)
|
||||
);
|
||||
TLB TLB (
|
||||
.clk(clk),
|
||||
.iEn(iEn),
|
||||
.dEn(dEn),
|
||||
|
||||
mapping mapping_data (
|
||||
.addr_in (dVA),
|
||||
.addr_out(dPA),
|
||||
.K0 (K0),
|
||||
.cached (dCached)
|
||||
.tlbwi (tlbwi),
|
||||
.tlbp (tlbp),
|
||||
.c0_Index (c0_Index),
|
||||
.c0_EntryHi (c0_EntryHi),
|
||||
.c0_PageMask(c0_PageMask),
|
||||
.c0_EntryLo1(c0_EntryLo1),
|
||||
.c0_EntryLo0(c0_EntryLo0),
|
||||
|
||||
.EntryHi (EntryHi),
|
||||
.PageMask(PageMask),
|
||||
.EntryLo1(EntryLo1),
|
||||
.EntryLo0(EntryLo0),
|
||||
.Index (Index),
|
||||
|
||||
.iVAddr (iVA),
|
||||
.iPAddr (iPA1),
|
||||
.iHit (iHit1),
|
||||
.iCached(iCached1),
|
||||
.iValid (iMValid1),
|
||||
|
||||
.dVAddr (dVA),
|
||||
.dPAddr (dPA1),
|
||||
.dHit (dHit1),
|
||||
.dCached(dCached1),
|
||||
.dDirty (dDirty1),
|
||||
.dValid (dMValid1)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
module mapping (
|
||||
input logic [2:0] K0,
|
||||
input word_t addr_in,
|
||||
output word_t addr_out,
|
||||
output logic cached
|
||||
);
|
||||
always_comb begin
|
||||
if (addr_in > 32'hBFFF_FFFF || addr_in <= 32'h7FFF_FFFF) begin // kseg2 + kseg3 + kuseg? -> tlb
|
||||
addr_out = addr_in;
|
||||
cached = 1'b1;
|
||||
end else if (addr_in > 32'h9FFF_FFFF) begin // kseg1 uncached
|
||||
addr_out = addr_in & 32'h1FFF_FFFF;
|
||||
cached = 1'b0;
|
||||
end else begin // kseg0 -> CP0.K0
|
||||
addr_out = addr_in & 32'h1FFF_FFFF;
|
||||
cached = (K0 == 3'b011);
|
||||
end
|
||||
// cached = ~(addr_out >= 32'h1faf0000 & addr_out <= 32'h1fafffff);
|
||||
end
|
||||
endmodule
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
module TLB (
|
||||
input clk,
|
||||
input rst,
|
||||
input logic iEn,
|
||||
input logic dEn,
|
||||
|
||||
// CP0
|
||||
input logic [2:0] K0,
|
||||
@ -67,7 +68,7 @@ module TLB (
|
||||
|
||||
assign EntryHi.zero = 5'b0;
|
||||
assign EntryHi.VPN2 = entry.VPN2;
|
||||
assign EntryHi.VPN2 = entry.ASID;
|
||||
assign EntryHi.ASID = entry.ASID;
|
||||
|
||||
assign PageMask.zero1 = 7'b0;
|
||||
assign PageMask.Mask = entry.PageMask;
|
||||
@ -98,7 +99,7 @@ module TLB (
|
||||
ffen #(32) mVAddr_ff (
|
||||
clk,
|
||||
{mVAddr, dVAddr[11:0]},
|
||||
1'b1,
|
||||
dEn,
|
||||
mVAddr1
|
||||
);
|
||||
TLB_Lookup Lookup_M(
|
||||
@ -118,7 +119,7 @@ module TLB (
|
||||
ffen #(32) fVAddr_ff (
|
||||
clk,
|
||||
iVAddr,
|
||||
1'b1,
|
||||
iEn,
|
||||
fVAddr1
|
||||
);
|
||||
TLB_Lookup Lookup_F (
|
||||
@ -129,7 +130,9 @@ module TLB (
|
||||
.PPN(fPAddr),
|
||||
.hit(fHit),
|
||||
.cached(fCached),
|
||||
.valid(fValid)
|
||||
.dirty(),
|
||||
.valid(fValid),
|
||||
.index()
|
||||
);
|
||||
|
||||
// Output
|
||||
|
@ -9,31 +9,35 @@
|
||||
`define DC_TAG_LENGTH 23 // Tag + Valid + Dirty
|
||||
`define DC_DATA_LENGTH 128 // 16Bytes
|
||||
|
||||
typedef logic [`DC_DATA_LENGTH-1:0] DCData_t;
|
||||
typedef logic [32-`DC_TAGL-1:0] DCTagL_t;
|
||||
typedef logic [`DC_TAGL-`DC_INDEXL-1:0] DCIndexL_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [32-`DC_TAGL-1:0] tag;
|
||||
DCTagL_t tag;
|
||||
logic dirty;
|
||||
logic valid;
|
||||
} DCTag_t;
|
||||
|
||||
typedef logic [`DC_DATA_LENGTH-1:0] DCData_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic wen;
|
||||
logic [`DC_TAGL-`DC_INDEXL-1:0] addr; // Index
|
||||
DCIndexL_t addr; // Index
|
||||
DCTag_t wdata;
|
||||
DCTag_t rdata;
|
||||
} DCTagRAM_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic wen;
|
||||
logic [`DC_TAGL-`DC_INDEXL-1:0] addr; // Index
|
||||
DCIndexL_t addr; // Index
|
||||
DCData_t wdata;
|
||||
DCData_t rdata;
|
||||
} DCDataRAM_t;
|
||||
|
||||
interface DCache_i;
|
||||
logic valid;
|
||||
word_t addr;
|
||||
DCIndexL_t index;
|
||||
DCTagL_t tag1;
|
||||
logic [1:0] sel1; // addr[3:2]
|
||||
logic hit;
|
||||
logic rvalid; // MMU(AXI) -> DCache
|
||||
DCData_t rdata;
|
||||
@ -46,11 +50,15 @@ interface DCache_i;
|
||||
DCData_t row;
|
||||
|
||||
modport cache(
|
||||
input valid, addr, rvalid, rdata, wvalid, wdata, wstrb,
|
||||
input valid,
|
||||
input index, tag1, sel1,
|
||||
input rvalid, rdata, wvalid, wdata, wstrb,
|
||||
output hit, dirt_valid, dirt_addr, dirt_data, row
|
||||
);
|
||||
modport mmu(
|
||||
output valid, addr, rvalid, rdata, wvalid, wdata, wstrb,
|
||||
output valid,
|
||||
output index, tag1, sel1,
|
||||
output rvalid, rdata, wvalid, wdata, wstrb,
|
||||
input hit, dirt_valid, dirt_addr, dirt_data, row
|
||||
);
|
||||
endinterface //DCache_i
|
||||
|
@ -9,36 +9,46 @@
|
||||
`define IC_TAG_LENGTH (32-`IC_TAGL+1) // Tag + Valid
|
||||
`define IC_DATA_LENGTH 256 // 32Bytes
|
||||
|
||||
typedef logic [`IC_DATA_LENGTH-1:0] ICData_t;
|
||||
typedef logic [32-`IC_TAGL-1:0] ICTagL_t;
|
||||
typedef logic [`IC_TAGL-`IC_INDEXL-1:0] ICIndexL_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic [32-`IC_TAGL-1:0] tag;
|
||||
ICTagL_t tag;
|
||||
logic valid;
|
||||
} ICTag_t;
|
||||
typedef logic [`IC_DATA_LENGTH-1:0] ICData_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic wen;
|
||||
logic [`IC_TAGL-`IC_INDEXL-1:0] addr; // Index
|
||||
ICIndexL_t addr; // Index
|
||||
ICTag_t wdata;
|
||||
ICTag_t rdata;
|
||||
} ICTagRAM_t;
|
||||
|
||||
typedef struct packed {
|
||||
logic wen;
|
||||
logic [`IC_TAGL-`IC_INDEXL-1:0] addr; // Index
|
||||
ICIndexL_t addr; // Index
|
||||
ICData_t wdata;
|
||||
ICData_t rdata;
|
||||
} ICDataRAM_t;
|
||||
|
||||
interface ICache_i;
|
||||
logic valid;
|
||||
word_t addr;
|
||||
ICIndexL_t index;
|
||||
ICTagL_t tag1;
|
||||
logic hit;
|
||||
ICData_t row;
|
||||
logic rvalid;
|
||||
ICData_t rdata;
|
||||
|
||||
modport cache(input valid, addr, output hit, row, input rvalid, rdata);
|
||||
modport mmu(output valid, addr, input hit, row, output rvalid, rdata);
|
||||
modport cache(input valid,
|
||||
input index, tag1,
|
||||
output hit, row,
|
||||
input rvalid, rdata);
|
||||
modport mmu(output valid,
|
||||
output index, tag1,
|
||||
input hit, row,
|
||||
output rvalid, rdata);
|
||||
endinterface //ICache_i
|
||||
|
||||
`endif
|
||||
|
Loading…
Reference in New Issue
Block a user