From 81741925aa996c57a9d3f3a4b52513f684fb9121 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 29 Dec 2021 17:12:20 -0600 Subject: [PATCH] Moved LSU Bus interface control path into it's own module. --- wally-pipelined/regression/wave.do | 5 +- wally-pipelined/src/cache/dcache.sv | 3 +- wally-pipelined/src/lsu/busfsm.sv | 136 ++++++++++++++++++++++++++++ wally-pipelined/src/lsu/lsu.sv | 109 +++------------------- 4 files changed, 150 insertions(+), 103 deletions(-) create mode 100644 wally-pipelined/src/lsu/busfsm.sv diff --git a/wally-pipelined/regression/wave.do b/wally-pipelined/regression/wave.do index 8cb29a8d..663a7dea 100644 --- a/wally-pipelined/regression/wave.do +++ b/wally-pipelined/regression/wave.do @@ -213,15 +213,13 @@ add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/ReadDataWordMuxM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/ReadDataM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/WriteDataM add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/SelUncachedAdr -add wave -noupdate -expand -group lsu -expand -group bus -color Gold /testbench/dut/hart/lsu/BusCurrState +add wave -noupdate -expand -group lsu -expand -group bus -color Gold /testbench/dut/hart/lsu/busfsm/BusCurrState add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/BusStall add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusRead add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusWrite add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusAdr add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusAck add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusHWDATA -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/UnCachedLsuBusRead -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/UnCachedLsuBusWrite add wave -noupdate -expand -group lsu -expand -group dcache -color Gold /testbench/dut/hart/lsu/dcache/dcachefsm/CurrState add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/WayHit add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWriteEnableM @@ -474,7 +472,6 @@ add wave -noupdate -group {pc selection} /testbench/dut/hart/ifu/PrivilegedNextP add wave -noupdate -group {pc selection} /testbench/dut/hart/ifu/PrivilegedChangePCM add wave -noupdate /testbench/dut/hart/priv/priv/csr/MEPC_REGW add wave -noupdate /testbench/dut/hart/lsu/LocalLsuBusAdr -add wave -noupdate /testbench/dut/hart/lsu/BasePAdrMaskedM TreeUpdate [SetDefaultTree] WaveRestoreCursors {{Cursor 7} {36865 ns} 1} {{Cursor 5} {49445 ns} 1} {{Cursor 3} {35522 ns} 0} {{Cursor 4} {49574 ns} 1} quietly wave cursor active 3 diff --git a/wally-pipelined/src/cache/dcache.sv b/wally-pipelined/src/cache/dcache.sv index 0023f97c..92b468ce 100644 --- a/wally-pipelined/src/cache/dcache.sv +++ b/wally-pipelined/src/cache/dcache.sv @@ -53,8 +53,6 @@ module dcache output logic [`PA_BITS-1:0] DCacheBusAdr, output logic [`XLEN-1:0] ReadDataBlockSetsM [(`DCACHE_BLOCKLENINBITS/`XLEN)-1:0], - output logic SelFlush, - input logic [`DCACHE_BLOCKLENINBITS-1:0] DCacheMemWriteData, @@ -119,6 +117,7 @@ module dcache logic SelEvict; logic LRUWriteEn; logic [NUMWAYS-1:0] VDWriteEnableWay; + logic SelFlush; // Read Path CPU (IEU) side diff --git a/wally-pipelined/src/lsu/busfsm.sv b/wally-pipelined/src/lsu/busfsm.sv new file mode 100644 index 00000000..8eb70a03 --- /dev/null +++ b/wally-pipelined/src/lsu/busfsm.sv @@ -0,0 +1,136 @@ +/////////////////////////////////////////// +// busfsm.sv +// +// Written: Ross Thompson ross1728@gmail.com +// Modified: +// +// Purpose: Load/Store Unit's interface to BUS +// +// 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 busfsm #(parameter integer WordCountThreshold, + parameter integer LOGWPL) + (input logic clk, + input logic reset, + + input logic IgnoreRequest, + input logic [1:0] LsuRWM, + input logic DCacheFetchLine, + input logic DCacheWriteLine, + input logic LsuBusAck, + input logic CPUBusy, + input logic CacheableM, + + output logic BusStall, + output logic LsuBusWrite, + output logic LsuBusRead, + output logic DCacheBusAck, + output logic BusCommittedM, + output logic SelUncachedAdr, + output logic [LOGWPL-1:0] WordCount); + + + + logic UnCachedLsuBusRead; + logic UnCachedLsuBusWrite; + logic CntEn, PreCntEn; + logic CntReset; + logic WordCountFlag; + logic [LOGWPL-1:0] NextWordCount; + + + typedef enum {STATE_BUS_READY, + STATE_BUS_FETCH, + STATE_BUS_WRITE, + STATE_BUS_UNCACHED_WRITE, + STATE_BUS_UNCACHED_WRITE_DONE, + STATE_BUS_UNCACHED_READ, + STATE_BUS_UNCACHED_READ_DONE, + STATE_BUS_CPU_BUSY} busstatetype; + + (* mark_debug = "true" *) busstatetype BusCurrState, BusNextState; + + + flopenr #(LOGWPL) + WordCountReg(.clk(clk), + .reset(reset | CntReset), + .en(CntEn), + .d(NextWordCount), + .q(WordCount)); + + assign NextWordCount = WordCount + 1'b1; + + assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]); + assign CntEn = PreCntEn & LsuBusAck; + + always_ff @(posedge clk) + if (reset) BusCurrState <= #1 STATE_BUS_READY; + else BusCurrState <= #1 BusNextState; + + always_comb begin + case(BusCurrState) + STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY; + else if(LsuRWM[0] & ~CacheableM) BusNextState = STATE_BUS_UNCACHED_WRITE; + else if(LsuRWM[1] & ~CacheableM) BusNextState = STATE_BUS_UNCACHED_READ; + else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH; + else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE; + STATE_BUS_UNCACHED_WRITE: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE; + else BusNextState = STATE_BUS_UNCACHED_WRITE; + STATE_BUS_UNCACHED_READ: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE; + else BusNextState = STATE_BUS_UNCACHED_READ; + STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; + else BusNextState = STATE_BUS_READY; + STATE_BUS_UNCACHED_READ_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; + else BusNextState = STATE_BUS_READY; + STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; + else BusNextState = STATE_BUS_READY; + STATE_BUS_FETCH: if (WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY; + else BusNextState = STATE_BUS_FETCH; + STATE_BUS_WRITE: if(WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY; + else BusNextState = STATE_BUS_WRITE; + endcase + end + + + assign CntReset = BusCurrState == STATE_BUS_READY; + assign BusStall = (BusCurrState == STATE_BUS_READY & ~IgnoreRequest & ((~CacheableM & (|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])) | + (BusCurrState == STATE_BUS_UNCACHED_WRITE); + assign LsuBusWrite = UnCachedLsuBusWrite | (BusCurrState == STATE_BUS_WRITE); + + assign UnCachedLsuBusRead = (BusCurrState == STATE_BUS_READY & ~CacheableM & (|LsuRWM[1])) | + (BusCurrState == STATE_BUS_UNCACHED_READ); + assign LsuBusRead = UnCachedLsuBusRead | (BusCurrState == STATE_BUS_FETCH); + + 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)) | + (BusCurrState == STATE_BUS_UNCACHED_READ | + BusCurrState == STATE_BUS_UNCACHED_READ_DONE | + BusCurrState == STATE_BUS_UNCACHED_WRITE | + BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE); +endmodule diff --git a/wally-pipelined/src/lsu/lsu.sv b/wally-pipelined/src/lsu/lsu.sv index 74cf0d38..d2207be0 100644 --- a/wally-pipelined/src/lsu/lsu.sv +++ b/wally-pipelined/src/lsu/lsu.sv @@ -342,17 +342,15 @@ module lsu localparam integer WORDSPERLINE = `DCACHE_BLOCKLENINBITS/`XLEN; localparam integer LOGWPL = $clog2(WORDSPERLINE); localparam integer BLOCKLEN = `DCACHE_BLOCKLENINBITS; - localparam integer WordCountThreshold = WORDSPERLINE - 1; + localparam integer BLOCKBYTELEN = BLOCKLEN/8; localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN); // temp - logic WordCountFlag; logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM; (* mark_debug = "true" *) logic [`XLEN-1:0] PreLsuBusHWDATA; - logic SelFlush; logic [`XLEN-1:0] ReadDataWordM; logic [`DCACHE_BLOCKLENINBITS-1:0] DCacheMemWriteData; @@ -360,12 +358,7 @@ module lsu logic [`XLEN-1:0] ReadDataWordMuxM; - logic [LOGWPL-1:0] WordCount, NextWordCount; - logic [`PA_BITS-1:0] BasePAdrMaskedM; - logic [OFFSETLEN-1:0] BasePAdrOffsetM; - logic CntEn, PreCntEn; - logic CntReset; logic [`PA_BITS-1:0] DCacheBusAdr; logic [`XLEN-1:0] ReadDataBlockSetsM [(`DCACHE_BLOCKLENINBITS/`XLEN)-1:0]; @@ -375,8 +368,6 @@ module lsu logic DCacheFetchLine; logic DCacheBusAck; - logic UnCachedLsuBusRead; - logic UnCachedLsuBusWrite; logic SelUncachedAdr; @@ -393,7 +384,6 @@ module lsu .DCacheCommittedM, .DCacheBusAdr, .ReadDataBlockSetsM, - .SelFlush, .DCacheMemWriteData, .DCacheFetchLine, .DCacheWriteLine, @@ -401,6 +391,8 @@ module lsu ); + + // sub word selection for read and writes and optional amo alu. mux2 #(`XLEN) UnCachedDataMux(.d0(ReadDataWordM), .d1(DCacheMemWriteData[`XLEN-1:0]), .s(SelUncachedAdr), @@ -429,15 +421,12 @@ module lsu .HWDATA(FinalWriteDataM)); - generate - if (`XLEN == 32) assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b010; - else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011; - endgenerate; // Bus Side logic // register the fetch data from the next level of memory. // This register should be necessary for timing. There is no register in the uncore or // ahblite controller between the memories and this cache. + logic [LOGWPL-1:0] WordCount; genvar index; generate @@ -452,93 +441,19 @@ module lsu assign LocalLsuBusAdr = SelUncachedAdr ? LsuPAdrM : DCacheBusAdr ; - assign LsuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLsuBusAdr; - assign PreLsuBusHWDATA = ReadDataBlockSetsM[WordCount]; - assign LsuBusHWDATA = SelUncachedAdr ? WriteDataM : PreLsuBusHWDATA; // *** why is this not FinalWriteDataM? which does not work. + generate + if (`XLEN == 32) assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b010; + else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011; + endgenerate; - - - assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]); - assign CntEn = PreCntEn & LsuBusAck; - - flopenr #(LOGWPL) - WordCountReg(.clk(clk), - .reset(reset | CntReset), - .en(CntEn), - .d(NextWordCount), - .q(WordCount)); - - assign NextWordCount = WordCount + 1'b1; - - typedef enum {STATE_BUS_READY, - STATE_BUS_FETCH, - STATE_BUS_WRITE, - STATE_BUS_UNCACHED_WRITE, - STATE_BUS_UNCACHED_WRITE_DONE, - STATE_BUS_UNCACHED_READ, - STATE_BUS_UNCACHED_READ_DONE, - STATE_BUS_CPU_BUSY} busstatetype; - - (* mark_debug = "true" *) busstatetype BusCurrState, BusNextState; - - always_ff @(posedge clk) - if (reset) BusCurrState <= #1 STATE_BUS_READY; - else BusCurrState <= #1 BusNextState; - - always_comb begin - BusNextState = STATE_BUS_READY; - - case(BusCurrState) - STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY; - else if(LsuRWM[0] & ~CacheableM) BusNextState = STATE_BUS_UNCACHED_WRITE; - else if(LsuRWM[1] & ~CacheableM) BusNextState = STATE_BUS_UNCACHED_READ; - else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH; - else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE; - STATE_BUS_UNCACHED_WRITE: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE; - else BusNextState = STATE_BUS_UNCACHED_WRITE; - STATE_BUS_UNCACHED_READ: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE; - else BusNextState = STATE_BUS_UNCACHED_READ; - STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; - else BusNextState = STATE_BUS_READY; - STATE_BUS_UNCACHED_READ_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; - else BusNextState = STATE_BUS_READY; - STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY; - else BusNextState = STATE_BUS_READY; - STATE_BUS_FETCH: if (WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY; - else BusNextState = STATE_BUS_FETCH; - STATE_BUS_WRITE: if(WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY; - else BusNextState = STATE_BUS_WRITE; - endcase - end - - - assign CntReset = BusCurrState == STATE_BUS_READY; - assign BusStall = (BusCurrState == STATE_BUS_READY & ~IgnoreRequest & ((~CacheableM & (|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])) | - (BusCurrState == STATE_BUS_UNCACHED_WRITE); - assign LsuBusWrite = UnCachedLsuBusWrite | (BusCurrState == STATE_BUS_WRITE); - - assign UnCachedLsuBusRead = (BusCurrState == STATE_BUS_READY & ~CacheableM & (|LsuRWM[1])) | - (BusCurrState == STATE_BUS_UNCACHED_READ); - assign LsuBusRead = UnCachedLsuBusRead | (BusCurrState == STATE_BUS_FETCH); - - 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)) | - (BusCurrState == STATE_BUS_UNCACHED_READ | - BusCurrState == STATE_BUS_UNCACHED_READ_DONE | - BusCurrState == STATE_BUS_UNCACHED_WRITE | - BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE); + busfsm #(WordCountThreshold, LOGWPL) + busfsm(.clk, .reset, .IgnoreRequest, .LsuRWM, .DCacheFetchLine, .DCacheWriteLine, + .LsuBusAck, .CPUBusy, .CacheableM, .BusStall, .LsuBusWrite, .LsuBusRead, + .DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount); endmodule