From f89c1d91dcdf3ff0492bd931573fcb62003b522a Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 4 Jan 2022 23:52:42 -0600 Subject: [PATCH] Renamed most signals inside cache.sv so they are agnostic to i or d. --- pipelined/src/cache/cache.sv | 69 +++--- pipelined/src/cache/cachefsm.sv | 398 ++++++++++++++++++++++++++++++++ pipelined/src/ifu/ifu.sv | 32 +-- pipelined/src/lsu/lsu.sv | 12 +- 4 files changed, 455 insertions(+), 56 deletions(-) create mode 100644 pipelined/src/cache/cachefsm.sv diff --git a/pipelined/src/cache/cache.sv b/pipelined/src/cache/cache.sv index f9b6da29..004a3677 100644 --- a/pipelined/src/cache/cache.sv +++ b/pipelined/src/cache/cache.sv @@ -34,34 +34,34 @@ module cache #(parameter integer LINELEN, input logic CPUBusy, // cpu side - input logic [1:0] LsuRWM, - input logic [1:0] LsuAtomicM, - input logic FlushDCacheM, + input logic [1:0] RW, + input logic [1:0] Atomic, + input logic FlushCache, input logic [11:0] LsuAdrE, // virtual address, but we only use the lower 12 bits. input logic [`PA_BITS-1:0] LsuPAdrM, // physical address input logic [11:0] PreLsuPAdrM, // physical or virtual address - input logic [`XLEN-1:0] FinalWriteDataM, - output logic [`XLEN-1:0] ReadDataWordM, - output logic DCacheCommittedM, + input logic [`XLEN-1:0] FinalWriteData, + output logic [`XLEN-1:0] ReadDataWord, + output logic CacheCommitted, // Bus fsm interface input logic IgnoreRequest, - output logic DCacheFetchLine, - output logic DCacheWriteLine, + output logic CacheFetchLine, + output logic CacheWriteLine, - input logic DCacheBusAck, - output logic [`PA_BITS-1:0] DCacheBusAdr, + input logic CacheBusAck, + output logic [`PA_BITS-1:0] CacheBusAdr, - input logic [LINELEN-1:0] DCacheMemWriteData, - output logic [`XLEN-1:0] ReadDataLineSetsM [(LINELEN/`XLEN)-1:0], + input logic [LINELEN-1:0] CacheMemWriteData, + output logic [`XLEN-1:0] ReadDataLineSets [(LINELEN/`XLEN)-1:0], - output logic DCacheStall, + output logic CacheStall, // to performance counters - output logic DCacheMiss, - output logic DCacheAccess, - input logic InvalidateICacheM + output logic CacheMiss, + output logic CacheAccess, + input logic InvalidateCacheM ); @@ -141,7 +141,7 @@ module cache #(parameter integer LINELEN, .VictimWay, .FlushWay, .SelFlush, .ReadDataLineWayMasked, .WayHit, .VictimDirtyWay, .VictimTagWay, - .InvalidateAll(InvalidateICacheM)); + .InvalidateAll(InvalidateCacheM)); generate if(NUMWAYS > 1) begin:vict @@ -175,10 +175,10 @@ module cache #(parameter integer LINELEN, generate if(DCACHE == 1) begin for (index = 0; index < WORDSPERLINE; index++) begin:readdatalinesetsmux - assign ReadDataLineSetsM[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)]; + assign ReadDataLineSets[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)]; end // variable input mux - assign ReadDataWordM = ReadDataLineSetsM[LsuPAdrM[LOGWPL + LOGXLENBYTES - 1 : LOGXLENBYTES]]; + assign ReadDataWord = ReadDataLineSets[LsuPAdrM[LOGWPL + LOGXLENBYTES - 1 : LOGXLENBYTES]]; end else begin logic [31:0] ReadLineSetsF [LINELEN/16-1:0]; @@ -190,9 +190,9 @@ module cache #(parameter integer LINELEN, assign FinalInstrRawF = ReadLineSetsF[LsuPAdrM[$clog2(LINELEN / 32) + 1 : 1]]; if (`XLEN == 64) begin - assign ReadDataWordM = {32'b0, FinalInstrRawF}; + assign ReadDataWord = {32'b0, FinalInstrRawF}; end else begin - assign ReadDataWordM = FinalInstrRawF; + assign ReadDataWord = FinalInstrRawF; end end @@ -216,8 +216,8 @@ module cache #(parameter integer LINELEN, - mux2 #(LINELEN) WriteDataMux(.d0({WORDSPERLINE{FinalWriteDataM}}), - .d1(DCacheMemWriteData), + mux2 #(LINELEN) WriteDataMux(.d0({WORDSPERLINE{FinalWriteData}}), + .d1(CacheMemWriteData), .s(SRAMLineWriteEnableM), .y(SRAMWriteData)); @@ -226,7 +226,7 @@ module cache #(parameter integer LINELEN, .d1({VictimTag, LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}), .d2({VictimTag, FlushAdrQ, {{OFFSETLEN}{1'b0}}}), .s({SelFlush, SelEvict}), - .y(DCacheBusAdr)); + .y(CacheBusAdr)); // flush address and way generation. @@ -261,20 +261,21 @@ module cache #(parameter integer LINELEN, assign FlushAdrFlag = FlushAdr == FlushAdrThreshold[INDEXLEN-1:0] & FlushWay[NUMWAYS-1]; // controller + // *** fixme logic CacheableM; assign CacheableM = 1; - // *** fixme - dcachefsm dcachefsm(.clk, .reset, .DCacheFetchLine, .DCacheWriteLine, .DCacheBusAck, - .LsuRWM, .LsuAtomicM, .CPUBusy, .CacheableM, .IgnoreRequest, - .CacheHit, .VictimDirty, .DCacheStall, .DCacheCommittedM, - .DCacheMiss, .DCacheAccess, .SelAdrM, .SetValid, - .ClearValid, .SetDirty, .ClearDirty, .SRAMWordWriteEnableM, - .SRAMLineWriteEnableM, .SelEvict, .SelFlush, - .FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst, - .FlushWayCntRst, .FlushAdrFlag, .FlushDCacheM, - .VDWriteEnable, .LRUWriteEn); + + cachefsm cachefsm(.clk, .reset, .CacheFetchLine, .CacheWriteLine, .CacheBusAck, + .RW, .Atomic, .CPUBusy, .CacheableM, .IgnoreRequest, + .CacheHit, .VictimDirty, .CacheStall, .CacheCommitted, + .CacheMiss, .CacheAccess, .SelAdrM, .SetValid, + .ClearValid, .SetDirty, .ClearDirty, .SRAMWordWriteEnableM, + .SRAMLineWriteEnableM, .SelEvict, .SelFlush, + .FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst, + .FlushWayCntRst, .FlushAdrFlag, .FlushCache, + .VDWriteEnable, .LRUWriteEn); endmodule // dcache diff --git a/pipelined/src/cache/cachefsm.sv b/pipelined/src/cache/cachefsm.sv new file mode 100644 index 00000000..77b5efb0 --- /dev/null +++ b/pipelined/src/cache/cachefsm.sv @@ -0,0 +1,398 @@ +/////////////////////////////////////////// +// dcache (data cache) fsm +// +// Written: ross1728@gmail.com August 25, 2021 +// Implements the L1 data cache fsm +// +// Purpose: Controller for the dcache fsm +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module cachefsm + (input logic clk, + input logic reset, + // inputs from IEU + input logic [1:0] RW, + input logic [1:0] Atomic, + input logic FlushCache, + // hazard inputs + input logic CPUBusy, + input logic CacheableM, + // interlock fsm + input logic IgnoreRequest, + // Bus inputs + input logic CacheBusAck, + // dcache internals + input logic CacheHit, + input logic VictimDirty, + input logic FlushAdrFlag, + + // hazard outputs + output logic CacheStall, + // counter outputs + output logic CacheMiss, + output logic CacheAccess, + // Bus outputs + output logic CacheCommitted, + output logic CacheWriteLine, + output logic CacheFetchLine, + + // dcache internals + output logic [1:0] SelAdrM, + output logic SetValid, + output logic ClearValid, + output logic SetDirty, + output logic ClearDirty, + output logic SRAMWordWriteEnableM, + output logic SRAMLineWriteEnableM, + output logic SelEvict, + output logic LRUWriteEn, + output logic SelFlush, + output logic FlushAdrCntEn, + output logic FlushWayCntEn, + output logic FlushAdrCntRst, + output logic FlushWayCntRst, + output logic VDWriteEnable + + ); + + logic AnyCPUReqM; + + typedef enum {STATE_READY, + + STATE_MISS_FETCH_WDV, + STATE_MISS_FETCH_DONE, + STATE_MISS_EVICT_DIRTY, + STATE_MISS_WRITE_CACHE_LINE, + STATE_MISS_READ_WORD, + STATE_MISS_READ_WORD_DELAY, + STATE_MISS_WRITE_WORD, + + STATE_CPU_BUSY, + STATE_CPU_BUSY_FINISH_AMO, + + STATE_FLUSH, + STATE_FLUSH_WRITE_BACK, + STATE_FLUSH_CLEAR_DIRTY} statetype; + + (* mark_debug = "true" *) statetype CurrState, NextState; + + assign AnyCPUReqM = |RW | (|Atomic); + + // outputs for the performance counters. + assign CacheAccess = AnyCPUReqM & CacheableM & CurrState == STATE_READY; + assign CacheMiss = CacheAccess & CacheableM & ~CacheHit; + + always_ff @(posedge clk) + if (reset) CurrState <= #1 STATE_READY; + else CurrState <= #1 NextState; + + // next state logic and some state ouputs. + always_comb begin + CacheStall = 1'b0; + SelAdrM = 2'b00; + SetValid = 1'b0; + ClearValid = 1'b0; + SetDirty = 1'b0; + ClearDirty = 1'b0; + SRAMWordWriteEnableM = 1'b0; + SRAMLineWriteEnableM = 1'b0; + SelEvict = 1'b0; + LRUWriteEn = 1'b0; + SelFlush = 1'b0; + FlushAdrCntEn = 1'b0; + FlushWayCntEn = 1'b0; + FlushAdrCntRst = 1'b0; + FlushWayCntRst = 1'b0; + VDWriteEnable = 1'b0; + NextState = STATE_READY; + CacheFetchLine = 1'b0; + CacheWriteLine = 1'b0; + + case (CurrState) + STATE_READY: begin + + CacheStall = 1'b0; + SelAdrM = 2'b00; + SRAMWordWriteEnableM = 1'b0; + SetDirty = 1'b0; + LRUWriteEn = 1'b0; + + // TLB Miss + if(IgnoreRequest) begin + // the LSU arbiter has not yet selected the PTW. + // The CPU needs to be stalled until that happens. + // If we set CacheStall for 1 cycle before going to + // PTW ready the CPU will stall. + // The page table walker asserts it's control 1 cycle + // after the TLBs miss. + SelAdrM = 2'b01; + NextState = STATE_READY; + end + + // Flush dcache to next level of memory + else if(FlushCache) begin + NextState = STATE_FLUSH; + CacheStall = 1'b1; + SelAdrM = 2'b10; + FlushAdrCntRst = 1'b1; + FlushWayCntRst = 1'b1; + end + + // amo hit + else if(Atomic[1] & (&RW) & CacheableM & CacheHit) begin + SelAdrM = 2'b01; + CacheStall = 1'b0; + + if(CPUBusy) begin + NextState = STATE_CPU_BUSY_FINISH_AMO; + SelAdrM = 2'b01; + end + else begin + SRAMWordWriteEnableM = 1'b1; + SetDirty = 1'b1; + LRUWriteEn = 1'b1; + NextState = STATE_READY; + end + end + // read hit valid cached + else if(RW[1] & CacheableM & CacheHit) begin + CacheStall = 1'b0; + LRUWriteEn = 1'b1; + + if(CPUBusy) begin + NextState = STATE_CPU_BUSY; + SelAdrM = 2'b01; + end + else begin + NextState = STATE_READY; + end + end + // write hit valid cached + else if (RW[0] & CacheableM & CacheHit) begin + SelAdrM = 2'b01; + CacheStall = 1'b0; + SRAMWordWriteEnableM = 1'b1; + SetDirty = 1'b1; + LRUWriteEn = 1'b1; + + if(CPUBusy) begin + NextState = STATE_CPU_BUSY; + SelAdrM = 2'b01; + end + else begin + NextState = STATE_READY; + end + end + // read or write miss valid cached + else if((|RW) & CacheableM & ~CacheHit) begin + NextState = STATE_MISS_FETCH_WDV; + CacheStall = 1'b1; + CacheFetchLine = 1'b1; + end + else NextState = STATE_READY; + end + + STATE_MISS_FETCH_WDV: begin + CacheStall = 1'b1; + SelAdrM = 2'b01; + + if (CacheBusAck) begin + NextState = STATE_MISS_FETCH_DONE; + end else begin + NextState = STATE_MISS_FETCH_WDV; + end + end + + STATE_MISS_FETCH_DONE: begin + CacheStall = 1'b1; + SelAdrM = 2'b01; + if(VictimDirty) begin + NextState = STATE_MISS_EVICT_DIRTY; + CacheWriteLine = 1'b1; + end else begin + NextState = STATE_MISS_WRITE_CACHE_LINE; + end + end + + STATE_MISS_WRITE_CACHE_LINE: begin + SRAMLineWriteEnableM = 1'b1; + CacheStall = 1'b1; + NextState = STATE_MISS_READ_WORD; + SelAdrM = 2'b01; + SetValid = 1'b1; + ClearDirty = 1'b1; + //LRUWriteEn = 1'b1; // DO not update LRU on SRAM fetch update. Wait for subsequent read/write + end + + STATE_MISS_READ_WORD: begin + SelAdrM = 2'b01; + CacheStall = 1'b1; + if (RW[0] & ~Atomic[1]) begin // handles stores and amo write. + NextState = STATE_MISS_WRITE_WORD; + end else begin + NextState = STATE_MISS_READ_WORD_DELAY; + // delay state is required as the read signal RW[1] is still high when we + // return to the ready state because the cache is stalling the cpu. + end + end + + STATE_MISS_READ_WORD_DELAY: begin + //SelAdrM = 2'b01; + SRAMWordWriteEnableM = 1'b0; + SetDirty = 1'b0; + LRUWriteEn = 1'b0; + if(&RW & Atomic[1]) begin // amo write + SelAdrM = 2'b01; + if(CPUBusy) begin + NextState = STATE_CPU_BUSY_FINISH_AMO; + end + else begin + SRAMWordWriteEnableM = 1'b1; + SetDirty = 1'b1; + LRUWriteEn = 1'b1; + NextState = STATE_READY; + end + end else begin + LRUWriteEn = 1'b1; + if(CPUBusy) begin + NextState = STATE_CPU_BUSY; + SelAdrM = 2'b01; + end + else begin + NextState = STATE_READY; + end + end + end + + STATE_MISS_WRITE_WORD: begin + SRAMWordWriteEnableM = 1'b1; + SetDirty = 1'b1; + SelAdrM = 2'b01; + LRUWriteEn = 1'b1; + if(CPUBusy) begin + NextState = STATE_CPU_BUSY; + SelAdrM = 2'b01; + end + else begin + NextState = STATE_READY; + end + end + + STATE_MISS_EVICT_DIRTY: begin + CacheStall = 1'b1; + SelAdrM = 2'b01; + SelEvict = 1'b1; + if(CacheBusAck) begin + NextState = STATE_MISS_WRITE_CACHE_LINE; + end else begin + NextState = STATE_MISS_EVICT_DIRTY; + end + end + + + STATE_CPU_BUSY: begin + SelAdrM = 2'b00; + if(CPUBusy) begin + NextState = STATE_CPU_BUSY; + SelAdrM = 2'b01; + end + else begin + NextState = STATE_READY; + end + end + + STATE_CPU_BUSY_FINISH_AMO: begin + SelAdrM = 2'b01; + SRAMWordWriteEnableM = 1'b0; + SetDirty = 1'b0; + LRUWriteEn = 1'b0; + if(CPUBusy) begin + NextState = STATE_CPU_BUSY_FINISH_AMO; + end + else begin + SRAMWordWriteEnableM = 1'b1; + SetDirty = 1'b1; + LRUWriteEn = 1'b1; + NextState = STATE_READY; + end + end + + STATE_FLUSH: begin + CacheStall = 1'b1; + SelAdrM = 2'b10; + SelFlush = 1'b1; + FlushAdrCntEn = 1'b1; + FlushWayCntEn = 1'b1; + if(VictimDirty) begin + NextState = STATE_FLUSH_WRITE_BACK; + FlushAdrCntEn = 1'b0; + FlushWayCntEn = 1'b0; + CacheWriteLine = 1'b1; + end else if (FlushAdrFlag) begin + NextState = STATE_READY; + CacheStall = 1'b0; + FlushAdrCntEn = 1'b0; + FlushWayCntEn = 1'b0; + end else begin + NextState = STATE_FLUSH; + end + end + + STATE_FLUSH_WRITE_BACK: begin + CacheStall = 1'b1; + SelAdrM = 2'b10; + SelFlush = 1'b1; + if(CacheBusAck) begin + NextState = STATE_FLUSH_CLEAR_DIRTY; + end else begin + NextState = STATE_FLUSH_WRITE_BACK; + end + end + + STATE_FLUSH_CLEAR_DIRTY: begin + CacheStall = 1'b1; + ClearDirty = 1'b1; + VDWriteEnable = 1'b1; + SelFlush = 1'b1; + SelAdrM = 2'b10; + FlushAdrCntEn = 1'b0; + FlushWayCntEn = 1'b0; + if(FlushAdrFlag) begin + NextState = STATE_READY; + CacheStall = 1'b0; + SelAdrM = 2'b00; + end else begin + NextState = STATE_FLUSH; + FlushAdrCntEn = 1'b1; + FlushWayCntEn = 1'b1; + end + end + + default: begin + NextState = STATE_READY; + end + endcase + end + + assign CacheCommitted = CurrState != STATE_READY; + +endmodule // cachefsm + diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index c4e261f9..c77f6b40 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -262,22 +262,22 @@ module ifu ( cache #(.LINELEN(`ICACHE_LINELENINBITS), .NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), .NUMWAYS(`ICACHE_NUMWAYS), .DCACHE(0)) - icache(.clk, .reset, .CPUBusy, .IgnoreRequest, .DCacheMemWriteData(ICacheMemWriteData) , .DCacheBusAck(ICacheBusAck), - .DCacheBusAdr(ICacheBusAdr), .DCacheStall(ICacheStallF), .ReadDataWordM(FinalInstrRawF_FIXME), - .DCacheFetchLine(ICacheFetchLine), - .DCacheWriteLine(), - .ReadDataLineSetsM(), - .DCacheMiss(), - .DCacheAccess(), - .FinalWriteDataM('0), - .LsuRWM(IfuRWF), //aways read - .LsuAtomicM(2'b00), - .FlushDCacheM(1'b0), - .LsuAdrE(PCNextFMux), - .LsuPAdrM(PCPF), - .PreLsuPAdrM(PCFMux[11:0]), - .DCacheCommittedM(), - .InvalidateICacheM); + icache(.clk, .reset, .CPUBusy, .IgnoreRequest, .CacheMemWriteData(ICacheMemWriteData) , .CacheBusAck(ICacheBusAck), + .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), .ReadDataWord(FinalInstrRawF_FIXME), + .CacheFetchLine(ICacheFetchLine), + .CacheWriteLine(), + .ReadDataLineSets(), + .CacheMiss(), + .CacheAccess(), + .FinalWriteData('0), + .RW(IfuRWF), //aways read + .Atomic(2'b00), + .FlushCache(1'b0), + .LsuAdrE(PCNextFMux), // fixme + .LsuPAdrM(PCPF), // fixme + .PreLsuPAdrM(PCFMux[11:0]), //fixme + .CacheCommitted(), + .InvalidateCacheM(InvalidateICacheM)); assign FinalInstrRawF = FinalInstrRawF_FIXME[31:0]; diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index 005db88e..8284a8aa 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -309,13 +309,13 @@ module lsu cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), .NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1)) dcache(.clk, .reset, .CPUBusy, - .LsuRWM(CacheableM ? LsuRWM : 2'b00), .FlushDCacheM, .LsuAtomicM(CacheableM ? LsuAtomicM : 2'b00), + .RW(CacheableM ? LsuRWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LsuAtomicM : 2'b00), .LsuAdrE, .LsuPAdrM, .PreLsuPAdrM(PreLsuPAdrM[11:0]), // still don't like this name PreLsuPAdrM, not always physical - .FinalWriteDataM, .ReadDataWordM, .DCacheStall, - .DCacheMiss, .DCacheAccess, - .IgnoreRequest, .DCacheCommittedM, - .DCacheBusAdr, .ReadDataLineSetsM, .DCacheMemWriteData, - .DCacheFetchLine, .DCacheWriteLine,.DCacheBusAck, .InvalidateICacheM(1'b0)); + .FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), .CacheStall(DCacheStall), + .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess), + .IgnoreRequest, .CacheCommitted(DCacheCommittedM), + .CacheBusAdr(DCacheBusAdr), .ReadDataLineSets(ReadDataLineSetsM), .CacheMemWriteData(DCacheMemWriteData), + .CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0)); end else begin : passthrough assign ReadDataWordM = 0; assign DCacheStall = 0;