diff --git a/src/AXI/AXI.sv b/src/AXI/AXI.sv index f3cac84..597a306 100644 --- a/src/AXI/AXI.sv +++ b/src/AXI/AXI.sv @@ -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; + inst.rdata = AXIRead.AXIReadData.rdata; + rdata.rdata = AXIRead.AXIReadData.rdata; - 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; - rdata.data_ok = AXIRead.AXIReadData.rlast; - end + 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; + inst.rvalid = 1'b0; + inst.data_ok = 1'b0; end end @@ -55,41 +50,27 @@ module AXI ( // Constants AXIRead.AXIReadAddr.arcache = 4'b0; AXIRead.AXIReadAddr.arlock = 2'b0; - - // 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; + // Burst + AXIRead.AXIReadAddr.arsize = 3'b010; + AXIRead.AXIReadAddr.arburst = 2'b10; // Wrap + 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; - inst.addr_ok = 1'b0; - end else if (inst.req) 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 + 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 = AXIRead.AXIReadData.arready; + inst.addr_ok = 1'b0; end else begin - inst.addr_ok = 1'b0; - rdata.addr_ok = 1'b0; + 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 = AXIRead.AXIReadData.arready; + rdata.addr_ok = 1'b0; end end @@ -99,49 +80,33 @@ module AXI ( // ============================== assign wdata.data_ok = AXIWrite.AXIWriteData.bvalid; - assign wdata.wready = AXIWrite.AXIWriteData.wready; + 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; - end + AXIWrite.AXIWriteAddr.wid = 4'b1; + AXIWrite.AXIWriteAddr.wdata = wdata.wdata; + AXIWrite.AXIWriteAddr.wstrb = wdata.wstrb; + AXIWrite.AXIWriteAddr.wlast = wdata.wlast; + AXIWrite.AXIWriteAddr.wvalid = wdata.wvalid; end - always_comb begin // Constants AXIWrite.AXIWriteAddr.awcache = 4'b0; AXIWrite.AXIWriteAddr.awlock = 2'b0; - - // 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; + // Burst + AXIWrite.AXIWriteAddr.awsize = 3'b010; + AXIWrite.AXIWriteAddr.awburst = 2'b01; // Incr + + 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; + AXIWrite.AXIWriteAddr.awaddr = wdata.addr; + AXIWrite.AXIWriteAddr.awlen = {2'b0, wdata.size}; + wdata.addr_ok = AXIWrite.AXIWriteData.awready; end diff --git a/src/Cache/DCache.sv b/src/Cache/DCache.sv index 9cfbccf..da915df 100644 --- a/src/Cache/DCache.sv +++ b/src/Cache/DCache.sv @@ -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) @@ -161,10 +148,10 @@ module DCache ( // ============================== // Choose Victim - assign victim = tagV[0] == 0 ? 4'b0001 - : tagV[1] == 0 ? 4'b0010 - : tagV[2] == 0 ? 4'b0100 - : tagV[3] == 0 ? 4'b1000 + assign victim = tagV[0] == 0 ? 4'b0001 + : tagV[1] == 0 ? 4'b0010 + : tagV[2] == 0 ? 4'b0100 + : tagV[3] == 0 ? 4'b1000 : nowLRU[0] == 0 & ~tagOut[0].dirty ? 4'b0001 : nowLRU[1] == 0 & ~tagOut[1].dirty ? 4'b0010 : nowLRU[2] == 0 & ~tagOut[2].dirty ? 4'b0100 @@ -178,11 +165,12 @@ module DCache ( assign port.dirt_valid = (state == LOOKUP) & |{tagV & {tagOut[3].dirty, tagOut[2].dirty, tagOut[1].dirty, tagOut[0].dirty} & victim}; assign port.dirt_addr = { - (victim[0] ? tagOut[0].tag : {(32-`DC_TAGL){1'b0}}) - | (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}; + (victim[0] ? tagOut[0].tag : {(32-`DC_TAGL){1'b0}}) + | (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}}), + 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,35 +202,35 @@ module DCache ( // ============================== mux2 #(`DC_TAGL-`DC_INDEXL) index_mux ( - index, - port.addr[`DC_TAGL-1:`DC_INDEXL], + index1, + port.index, en1, baddr ); // 地址 - assign TagRAM0.addr = baddr; - assign TagRAM1.addr = baddr; - assign TagRAM2.addr = baddr; - assign TagRAM3.addr = baddr; + assign TagRAM0.addr = baddr; + assign TagRAM1.addr = baddr; + assign TagRAM2.addr = baddr; + assign TagRAM3.addr = baddr; assign DataRAM0.addr = baddr; assign DataRAM1.addr = baddr; 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; diff --git a/src/Cache/ICache.sv b/src/Cache/ICache.sv index 77caf82..0a1acfb 100644 --- a/src/Cache/ICache.sv +++ b/src/Cache/ICache.sv @@ -4,7 +4,8 @@ `include "AXI.svh" module ICache ( - input clk, rst, + input clk, + input rst, ICache_i.cache port ); @@ -13,59 +14,70 @@ module ICache ( // ============================== // Four way assoc bram controller: - ICTagRAM_t TagRAM0, TagRAM1, TagRAM2, TagRAM3; + ICTagRAM_t TagRAM0, TagRAM1, TagRAM2, TagRAM3; ICDataRAM_t DataRAM0, DataRAM1, DataRAM2, DataRAM3; logic [3:0] LRU[64]; logic [3:0] nextLRU; logic [3:0] nowLRU; - ICTag_t tagOut[4]; - ICData_t dataOut[4]; + ICTag_t tagOut[4]; + 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 hit; logic [3:0] hitWay; - ICData_t cacheLine; + ICData_t cacheLine; 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; - logic bwe; + 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) @@ -110,10 +119,10 @@ module ICache ( // ============================== // Choose Victim - assign victim = tagV[0] == 0 ? 4'b0001 : - tagV[1] == 0 ? 4'b0010 : - tagV[2] == 0 ? 4'b0100 : - tagV[3] == 0 ? 4'b1000 : + assign victim = tagV[0] == 0 ? 4'b0001 : + tagV[1] == 0 ? 4'b0010 : + tagV[2] == 0 ? 4'b0100 : + tagV[3] == 0 ? 4'b1000 : nowLRU[0] == 0 ? 4'b0001 : nowLRU[1] == 0 ? 4'b0010 : nowLRU[2] == 0 ? 4'b0100 : @@ -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 diff --git a/src/MMU/MMU.sv b/src/MMU/MMU.sv index 91da026..f85e49a 100644 --- a/src/MMU/MMU.sv +++ b/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 [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) + .K0 (K0), + .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 diff --git a/src/MMU/TLB.sv b/src/MMU/TLB.sv index c64865e..1a490e7 100644 --- a/src/MMU/TLB.sv +++ b/src/MMU/TLB.sv @@ -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 diff --git a/src/include/DCache.svh b/src/include/DCache.svh index 362324e..8d42f20 100644 --- a/src/include/DCache.svh +++ b/src/include/DCache.svh @@ -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; - logic dirty; - logic valid; + 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 - DCTag_t wdata; - DCTag_t rdata; + logic wen; + 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 - DCData_t wdata; - DCData_t rdata; + logic wen; + 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,12 +50,16 @@ 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, - input hit, dirt_valid, dirt_addr, dirt_data, row + output valid, + output index, tag1, sel1, + output rvalid, rdata, wvalid, wdata, wstrb, + input hit, dirt_valid, dirt_addr, dirt_data, row ); endinterface //DCache_i diff --git a/src/include/ICache.svh b/src/include/ICache.svh index 50a2511..4503430 100644 --- a/src/include/ICache.svh +++ b/src/include/ICache.svh @@ -9,36 +9,46 @@ `define IC_TAG_LENGTH (32-`IC_TAGL+1) // Tag + Valid `define IC_DATA_LENGTH 256 // 32Bytes -typedef struct packed { - logic [32-`IC_TAGL-1:0] tag; - logic valid; -} ICTag_t; -typedef logic [`IC_DATA_LENGTH-1:0] ICData_t; +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 wen; - logic [`IC_TAGL-`IC_INDEXL-1:0] addr; // Index - ICTag_t wdata; - ICTag_t rdata; + ICTagL_t tag; + logic valid; +} ICTag_t; + +typedef struct packed { + logic wen; + 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 - ICData_t wdata; - ICData_t rdata; + logic wen; + ICIndexL_t addr; // Index + ICData_t wdata; + ICData_t rdata; } ICDataRAM_t; interface ICache_i; - logic valid; - word_t addr; - logic hit; - ICData_t row; - logic rvalid; - ICData_t rdata; + logic valid; + 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