mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Added buscachefsm for system with bus and cache
This commit is contained in:
parent
5340c45dfc
commit
69dff87feb
192
pipelined/src/lsu/buscachefsm.sv
Normal file
192
pipelined/src/lsu/buscachefsm.sv
Normal file
@ -0,0 +1,192 @@
|
||||
///////////////////////////////////////////
|
||||
// busfsm.sv
|
||||
//
|
||||
// Written: Ross Thompson ross1728@gmail.com December 29, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Load/Store Unit's interface to BUS for cache-based system
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// MIT LICENSE
|
||||
// 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 buscachefsm #(parameter integer WordCountThreshold,
|
||||
parameter integer LOGWPL, parameter logic CACHE_ENABLED )
|
||||
(input logic clk,
|
||||
input logic reset,
|
||||
|
||||
input logic IgnoreRequest,
|
||||
input logic [1:0] RW,
|
||||
input logic CacheFetchLine,
|
||||
input logic CacheWriteLine,
|
||||
input logic BusAck,
|
||||
input logic BusInit, // This might be better as LSUBusLock, or to send this using BusAck.
|
||||
input logic CPUBusy,
|
||||
input logic Cacheable,
|
||||
|
||||
output logic BusStall,
|
||||
output logic BusWrite,
|
||||
output logic SelBusWord,
|
||||
output logic BusRead,
|
||||
output logic [2:0] HBURST,
|
||||
output logic BusTransComplete,
|
||||
output logic [1:0] HTRANS,
|
||||
output logic CacheBusAck,
|
||||
output logic BusCommitted,
|
||||
output logic SelUncachedAdr,
|
||||
output logic BufferCaptureEn,
|
||||
output logic [LOGWPL-1:0] WordCount, WordCountDelayed);
|
||||
|
||||
|
||||
|
||||
logic UnCachedBusRead;
|
||||
logic UnCachedBusWrite;
|
||||
logic CntEn, PreCntEn;
|
||||
logic CntReset;
|
||||
logic WordCountFlag;
|
||||
logic [LOGWPL-1:0] NextWordCount;
|
||||
logic UnCachedAccess, UnCachedRW;
|
||||
logic [2:0] LocalBurstType;
|
||||
|
||||
|
||||
typedef enum logic [2:0] {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;
|
||||
|
||||
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
|
||||
|
||||
(* mark_debug = "true" *) busstatetype BusCurrState, BusNextState;
|
||||
|
||||
// Used to send address for address stage of AHB.
|
||||
flopenr #(LOGWPL)
|
||||
WordCountReg(.clk(clk),
|
||||
.reset(reset | CntReset),
|
||||
.en(CntEn),
|
||||
.d(NextWordCount),
|
||||
.q(WordCount));
|
||||
|
||||
// Used to store data from data phase of AHB.
|
||||
flopenr #(LOGWPL)
|
||||
WordCountDelayedReg(.clk(clk),
|
||||
.reset(reset | CntReset),
|
||||
.en(CntEn),
|
||||
.d(WordCount),
|
||||
.q(WordCountDelayed));
|
||||
|
||||
assign NextWordCount = WordCount + 1'b1;
|
||||
|
||||
assign PreCntEn = (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_WRITE);
|
||||
assign WordCountFlag = (WordCountDelayed == WordCountThreshold[LOGWPL-1:0]); // Detect when we are waiting on the final access.
|
||||
assign CntEn = (PreCntEn & BusAck | BusInit) & ~WordCountFlag & ~UnCachedRW; // Want to count when doing cache accesses and we aren't wrapping up.
|
||||
|
||||
assign UnCachedAccess = ~CACHE_ENABLED | ~Cacheable;
|
||||
|
||||
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(RW[0] & UnCachedAccess) BusNextState = STATE_BUS_UNCACHED_WRITE;
|
||||
else if(RW[1] & UnCachedAccess) BusNextState = STATE_BUS_UNCACHED_READ;
|
||||
else if(CacheFetchLine) BusNextState = STATE_BUS_FETCH;
|
||||
else if(CacheWriteLine) BusNextState = STATE_BUS_WRITE;
|
||||
else BusNextState = STATE_BUS_READY;
|
||||
STATE_BUS_UNCACHED_WRITE: if(BusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE;
|
||||
else BusNextState = STATE_BUS_UNCACHED_WRITE;
|
||||
STATE_BUS_UNCACHED_READ: if(BusAck) 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 & BusAck) begin
|
||||
if (CacheFetchLine) BusNextState = STATE_BUS_FETCH;
|
||||
else if (CacheWriteLine) BusNextState = STATE_BUS_WRITE;
|
||||
else BusNextState = STATE_BUS_READY;
|
||||
end else BusNextState = STATE_BUS_FETCH;
|
||||
STATE_BUS_WRITE: if(WordCountFlag & BusAck) begin
|
||||
if (CacheFetchLine) BusNextState = STATE_BUS_FETCH;
|
||||
else if (CacheWriteLine) BusNextState = STATE_BUS_WRITE;
|
||||
else BusNextState = STATE_BUS_READY;
|
||||
end else BusNextState = STATE_BUS_WRITE;
|
||||
default: BusNextState = STATE_BUS_READY;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case(WordCountThreshold)
|
||||
0: LocalBurstType = 3'b000;
|
||||
3: LocalBurstType = 3'b011; // INCR4
|
||||
7: LocalBurstType = 3'b101; // INCR8
|
||||
15: LocalBurstType = 3'b111; // INCR16
|
||||
default: LocalBurstType = 3'b001; // INCR without end.
|
||||
endcase
|
||||
end
|
||||
|
||||
assign HBURST = (UnCachedRW) ? 3'b0 : LocalBurstType; // Don't want to use burst when doing an Uncached Access.
|
||||
assign BusTransComplete = (UnCachedRW) ? BusAck : WordCountFlag & BusAck;
|
||||
// Use SEQ if not doing first word, NONSEQ if doing the first read/write, and IDLE if finishing up.
|
||||
assign HTRANS = (|WordCount) & ~UnCachedRW ? AHB_SEQ : (BusRead | BusWrite) & (~BusTransComplete) ? AHB_NONSEQ : AHB_IDLE;
|
||||
// Reset if we aren't initiating a transaction or if we are finishing a transaction.
|
||||
assign CntReset = BusCurrState == STATE_BUS_READY & ~(CacheFetchLine | CacheWriteLine) | BusTransComplete;
|
||||
|
||||
assign BusStall = (BusCurrState == STATE_BUS_READY & ~IgnoreRequest & ((UnCachedAccess & (|RW)) | CacheFetchLine | CacheWriteLine)) |
|
||||
(BusCurrState == STATE_BUS_UNCACHED_WRITE) |
|
||||
(BusCurrState == STATE_BUS_UNCACHED_READ) |
|
||||
(BusCurrState == STATE_BUS_FETCH) |
|
||||
(BusCurrState == STATE_BUS_WRITE);
|
||||
assign UnCachedBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & RW[0] & ~IgnoreRequest) |
|
||||
(BusCurrState == STATE_BUS_UNCACHED_WRITE);
|
||||
assign BusWrite = UnCachedBusWrite | (BusCurrState == STATE_BUS_WRITE & ~WordCountFlag);
|
||||
assign SelBusWord = (BusCurrState == STATE_BUS_READY & UnCachedAccess & RW[0]) |
|
||||
(BusCurrState == STATE_BUS_UNCACHED_WRITE) |
|
||||
(BusCurrState == STATE_BUS_WRITE);
|
||||
|
||||
assign UnCachedBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & RW[1] & ~IgnoreRequest) |
|
||||
(BusCurrState == STATE_BUS_UNCACHED_READ);
|
||||
assign BusRead = UnCachedBusRead | (BusCurrState == STATE_BUS_FETCH & ~(WordCountFlag)) | (BusCurrState == STATE_BUS_READY & CacheFetchLine);
|
||||
assign BufferCaptureEn = UnCachedBusRead | BusCurrState == STATE_BUS_FETCH;
|
||||
|
||||
// Makes bus only do uncached reads/writes when we actually do uncached reads/writes. Needed because Cacheable is 0 when flushing cache.
|
||||
assign UnCachedRW = UnCachedBusWrite | UnCachedBusRead;
|
||||
|
||||
assign CacheBusAck = (BusCurrState == STATE_BUS_FETCH & WordCountFlag & BusAck) |
|
||||
(BusCurrState == STATE_BUS_WRITE & WordCountFlag & BusAck);
|
||||
assign BusCommitted = BusCurrState != STATE_BUS_READY;
|
||||
assign SelUncachedAdr = (BusCurrState == STATE_BUS_READY & (|RW & UnCachedAccess)) |
|
||||
(BusCurrState == STATE_BUS_UNCACHED_READ |
|
||||
BusCurrState == STATE_BUS_UNCACHED_READ_DONE |
|
||||
BusCurrState == STATE_BUS_UNCACHED_WRITE |
|
||||
BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE) |
|
||||
~CACHE_ENABLED; // if no Cache always select uncachedadr.
|
||||
endmodule
|
@ -88,7 +88,7 @@ module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, CACHE_ENABLED)
|
||||
|
||||
mux2 #(3) sizemux(.d0(`XLEN == 32 ? 3'b010 : 3'b011), .d1(Funct3), .s(SelUncachedAdr), .y(HSIZE));
|
||||
|
||||
busfsm #(WordCountThreshold, LOGWPL, CACHE_ENABLED) busfsm(
|
||||
buscachefsm #(WordCountThreshold, LOGWPL, CACHE_ENABLED) buscachefsm(
|
||||
.clk, .reset, .IgnoreRequest, .RW, .CacheFetchLine, .CacheWriteLine,
|
||||
.BusAck, .BusInit, .CPUBusy, .Cacheable, .BusStall, .BusWrite, .SelBusWord, .BusRead, .BufferCaptureEn,
|
||||
.HBURST, .HTRANS, .BusTransComplete, .CacheBusAck, .BusCommitted, .SelUncachedAdr, .WordCount, .WordCountDelayed);
|
||||
|
@ -4,7 +4,7 @@
|
||||
// Written: Ross Thompson ross1728@gmail.com December 29, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Load/Store Unit's interface to BUS
|
||||
// Purpose: Load/Store Unit's interface to BUS for cacheless system
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user