diff --git a/wally-pipelined/config/rv32ic/wally-config.vh b/wally-pipelined/config/rv32ic/wally-config.vh index e4e0bc480..ade57a71a 100644 --- a/wally-pipelined/config/rv32ic/wally-config.vh +++ b/wally-pipelined/config/rv32ic/wally-config.vh @@ -50,7 +50,7 @@ `define UARCH_SUPERSCALR 0 `define UARCH_SINGLECYCLE 0 `define MEM_DTIM 1 -`define MEM_DCACHE 1 +`define MEM_DCACHE 0 `define MEM_IROM 1 `define MEM_ICACHE 1 `define MEM_VIRTMEM 0 diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index eda0490b7..208056d3b 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -218,7 +218,7 @@ module ifu ( assign LocalIfuBusAdr = SelUncachedAdr ? PCPFmmu : ICacheBusAdr; assign IfuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIfuBusAdr; - busfsm #(WordCountThreshold, LOGWPL) + busfsm #(WordCountThreshold, LOGWPL, `MEM_ICACHE) busfm(.clk, .reset, .IgnoreRequest, .LsuRWM(2'b10), .DCacheFetchLine(ICacheFetchLine), .DCacheWriteLine(1'b0), .LsuBusAck(IfuBusAck), diff --git a/wally-pipelined/src/lsu/busfsm.sv b/wally-pipelined/src/lsu/busfsm.sv index 31dc603c3..6f8a39215 100644 --- a/wally-pipelined/src/lsu/busfsm.sv +++ b/wally-pipelined/src/lsu/busfsm.sv @@ -27,7 +27,7 @@ module busfsm #(parameter integer WordCountThreshold, - parameter integer LOGWPL) + parameter integer LOGWPL, parameter logic CacheEnabled ) (input logic clk, input logic reset, @@ -55,7 +55,8 @@ module busfsm #(parameter integer WordCountThreshold, logic CntReset; logic WordCountFlag; logic [LOGWPL-1:0] NextWordCount; - + logic UnCachedAccess; + typedef enum {STATE_BUS_READY, STATE_BUS_FETCH, @@ -81,6 +82,8 @@ module busfsm #(parameter integer WordCountThreshold, assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]); assign CntEn = PreCntEn & LsuBusAck; + assign UnCachedAccess = ~CacheEnabled | ~CacheableM; + always_ff @(posedge clk) if (reset) BusCurrState <= #1 STATE_BUS_READY; else BusCurrState <= #1 BusNextState; @@ -88,8 +91,8 @@ module busfsm #(parameter integer WordCountThreshold, always_comb begin case(BusCurrState) STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY; - else if(LsuRWM[0] & (~CacheableM | ~`MEM_DCACHE)) BusNextState = STATE_BUS_UNCACHED_WRITE; - else if(LsuRWM[1] & (~CacheableM | ~`MEM_DCACHE)) BusNextState = STATE_BUS_UNCACHED_READ; + else if(LsuRWM[0] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_WRITE; + else if(LsuRWM[1] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_READ; else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH; else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE; else BusNextState = STATE_BUS_READY; @@ -113,27 +116,27 @@ module busfsm #(parameter integer WordCountThreshold, assign CntReset = BusCurrState == STATE_BUS_READY; - assign BusStall = (BusCurrState == STATE_BUS_READY & ~IgnoreRequest & ((~CacheableM & (|LsuRWM)) | DCacheFetchLine | DCacheWriteLine)) | + assign BusStall = (BusCurrState == STATE_BUS_READY & ~IgnoreRequest & ((UnCachedAccess & (|LsuRWM)) | DCacheFetchLine | DCacheWriteLine)) | (BusCurrState == STATE_BUS_UNCACHED_WRITE) | (BusCurrState == STATE_BUS_UNCACHED_READ) | (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_WRITE); assign PreCntEn = BusCurrState == STATE_BUS_FETCH | BusCurrState == STATE_BUS_WRITE; - assign UnCachedLsuBusWrite = (BusCurrState == STATE_BUS_READY & ~CacheableM & (LsuRWM[0])) | + assign UnCachedLsuBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (LsuRWM[0])) | (BusCurrState == STATE_BUS_UNCACHED_WRITE); assign LsuBusWrite = UnCachedLsuBusWrite | (BusCurrState == STATE_BUS_WRITE); - assign UnCachedLsuBusRead = (BusCurrState == STATE_BUS_READY & ~CacheableM & (|LsuRWM[1])) | + assign UnCachedLsuBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (|LsuRWM[1])) | (BusCurrState == STATE_BUS_UNCACHED_READ); assign LsuBusRead = UnCachedLsuBusRead | (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_READY & DCacheFetchLine); assign DCacheBusAck = (BusCurrState == STATE_BUS_FETCH & WordCountFlag & LsuBusAck) | (BusCurrState == STATE_BUS_WRITE & WordCountFlag & LsuBusAck); assign BusCommittedM = BusCurrState != STATE_BUS_READY; - assign SelUncachedAdr = (BusCurrState == STATE_BUS_READY & (|LsuRWM & ~CacheableM)) | + assign SelUncachedAdr = (BusCurrState == STATE_BUS_READY & (|LsuRWM & UnCachedAccess)) | (BusCurrState == STATE_BUS_UNCACHED_READ | BusCurrState == STATE_BUS_UNCACHED_READ_DONE | BusCurrState == STATE_BUS_UNCACHED_WRITE | BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE) | - ~`MEM_DCACHE; // if no dcache always select uncachedadr. + ~CacheEnabled; // if no dcache always select uncachedadr. endmodule diff --git a/wally-pipelined/src/lsu/lsu.sv b/wally-pipelined/src/lsu/lsu.sv index dfd210636..160fbe8c5 100644 --- a/wally-pipelined/src/lsu/lsu.sv +++ b/wally-pipelined/src/lsu/lsu.sv @@ -273,8 +273,8 @@ module lsu // 2. cache `MEM_DCACHE // 3. wire pass-through - localparam integer WORDSPERLINE = `MEM_DCACHE ? `DCACHE_BLOCKLENINBITS/`XLEN : `XLEN/8; - localparam integer LOGWPL = $clog2(WORDSPERLINE); + localparam integer WORDSPERLINE = `MEM_DCACHE ? `DCACHE_BLOCKLENINBITS/`XLEN : 1; + localparam integer LOGWPL = `MEM_DCACHE ? $clog2(WORDSPERLINE) : 1; localparam integer BLOCKLEN = `MEM_DCACHE ? `DCACHE_BLOCKLENINBITS : `XLEN; localparam integer WordCountThreshold = `MEM_DCACHE ? WORDSPERLINE - 1 : 0; @@ -384,7 +384,7 @@ module lsu else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011; endgenerate; - busfsm #(WordCountThreshold, LOGWPL) + busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE) busfsm(.clk, .reset, .IgnoreRequest, .LsuRWM, .DCacheFetchLine, .DCacheWriteLine, .LsuBusAck, .CPUBusy, .CacheableM, .BusStall, .LsuBusWrite, .LsuBusRead, .DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount); diff --git a/wally-pipelined/testbench/testbench.sv b/wally-pipelined/testbench/testbench.sv index 074f79ea2..cec5d6a0c 100644 --- a/wally-pipelined/testbench/testbench.sv +++ b/wally-pipelined/testbench/testbench.sv @@ -365,68 +365,74 @@ module DCacheFlushFSM input logic start, output logic done); - localparam integer numlines = testbench.dut.hart.lsu.dcache.dcache.NUMLINES; - localparam integer numways = testbench.dut.hart.lsu.dcache.dcache.NUMWAYS; - localparam integer blockbytelen = testbench.dut.hart.lsu.dcache.dcache.BLOCKBYTELEN; - localparam integer numwords = testbench.dut.hart.lsu.dcache.dcache.BLOCKLEN/`XLEN; - localparam integer lognumlines = $clog2(numlines); - localparam integer logblockbytelen = $clog2(blockbytelen); - localparam integer lognumways = $clog2(numways); - localparam integer tagstart = lognumlines + logblockbytelen; - - - - genvar index, way, cacheWord; - logic [`XLEN-1:0] CacheData [numways-1:0] [numlines-1:0] [numwords-1:0]; - logic [`XLEN-1:0] CacheTag [numways-1:0] [numlines-1:0] [numwords-1:0]; - logic CacheValid [numways-1:0] [numlines-1:0] [numwords-1:0]; - logic CacheDirty [numways-1:0] [numlines-1:0] [numwords-1:0]; - logic [`PA_BITS-1:0] CacheAdr [numways-1:0] [numlines-1:0] [numwords-1:0]; genvar adr; logic [`XLEN-1:0] ShadowRAM[`RAM_BASE>>(1+`XLEN/32):(`RAM_RANGE+`RAM_BASE)>>1+(`XLEN/32)]; generate - for(index = 0; index < numlines; index++) begin - for(way = 0; way < numways; way++) begin - for(cacheWord = 0; cacheWord < numwords; cacheWord++) begin - copyShadow #(.tagstart(tagstart), - .logblockbytelen(logblockbytelen)) - copyShadow(.clk, - .start, - .tag(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].CacheTagMem.StoredData[index]), - .valid(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].ValidBits[index]), - .dirty(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].DirtyBits[index]), - .data(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].word[cacheWord].CacheDataMem.StoredData[index]), - .index(index), - .cacheWord(cacheWord), - .CacheData(CacheData[way][index][cacheWord]), - .CacheAdr(CacheAdr[way][index][cacheWord]), - .CacheTag(CacheTag[way][index][cacheWord]), - .CacheValid(CacheValid[way][index][cacheWord]), - .CacheDirty(CacheDirty[way][index][cacheWord])); - end + if(`MEM_DCACHE) begin + localparam integer numlines = testbench.dut.hart.lsu.dcache.dcache.NUMLINES; + localparam integer numways = testbench.dut.hart.lsu.dcache.dcache.NUMWAYS; + localparam integer blockbytelen = testbench.dut.hart.lsu.dcache.dcache.BLOCKBYTELEN; + localparam integer numwords = testbench.dut.hart.lsu.dcache.dcache.BLOCKLEN/`XLEN; + localparam integer lognumlines = $clog2(numlines); + localparam integer logblockbytelen = $clog2(blockbytelen); + localparam integer lognumways = $clog2(numways); + localparam integer tagstart = lognumlines + logblockbytelen; + + + + genvar index, way, cacheWord; + logic [`XLEN-1:0] CacheData [numways-1:0] [numlines-1:0] [numwords-1:0]; + logic [`XLEN-1:0] CacheTag [numways-1:0] [numlines-1:0] [numwords-1:0]; + logic CacheValid [numways-1:0] [numlines-1:0] [numwords-1:0]; + logic CacheDirty [numways-1:0] [numlines-1:0] [numwords-1:0]; + logic [`PA_BITS-1:0] CacheAdr [numways-1:0] [numlines-1:0] [numwords-1:0]; + for(index = 0; index < numlines; index++) begin + for(way = 0; way < numways; way++) begin + for(cacheWord = 0; cacheWord < numwords; cacheWord++) begin + copyShadow #(.tagstart(tagstart), + .logblockbytelen(logblockbytelen)) + copyShadow(.clk, + .start, + .tag(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].CacheTagMem.StoredData[index]), + .valid(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].ValidBits[index]), + .dirty(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].DirtyBits[index]), + .data(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].word[cacheWord].CacheDataMem.StoredData[index]), + .index(index), + .cacheWord(cacheWord), + .CacheData(CacheData[way][index][cacheWord]), + .CacheAdr(CacheAdr[way][index][cacheWord]), + .CacheTag(CacheTag[way][index][cacheWord]), + .CacheValid(CacheValid[way][index][cacheWord]), + .CacheDirty(CacheDirty[way][index][cacheWord])); + end + end end - end + + integer i, j, k; + + always @(posedge clk) begin + if (start) begin #1 + #1 + for(i = 0; i < numlines; i++) begin + for(j = 0; j < numways; j++) begin + for(k = 0; k < numwords; k++) begin + if (CacheValid[j][i][k] && CacheDirty[j][i][k]) begin + ShadowRAM[CacheAdr[j][i][k] >> $clog2(`XLEN/8)] = CacheData[j][i][k]; + end + end + end + end + end + end + + + end endgenerate - integer i, j, k; - - always @(posedge clk) begin - if (start) begin #1 - #1 - for(i = 0; i < numlines; i++) begin - for(j = 0; j < numways; j++) begin - for(k = 0; k < numwords; k++) begin - if (CacheValid[j][i][k] && CacheDirty[j][i][k]) begin - ShadowRAM[CacheAdr[j][i][k] >> $clog2(`XLEN/8)] = CacheData[j][i][k]; - end - end - end - end - end - end + flop #(1) doneReg(.clk(clk), .d(start),