tlb mmu with cache

simplify AXI
This commit is contained in:
Paul Pan 2021-08-10 21:34:12 +08:00
parent a83967f9b9
commit 94e9b7bcbd
7 changed files with 291 additions and 309 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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