From 7a129c75cd1a85c2c00290f74aeb7eaf0f947063 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 10 Mar 2022 15:48:31 -0600 Subject: [PATCH] Added byte write enables to cache SRAMs. --- pipelined/src/cache/cache.sv | 5 +++-- pipelined/src/cache/cacheway.sv | 9 ++++++--- pipelined/src/cache/sram1p1rw.sv | 19 ++++++++++++++++--- pipelined/src/ifu/ifu.sv | 1 + pipelined/src/lsu/lsu.sv | 6 ++++-- pipelined/src/uncore/subwordwrite.sv | 6 +++++- pipelined/src/uncore/uncore.sv | 2 +- 7 files changed, 36 insertions(+), 12 deletions(-) diff --git a/pipelined/src/cache/cache.sv b/pipelined/src/cache/cache.sv index 0b6184f2..a4b64fed 100644 --- a/pipelined/src/cache/cache.sv +++ b/pipelined/src/cache/cache.sv @@ -41,6 +41,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, DCACHE = 1) ( input logic InvalidateCacheM, input logic [11:0] NextAdr, // virtual address, but we only use the lower 12 bits. input logic [`PA_BITS-1:0] PAdr, // physical address + input logic [(`XLEN-1)/8:0] ByteWEN, input logic [`XLEN-1:0] FinalWriteData, output logic CacheCommitted, output logic CacheStall, @@ -50,7 +51,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, DCACHE = 1) ( output logic save, restore, // lsu control input logic IgnoreRequestTLB, - input logic IgnoreRequestTrapM, + input logic IgnoreRequestTrapM, input logic Cacheable, // Bus fsm interface output logic CacheFetchLine, @@ -114,7 +115,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, DCACHE = 1) ( // Array of cache ways, along with victim, hit, dirty, and read merging logic cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN) CacheWays[NUMWAYS-1:0]( - .clk, .reset, .RAdr, .PAdr, .CacheWriteData, + .clk, .reset, .RAdr, .PAdr, .CacheWriteData, .ByteWEN, .SetValidWay, .ClearValidWay, .SetDirtyWay, .ClearDirtyWay, .SelEvict, .VictimWay, .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .VictimDirtyWay, .VictimTagWay, .Invalidate(InvalidateCacheM)); diff --git a/pipelined/src/cache/cacheway.sv b/pipelined/src/cache/cacheway.sv index d9dfdfff..4a0694e7 100644 --- a/pipelined/src/cache/cacheway.sv +++ b/pipelined/src/cache/cacheway.sv @@ -47,7 +47,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, input logic VictimWay, input logic FlushWay, input logic Invalidate, - + input logic [(`XLEN-1)/8:0] ByteWEN, output logic [LINELEN-1:0] ReadDataLineWay, output logic HitWay, @@ -69,6 +69,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, logic [$clog2(NUMLINES)-1:0] RAdrD; logic [2**LOGWPL-1:0] MemPAdrDecoded; logic [LINELEN/`XLEN-1:0] SelectedWriteWordEn; + logic [(`XLEN-1)/8:0] FinalByteWEN; ///////////////////////////////////////////////////////////////////////////////////////////// // Write Enable demux @@ -77,13 +78,15 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, .bin(PAdr[LOGWPL+LOGXLENBYTES-1:LOGXLENBYTES]), .decoded(MemPAdrDecoded)); // If writing the whole line set all write enables to 1, else only set the correct word. assign SelectedWriteWordEn = SetValidWay ? '1 : SetDirtyWay ? MemPAdrDecoded : '0; // OR-AND + //assign FinalByteWEN = SetValidWay ? '1 : ByteWEN; // OR + assign FinalByteWEN = '1;//SetValidWay ? '1 : ByteWEN; // OR ///////////////////////////////////////////////////////////////////////////////////////////// // Tag Array ///////////////////////////////////////////////////////////////////////////////////////////// sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, - .Adr(RAdr), .ReadData(ReadTag), + .Adr(RAdr), .ReadData(ReadTag), .ByteWEN('1), .CacheWriteData(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .WriteEnable(SetValidWay)); // AND portion of distributed tag multiplexer @@ -102,7 +105,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(`XLEN)) CacheDataMem(.clk, .Adr(RAdr), .ReadData(ReadDataLine[(words+1)*`XLEN-1:words*`XLEN] ), .CacheWriteData(CacheWriteData[(words+1)*`XLEN-1:words*`XLEN]), - .WriteEnable(SelectedWriteWordEn[words])); + .WriteEnable(SelectedWriteWordEn[words]), .ByteWEN(FinalByteWEN)); end // AND portion of distributed read multiplexers diff --git a/pipelined/src/cache/sram1p1rw.sv b/pipelined/src/cache/sram1p1rw.sv index 33f022a8..06581d0c 100644 --- a/pipelined/src/cache/sram1p1rw.sv +++ b/pipelined/src/cache/sram1p1rw.sv @@ -38,18 +38,31 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) ( input logic [$clog2(DEPTH)-1:0] Adr, input logic [WIDTH-1:0] CacheWriteData, input logic WriteEnable, + input logic [(WIDTH-1)/8:0] ByteWEN, output logic [WIDTH-1:0] ReadData); logic [WIDTH-1:0] StoredData[DEPTH-1:0]; logic [$clog2(DEPTH)-1:0] AdrD; logic WriteEnableD; + always_ff @(posedge clk) AdrD <= Adr; + + genvar index; + for(index = 0; index < WIDTH/8; index++) begin always_ff @(posedge clk) begin - AdrD <= Adr; - if (WriteEnable) begin - StoredData[Adr] <= #1 CacheWriteData; + if (WriteEnable & ByteWEN[index]) begin + StoredData[Adr][8*(index+1)-1:8*index] <= #1 CacheWriteData[8*(index+1)-1:8*index]; end end + end + // if not a multiple of 8, MSByte is not 8 bits long. + if(WIDTH%8 != 0) begin + always_ff @(posedge clk) begin + if (WriteEnable & ByteWEN[WIDTH/8]) begin + StoredData[Adr][WIDTH-1:WIDTH-WIDTH%8] <= #1 CacheWriteData[WIDTH-1:WIDTH-WIDTH%8]; + end + end + end assign ReadData = StoredData[AdrD]; endmodule diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index c2df1380..888115f2 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -220,6 +220,7 @@ module ifu ( .CacheWriteLine(), .ReadDataLine(ReadDataLine), .save, .restore, .Cacheable(CacheableF), .CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess), + .ByteWEN('0), .FinalWriteData('0), .RW(2'b10), .Atomic('0), .FlushCache('0), diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index ddf0f77d..71cea191 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -105,7 +105,8 @@ module lsu ( logic LSUBusWriteCrit; logic DataDAPageFaultM; logic [`XLEN-1:0] LSUWriteDataM; - + logic [(`XLEN-1)/8:0] FinalByteWENM; + // *** TO DO: Burst mode, byte write enables to DTIM, cache, exeternal memory, remove subword write from uncore, flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); @@ -234,6 +235,7 @@ module lsu ( .NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1)) dcache( .clk, .reset, .CPUBusy, .save, .restore, .RW(LSURWM), .Atomic(LSUAtomicM), .FlushCache(FlushDCacheM), .NextAdr(LSUAdrE), .PAdr(LSUPAdrM), + .ByteWEN(FinalByteWENM), .FinalWriteData(FinalWriteDataM), .Cacheable(CacheableM), .CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess), .IgnoreRequestTLB, .IgnoreRequestTrapM, .CacheCommitted(DCacheCommittedM), @@ -259,7 +261,7 @@ module lsu ( //assign ReadDataWordMaskedM = ReadDataWordM; // *** this change only works because the i/o devices dont' write bytes other than the ones specific to their address. subwordwrite subwordwrite(.HRDATA(ReadDataWordMaskedM), .HADDRD(LSUPAdrM[2:0]), .HSIZED({LSUFunct3M[2], 1'b0, LSUFunct3M[1:0]}), - .HWDATAIN(FinalAMOWriteDataM), .HWDATA(FinalWriteDataM)); + .HWDATAIN(FinalAMOWriteDataM), .HWDATA(FinalWriteDataM), .ByteWEN(FinalByteWENM)); end else assign FinalWriteDataM = FinalAMOWriteDataM; diff --git a/pipelined/src/uncore/subwordwrite.sv b/pipelined/src/uncore/subwordwrite.sv index f984038b..bfc4684f 100644 --- a/pipelined/src/uncore/subwordwrite.sv +++ b/pipelined/src/uncore/subwordwrite.sv @@ -35,14 +35,17 @@ module subwordwrite ( input logic [2:0] HADDRD, input logic [3:0] HSIZED, input logic [`XLEN-1:0] HWDATAIN, - output logic [`XLEN-1:0] HWDATA + output logic [`XLEN-1:0] HWDATA, + output logic [`XLEN/8-1:0] ByteWEN ); logic [`XLEN-1:0] WriteDataSubwordDuplicated; + if (`XLEN == 64) begin:sww logic [7:0] ByteMaskM; // Compute write mask + assign ByteWEN = ByteMaskM; always_comb case(HSIZED[1:0]) 2'b00: begin ByteMaskM = 8'b00000000; ByteMaskM[HADDRD[2:0]] = 1; end // sb @@ -81,6 +84,7 @@ module subwordwrite ( end else begin:sww // 32-bit logic [3:0] ByteMaskM; // Compute write mask + assign ByteWEN = ByteMaskM; always_comb case(HSIZED[1:0]) 2'b00: begin ByteMaskM = 4'b0000; ByteMaskM[HADDRD[1:0]] = 1; end // sb diff --git a/pipelined/src/uncore/uncore.sv b/pipelined/src/uncore/uncore.sv index f2cd40a2..5968898b 100644 --- a/pipelined/src/uncore/uncore.sv +++ b/pipelined/src/uncore/uncore.sv @@ -95,7 +95,7 @@ module uncore ( subwordwrite sww( .HRDATA, .HADDRD, .HSIZED, - .HWDATAIN, .HWDATA); + .HWDATAIN, .HWDATA, .ByteWEN()); else assign HWDATA = HWDATAIN;